From f3ea8961f1b50175ad659cecc590a5944f99dadf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Skarpsv=C3=A4rd?= <145796632+Code-lab-web@users.noreply.github.com> Date: Tue, 18 Mar 2025 13:42:16 +0000 Subject: [PATCH 1/3] $ git add index.html $ git add . $ git status --- .html | 32 + script.ts | 827 ++++++++++++++++++++ "var source = new EventSource(\"demo_sse.p" | 27 + 3 files changed, 886 insertions(+) create mode 100644 .html create mode 100644 script.ts create mode 100644 "var source = new EventSource(\"demo_sse.p" diff --git a/.html b/.html new file mode 100644 index 0000000..43357dc --- /dev/null +++ b/.html @@ -0,0 +1,32 @@ + + + + +

Count numbers:

+ + + + + + + \ No newline at end of file diff --git a/script.ts b/script.ts new file mode 100644 index 0000000..52e12e3 --- /dev/null +++ b/script.ts @@ -0,0 +1,827 @@ +api.openweathermap.org/data/2.5/forecast?lat={lat}&lon={lon}&appid={} +{ + api.openweathermap.org/data/2.5/forecast?lat=44.34&lon=10.99&appid={} + { + { + "cod": "200", + "message": 0, + "cnt": 40, + "list": [ + { + "dt": 1661871600, + "main": { + "temp": 296.76, + "feels_like": 296.98, + "temp_min": 296.76, + "temp_max": 297.87, + "pressure": 1015, + "sea_level": 1015, + "grnd_level": 933, + "humidity": 69, + "temp_kf": -1.11 + }, + "weather": [ + { + "id": 500, + "main": "Rain", + "description": "light rain", + "icon": "10d" + } + ], + "clouds": { + "all": 100 + }, + "wind": { + "speed": 0.62, + "deg": 349, + "gust": 1.18 + }, + "visibility": 10000, + "pop": 0.32, + "rain": { + "3h": 0.26 + }, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-08-30 15:00:00" + }, + { + "dt": 1661882400, + "main": { + "temp": 295.45, + "feels_like": 295.59, + "temp_min": 292.84, + "temp_max": 295.45, + "pressure": 1015, + "sea_level": 1015, + "grnd_level": 931, + "humidity": 71, + "temp_kf": 2.61 + }, + "weather": [ + { + "id": 500, + "main": "Rain", + "description": "light rain", + "icon": "10n" + } + ], + "clouds": { + "all": 96 + }, + "wind": { + "speed": 1.97, + "deg": 157, + "gust": 3.39 + }, + "visibility": 10000, + "pop": 0.33, + "rain": { + "3h": 0.57 + }, + "sys": { + "pod": "n" + }, + "dt_txt": "2022-08-30 18:00:00" + }, + { + "dt": 1661893200, + "main": { + "temp": 292.46, + "feels_like": 292.54, + "temp_min": 290.31, + "temp_max": 292.46, + "pressure": 1015, + "sea_level": 1015, + "grnd_level": 931, + "humidity": 80, + "temp_kf": 2.15 + }, + "weather": [ + { + "id": 500, + "main": "Rain", + "description": "light rain", + "icon": "10n" + } + ], + "clouds": { + "all": 68 + }, + "wind": { + "speed": 2.66, + "deg": 210, + "gust": 3.58 + }, + "visibility": 10000, + "pop": 0.7, + "rain": { + "3h": 0.49 + }, + "sys": { + "pod": "n" + }, + "dt_txt": "2022-08-30 21:00:00" + }, + .... + { + "dt": 1662292800, + "main": { + "temp": 294.93, + "feels_like": 294.83, + "temp_min": 294.93, + "temp_max": 294.93, + "pressure": 1018, + "sea_level": 1018, + "grnd_level": 935, + "humidity": 64, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 88 + }, + "wind": { + "speed": 1.14, + "deg": 17, + "gust": 1.57 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-09-04 12:00:00" + } + ], + "city": { + "id": 3163858, + "name": "Zocca", + "coord": { + "lat": 44.34, + "lon": 10.99 + }, + "country": "IT", + "population": 4593, + "timezone": 7200, + "sunrise": 1661834187, + "sunset": 1661882248 + } + } + + + Zocca + + IT + 7200 + + + + + + 0 + + + + + + + + ... + + + + + XML format API response fields + { + "main":{ +"temp":306.15, //current temperature +"pressure":1013, +"humidity":44, +"temp_min":30.15, //min current temperature in the city +"temp_max":306.15 //max current temperature in the city +}, + } + } +} +} +"dt":1406080800, +"temp":{ + "day":297.77, //daily averaged temperature + "min":293.52, //daily min temperature + "max":297.77, //daily max temperature + "night":293.52, //night temperature + "eve":297.77, //evening temperature + "morn":297.77}, //morning temperature + { + api.openweathermap.org/data/2.5/forecast?q={city name}&appid={API key} + +api.openweathermap.org/data/2.5/forecast?q={city name},{country code}&appid={API key} + +api.openweathermap.org/data/2.5/forecast?q={city name},{state code},{country code}&appid={API key} + } + api.openweathermap.org/data/2.5/forecast?q=London,us&mode=xml&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?q=München,DE&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?id={city ID}&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?id=524901&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?zip={zip code},{country code}&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?zip=94040,us&appid={API key} +} +api.openweathermap.org/data/2.5/weather?q=London&appid={API key} + + + +{ +"cod": "200", +"message": 0, +"cnt": 40, +"list": [ +{ + "dt": 1647345600, + "main": { + "temp": 287.39, + "feels_like": 286.38, + "temp_min": 286.69, + "temp_max": 287.39, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1018, + "humidity": 58, + "temp_kf": 0.7 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 71 + }, + "wind": { + "speed": 3.08, + "deg": 128, + "gust": 4.3 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-15 12:00:00" +}, +{ + "dt": 1647356400, + "main": { + "temp": 287.09, + "feels_like": 286.13, + "temp_min": 286.5, + "temp_max": 287.09, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1016, + "humidity": 61, + "temp_kf": 0.59 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 81 + }, + "wind": { + "speed": 3.28, + "deg": 168, + "gust": 3.96 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-15 15:00:00" +}, +{ + "dt": 1647367200, + "main": { + "temp": 285.44, + "feels_like": 284.6, + "temp_min": 284.47, + "temp_max": 285.44, + "pressure": 1020, + "sea_level": 1020, + "grnd_level": 1016, + "humidity": 72, + "temp_kf": 0.97 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 90 + }, + "wind": { + "speed": 2.7, + "deg": 183, + "gust": 5.59 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-15 18:00:00" +}, +..... + { + "dt": 1647766800, + "main": { + "temp": 282.42, + "feels_like": 280, + "temp_min": 282.42, + "temp_max": 282.42, + "pressure": 1036, + "sea_level": 1036, + "grnd_level": 1033, + "humidity": 60, + "temp_kf": 0 + }, + "weather": [ + { + "id": 802, + "main": "Clouds", + "description": "scattered clouds", + "icon": "03d" + } + ], + "clouds": { + "all": 39 + }, + "wind": { + "speed": 4.58, + "deg": 83, + "gust": 8.45 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-20 09:00:00" +} +], +"city": { +"id": 2643743, +"name": "London", +"coord": { + "lat": 51.5085, + "lon": -0.1257 +}, +"country": "GB", +"population": 1000000, +"timezone": 0, +"sunrise": 1647324902, +"sunset": 1647367441 +} +} + + + +Zocca + +IT +7200 + + + + + +0 + + + + + + + +... + + + +{ +"main":{ +"temp":306.15, //current temperature +"pressure":1013, +"humidity":44, +"temp_min":30.15, //min current temperature in the city +"temp_max":306.15 //max current temperature in the city +}, + + "dt":1406080800, +"temp":{ + "day":297.77, //daily averaged temperature + "min":293.52, //daily min temperature + "max":297.77, //daily max temperature + "night":293.52, //night temperature + "eve":297.77, //evening temperature + "morn":297.77}, //morning temperature + +} +api.openweathermap.org/data/2.5/forecast?q={city name}&appid={API key} + +api.openweathermap.org/data/2.5/forecast?q={city name},{country code}&appid={API key} + +api.openweathermap.org/data/2.5/forecast?q={city name},{state code},{country code}&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?q=London,us&mode=xml&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?q=München,DE&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?id={city ID}&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?id=524901&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?zip={zip code},{country code}&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?zip=94040,us&appid={API key} +} +api.openweathermap.org/data/2.5/weather?q=London&appid={API key} + + + +{ +"cod": "200", +"message": 0, +"cnt": 40, +"list": [ +{ + "dt": 1647345600, + "main": { + "temp": 287.39, + "feels_like": 286.38, + "temp_min": 286.69, + "temp_max": 287.39, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1018, + "humidity": 58, + "temp_kf": 0.7 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 71 + }, + "wind": { + "speed": 3.08, + "deg": 128, + "gust": 4.3 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-15 12:00:00" +}, +{ + "dt": 1647356400, + "main": { + "temp": 287.09, + "feels_like": 286.13, + "temp_min": 286.5, + "temp_max": 287.09, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1016, + "humidity": 61, + "temp_kf": 0.59 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 81 + }, + "wind": { + "speed": 3.28, + "deg": 168, + "gust": 3.96 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-15 15:00:00" +}, +{ + "dt": 1647367200, + "main": { + "temp": 285.44, + "feels_like": 284.6, + "temp_min": 284.47, + "temp_max": 285.44, + "pressure": 1020, + "sea_level": 1020, + "grnd_level": 1016, + "humidity": 72, + "temp_kf": 0.97 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 90 + }, + "wind": { + "speed": 2.7, + "deg": 183, + "gust": 5.59 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-15 18:00:00" +}, +..... + { + "dt": 1647766800, + "main": { + "temp": 282.42, + "feels_like": 280, + "temp_min": 282.42, + "temp_max": 282.42, + "pressure": 1036, + "sea_level": 1036, + "grnd_level": 1033, + "humidity": 60, + "temp_kf": 0 + }, + "weather": [ + { + "id": 802, + "main": "Clouds", + "description": "scattered clouds", + "icon": "03d" + } + ], + "clouds": { + "all": 39 + }, + "wind": { + "speed": 4.58, + "deg": 83, + "gust": 8.45 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-20 09:00:00" +} +], +"city": { +"id": 2643743, +"name": "London", +"coord": { + "lat": 51.5085, + "lon": -0.1257 +}, +"country": "GB", +"population": 1000000, +"timezone": 0, +"sunrise": 1647324902, +"sunset": 1647367441 +} +} +api.openweathermap.org/data/2.5/weather?q=London&mode=xml + + + + + +London + +GB +0 + + + + + +0 + + + + + + + +.... + + + +} +https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&cnt=3&appid={API key} +} +https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&appid={API key} +} +https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&appid={API key}&units=metric +} +https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&appid={API key}&units=imperial +} +http://api.openweathermap.org/data/2.5/forecast?id=524901&lang={lang} +} +http://api.openweathermap.org/data/2.5/forecast?id=524901&lang=zh_cn&appid={API key} +} +api.openweathermap.org/data/2.5/forecast?q=London,uk&callback=test&appid={API key} + } diff --git "a/var source = new EventSource(\"demo_sse.p" "b/var source = new EventSource(\"demo_sse.p" new file mode 100644 index 0000000..79614d6 --- /dev/null +++ "b/var source = new EventSource(\"demo_sse.p" @@ -0,0 +1,27 @@ +var source = new EventSource("demo_sse.php"); +source.onmessage = function(event) { + document.getElementById("result").innerHTML += event.data + "
"; +}; +} +if(typeof(EventSource) !== "undefined") { + // Yes! Server-sent events support! + // Some code..... +} else { + // Sorry! No server-sent events support.. +} + +} +<% +Response.ContentType = "text/event-stream" +Response.Expires = -1 +Response.Write("data: The server time is: " & now()) +Response.Flush() +%> +} \ No newline at end of file From 1d2968fdd10653798ef2f0954099941478df0600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Skarpsv=C3=A4rd?= <145796632+Code-lab-web@users.noreply.github.com> Date: Tue, 18 Mar 2025 17:25:34 +0000 Subject: [PATCH 2/3] $ git add --- index.html | 20 +++++++++++++++ script.js | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ style.css | 14 +++++++++++ 3 files changed, 106 insertions(+) create mode 100644 index.html create mode 100644 script.js create mode 100644 style.css diff --git a/index.html b/index.html new file mode 100644 index 0000000..19f1c0a --- /dev/null +++ b/index.html @@ -0,0 +1,20 @@ + + + + + + + Meetup #2 GIT in Teams + +

Weather app

+ +
+
Test Weatherapp
+
+ + + + \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..0f2a2f9 --- /dev/null +++ b/script.js @@ -0,0 +1,72 @@ +fetch("https"jsonplaceholder.typicode.com/posts") +.then((response) => response.json()) +const posts = json; +posts.forEach((post, index) => { +} +.then(json =>document.getElementById("Weatherapp").innerHTML += json.length) + +} +function showError(error) { + switch(error.code) { + case error.PERMISSION_DENIED: + x.innerHTML = "User denied the request for Geolocation." + break; + case error.POSITION_UNAVAILABLE: + x.innerHTML = "Location information is unavailable." + break; + case error.TIMEOUT: + x.innerHTML = "The request to get user location timed out." + break; + case error.UNKNOWN_ERROR: + x.innerHTML = "An unknown error occurred." + break; + } +} + \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..836b015 --- /dev/null +++ b/style.css @@ -0,0 +1,14 @@ +@import url('https://fonts.googleapis.com/css2family=Roboto:wgt100;400;500&display=swap'); +body{ + font-family: 'Roboto' , sans-serif; + .Wheatherapp { + display:flex; + width: 1600px; + flex-wrap: wrap; + } + + .Wheatherapp { + padding: 20px; + width: 320px; + } +} \ No newline at end of file From dada631e8dd250a21e522a1d3cd41405551365c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Skarpsv=C3=A4rd?= Date: Thu, 27 Mar 2025 16:51:03 +0100 Subject: [PATCH 3/3] upload of code --- .vscode/launch.json | 0 .html | 69 +- api.js | 5 + hook.js | 1087 ++++++++++++++++++++++++++++++++ installhook.js | 1432 ++++++++++++++++++++++++++++++++++++++++++ no.DOM.js | 76 +++ rightclick.js | 82 +++ script.js | 364 +++++++++-- script.ts | 954 ++++------------------------ style.2.css | 136 ++++ style.css | 409 +++++++++++- style3.css | 91 +++ style4.css | 136 ++++ style5.css | 271 ++++++++ svg.xml | 6 + weather.js | 189 ++++++ weather.xml | 809 ++++++++++++++++++++++++ 17 files changed, 5188 insertions(+), 928 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 api.js create mode 100644 hook.js create mode 100644 installhook.js create mode 100644 no.DOM.js create mode 100644 rightclick.js create mode 100644 style.2.css create mode 100644 style3.css create mode 100644 style4.css create mode 100644 style5.css create mode 100644 svg.xml create mode 100644 weather.js create mode 100644 weather.xml diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e69de29 diff --git a/.html b/.html index 43357dc..f13560f 100644 --- a/.html +++ b/.html @@ -1,32 +1,45 @@ - - + + + + + My weather app + + + -

Count numbers:

- - + +
+
+

+ | +

+

+

+
+
+ +

+
+
- - - - \ No newline at end of file + + + + diff --git a/api.js b/api.js new file mode 100644 index 0000000..ff2a569 --- /dev/null +++ b/api.js @@ -0,0 +1,5 @@ +const API_KEY = "548773e920254208b83a2e2bdadb8f0e"; + + + + diff --git a/hook.js b/hook.js new file mode 100644 index 0000000..7dc9a18 --- /dev/null +++ b/hook.js @@ -0,0 +1,1087 @@ +( () => { + var e, t, r = { + 6064: (e, t, r) => { + e.exports = r(3619).Observable + } + , + 3619: (e, t) => { + "use strict"; + t.Observable = void 0; + const r = e => Boolean(Symbol[e]) + , n = e => r(e) ? Symbol[e] : "@@" + e + , o = n("iterator") + , i = n("observable") + , s = n("species"); + function a(e, t) { + let r = e[t]; + if (null != r) { + if ("function" != typeof r) + throw new TypeError(r + " is not a function"); + return r + } + } + function c(e) { + let t = e.constructor; + return void 0 !== t && (t = t[s], + null === t && (t = void 0)), + void 0 !== t ? t : b + } + function u(e) { + u.log ? u.log(e) : setTimeout(( () => { + throw e + } + )) + } + function l(e) { + Promise.resolve().then(( () => { + try { + e() + } catch (e) { + u(e) + } + } + )) + } + function f(e) { + let t = e._cleanup; + if (void 0 !== t && (e._cleanup = void 0, + t)) + try { + if ("function" == typeof t) + t(); + else { + let e = a(t, "unsubscribe"); + e && e.call(t) + } + } catch (e) { + u(e) + } + } + function p(e) { + e._observer = void 0, + e._queue = void 0, + e._state = "closed" + } + function d(e, t, r) { + e._state = "running"; + let n = e._observer; + try { + let o = a(n, t); + switch (t) { + case "next": + o && o.call(n, r); + break; + case "error": + if (p(e), + !o) + throw r; + o.call(n, r); + break; + case "complete": + p(e), + o && o.call(n) + } + } catch (e) { + u(e) + } + "closed" === e._state ? f(e) : "running" === e._state && (e._state = "ready") + } + function y(e, t, r) { + if ("closed" !== e._state) { + if ("buffering" !== e._state) + return "ready" !== e._state ? (e._state = "buffering", + e._queue = [{ + type: t, + value: r + }], + void l(( () => function(e) { + let t = e._queue; + if (t) { + e._queue = void 0, + e._state = "ready"; + for (let r = 0; r < t.length && (d(e, t[r].type, t[r].value), + "closed" !== e._state); ++r) + ; + } + }(e)))) : void d(e, t, r); + e._queue.push({ + type: t, + value: r + }) + } + } + class g { + constructor(e, t) { + this._cleanup = void 0, + this._observer = e, + this._queue = void 0, + this._state = "initializing"; + let r = this + , n = { + get closed() { + return "closed" === r._state + }, + next(e) { + y(r, "next", e) + }, + error(e) { + y(r, "error", e) + }, + complete() { + y(r, "complete") + } + }; + try { + this._cleanup = t.call(void 0, n) + } catch (e) { + n.error(e) + } + "initializing" === this._state && (this._state = "ready") + } + get closed() { + return "closed" === this._state + } + unsubscribe() { + "closed" !== this._state && (p(this), + f(this)) + } + } + class b { + constructor(e) { + if (!(this instanceof b)) + throw new TypeError("Observable cannot be called as a function"); + if ("function" != typeof e) + throw new TypeError("Observable initializer must be a function"); + this._subscriber = e + } + subscribe(e) { + return "object" == typeof e && null !== e || (e = { + next: e, + error: arguments[1], + complete: arguments[2] + }), + new g(e,this._subscriber) + } + forEach(e) { + return new Promise(( (t, r) => { + if ("function" != typeof e) + return void r(new TypeError(e + " is not a function")); + function n() { + o.unsubscribe(), + t() + } + let o = this.subscribe({ + next(t) { + try { + e(t, n) + } catch (e) { + r(e), + o.unsubscribe() + } + }, + error: r, + complete: t + }) + } + )) + } + map(e) { + if ("function" != typeof e) + throw new TypeError(e + " is not a function"); + return new (c(this))((t => this.subscribe({ + next(r) { + try { + r = e(r) + } catch (e) { + return t.error(e) + } + t.next(r) + }, + error(e) { + t.error(e) + }, + complete() { + t.complete() + } + }))) + } + filter(e) { + if ("function" != typeof e) + throw new TypeError(e + " is not a function"); + return new (c(this))((t => this.subscribe({ + next(r) { + try { + if (!e(r)) + return + } catch (e) { + return t.error(e) + } + t.next(r) + }, + error(e) { + t.error(e) + }, + complete() { + t.complete() + } + }))) + } + reduce(e) { + if ("function" != typeof e) + throw new TypeError(e + " is not a function"); + let t = c(this) + , r = arguments.length > 1 + , n = !1 + , o = arguments[1]; + return new t((t => this.subscribe({ + next(i) { + let s = !n; + if (n = !0, + !s || r) + try { + o = e(o, i) + } catch (e) { + return t.error(e) + } + else + o = i + }, + error(e) { + t.error(e) + }, + complete() { + if (!n && !r) + return t.error(new TypeError("Cannot reduce an empty sequence")); + t.next(o), + t.complete() + } + }))) + } + async all() { + let e = []; + return await this.forEach((t => e.push(t))), + e + } + concat(...e) { + let t = c(this); + return new t((r => { + let n, o = 0; + return function i(s) { + n = s.subscribe({ + next(e) { + r.next(e) + }, + error(e) { + r.error(e) + }, + complete() { + o === e.length ? (n = void 0, + r.complete()) : i(t.from(e[o++])) + } + }) + }(this), + () => { + n && (n.unsubscribe(), + n = void 0) + } + } + )) + } + flatMap(e) { + if ("function" != typeof e) + throw new TypeError(e + " is not a function"); + let t = c(this); + return new t((r => { + let n = [] + , o = this.subscribe({ + next(o) { + if (e) + try { + o = e(o) + } catch (e) { + return r.error(e) + } + let s = t.from(o).subscribe({ + next(e) { + r.next(e) + }, + error(e) { + r.error(e) + }, + complete() { + let e = n.indexOf(s); + e >= 0 && n.splice(e, 1), + i() + } + }); + n.push(s) + }, + error(e) { + r.error(e) + }, + complete() { + i() + } + }); + function i() { + o.closed && 0 === n.length && r.complete() + } + return () => { + n.forEach((e => e.unsubscribe())), + o.unsubscribe() + } + } + )) + } + [i]() { + return this + } + static from(e) { + let t = "function" == typeof this ? this : b; + if (null == e) + throw new TypeError(e + " is not an object"); + let n = a(e, i); + if (n) { + let r = n.call(e); + if (Object(r) !== r) + throw new TypeError(r + " is not an object"); + return function(e) { + return e instanceof b + }(r) && r.constructor === t ? r : new t((e => r.subscribe(e))) + } + if (r("iterator") && (n = a(e, o), + n)) + return new t((t => { + l(( () => { + if (!t.closed) { + for (let r of n.call(e)) + if (t.next(r), + t.closed) + return; + t.complete() + } + } + )) + } + )); + if (Array.isArray(e)) + return new t((t => { + l(( () => { + if (!t.closed) { + for (let r = 0; r < e.length; ++r) + if (t.next(e[r]), + t.closed) + return; + t.complete() + } + } + )) + } + )); + throw new TypeError(e + " is not observable") + } + static of(...e) { + return new ("function" == typeof this ? this : b)((t => { + l(( () => { + if (!t.closed) { + for (let r = 0; r < e.length; ++r) + if (t.next(e[r]), + t.closed) + return; + t.complete() + } + } + )) + } + )) + } + static get[s]() { + return this + } + } + t.Observable = b, + Object.defineProperty(b, Symbol("extensions"), { + value: { + symbol: i, + hostReportError: u + }, + configurable: !0 + }) + } + }, n = {}; + function o(e) { + var t = n[e]; + if (void 0 !== t) + return t.exports; + var i = n[e] = { + exports: {} + }; + return r[e](i, i.exports, o), + i.exports + } + o.n = e => { + var t = e && e.__esModule ? () => e.default : () => e; + return o.d(t, { + a: t + }), + t + } + , + t = Object.getPrototypeOf ? e => Object.getPrototypeOf(e) : e => e.__proto__, + o.t = function(r, n) { + if (1 & n && (r = this(r)), + 8 & n) + return r; + if ("object" == typeof r && r) { + if (4 & n && r.__esModule) + return r; + if (16 & n && "function" == typeof r.then) + return r + } + var i = Object.create(null); + o.r(i); + var s = {}; + e = e || [null, t({}), t([]), t(t)]; + for (var a = 2 & n && r; "object" == typeof a && !~e.indexOf(a); a = t(a)) + Object.getOwnPropertyNames(a).forEach((e => s[e] = () => r[e])); + return s.default = () => r, + o.d(i, s), + i + } + , + o.d = (e, t) => { + for (var r in t) + o.o(t, r) && !o.o(e, r) && Object.defineProperty(e, r, { + enumerable: !0, + get: t[r] + }) + } + , + o.o = (e, t) => Object.prototype.hasOwnProperty.call(e, t), + o.r = e => { + "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { + value: "Module" + }), + Object.defineProperty(e, "__esModule", { + value: !0 + }) + } + , + ( () => { + "use strict"; + const e = { + rE: "4.19.11" + }; + var t = o.t(e, 2); + var r = function(e, t) { + return r = Object.setPrototypeOf || { + __proto__: [] + }instanceof Array && function(e, t) { + e.__proto__ = t + } + || function(e, t) { + for (var r in t) + Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]) + } + , + r(e, t) + }; + function n(e, t) { + if ("function" != typeof t && null !== t) + throw new TypeError("Class extends value " + String(t) + " is not a constructor or null"); + function n() { + this.constructor = e + } + r(e, t), + e.prototype = null === t ? Object.create(t) : (n.prototype = t.prototype, + new n) + } + Object.create; + Object.create; + "function" == typeof SuppressedError && SuppressedError; + var i = "Invariant Violation" + , s = Object.setPrototypeOf + , a = void 0 === s ? function(e, t) { + return e.__proto__ = t, + e + } + : s + , c = function(e) { + function t(r) { + void 0 === r && (r = i); + var n = e.call(this, "number" == typeof r ? i + ": " + r + " (see https://github.com/apollographql/invariant-packages)" : r) || this; + return n.framesToPop = 1, + n.name = i, + a(n, t.prototype), + n + } + return n(t, e), + t + }(Error); + function u(e, t) { + if (!e) + throw new c(t) + } + var l = ["debug", "log", "warn", "error", "silent"] + , f = l.indexOf("log"); + function p(e) { + return function() { + if (l.indexOf(e) >= f) + return (console[e] || console.log).apply(console, arguments) + } + } + !function(e) { + e.debug = p("debug"), + e.log = p("log"), + e.warn = p("warn"), + e.error = p("error") + }(u || (u = {})); + var d = "3.11.10"; + function y(e) { + try { + return e() + } catch (e) {} + } + const g = y((function() { + return globalThis + } + )) || y((function() { + return window + } + )) || y((function() { + return self + } + )) || y((function() { + return global + } + )) || y((function() { + return y.constructor("return this")() + } + )); + var b = new Map; + function h(e, t) { + void 0 === t && (t = 0); + var r, n, o = (r = "stringifyForDisplay", + n = b.get(r) || 1, + b.set(r, n + 1), + "".concat(r, ":").concat(n, ":").concat(Math.random().toString(36).slice(2))); + return JSON.stringify(e, (function(e, t) { + return void 0 === t ? o : t + } + ), t).split(JSON.stringify(o)).join("") + } + function m(e) { + return function(t) { + for (var r = [], n = 1; n < arguments.length; n++) + r[n - 1] = arguments[n]; + if ("number" == typeof t) { + var o = t; + (t = _(o)) || (t = O(o, r), + r = []) + } + e.apply(void 0, [t].concat(r)) + } + } + Object.assign((function(e, t) { + for (var r = [], n = 2; n < arguments.length; n++) + r[n - 2] = arguments[n]; + e || u(e, _(t, r) || O(t, r)) + } + ), { + debug: m(u.debug), + log: m(u.log), + warn: m(u.warn), + error: m(u.error) + }); + var v = Symbol.for("ApolloErrorMessageHandler_" + d); + function w(e) { + if ("string" == typeof e) + return e; + try { + return h(e, 2).slice(0, 1e3) + } catch (e) { + return "" + } + } + function _(e, t) { + if (void 0 === t && (t = []), + e) + return g[v] && g[v](e, t.map(w)) + } + function O(e, t) { + if (void 0 === t && (t = []), + e) + return "An error occurred! For more details, see the full error text at https://go.apollo.dev/c/err#".concat(encodeURIComponent(JSON.stringify({ + version: d, + message: e, + args: t.map(w) + }))) + } + globalThis.__DEV__; + function E(e) { + return { + clientErrors: e.clientErrors?.map((e => e.message)) ?? [], + name: "ApolloError", + networkError: e.networkError ? L(e.networkError) : void 0, + message: e.message, + graphQLErrors: e.graphQLErrors, + protocolErrors: e.protocolErrors?.map((e => e.message)) ?? [] + } + } + function S(e) { + const {options: t} = e + , r = { + ...(n = t, + o = ["context", "pollInterval", "partialRefetch", "canonizeResults", "returnPartialData", "refetchWritePolicy", "notifyOnNetworkStatusChange", "fetchPolicy", "errorPolicy"], + o.reduce(( (e, t) => t in n ? { + ...e, + [t]: n[t] + } : e), {})), + nextFetchPolicy: "function" == typeof t.nextFetchPolicy ? "" : t.nextFetchPolicy + }; + var n, o; + return null == r.nextFetchPolicy && delete r.nextFetchPolicy, + r.context && (r.context = JSON.parse(JSON.stringify(r.context, ( (e, t) => "function" == typeof t ? "" : t)))), + r + } + function L(e) { + return "object" != typeof e ? { + message: String(e), + name: typeof e + } : { + message: e.message, + name: e.name, + stack: e.stack + } + } + function x(e) { + return e ? function(e) { + return "ApolloError" === e.name + }(e) ? E(e) : L(e) : null + } + function P(e) { + return "object" == typeof e && null !== e && "source"in e && "apollo-client-devtools" === e.source + } + function T(e, t={}) { + const {jsonSerialize: r} = t + , n = new Set; + return { + addListener(t) { + function r({data: e}) { + if (n.has(e.id)) + return n.delete(e.id); + t(e) + } + return e.addEventListener("message", r), + () => { + e.removeEventListener("message", r) + } + }, + postMessage(t) { + n.add(t.id), + setTimeout(( () => n.delete(t.id)), 10), + e.postMessage(r ? JSON.parse(JSON.stringify(t)) : t, "*") + } + } + } + function j() { + const e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + return new Array(10).fill(null).map(( () => e[Math.floor(62 * Math.random())])).join("") + } + function k(e) { + let t = null; + const r = new Map; + function n(e) { + if (!function(e) { + return P(e) && "actor" === e.type + }(e)) + return; + const t = r.get(e.message.type); + if (t) + for (const r of t) + r(e.message) + } + return { + on: (o, i, s={}) => { + let a = r.get(o); + a || (a = new Set, + r.set(o, a)), + a.add(i), + t || (t = e.addListener(n)); + const c = () => { + a.delete(i), + 0 === a.size && r.delete(o), + 0 === r.size && t && (t(), + t = null) + } + ; + return s.signal && s.signal.addEventListener("abort", c, { + once: !0 + }), + c + } + , + send: t => { + e.postMessage({ + id: j(), + source: "apollo-client-devtools", + type: "actor", + message: t + }) + } + } + } + const M = [EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError].reduce(( (e, t) => e.set(t.name, t)), new Map); + var A = o(6064) + , C = o.n(A); + const {rE: q} = t + , D = Symbol.for("apollo.devtools") + , I = function(e) { + return k(T(e)) + }(window) + , N = T(window, { + jsonSerialize: !0 + }) + , R = function(e) { + const t = new Map; + let r = null; + function n(e) { + (function(e) { + return P(e) && "rpcRequest" === e.type + } + )(e) && t.get(e.name)?.(e) + } + return function(o, i, s={}) { + if (t.has(o)) + throw new Error("Only one rpc handler can be registered per type"); + t.set(o, (async ({id: t, params: r}) => { + try { + const n = await Promise.resolve(i(...r)); + e.postMessage({ + source: "apollo-client-devtools", + type: "rpcResponse", + id: j(), + sourceId: t, + result: n + }) + } catch (r) { + e.postMessage({ + source: "apollo-client-devtools", + type: "rpcResponse", + id: j(), + sourceId: t, + error: (n = r, + n instanceof Error ? { + name: n.name, + message: n.message, + stack: n.stack + } : { + message: String(n) + }) + }) + } + var n + } + )), + r || (r = e.addListener(n)); + const a = () => { + t.delete(o), + 0 === t.size && r && (r(), + r = null) + } + ; + return s.signal && s.signal.addEventListener("abort", a, { + once: !0 + }), + a + } + }(N) + , Q = (z = N, + { + timeout: 3e4, + withTimeout(e) { + return { + ...this, + timeout: e + } + }, + request(e, ...t) { + return new Promise(( (r, n) => { + const o = j() + , i = setTimeout(( () => { + s(), + n(new Error("RPC_MESSAGE_TIMEOUT")) + } + ), this.timeout) + , s = z.addListener((e => { + (function(e) { + return P(e) && "rpcResponse" === e.type + } + )(e) && e.sourceId === o && ("error"in e ? n(function({name: e, message: t, stack: r}) { + const n = new (e ? M.get(e) ?? Error : Error)(t); + return e && n.name !== e && (n.name = e), + r && (n.stack = r), + n + }(e.error)) : r(e.result), + clearTimeout(i), + s()) + } + )); + z.postMessage({ + source: "apollo-client-devtools", + type: "rpcRequest", + id: o, + name: e, + params: t + }) + } + )) + } + }); + var z; + function J(e) { + const t = e; + return t?.queryManager.getObservableQueries ? function(e) { + const t = []; + return e && e.forEach(( (e, r) => { + const n = e + , {document: o, variables: i} = n.queryInfo + , s = n.queryInfo.getDiff(); + if (!o) + return; + if ("IntrospectionQuery" === (o.definitions.filter((function(e) { + return "OperationDefinition" === e.kind && !!e.name + } + )).map((function(e) { + return e.name.value + } + ))[0] || null)) + return; + const {pollingInfo: a} = n + , {networkStatus: c, error: u} = n.getCurrentResult(!1); + t.push({ + id: r, + document: o, + variables: i, + cachedData: s.result, + options: S(e), + networkStatus: c, + error: u ? E(u) : void 0, + pollInterval: a && Math.floor(a.interval) + }) + } + )), + t + }(t.queryManager.getObservableQueries("active")) : function(e) { + let t = []; + return e && (t = [...e.entries()].map(( ([e,{document: t, variables: r, diff: n, networkStatus: o}]) => ({ + id: e, + document: t, + variables: r, + cachedData: n?.result, + networkStatus: o ?? 1 + })))), + t + }(t?.queryManager.queries) + } + function F(e) { + const t = e; + return function(e) { + const t = Object.keys(e); + return 0 === t.length ? [] : t.map((t => { + const {mutation: r, variables: n, loading: o, error: i} = e[t]; + return { + document: r, + variables: n, + loading: o, + error: x(i) + } + } + )) + }((t?.queryManager.mutationStore?.getStore ? t.queryManager.mutationStore?.getStore() : t?.queryManager.mutationStore) ?? {}) + } + const G = new Map + , H = { + get ApolloClient() { + return $("window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__.ApolloClient"), + W + }, + version: q, + getQueries: () => ($("window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__.getQueries()"), + J(H.ApolloClient)), + getMutations: () => ($("window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__.getMutations()"), + F(H.ApolloClient)), + getCache: () => ($("window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__.getCache()"), + H.ApolloClient?.cache.extract(!0) ?? {}) + }; + function V(e) { + return { + id: G.get(e), + name: "devtoolsConfig"in e ? e.devtoolsConfig.name : void 0, + version: e.version, + queryCount: J(e).length, + mutationCount: F(e).length + } + } + function B(e) { + const [t] = [...G.entries()].find(( ([,t]) => t === e)) ?? []; + return t + } + function K(e) { + if (!G.has(e)) { + const t = j(); + G.set(e, t), + function(e) { + const t = e.stop; + e.stop = () => { + const r = G.get(e); + G.delete(e), + window.__APOLLO_CLIENT__ === e && (window.__APOLLO_CLIENT__ = void 0), + I.send({ + type: "clientTerminated", + clientId: r + }), + t.call(e) + } + }(e), + I.send({ + type: "registerClient", + payload: V(e) + }) + } + !function(e, t) { + e.request("getErrorCodes", t).catch(( () => {} + )).then((e => { + if (!e) + return; + const r = Symbol.for("ApolloErrorMessageHandler_" + t) + , n = globalThis; + function o(e, t) { + if ("number" == typeof e) { + const t = n[r][e]; + if (!e || !t?.message) + return; + e = t.message + } + return t.reduce(( (e, t) => e.replace(/%[sdfo]/, String(t))), String(e)) + } + n[r] || (n[r] = o); + const i = n[r]; + (i === o || Object.keys(i).some((e => /^\d+$/.test(e)))) && Object.assign(i, e, { + ...i + }) + } + )) + }(Q, e.version) + } + Object.defineProperty(window, "__APOLLO_DEVTOOLS_GLOBAL_HOOK__", { + get: () => H, + configurable: !0 + }), + R("getClients", ( () => [...G.keys()].map(V))), + R("getClient", (e => { + const t = B(e); + return t ? V(t) : null + } + )), + R("getQueries", (e => J(B(e)))), + R("getMutations", (e => F(B(e)))), + R("getCache", (e => B(e)?.cache.extract(!0) ?? {})), + function(e, t, r={}) { + e.on("explorerRequest", (n => { + const {clientId: o, operation: i, operationName: s, fetchPolicy: a, variables: c} = n.payload + , u = t(o); + if (!u) + throw new Error("Could not find selected client"); + const l = JSON.parse(JSON.stringify(i)) + , f = l.definitions.reduce(( (e, t) => (("OperationDefinition" === t.kind && t.name?.value === s || "OperationDefinition" !== t.kind) && e.push(t), + e)), []); + l.definitions = f; + const p = function(e) { + let t; + for (const r of e.definitions) { + if ("OperationDefinition" === r.kind) { + const e = r.operation; + if ("query" === e || "mutation" === e || "subscription" === e) + return r + } + "FragmentDefinition" !== r.kind || t || (t = r) + } + if (t) + return t; + throw new Error("Expected a parsed GraphQL query with a query, mutation, subscription, or a fragment.") + }(l) + , d = "OperationDefinition" === p.kind && "mutation" === p.operation ? new (C())((e => { + u.mutate({ + mutation: l, + variables: c + }).then((t => { + e.next(t) + } + )) + } + )) : u.watchQuery({ + query: l, + variables: c, + fetchPolicy: a + }) + , y = d?.subscribe((t => { + e.send({ + type: "explorerResponse", + payload: { + operationName: s, + response: t + } + }) + } + ), (t => { + e.send({ + type: "explorerResponse", + payload: { + operationName: s, + response: { + errors: t.graphQLErrors.length ? t.graphQLErrors : t.networkError && "result"in t.networkError ? "string" == typeof t.networkError?.result ? t.networkError?.result : t.networkError?.result.errors ?? [] : [], + error: t, + data: null, + loading: !1, + networkStatus: 8 + } + } + }) + } + )); + "OperationDefinition" === p.kind && "subscription" === p.operation && (e.on("explorerSubscriptionTermination", ( () => { + y?.unsubscribe() + } + ), r), + r.signal && r.signal.addEventListener("abort", ( () => { + y?.unsubscribe() + } + ), { + once: !0 + })) + } + ), r) + }(I, B); + const U = window[D]; + window[D] = { + push: K + }, + Array.isArray(U) && U.forEach(K); + let W = window.__APOLLO_CLIENT__; + function $(e) { + console.warn(`[Apollo Client Devtools]: '${e}' is deprecated and will be removed in a future version.`) + } + Object.defineProperty(window, "__APOLLO_CLIENT__", { + get: () => W, + set(e) { + e && setTimeout(( () => K(e))), + W = e + }, + configurable: !0 + }), + W && K(W) + } + )() +} +)(); diff --git a/installhook.js b/installhook.js new file mode 100644 index 0000000..965779b --- /dev/null +++ b/installhook.js @@ -0,0 +1,1432 @@ +(() => { + var e = { + 4659: (e, t, n) => { + } + } +})(); + "use strict"; + var r = n(8715), + o = n(1147), + i = Object.assign, + a = o.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, + l = Symbol.for("react.context"), + s = Symbol.for("react.memo_cache_sentinel"), + u = Object.prototype.hasOwnProperty, + c = [], + p = null; + + function getPrimitiveStackCache() { + if (null === p) { + var e = new Map; + try { + // code that might throw an error + try { + // code that might throw an error + } catch (e) { + // handle error + if (g.useContext({ + _currentValue: null + }), + g.useState(null), + g.useReducer((function (e) { + return e; + }), { + // handle success + })); + } + } + } + } + } + } + } + } + } catch (e) { + // handle error + } + } catch (e) { + // handle error + } + } catch (e) { + // handle error + } + try { + g.useRef(null); + if ("function" == typeof g.useCacheRefresh) { g.useCacheRefresh(); } + g.useLayoutEffect((function () {})); + g.useInsertionEffect((function () {})); + g.useEffect((function () {})); + g.useImperativeHandle(void 0, (function () { + return null + }) + ); + } + catch (error) { + // handle error + } + } + } + } + } + } + } + } + } + } + } + } + g.useDebugValue(null); + g.useCallback((function () {})); + g.useTransition(); + g.useSyncExternalStore((function () { + return function () {} + }), (function () { + return null + }), (function () { + return null + })); + g.useDeferredValue(null); + g.useMemo((function () { + return null + })); + g.useOptimistic(null, (function (e) { + return e + })); + g.useFormState((function (e) { + return e + }), null); + g.useActionState((function (e) { + return e + }), null); + g.useHostTransitionStatus(); + if ("function" == typeof g.useMemoCache) g.useMemoCache(0); + if ("function" == typeof g.use) { + g.use({ + $$typeof: l, + _currentValue: null + }); + g.use({ + then: function () {}, + status: "fulfilled", + value: null + }); + try { + g.use({ + then: function () {} + }); + } catch (e) {} + } + g.useId(); + if ("function" == typeof g.useResourceEffect) g.useResourceEffect((function () { + return {} + }), []); + if ("function" == typeof g.useEffectEvent) g.useEffectEvent((function () {})); + } catch (e) { + // handle error + } finally { + var t = c; + c = []; + } + for (var n = 0; n < t.length; n++) { + var o = t[n]; + e.set(o.primitive, r.parse(o.stackError)); + } + p = e; + } + return p; + } + + var f = null, + d = null, + m = null; + + function nextHook() { + var e = d; + return null !== e && (d = e.next), e; + } + + function readContext(e) { + if (null === f) return e._currentValue; + if (null === m) throw Error("Context reads do not line up with context dependencies. This is a bug in React Debug Tools."); + return u.call(m, "memoizedValue") ? (e = m.memoizedValue, m = m.next) : e = e._currentValue, e; + } + + var h = Error("Suspense Exception: This is not a real error! It's an implementation detail of `use` to interrupt the current render. You must either rethrow it immediately, or move the `use` call outside of the `try/catch` block. Capturing without rethrowing will lead to unexpected behavior.\n\nTo handle async errors, wrap your component in an error boundary, or call the promise's `.catch` method and pass the result to `use`."); + var g = { + use: function (e) { + if (null !== e && "object" == typeof e) { + if ("function" == typeof e.then) { + switch (e.status) { + case "fulfilled": + var t = e.value; + return c.push({ + displayName: null, + primitive: "Promise", + stackError: Error(), + value: t, + debugInfo: void 0 === e._debugInfo ? null : e._debugInfo, + dispatcherHookName: "Use" + }), t; + case "rejected": + throw e.reason; + } + throw c.push({ + displayName: null, + primitive: "Unresolved", + stackError: Error(), + value: e, + debugInfo: void 0 === e._debugInfo ? null : e._debugInfo, + dispatcherHookName: "Use" + }), h; + } + if (e.$$typeof === l) return t = readContext(e), c.push({ + displayName: e.displayName || "Context", + primitive: "Context (use)", + stackError: Error(), + value: t, + debugInfo: null, + dispatcherHookName: "Use" + }), t; + } + throw Error("An unsupported type was passed to use(): " + String(e)); + }, + readContext, + useCacheRefresh: function () { + var e = nextHook(); + return c.push({ + displayName: null, + primitive: "CacheRefresh", + stackError: Error(), + value: null !== e ? e.memoizedState : function () {}, + debugInfo: null, + dispatcherHookName: "CacheRefresh" + }), function () {}; + }, + useCallback: function (e) { + var t = nextHook(); + return c.push({ + displayName: null, + primitive: "Callback", + stackError: Error(), + value: null !== t ? t.memoizedState[0] : e, + debugInfo: null, + dispatcherHookName: "Callback" + }), e; + }, + useContext: function (e) { + var t = readContext(e); + return c.push({ + displayName: e.displayName || null, + primitive: "Context", + stackError: Error(), + value: t, + debugInfo: null, + dispatcherHookName: "Context" + }), t; + }, + useEffect: function (e) { + nextHook(), c.push({ + displayName: null, + primitive: "Effect", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "Effect" + }); + }, + useImperativeHandle: function (e) { + nextHook(); + var t = void 0; + null !== e && "object" == typeof e && (t = e.current), c.push({ + displayName: null, + primitive: "ImperativeHandle", + stackError: Error(), + value: t, + debugInfo: null, + dispatcherHookName: "ImperativeHandle" + }); + }, + useDebugValue: function (e, t) { + c.push({ + displayName: null, + primitive: "DebugValue", + stackError: Error(), + value: "function" == typeof t ? t(e) : e, + debugInfo: null, + dispatcherHookName: "DebugValue" + }); + }, + useLayoutEffect: function (e) { + nextHook(), c.push({ + displayName: null, + primitive: "LayoutEffect", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "LayoutEffect" + }); + }, + useInsertionEffect: function (e) { + nextHook(), c.push({ + displayName: null, + primitive: "InsertionEffect", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "InsertionEffect" + }); + }, + useMemo: function (e) { + var t = nextHook(); + return e = null !== t ? t.memoizedState[0] : e(), c.push({ + displayName: null, + primitive: "Memo", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "Memo" + }), e; + }, + useMemoCache: function (e) { + var t = f; + if (null == t) return []; + if (null == (t = null != t.updateQueue ? t.updateQueue.memoCache : null)) return []; + var n = t.data[t.index]; + if (void 0 === n) { + n = t.data[t.index] = Array(e); + for (var r = 0; r < e; r++) n[r] = s; + } + return t.index++, n; + }, + useOptimistic: function (e) { + var t = nextHook(); + return e = null !== t ? t.memoizedState : e, c.push({ + displayName: null, + primitive: "Optimistic", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "Optimistic" + }), [e, function () {}]; + }, + useReducer: function (e, t, n) { + return t = null !== (e = nextHook()) ? e.memoizedState : void 0 !== n ? n(t) : t, c.push({ + displayName: null, + primitive: "Reducer", + stackError: Error(), + value: t, + debugInfo: null, + dispatcherHookName: "Reducer" + }), [t, function () {}]; + }, + useRef: function (e) { + var t = nextHook(); + return e = null !== t ? t.memoizedState : { + current: e + }, c.push({ + displayName: null, + primitive: "Ref", + stackError: Error(), + value: e.current, + debugInfo: null, + dispatcherHookName: "Ref" + }), e; + }, + useState: function (e) { + var t = nextHook(); + return e + if (void 0 === n) { + n = t.data[t.index] = Array(e); + for (var r = 0; r < e; r++) + n[r] = s + } + return t.index++, + n + }, + useOptimistic: function(e) { + var t = nextHook(); + return e = null !== t ? t.memoizedState : e, + c.push({ + displayName: null, + primitive: "Optimistic", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "Optimistic" + }), + [e, function() {} + ] + }, + useReducer: function(e, t, n) { + return t = null !== (e = nextHook()) ? e.memoizedState : void 0 !== n ? n(t) : t, + c.push({ + displayName: null, + primitive: "Reducer", + stackError: Error(), + value: t, + debugInfo: null, + dispatcherHookName: "Reducer" + }), + [t, function() {} + ] + }, + useRef: function(e) { + var t = nextHook(); + return e = null !== t ? t.memoizedState : { + current: e + }, + c.push({ + displayName: null, + primitive: "Ref", + stackError: Error(), + value: e.current, + debugInfo: null, + dispatcherHookName: "Ref" + }), + e + }, + useState: function(e) { + var t = nextHook(); + return e = null !== t ? t.memoizedState : "function" == typeof e ? e() : e, + c.push({ + displayName: null, + primitive: "State", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "State" + }), + [e, function() {} + ] + }, + useTransition: function() { + var e = nextHook(); + return nextHook(), + e = null !== e && e.memoizedState, + c.push({ + displayName: null, + primitive: "Transition", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "Transition" + }), + [e, function() {} + ] + }, + useSyncExternalStore: function(e, t) { + return nextHook(), + nextHook(), + e = t(), + c.push({ + displayName: null, + primitive: "SyncExternalStore", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "SyncExternalStore" + }), + e + }, + useDeferredValue: function(e) { + var t = nextHook(); + return e = null !== t ? t.memoizedState : e, + c.push({ + displayName: null, + primitive: "DeferredValue", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "DeferredValue" + }), + e + }, + useId: function() { + var e = nextHook(); + return e = null !== e ? e.memoizedState : "", + c.push({ + displayName: null, + primitive: "Id", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "Id" + }), + e + }, + useFormState: function(e, t) { + var n = nextHook(); + nextHook(), + nextHook(), + e = Error(); + var r = null + , o = null; + if (null !== n) + if ("object" == typeof (t = n.memoizedState) && null !== t && "function" == typeof t.then) + switch (t.status) { + case "fulfilled": + var i = t.value; + r = void 0 === t._debugInfo ? null : t._debugInfo; + break; + case "rejected": + o = t.reason; + break; + default: + o = h, + r = void 0 === t._debugInfo ? null : t._debugInfo, + i = t + } + else + i = t; + else + i = t; + if (c.push({ + displayName: null, + primitive: "FormState", + stackError: e, + value: i, + debugInfo: r, + dispatcherHookName: "FormState" + }), + null !== o) + throw o; + return [i, function() {} + , !1] + }, + useActionState: function(e, t) { + var n = nextHook(); + nextHook(), + nextHook(), + e = Error(); + var r = null + , o = null; + if (null !== n) + if ("object" == typeof (t = n.memoizedState) && null !== t && "function" == typeof t.then) + switch (t.status) { + case "fulfilled": + var i = t.value; + r = void 0 === t._debugInfo ? null : t._debugInfo; + break; + case "rejected": + o = t.reason; + break; + default: + o = h, + r = void 0 === t._debugInfo ? null : t._debugInfo, + i = t + } + else + i = t; + else + i = t; + if (c.push({ + displayName: null, + primitive: "ActionState", + stackError: e, + value: i, + debugInfo: r, + dispatcherHookName: "ActionState" + }), + null !== o) + throw o; + return [i, function() {} + , !1] + }, + useHostTransitionStatus: function() { + var e = readContext({ + _currentValue: null + }); + return c.push({ + displayName: null, + primitive: "HostTransitionStatus", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "HostTransitionStatus" + }), + e + }, + useEffectEvent: function(e) { + return nextHook(), + c.push({ + displayName: null, + primitive: "EffectEvent", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "EffectEvent" + }), + e + }, + useResourceEffect: function(e) { + nextHook(), + c.push({ + displayName: null, + primitive: "ResourceEffect", + stackError: Error(), + value: e, + debugInfo: null, + dispatcherHookName: "ResourceEffect" + }); + } + } + , y = "undefined" == typeof Proxy ? g : new Proxy(g,{ + get: function(e, t) { + if (e.hasOwnProperty(t)) + return e[t]; + throw (e = Error("Missing method in Dispatcher: " + t)).name = "ReactDebugToolsUnsupportedHookError", + e + } + }); + var v = 0; + function findSharedIndex(e, t, n) { + var r = t[n].source + , o = 0; + e: for (; o < e.length; o++) + if (e[o].source === r) { + for (var i = n + 1, a = o + 1; i < t.length && a < e.length; i++, + a++) + if (e[a].source !== t[i].source) + continue e; + return o + } + return -1 + } + function isReactWrapper(e, t) { + return e = parseHookName(e), + "HostTransitionStatus" === t ? e === t || "FormStatus" === e : e === t + } + function parseHookName(e) { + if (!e) + return ""; + var t = e.lastIndexOf("[as "); + if (-1 !== t) + return parseHookName(e.slice(t + 4, -1)); + if (t = -1 === (t = e.lastIndexOf(".")) ? 0 : t + 1, + e.slice(t).startsWith("unstable_") && (t += 9), + e.slice(t).startsWith("experimental_") && (t += 13), + "use" === e.slice(t, t + 3)) { + if (3 == e.length - t) + return "Use"; + t += 3 + } + return e.slice(t) + } + function buildTree(e, t) { + for (var n = [], o = null, i = n, a = 0, l = [], s = 0; s < t.length; s++) { + var u = t[s] + , c = e + , p = r.parse(u.stackError); + e: { + var f = p + , d = findSharedIndex(f, c, v); + if (-1 !== d) + c = d; + else { + for (var m = 0; m < c.length && 5 > m; m++) + if (-1 !== (d = findSharedIndex(f, c, m))) { + v = m, + c = d; + break e + } + c = -1 + } + } + e: { + if (f = p, + void 0 !== (d = getPrimitiveStackCache().get(u.primitive))) + for (m = 0; m < d.length && m < f.length; m++) + if (d[m].source !== f[m].source) { + m < f.length - 1 && isReactWrapper(f[m].functionName, u.dispatcherHookName) && m++, + m < f.length - 1 && isReactWrapper(f[m].functionName, u.dispatcherHookName) && m++, + f = m; + break e + } + f = -1 + } + if (f = (p = -1 === c || -1 === f || 2 > c - f ? -1 === f ? [null, null] : [p[f - 1], null] : [p[f - 1], p.slice(f, c - 1)])[0], + p = p[1], + null === (c = u.displayName) && null !== f && (c = parseHookName(f.functionName) || parseHookName(u.dispatcherHookName)), + null !== p) { + if (f = 0, + null !== o) { + for (; f < p.length && f < o.length && p[p.length - f - 1].source === o[o.length - f - 1].source; ) + f++; + for (o = o.length - 1; o > f; o--) + i = l.pop() + } + for (o = p.length - f - 1; 1 <= o; o--) + f = [], + d = p[o], + d = { + id: null, + isStateEditable: !1, + name: parseHookName(p[o - 1].functionName), + value: void 0, + subHooks: f, + debugInfo: null, + hookSource: { + lineNumber: d.lineNumber, + columnNumber: d.columnNumber, + functionName: d.functionName, + fileName: d.fileName + } + }, + i.push(d), + l.push(i), + i = f; + o = p + } + f = u.primitive, + d = u.debugInfo, + u = { + id: "Context" === f || "Context (use)" === f || "DebugValue" === f || "Promise" === f || "Unresolved" === f || "HostTransitionStatus" === f ? null : a++, + isStateEditable: "Reducer" === f || "State" === f, + name: c || f, + value: u.value, + subHooks: [], + debugInfo: d, + hookSource: null + }, + c = { + lineNumber: null, + functionName: null, + fileName: null, + columnNumber: null + }, + p && 1 <= p.length && (p = p[0], + c.lineNumber = p.lineNumber, + c.functionName = p.functionName, + c.fileName = p.fileName, + c.columnNumber = p.columnNumber), + u.hookSource = c, + i.push(u) + } + return processDebugValues(n, null), + n + } + function processDebugValues(e, t) { + for (var n = [], r = 0; r < e.length; r++) { + var o = e[r]; + "DebugValue" === o.name && 0 === o.subHooks.length ? (e.splice(r, 1), + r--, + n.push(o)) : processDebugValues(o.subHooks, o) + } + null !== t && (1 === n.length ? t.value = n[0].value : 1 < n.length && (t.value = n.map((function(e) { + return e.value + } + )))) + } + function handleRenderFunctionError(e) { + if (e !== h) { + if (e instanceof Error && "ReactDebugToolsUnsupportedHookError" === e.name) + throw e; + var t = Error("Error rendering inspected component", { + cause: e + }); + throw t.name = "ReactDebugToolsRenderError", + t.cause = e, + t + } + } + function inspectHooks(e, t, n) { + null == n && (n = a); + var o = n.H; + n.H = y; + try { + var i = Error(); + e(t) + } catch (e) { + handleRenderFunctionError(e) + } finally { + e = c, + c = [], + n.H = o + } + return buildTree(n = r.parse(i), e) + } + t.inspectHooksOfFiber = function(e, t) { + if (null == t && (t = a), + 0 !== e.tag && 15 !== e.tag && 11 !== e.tag) + throw Error("Unknown Fiber. Needs to be a function component to inspect hooks."); + if (getPrimitiveStackCache(), + d = e.memoizedState, + f = e, + u.call(f, "dependencies")) { + var n = f.dependencies; + m = null !== n ? n.firstContext : null + } else if (u.call(f, "dependencies_old")) + n = f.dependencies_old, + m = null !== n ? n.firstContext : null; + else if (u.call(f, "dependencies_new")) + n = f.dependencies_new, + m = null !== n ? n.firstContext : null; + else { + if (!u.call(f, "contextDependencies")) + throw Error("Unsupported React version. This is a bug in React Debug Tools."); + n = f.contextDependencies, + m = null !== n ? n.first : null + } + n = e.type; + var o = e.memoizedProps; + if (n !== e.elementType && n && n.defaultProps) { + o = i({}, o); + var l = n.defaultProps; + for (s in l) + void 0 === o[s] && (o[s] = l[s]) + } + var s = new Map; + try { + if (null !== m && !u.call(m, "memoizedValue")) + for (l = e; l; ) { + if (10 === l.tag) { + var p = l.type; + void 0 !== p._context && (p = p._context), + s.has(p) || (s.set(p, p._currentValue), + p._currentValue = l.memoizedProps.value) + } + l = l.return + } + if (11 === e.tag) { + var h = n.render; + p = o; + var g = e.ref + , v = (e = t).H; + e.H = y; + try { + var b = Error(); + h(p, g) + } catch (e) { + handleRenderFunctionError(e) + } finally { + var w = c; + c = [], + e.H = v + } + return buildTree(r.parse(b), w) + } + return inspectHooks(n, o, t) + } finally { + m = d = f = null, + s.forEach((function(e, t) { + return t._currentValue = e + } + )) + } + } + } + 8830: (e, t, n) => { + "use strict"; + e.exports = n(4659) + } + , + 5945: (e, t, n) => { + "use strict"; + var r = n(397) + , o = Symbol.for("react.transitional.element") + , i = Symbol.for("react.portal") + , a = Symbol.for("react.fragment") + , l = Symbol.for("react.strict_mode") + , s = Symbol.for("react.profiler") + , u = Symbol.for("react.consumer") + , c = Symbol.for("react.context") + , p = Symbol.for("react.forward_ref") + , f = Symbol.for("react.suspense") + , d = Symbol.for("react.suspense_list") + , m = Symbol.for("react.memo") + , h = Symbol.for("react.lazy") + , g = Symbol.for("react.offscreen") + , y = Symbol.for("react.postpone") + , v = Symbol.for("react.view_transition") + , b = Symbol.iterator; + var w = { + isMounted: function() { + return !1 + }, + enqueueForceUpdate: function() {}, + enqueueReplaceState: function() {}, + enqueueSetState: function() {} + } + , C = Object.assign + , E = {}; + function Component(e, t, n) { + this.props = e, + this.context = t, + this.refs = E, + this.updater = n || w + } + function ComponentDummy() {} + function PureComponent(e, t, n) { + this.props = e, + this.context = t, + this.refs = E, + this.updater = n || w + } + Component.prototype.isReactComponent = {}, + Component.prototype.setState = function(e, t) { + if ("object" != typeof e && "function" != typeof e && null != e) + throw Error("takes an object of state variables to update or a function which returns an object of state variables."); + this.updater.enqueueSetState(this, e, t, "setState") + } + , + Component.prototype.forceUpdate = function(e) { + this.updater.enqueueForceUpdate(this, e, "forceUpdate") + } + , + ComponentDummy.prototype = Component.prototype; + var k = PureComponent.prototype = new ComponentDummy; + k.constructor = PureComponent, + C(k, Component.prototype), + k.isPureReactComponent = !0; + var S = Array.isArray + , _ = { + H: null, + A: null, + T: null, + S: null, + V: null + } + , I = Object.prototype.hasOwnProperty; + function ReactElement(e, t, n, r, i, a) { + return n = a.ref, + { + $$typeof: o, + type: e, + key: t, + ref: void 0 !== n ? n : null, + props: a + } + } + function isValidElement(e) { + return "object" == typeof e && null !== e && e.$$typeof === o + } + var R = /\/+/g; + function getElementKey(e, t) { + return "object" == typeof e && null !== e && null != e.key ? (n = "" + e.key, + r = { + "=": "=0", + ":": "=2" + }, + "$" + n.replace(/[=:]/g, (function(e) { + return r[e] + } + ))) : t.toString(36); + var n, r + } + function noop$1() {} + function mapIntoArray(e, t, n, r, a) { + var l = typeof e; + "undefined" !== l && "boolean" !== l || (e = null); + var s, u, c = !1; + if (null === e) + c = !0; + else + switch (l) { + case "bigint": + case "string": + case "number": + c = !0; + break; + case "object": + switch (e.$$typeof) { + case o: + case i: + c = !0; + break; + case h: + return mapIntoArray((c = e._init)(e._payload), t, n, r, a) + } + } + if (c) + return a = a(e), + c = "" === r ? "." + getElementKey(e, 0) : r, + S(a) ? (n = "", + null != c && (n = c.replace(R, "$&/") + "/"), + mapIntoArray(a, t, n, "", (function(e) { + return e + } + ))) : null != a && (isValidElement(a) && (s = a, + u = n + (null == a.key || e && e.key === a.key ? "" : ("" + a.key).replace(R, "$&/") + "/") + c, + a = ReactElement(s.type, u, void 0, 0, 0, s.props)), + t.push(a)), + 1; + c = 0; + var p, f = "" === r ? "." : r + ":"; + if (S(e)) + for (var d = 0; d < e.length; d++) + c += mapIntoArray(r = e[d], t, n, l = f + getElementKey(r, d), a); + else if ("function" == typeof (d = null === (p = e) || "object" != typeof p ? null : "function" == typeof (p = b && p[b] || p["@@iterator"]) ? p : null)) + for (e = d.call(e), + d = 0; !(r = e.next()).done; ) + c += mapIntoArray(r = r.value, t, n, l = f + getElementKey(r, d++), a); + else if ("object" === l) { + if ("function" == typeof e.then) + return mapIntoArray(function(e) { + switch (e.status) { + case "fulfilled": + return e.value; + case "rejected": + throw e.reason; + default: + switch ("string" == typeof e.status ? e.then(noop$1, noop$1) : (e.status = "pending", + e.then((function(t) { + "pending" === e.status && (e.status = "fulfilled", + e.value = t) + } + ), (function(t) { + "pending" === e.status && (e.status = "rejected", + e.reason = t) + } + ))), + e.status) { + case "fulfilled": + return e.value; + case "rejected": + throw e.reason + } + } + throw e + }(e), t, n, r, a); + throw t = String(e), + Error("Objects are not valid as a React child (found: " + ("[object Object]" === t ? "object with keys {" + Object.keys(e).join(", ") + "}" : t) + "). If you meant to render a collection of children, use an array instead.") + } + return c + } + function mapChildren(e, t, n) { + if (null == e) + return e; + var r = [] + , o = 0; + return mapIntoArray(e, r, "", "", (function(e) { + return t.call(n, e, o++) + } + )), + r + } + function lazyInitializer(e) { + if (-1 === e._status) { + var t = e._result; + (t = t()).then((function(t) { + 0 !== e._status && -1 !== e._status || (e._status = 1, + e._result = t) + } + ), (function(t) { + 0 !== e._status && -1 !== e._status || (e._status = 2, + e._result = t) + } + )), + -1 === e._status && (e._status = 0, + e._result = t) + } + if (1 === e._status) + return e._result.default; + throw e._result + } + function useOptimistic(e, t) { + return _.H.useOptimistic(e, t) + } + var x = "function" == typeof reportError ? reportError : function(e) { + if ("object" == typeof window && "function" == typeof window.ErrorEvent) { + var t = new window.ErrorEvent("error",{ + bubbles: !0, + cancelable: !0, + message: "object" == typeof e && null !== e && "string" == typeof e.message ? String(e.message) : String(e), + error: e + }); + if (!window.dispatchEvent(t)) + return + } else if ("object" == typeof r && "function" == typeof r.emit) + return void r.emit("uncaughtException", e); + console.error(e) + } + ; + function noop() {} + t.Children = { + map: mapChildren, + forEach: function(e, t, n) { + mapChildren(e, (function() { + t.apply(this, arguments) + } + ), n) + }, + count: function(e) { + var t = 0; + return mapChildren(e, (function() { + t++ + } + )), + t + }, + toArray: function(e) { + return mapChildren(e, (function(e) { + return e + } + )) || [] + }, + only: function(e) { + if (!isValidElement(e)) + throw Error("React.Children.only expected to receive a single React element child."); + return e + } + }, + t.Component = Component, + t.Fragment = a, + t.Profiler = s, + t.PureComponent = PureComponent, + t.StrictMode = l, + t.Suspense = f, + t.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = _, + t.__COMPILER_RUNTIME = { + __proto__: null, + c: function(e) { + return _.H.useMemoCache(e) + } + }, + t.act = function() { + throw Error("act(...) is not supported in production builds of React.") + } + , + t.cache = function(e) { + return function() { + return e.apply(null, arguments) + } + } + , + t.captureOwnerStack = function() { + return null + } + , + t.cloneElement = function(e, t, n) { + if (null == e) + throw Error("The argument must be a React element, but you passed " + e + "."); + var r = C({}, e.props) + , o = e.key; + if (null != t) + for (i in void 0 !== t.ref && void 0, + void 0 !== t.key && (o = "" + t.key), + t) + !I.call(t, i) || "key" === i || "__self" === i || "__source" === i || "ref" === i && void 0 === t.ref || (r[i] = t[i]); + var i = arguments.length - 2; + if (1 === i) + r.children = n; + else if (1 < i) { + for (var a = Array(i), l = 0; l < i; l++) + a[l] = arguments[l + 2]; + r.children = a + } + return ReactElement(e.type, o, void 0, 0, 0, r) + } + , + t.createContext = function(e) { + return (e = { + $$typeof: c, + _currentValue: e, + _currentValue2: e, + _threadCount: 0, + Provider: null, + Consumer: null + }).Provider = e, + e.Consumer = { + $$typeof: u, + _context: e + }, + e + } + , + t.createElement = function(e, t, n) { + var r, o = {}, i = null; + if (null != t) + for (r in void 0 !== t.key && (i = "" + t.key), + t) + I.call(t, r) && "key" !== r && "__self" !== r && "__source" !== r && (o[r] = t[r]); + var a = arguments.length - 2; + if (1 === a) + o.children = n; + else if (1 < a) { + for (var l = Array(a), s = 0; s < a; s++) + l[s] = arguments[s + 2]; + o.children = l + } + if (e && e.defaultProps) + for (r in a = e.defaultProps) + void 0 === o[r] && (o[r] = a[r]); + return ReactElement(e, i, void 0, 0, 0, o) + } + , + t.createRef = function() { + return { + current: null + } + } + , + t.experimental_useEffectEvent = function(e) { + return _.H.useEffectEvent(e) + } + , + t.experimental_useOptimistic = function(e, t) { + return useOptimistic(e, t) + } + , + t.experimental_useResourceEffect = void 0, + t.forwardRef = function(e) { + return { + $$typeof: p, + render: e + } + } + , + t.isValidElement = isValidElement, + t.lazy = function(e) { + return { + $$typeof: h, + _payload: { + _status: -1, + _result: e + }, + _init: lazyInitializer + } + } + , + t.memo = function(e, t) { + return { + $$typeof: m, + type: e, + compare: void 0 === t ? null : t + } + } + , + t.startTransition = function(e) { + var t = _.T + , n = {}; + _.T = n; + try { + var r = e() + , o = _.S; + null !== o && o(n, r), + "object" == typeof r && null !== r && "function" == typeof r.then && r.then(noop, x) + } catch (e) { + x(e) + } finally { + _.T = t + } + } + , + t.unstable_Activity = g, + t.unstable_SuspenseList = d, + t.unstable_ViewTransition = v, + t.unstable_addTransitionType = function(e) { + var t = _.V; + null === t ? _.V = [e] : -1 === t.indexOf(e) && t.push(e) + } + , + t.unstable_getCacheForType = function(e) { + var t = _.A; + return t ? t.getCacheForType(e) : e() + } + , + t.unstable_postpone = function(e) { + throw (e = Error(e)).$$typeof = y, + e + } + , + t.unstable_useCacheRefresh = function() { + return _.H.useCacheRefresh() + } + , + t.use = function(e) { + return _.H.use(e) + } + , + t.useActionState = function(e, t, n) { + return _.H.useActionState(e, t, n) + } + , + t.useCallback = function(e, t) { + return _.H.useCallback(e, t) + } + , + t.useContext = function(e) { + return _.H.useContext(e) + } + , + t.useDebugValue = function() {} + , + t.useDeferredValue = function(e, t) { + return _.H.useDeferredValue(e, t) + } + , + t.useEffect = function(e, t) { + return _.H.useEffect(e, t) + } + , + t.useId = function() { + return _.H.useId() + } + , + t.useImperativeHandle = function(e, t, n) { + return _.H.useImperativeHandle(e, t, n) + } + , + t.useInsertionEffect = function(e, t) { + return _.H.useInsertionEffect(e, t) + } + , + t.useLayoutEffect = function(e, t) { + return _.H.useLayoutEffect(e, t) + } + , + t.useMemo = function(e, t) { + return _.H.useMemo(e, t) + } + , + t.useOptimistic = useOptimistic, + t.useReducer = function(e, t, n) { + return _.H.useReducer(e, t, n) + } + , + t.useRef = function(e) { + return _.H.useRef(e) + } + , + t.useState = function(e) { + return _.H.useState(e) + } + , + t.useSyncExternalStore = function(e, t, n) { + return _.H.useSyncExternalStore(e, t, n) + } + , + t.useTransition = function() { + return _.H.useTransition() + } + , + t.version = "19.1.0-experimental-44c3d3d6-20250207" + } + , + 1147: (e, t, n) => { + "use strict"; + e.exports = n(5945) + } + , + 8715: function(e, t, n) { + var r, o, i; + !function(a, l) { + "use strict"; + o = [n(7356)], + void 0 === (i = "function" == typeof (r = function(e) { + var t = /(^|@)\S+:\d+/ + , n = /^\s*at .*(\S+:\d+|\(native\))/m + , r = /^(eval@)?(\[native code])?$/; + return { + parse: function(e) { + if (void 0 !== e.stacktrace || void 0 !== e["opera#sourceloc"]) + return this.parseOpera(e); + if (e.stack && e.stack.match(n)) + return this.parseV8OrIE(e); + if (e.stack) + return this.parseFFOrSafari(e); + throw new Error("Cannot parse given Error object") + }, + extractLocation: function(e) { + if (-1 === e.indexOf(":")) + return [e]; + var t = /(.+?)(?::(\d+))?(?::(\d+))?$/.exec(e.replace(/[()]/g, "")); + return [t[1], t[2] || void 0, t[3] || void 0] + }, + parseV8OrIE: function(t) { + return t.stack.split("\n").filter((function(e) { + return !!e.match(n) + } + ), this).map((function(t) { + t.indexOf("(eval ") > -1 && (t = t.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(\),.*$)/g, "")); + var n = t.replace(/^\s+/, "").replace(/\(eval code/g, "(") + , r = n.match(/ (\((.+):(\d+):(\d+)\)$)/) + , o = (n = r ? n.replace(r[0], "") : n).split(/\s+/).slice(1) + , i = this.extractLocation(r ? r[1] : o.pop()) + , a = o.join(" ") || void 0 + , l = ["eval", ""].indexOf(i[0]) > -1 ? void 0 : i[0]; + return new e({ + functionName: a, + fileName: l, + lineNumber: i[1], + columnNumber: i[2], + source: t + }); + } + ), this) + }, + parseFFOrSafari: function(t) { + return t.stack.split("\n").filter((function(e) { + return !e.match(r) + } + ), this).map((function(t) { + if (t.indexOf(" > eval") > -1 && (t = t.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1")), + -1 === t.indexOf("@") && -1 === t.indexOf(":")) + return new e({ + functionName: t + }); + var n = /((.*".+"[^@]*)?[^@]*)(?:@)/ + , r = t.match(n) + , o = r && r[1] ? r[1] : void 0 + , i = this.extractLocation(t.replace(n, "")); + return new e({ + functionName: o, + fileName: i[0], + lineNumber: i[1], + columnNumber: i[2], + source: t + }); + } + ), this) + }, + parseOpera: function(e) { + return !e.stacktrace || e.message.indexOf("\n") > -1 && e.message.split("\n").length > e.stacktrace.split("\n").length ? this.parseOpera9(e) : e.stack ? this.parseOpera11(e) : this.parseOpera10(e) + }, + parseOpera9: function(t) { + for (var n = /Line (\d+).*script (?:in )?(\S+)/i, r = t.message.split("\n"), o = [], i = 2, a = r.length; i < a; i += 2) { + var l = n.exec(r[i]); + l && o.push(new e({ + fileName: l[2], + lineNumber: l[1], + source: r[i] + })) + } + return o + }, + parseOpera10: function(t) { + for (var n = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i, r = t.stacktrace.split("\n"), o = [], i = 0, a = r.length; i < a; i += 2) { + var l = n.exec(r[i]); + l && o.push(new e({ + functionName: l[3] || void 0, + fileName: l[2], + lineNumber: l[1], + source: r[i] + })) + } + return o + }, + parseOpera11: function(n) { + return n.stack.split("\n").filter((function(e) { + return !!e.match(t) && !e.match(/^Error created at/) + } + ), this).map((function(t) { + var n, r = t.split("@"), o = this.extractLocation(r.pop()), i = r.shift() || "", a = i.replace(//, "$2").replace(/\([^)]*\)/g, "") || void 0; + i.match(/\(([^)]*)\)/) && (n = i.replace(/^[^(]+\(([^)]*)\)$/, "$1")); + var l = void 0 === n || "[arguments not available]" === n ? void 0 : n.split(","); + return new e({ + functionName: a, + args: l, + fileName: o[0], + lineNumber: o[1], + columnNumber: o[2], + source: t + }); + } + })); + } + } + } + } + } + + \ No newline at end of file diff --git a/no.DOM.js b/no.DOM.js new file mode 100644 index 0000000..7181437 --- /dev/null +++ b/no.DOM.js @@ -0,0 +1,76 @@ +//function to prevent inspection of page through google inspector + +function detectConsoleAccess(event) { + const isConsoleShortcut = + event.altKey && event.metaKey && event.code === "KeyJ" + const isInspectorShortcut = + event.altKey && event.metaKey && event.code === "KeyI" + const isRightClick = event.which === 3 || event.button === 2 + const isControlClick = event.ctrlKey && !event.metaKey && event.button === 0 + const message = `This function has been disabled to prevent you from looking through the code! + + ` + if (isConsoleShortcut) { + event.preventDefault() + alert(message) + } else if (isInspectorShortcut) { + event.preventDefault() + alert(message) + } else if (isRightClick) { + event.preventDefault() + alert(message) + } else if (isControlClick) { + event.preventDefault() + alert(message) + } + } + + window.addEventListener("keydown", detectConsoleAccess) + + document.addEventListener( + "keydown", + function () { + if (keyCode == 123) { + alert( + `This function has been disabled to prevent you from looking through the code! + ` + ) + return false + } else if (ctrlKey && altKey == 73) { + alert( + `This function has been disabled to prevent you from looking through the code! + ` + ) + return false + } else if (event.ctrlKey && event.keyCode == 85) { + alert( + `This function has been disabled to prevent you from looking through the code! + ` + ) + return false + } + }, + false + ) + + if (document.addEventListener) { + document.addEventListener( + "contextmenu", + function (e) { + alert( + `This function has been disabled to prevent you from looking through the code! + ` + ) + e.preventDefault() + }, + false + ) + } else { + document.attachEvent("oncontextmenu", function () { + alert( + `This function has been disabled to prevent you from looking through the code! + ` + ) + window.event.returnValue = false + }) + } \ No newline at end of file diff --git a/rightclick.js b/rightclick.js new file mode 100644 index 0000000..44612cc --- /dev/null +++ b/rightclick.js @@ -0,0 +1,82 @@ +//function to prevent inspection of page through google inspector + +function detectConsoleAccess(event) { + const isConsoleShortcut = + event.altKey && event.metaKey && event.code === "KeyJ"; + const isInspectorShortcut = + event.altKey && event.metaKey && event.code === "KeyI"; + const isRightClick = event.which === 3 || event.button === 2; + const isControlClick = event.ctrlKey && !event.metaKey && event.button === 0; + const message = `This function has been disabled to prevent you from looking through the code! + + `; + if (isConsoleShortcut) { + event.preventDefault(); + alert(message); + } else if (isInspectorShortcut) { + event.preventDefault(); + alert(message); + } else if (isRightClick) { + event.preventDefault(); + alert(message); + } else if (isControlClick) { + event.preventDefault(); + alert(message); + } + } + + window.addEventListener("keydown", detectConsoleAccess); + + document.addEventListener( + "keydown", + function () { + if (keyCode == 123) { + alert( + `This function has been disabled to prevent you from looking through the code! + + ` + ); + return false; + } else if (ctrlKey && altKey == 73) { + alert( + `This function has been disabled to prevent you from looking through the code! + + ` + ); + return false; + } else if (event.ctrlKey && event.keyCode == 85) { + alert( + `This function has been disabled to prevent you from looking through the code! + + ` + ); + return false; + } + }, + false + ); + + if (document.addEventListener) { + document.addEventListener( + "contextmenu", + function (e) { + alert( + `This function has been disabled to prevent you from looking through the code! + + ` + ); + e.preventDefault(); + }, + false + ); + } else { + document.attachEvent("oncontextmenu", function () { + alert( + `This function has been disabled to prevent you from looking through the code! + + ` + ); + window.event.returnValue = false; + }); + } + \ No newline at end of file diff --git a/script.js b/script.js index 0f2a2f9..dc2c3ec 100644 --- a/script.js +++ b/script.js @@ -1,72 +1,302 @@ -fetch("https"jsonplaceholder.typicode.com/posts") -.then((response) => response.json()) -const posts = json; -posts.forEach((post, index) => { -} -.then(json =>document.getElementById("Weatherapp").innerHTML += json.length) - -} -function showError(error) { - switch(error.code) { - case error.PERMISSION_DENIED: - x.innerHTML = "User denied the request for Geolocation." - break; - case error.POSITION_UNAVAILABLE: - x.innerHTML = "Location information is unavailable." - break; - case error.TIMEOUT: - x.innerHTML = "The request to get user location timed out." - break; - case error.UNKNOWN_ERROR: - x.innerHTML = "An unknown error occurred." - break; +//All global varibles +const tempToday = document.getElementById("tempToday"); +const tempTextCelsius = document.querySelector(".tempTextCelsius"); +const cityName = document.getElementById("cityName"); +const localTime = document.getElementById("localTime"); +const weatherDescription = document.getElementById("weatherDescription"); +const mainIcon = document.getElementById("mainIcon"); + +const sunriseText = document.getElementById("sunriseText"); +const sunsetText = document.getElementById("sunsetText"); + +const weatherFeature = document.getElementById("weatherFeature"); +const featureImage = document.querySelector(".feature-image"); +const backgroundTopGradient = document.getElementById("backgroundTopGradient"); + +const searchMenuBtn = document.getElementById("searchMenuBtn"); +const closeSearchMenu = document.getElementById("closeSearchMenu"); +const searchBtn = document.getElementById("searchBtn"); +const inputField = document.getElementById("inputField"); +const switchFavoriteCity = document.getElementById("switchBtn"); + +const weatherForecast = document.getElementById("weatherForecast"); +const forecastWeekdays = document.getElementById("forecastWeekdays"); +const forecastIcon = document.getElementById("forecastIcon"); +const forecastDescription = document.getElementById("forecastDescription"); +const forecastTemp = document.getElementById("forecastTemp"); +const forecastWind = document.getElementById("forecastWind"); + +const cityText = document.querySelector(".cityText"); +const tempText = document.querySelector(".tempText"); +const describeText = document.querySelector(".describeText"); + +//Variables we can use later to automate API-fethcing: +const apiKey = "548773e920254208b83a2e2bdadb8f0e"; +let city = "London"; + +const todaysWeatherFeature = (London) => { + fetch( + `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&APPID=548773e920254208b83a2e2bdadb8f0e` + ) + .then((response) => { + return response.json(); + }) + .then((json) => { + //Get today's weather + let { icon } = json.weather[0]; + cityName.innerText = `${json.name}`; + tempToday.innerText = `${json.main.temp.toFixed(0)}`; + tempTextCelsius.innerText = `°C`; + weatherDescription.innerText = `${json.weather[0].description}`; + mainIcon.innerHTML = `weather icon`; + + // Get current time (hours/minutes) in time zome + const currentLocalTime = new Date((json.dt + json.timezone) * 1000); + const localTimeValue = currentLocalTime.toLocaleTimeString(["en-GB"], { + timeStyle: "short", + timeZone: "UTC", + }); + + //Modifying the HTML based on the output of current time in hours/minutes + localTime.innerHTML = `Time: ${localTimeValue}`; + + // Get sunrise and sunset time with the city's timezone + const sunriseTime = new Date((json.sys.sunrise + json.timezone) * 1000); //Gives us the time in "human" form (as a date), mult. by 1000 to get it in ms. + sunriseTime.setMinutes( + sunriseTime.getMinutes() + sunriseTime.getTimezoneOffset() + ); + const sunriseShort = sunriseTime.toLocaleTimeString(["en-GB"], { + timeStyle: "short", + }); //Transforms it into just the Hour/minutes. Select the short variant to get the time with minutes and not seconds. + const sunsetTime = new Date((json.sys.sunset + json.timezone) * 1000); + sunsetTime.setMinutes( + sunsetTime.getMinutes() + sunsetTime.getTimezoneOffset() + ); + const sunsetShort = sunsetTime.toLocaleTimeString(["en-GB"], { + timeStyle: "short", + }); + + //Modifying the HTML based on our input: + sunriseText.innerHTML = `

sunrise

+

${sunriseShort}

`; + sunsetText.innerHTML = `

sunset

+

${sunsetShort}

`; + + //Today's weather varible + const todaysWeather = json.weather[0].main; + + //Get current local time with timezone + const getTime = new Date(); + getTime.setMinutes(getTime.getMinutes() + getTime.getTimezoneOffset()); + getTime.setSeconds(getTime.getSeconds() + json.timezone); + + //Get time in hours to compare + const currentTime = getTime.getHours(); + const sunriseTimeHour = sunriseTime.getHours(); + const sunsetTimeHour = sunsetTime.getHours(); + + //Image feature + if (currentTime >= sunriseTimeHour && currentTime <= sunsetTimeHour) { + //During daytime => show image depending on weather + if (todaysWeather === "Clear") { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1613931189161-1f4d2660bd1e?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc0MDczNDI&ixlib=rb-4.0.3&q=80')"; + } else if (todaysWeather === "Clouds") { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1424111113808-b7be56a9f3d6?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzcyNTczNTA&ixlib=rb-4.0.3&q=80')"; + } else if (todaysWeather === "Rain") { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1424111113808-b7be56a9f3d6?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzcyNTczNTA&ixlib=rb-4.0.3&q=80')"; + } else if (todaysWeather === "Snow") { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1610486549369-585a0e6d8cc4?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc0MDc4NDE&ixlib=rb-4.0.3&q=80')"; + } else if (todaysWeather === "Thunderstorm") { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1602088501827-7912e1b4a7bd?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc0MDc5ODI&ixlib=rb-4.0.3&q=80')"; + } else if (todaysWeather === "Drizzle") { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1554039362-6daf559ddb63?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc0MDgyNDk&ixlib=rb-4.0.3&q=80')"; + } else if (todaysWeather === "Atmosphere" || todaysWeather === "Haze") { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1543226549-10d29b2cfaf0?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc0MDg0MTI&ixlib=rb-4.0.3&q=80')"; + } else { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1424111113808-b7be56a9f3d6?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzcyNTczNTA&ixlib=rb-4.0.3&q=80')"; + } + } else { + //During nighttime => show image depending on weather + if (todaysWeather === "Clear") { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1620055374842-145f66ec4652?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc0MDkxMTY&ixlib=rb-4.0.3&q=80')"; + } else if (todaysWeather === "Snow") { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1602857731804-80e82120ff27?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc0MDkzNzQ&ixlib=rb-4.0.3&q=80')"; + } else if (todaysWeather === "Rain") { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1505144992585-d281c0e2cff8?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc0MDk1OTA&ixlib=rb-4.0.3&q=80')"; + } else if (todaysWeather === "Clouds") { + featureImage.style.backgroundImage = + "url('https://images.unsplash.com/photo-1518352724948-729151797553?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc0MDk1OTA&ixlib=rb-4.0.3&q=80')"; + } else { + featureImage.style.backgroundImage = + "url(' https://images.unsplash.com/photo-1604083142449-79b1babd12d4?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc0MTIwOTM&ixlib=rb-4.0.3&q=80')"; + } + } + + const gradientDayNight = () => { + //Remove all classes to be added later + const gradientStyle = [ + "morning", + "midday", + "afternoon", + "duskSunset", + "evening", + "midnight", + "dawnSunrise", + ]; + backgroundTopGradient.classList.remove(...gradientStyle); + + if (currentTime > 7 && currentTime <= 11) { + backgroundTopGradient.classList.add("morning"); + } else if (currentTime > 11 && currentTime <= 14) { + backgroundTopGradient.classList.add("midday"); + } else if (currentTime > 14 && currentTime < 17) { + backgroundTopGradient.classList.add("afternoon"); + } else if (currentTime >= 17 && currentTime <= 19) { + backgroundTopGradient.classList.add("duskSunset"); + } else if (currentTime > 19 && currentTime <= 23) { + backgroundTopGradient.classList.add("evening"); + } else if (currentTime > 23 || currentTime < 5) { + backgroundTopGradient.classList.add("midnight"); + } else { + backgroundTopGradient.classList.add("dawnSunrise"); + } + }; + gradientDayNight(); + }); +}; + +const weatherForecastData = (London) => { + fetch( + `https://api.openweathermap.org/data/2.5/forecast?q=${city}&units=metric&APPID=${apiKey}` + ) + .then((forecastResponse) => { + return forecastResponse.json(); + }) + .then((result) => { + if (result.cod !== "404") { + //If the user did NOT search for a city that does not exist + + const todaysDate = new Date().toString().split(" ")[0]; //Today's date in text form + const filterData = result.list.filter((weatherDay) => + weatherDay.dt_txt.includes("12:00") + ); //Filters out the data at 12:00 every day + + filterData.forEach((date) => { + const weekDay = new Date(date.dt * 1000).toString().split(" ")[0]; //All the five days dates' convertet from numbers to text + if (weekDay !== todaysDate) { + let { icon } = date.weather[0]; + forecastWeekdays.innerHTML += `

${weekDay}

`; + forecastIcon.innerHTML += `weather icon`; + forecastTemp.innerHTML += `

${date.main.temp.toFixed(0)}°C

`; + forecastWind.innerHTML += `

${date.wind.speed}m/s

`; + } + }); + } else { + //If the user DID search for a city that does not exist. Alerts user that the city cant be found. Then runs Stockholm again. + alert("Oops, city not found! Check your spelling please."); + todaysWeatherFeature("London"); + weatherForecastData("London"); + } + }); } -} - \ No newline at end of file +}); diff --git a/script.ts b/script.ts index 52e12e3..ef9a573 100644 --- a/script.ts +++ b/script.ts @@ -1,827 +1,141 @@ -api.openweathermap.org/data/2.5/forecast?lat={lat}&lon={lon}&appid={} -{ - api.openweathermap.org/data/2.5/forecast?lat=44.34&lon=10.99&appid={} +const sampleData = { + cod: "200", + message: 0, + cnt: 40, + list: [ { + dt: 1661871600, + main: { + temp: 296.76, + feels_like: 296.98, + temp_min: 296.76, + temp_max: 297.87, + pressure: 1015, + sea_level: 1015, + grnd_level: 933, + humidity: 69, + temp_kf: -1.11 + }, + weather: [ { - "cod": "200", - "message": 0, - "cnt": 40, - "list": [ - { - "dt": 1661871600, - "main": { - "temp": 296.76, - "feels_like": 296.98, - "temp_min": 296.76, - "temp_max": 297.87, - "pressure": 1015, - "sea_level": 1015, - "grnd_level": 933, - "humidity": 69, - "temp_kf": -1.11 - }, - "weather": [ - { - "id": 500, - "main": "Rain", - "description": "light rain", - "icon": "10d" - } - ], - "clouds": { - "all": 100 - }, - "wind": { - "speed": 0.62, - "deg": 349, - "gust": 1.18 - }, - "visibility": 10000, - "pop": 0.32, - "rain": { - "3h": 0.26 - }, - "sys": { - "pod": "d" - }, - "dt_txt": "2022-08-30 15:00:00" - }, - { - "dt": 1661882400, - "main": { - "temp": 295.45, - "feels_like": 295.59, - "temp_min": 292.84, - "temp_max": 295.45, - "pressure": 1015, - "sea_level": 1015, - "grnd_level": 931, - "humidity": 71, - "temp_kf": 2.61 - }, - "weather": [ - { - "id": 500, - "main": "Rain", - "description": "light rain", - "icon": "10n" - } - ], - "clouds": { - "all": 96 - }, - "wind": { - "speed": 1.97, - "deg": 157, - "gust": 3.39 - }, - "visibility": 10000, - "pop": 0.33, - "rain": { - "3h": 0.57 - }, - "sys": { - "pod": "n" - }, - "dt_txt": "2022-08-30 18:00:00" - }, - { - "dt": 1661893200, - "main": { - "temp": 292.46, - "feels_like": 292.54, - "temp_min": 290.31, - "temp_max": 292.46, - "pressure": 1015, - "sea_level": 1015, - "grnd_level": 931, - "humidity": 80, - "temp_kf": 2.15 - }, - "weather": [ - { - "id": 500, - "main": "Rain", - "description": "light rain", - "icon": "10n" - } - ], - "clouds": { - "all": 68 - }, - "wind": { - "speed": 2.66, - "deg": 210, - "gust": 3.58 - }, - "visibility": 10000, - "pop": 0.7, - "rain": { - "3h": 0.49 - }, - "sys": { - "pod": "n" - }, - "dt_txt": "2022-08-30 21:00:00" - }, - .... - { - "dt": 1662292800, - "main": { - "temp": 294.93, - "feels_like": 294.83, - "temp_min": 294.93, - "temp_max": 294.93, - "pressure": 1018, - "sea_level": 1018, - "grnd_level": 935, - "humidity": 64, - "temp_kf": 0 - }, - "weather": [ - { - "id": 804, - "main": "Clouds", - "description": "overcast clouds", - "icon": "04d" - } - ], - "clouds": { - "all": 88 - }, - "wind": { - "speed": 1.14, - "deg": 17, - "gust": 1.57 - }, - "visibility": 10000, - "pop": 0, - "sys": { - "pod": "d" - }, - "dt_txt": "2022-09-04 12:00:00" - } - ], - "city": { - "id": 3163858, - "name": "Zocca", - "coord": { - "lat": 44.34, - "lon": 10.99 - }, - "country": "IT", - "population": 4593, - "timezone": 7200, - "sunrise": 1661834187, - "sunset": 1661882248 - } - } - - - Zocca - - IT - 7200 - - - - - - 0 - - - - - - - - ... - - - - - XML format API response fields - { - "main":{ -"temp":306.15, //current temperature -"pressure":1013, -"humidity":44, -"temp_min":30.15, //min current temperature in the city -"temp_max":306.15 //max current temperature in the city -}, - } - } -} -} -"dt":1406080800, -"temp":{ - "day":297.77, //daily averaged temperature - "min":293.52, //daily min temperature - "max":297.77, //daily max temperature - "night":293.52, //night temperature - "eve":297.77, //evening temperature - "morn":297.77}, //morning temperature - { - api.openweathermap.org/data/2.5/forecast?q={city name}&appid={API key} - -api.openweathermap.org/data/2.5/forecast?q={city name},{country code}&appid={API key} - -api.openweathermap.org/data/2.5/forecast?q={city name},{state code},{country code}&appid={API key} - } - api.openweathermap.org/data/2.5/forecast?q=London,us&mode=xml&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?q=München,DE&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?id={city ID}&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?id=524901&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?zip={zip code},{country code}&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?zip=94040,us&appid={API key} -} -api.openweathermap.org/data/2.5/weather?q=London&appid={API key} - - - -{ -"cod": "200", -"message": 0, -"cnt": 40, -"list": [ -{ - "dt": 1647345600, - "main": { - "temp": 287.39, - "feels_like": 286.38, - "temp_min": 286.69, - "temp_max": 287.39, - "pressure": 1021, - "sea_level": 1021, - "grnd_level": 1018, - "humidity": 58, - "temp_kf": 0.7 - }, - "weather": [ + id: 500, + main: "Rain", + description: "light rain", + icon: "10d" + } + ], + clouds: { + all: 100 + }, + wind: { + speed: 0.62, + deg: 349, + gust: 1.18 + }, + visibility: 10000, + pop: 0.32, + rain: { + "3h": 0.26 + }, + sys: { + pod: "d" + }, + dt_txt: "2022-08-30 15:00:00" + }, { - "id": 803, - "main": "Clouds", - "description": "broken clouds", - "icon": "04d" - } - ], - "clouds": { - "all": 71 - }, - "wind": { - "speed": 3.08, - "deg": 128, - "gust": 4.3 - }, - "visibility": 10000, - "pop": 0, - "sys": { - "pod": "d" - }, - "dt_txt": "2022-03-15 12:00:00" -}, -{ - "dt": 1647356400, - "main": { - "temp": 287.09, - "feels_like": 286.13, - "temp_min": 286.5, - "temp_max": 287.09, - "pressure": 1021, - "sea_level": 1021, - "grnd_level": 1016, - "humidity": 61, - "temp_kf": 0.59 - }, - "weather": [ - { - "id": 803, - "main": "Clouds", - "description": "broken clouds", - "icon": "04d" - } - ], - "clouds": { - "all": 81 - }, - "wind": { - "speed": 3.28, - "deg": 168, - "gust": 3.96 - }, - "visibility": 10000, - "pop": 0, - "sys": { - "pod": "d" - }, - "dt_txt": "2022-03-15 15:00:00" -}, -{ - "dt": 1647367200, - "main": { - "temp": 285.44, - "feels_like": 284.6, - "temp_min": 284.47, - "temp_max": 285.44, - "pressure": 1020, - "sea_level": 1020, - "grnd_level": 1016, - "humidity": 72, - "temp_kf": 0.97 - }, - "weather": [ - { - "id": 804, - "main": "Clouds", - "description": "overcast clouds", - "icon": "04d" - } - ], - "clouds": { - "all": 90 - }, - "wind": { - "speed": 2.7, - "deg": 183, - "gust": 5.59 - }, - "visibility": 10000, - "pop": 0, - "sys": { - "pod": "d" - }, - "dt_txt": "2022-03-15 18:00:00" -}, -..... - { - "dt": 1647766800, - "main": { - "temp": 282.42, - "feels_like": 280, - "temp_min": 282.42, - "temp_max": 282.42, - "pressure": 1036, - "sea_level": 1036, - "grnd_level": 1033, - "humidity": 60, - "temp_kf": 0 - }, - "weather": [ - { - "id": 802, - "main": "Clouds", - "description": "scattered clouds", - "icon": "03d" - } - ], - "clouds": { - "all": 39 - }, - "wind": { - "speed": 4.58, - "deg": 83, - "gust": 8.45 - }, - "visibility": 10000, - "pop": 0, - "sys": { - "pod": "d" - }, - "dt_txt": "2022-03-20 09:00:00" -} -], -"city": { -"id": 2643743, -"name": "London", -"coord": { - "lat": 51.5085, - "lon": -0.1257 -}, -"country": "GB", -"population": 1000000, -"timezone": 0, -"sunrise": 1647324902, -"sunset": 1647367441 -} -} - - - -Zocca - -IT -7200 - - - - - -0 - - - - - - - -... - - - -{ -"main":{ -"temp":306.15, //current temperature -"pressure":1013, -"humidity":44, -"temp_min":30.15, //min current temperature in the city -"temp_max":306.15 //max current temperature in the city -}, - - "dt":1406080800, -"temp":{ - "day":297.77, //daily averaged temperature - "min":293.52, //daily min temperature - "max":297.77, //daily max temperature - "night":293.52, //night temperature - "eve":297.77, //evening temperature - "morn":297.77}, //morning temperature - -} -api.openweathermap.org/data/2.5/forecast?q={city name}&appid={API key} - -api.openweathermap.org/data/2.5/forecast?q={city name},{country code}&appid={API key} - -api.openweathermap.org/data/2.5/forecast?q={city name},{state code},{country code}&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?q=London,us&mode=xml&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?q=München,DE&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?id={city ID}&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?id=524901&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?zip={zip code},{country code}&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?zip=94040,us&appid={API key} -} -api.openweathermap.org/data/2.5/weather?q=London&appid={API key} - - - -{ -"cod": "200", -"message": 0, -"cnt": 40, -"list": [ -{ - "dt": 1647345600, - "main": { - "temp": 287.39, - "feels_like": 286.38, - "temp_min": 286.69, - "temp_max": 287.39, - "pressure": 1021, - "sea_level": 1021, - "grnd_level": 1018, - "humidity": 58, - "temp_kf": 0.7 - }, - "weather": [ - { - "id": 803, - "main": "Clouds", - "description": "broken clouds", - "icon": "04d" - } - ], - "clouds": { - "all": 71 - }, - "wind": { - "speed": 3.08, - "deg": 128, - "gust": 4.3 - }, - "visibility": 10000, - "pop": 0, - "sys": { - "pod": "d" - }, - "dt_txt": "2022-03-15 12:00:00" -}, -{ - "dt": 1647356400, - "main": { - "temp": 287.09, - "feels_like": 286.13, - "temp_min": 286.5, - "temp_max": 287.09, - "pressure": 1021, - "sea_level": 1021, - "grnd_level": 1016, - "humidity": 61, - "temp_kf": 0.59 - }, - "weather": [ - { - "id": 803, - "main": "Clouds", - "description": "broken clouds", - "icon": "04d" - } - ], - "clouds": { - "all": 81 - }, - "wind": { - "speed": 3.28, - "deg": 168, - "gust": 3.96 - }, - "visibility": 10000, - "pop": 0, - "sys": { - "pod": "d" - }, - "dt_txt": "2022-03-15 15:00:00" -}, -{ - "dt": 1647367200, - "main": { - "temp": 285.44, - "feels_like": 284.6, - "temp_min": 284.47, - "temp_max": 285.44, - "pressure": 1020, - "sea_level": 1020, - "grnd_level": 1016, - "humidity": 72, - "temp_kf": 0.97 - }, - "weather": [ - { - "id": 804, - "main": "Clouds", - "description": "overcast clouds", - "icon": "04d" - } - ], - "clouds": { - "all": 90 - }, - "wind": { - "speed": 2.7, - "deg": 183, - "gust": 5.59 - }, - "visibility": 10000, - "pop": 0, - "sys": { - "pod": "d" - }, - "dt_txt": "2022-03-15 18:00:00" -}, -..... - { - "dt": 1647766800, - "main": { - "temp": 282.42, - "feels_like": 280, - "temp_min": 282.42, - "temp_max": 282.42, - "pressure": 1036, - "sea_level": 1036, - "grnd_level": 1033, - "humidity": 60, - "temp_kf": 0 - }, - "weather": [ + dt: 1661882400, + main: { + temp: 295.45, + feels_like: 295.59, + temp_min: 292.84, + temp_max: 295.45, + pressure: 1015, + sea_level: 1015, + grnd_level: 931, + humidity: 71, + temp_kf: 2.61 + }, + weather: [ + { + id: 500, + main: "Rain", + description: "light rain", + icon: "10n" + } + ], + clouds: { + all: 96 + }, + wind: { + speed: 1.97, + deg: 157, + gust: 3.39 + }, + visibility: 10000, + pop: 0.33, + rain: { + "3h": 0.57 + }, + sys: { + pod: "n" + }, + dt_txt: "2022-08-30 18:00:00" + }, { - "id": 802, - "main": "Clouds", - "description": "scattered clouds", - "icon": "03d" + dt: 1661893200, + main: { + temp: 292.46, + feels_like: 292.54, + temp_min: 290.31, + temp_max: 292.46, + pressure: 1015, + sea_level: 1015, + grnd_level: 931, + humidity: 80, + temp_kf: 2.15 + }, + weather: [ + { + id: 500, + main: "Rain", + description: "light rain", + icon: "10n" + } + ], + clouds: { + all: 68 + }, + wind: { + speed: 2.66, + deg: 210, + gust: 3.58 + }, + visibility: 10000, + pop: 0.7, + rain: { + "3h": 0.49 + }, + sys: { + pod: "n" + }, + dt_txt: "2022-08-30 21:00:00" } + // Add more entries as needed ], - "clouds": { - "all": 39 - }, - "wind": { - "speed": 4.58, - "deg": 83, - "gust": 8.45 - }, - "visibility": 10000, - "pop": 0, - "sys": { - "pod": "d" - }, - "dt_txt": "2022-03-20 09:00:00" -} -], -"city": { -"id": 2643743, -"name": "London", -"coord": { - "lat": 51.5085, - "lon": -0.1257 -}, -"country": "GB", -"population": 1000000, -"timezone": 0, -"sunrise": 1647324902, -"sunset": 1647367441 -} -} -api.openweathermap.org/data/2.5/weather?q=London&mode=xml - - - - - -London - -GB -0 - - - - - -0 - - - - - - - -.... - - - -} -https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&cnt=3&appid={API key} -} -https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&appid={API key} -} -https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&appid={API key}&units=metric -} -https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&appid={API key}&units=imperial -} -http://api.openweathermap.org/data/2.5/forecast?id=524901&lang={lang} -} -http://api.openweathermap.org/data/2.5/forecast?id=524901&lang=zh_cn&appid={API key} -} -api.openweathermap.org/data/2.5/forecast?q=London,uk&callback=test&appid={API key} + city: { + id: 3163858, + name: "Zocca", + coord: { + lat: 44.34, + lon: 10.99 + }, + country: "IT", + population: 4593, + timezone: 7200, + sunrise: 1661834187, + sunset: 1661882248 } +}; + +const WEATHER_API_KEY = '548773e920254208b83a2e2bdadb8f0e'; +const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=London&appid=${WEATHER_API_KEY}`; diff --git a/style.2.css b/style.2.css new file mode 100644 index 0000000..e7e3080 --- /dev/null +++ b/style.2.css @@ -0,0 +1,136 @@ +body { + font-family: 'Montserrat', sans-serif; + margin: 30px; + display: flex; + flex-direction: column; + align-items: center; + } + .cloudy { + background: #F4F7F8; + color: #F47775; + } + + .sunny { + background: #F7E9B9; + color: #2A5510; + } + + .rainy { + background: #A3DEF7; + color: #164A68; + } + + .unknown { + background: #dbf6e9; + color: #31326f; + } + + .todays-numbers { + margin-bottom: 30px; + } + + p { + font-size: 18px; + margin: 2px; + } + + .todays-description h2 { + font-size: 32px; + max-width: 400px; + } + + .todays-description img { + height: 70px; + } + + .forecast { + width: 100%; + max-width: 400px; + } + + .forecast div { + display: flex; + justify-content: space-between; + border-bottom: 1px dashed; + } + + footer { + width: 100%; + max-width: 400px; + } + + input { + background: #F4F7F8; + height: 20px; + width: 200px; + font-size: 16px; + border: 1px solid; + border-radius: 4px; + padding: 4px 8px; + margin: 30px 0; + } + + .cloudy input, .cloudy input::placeholder { + color: #F47775; + } + + .rainy input, .rainy input::placeholder { + color: #164A68; + } + + .sunny input, .sunny input::placeholder { + color: #2A5510; + border-radius: 4px; + } + + button { + color: white; + height: 30px; + font-size: 16px; + border-radius: 4px; + padding: 4px 8px; + border: none; + border-radius: 4px; + } + + .cloudy button { + background: #F47775; + } + + .rainy button { + background: #164A68; + } + + .sunny button { + background: #2A5510; + border-radius: 4px; + } + + .error { + font-size: 14px; + } + + @media (min-width: 668px) { + .todays-numbers p { + font-size: 20px; + } + + .todays-description img { + width: 150px; + } + + .todays-description h2 { + font-size: 38px; + max-width: 500px; + } + + .forecast { + max-width: 500px; + } + + footer { + width: 100%; + max-width: 500px; + } + } + \ No newline at end of file diff --git a/style.css b/style.css index 836b015..8c28103 100644 --- a/style.css +++ b/style.css @@ -1,14 +1,397 @@ -@import url('https://fonts.googleapis.com/css2family=Roboto:wgt100;400;500&display=swap'); -body{ - font-family: 'Roboto' , sans-serif; - .Wheatherapp { - display:flex; - width: 1600px; - flex-wrap: wrap; - } - - .Wheatherapp { +@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap'); + +/*Variables*/ +:root { + /*Colors:*/ + --switch-button-color: #757AFF; /*Remove later, should be set by the gradient*/ + --container-color: #e0e0e0; + + /*Dimensions:*/ + --top-background-bottom-position: 355px; + + /*Other:*/ + --top-background-opacity: 0.7; +} + +body { + font-family: 'Roboto', sans-serif; + margin: 0; + padding:0; + height: 100%; + background-color: var(--container-color); +} + +.nav { + margin-bottom: 0; + display: flex; + align-items: center; + position: relative; +} + +.container { + background-color: var(--container-color); + width: 100%; + max-width: 500px; + margin: 0 auto; + overflow: hidden; + position: relative; + display: flex; + flex-direction: column; + height: 800px; +} + +.feature-image { /*Uses a background img placed over the gradient*/ + background: url('') 50% bottom / contain; /*Set by JS in todaysWeatherFeature*/ + opacity: var(--top-background-opacity); + height: 800px; + width: 800px; + border-radius: 50%; + position: absolute; + bottom: var(--top-background-bottom-position); + right: 50%; + transform: translate(50%); +} + +.background-top-gradient { /*Uses a background gradient behind the transparent image*/ + background-color: black; + height: 800px; + width: 800px; + border-radius: 50%; + position: absolute; + bottom: var(--top-background-bottom-position); + right: 50%; + transform: translate(50%); +} + +.search { + display: flex; + flex-direction: row; + border: 1px solid rgba(255, 255, 255, 0.363); +} + +.search-bar { + margin: auto; + border: none; + padding: 2px 10px; + background-color: rgba(255, 255, 255, 0.3); + color: white; + width: 100%; + max-width: 600px; + height: 30px; + font-size: 17px; /*All font sizes under 16px create the zoom error*/ +} + +.search-bar:focus { + outline: none; +} + +.search-button { + border: none; + color: white; + background-color: transparent; + cursor: pointer; +} + +.search-button:hover { + opacity: 0.7; +} + +.search-icon, +.x-icon { + height: 30px; + width: 30px; + padding: 20px 10px 20px 20px; +} + +svg { + color: white; +} + +.mainWrapper { + color: white; + margin: 0px 20px; + padding: 0 15px 0 15px; + position: relative; +} + +.mainWrapper .tempText { + display: flex; + flex-direction: row; +} + +.mainWrapper .tempNumber { + font-size: 102px; + margin: 0; + font-weight: 900; +} + +.tempTextCelsius { + display: inline; + font-size: 36px; + margin-top: 15px; + margin-left: 5px; +} + +.mainWrapper .cityText { + font-size: 32px; + font-weight: 200; + margin: 0 0 5px 0; +} + +.local-time { + margin: 0; + font-weight: 200; + font-size: 16px; +} + +.description-icon { + display: flex; + margin-top: 0; +} + +.mainWrapper .describeText { + font-size: 16px; + font-weight: 200; + margin: auto 0 auto 0; + text-transform: capitalize; +} + +.main-icon { + object-fit: cover; + height: 62px; + width: 80px; + position: relative; +} + +.sun-position { + position: relative; + display: flex; + flex-direction: row; + justify-content: space-evenly; +} + +#sunriseText, +#sunsetText { + display: flex; + flex-direction: row; + font-size: 16px; +} + +.sun-position .time-data { + margin: auto auto; + padding: 15px; +} + + +.switch-section { + position: relative; +} + +#switchBtn { + background: rgb(22, 60, 82); + border: none; + border-radius: 50%; + width: 90px; + height: 90px; + margin: 0 auto 0 75%; + cursor: pointer; +} + +.fa-solid { + font-size:25px; + color:#ffffff; +} + +/* Feature gradient */ +.background-top-gradient.morning, .background-top-gradient.morning ~ .switch-section #switchBtn { + background: linear-gradient(217deg, rgba(148, 197, 248, 0), rgba(166, 230, 255, 0) 70.71%), + linear-gradient(127deg, rgba(166, 230, 255, 0.8), rgba(177, 181, 234, 0.5) 70.71%), + linear-gradient(336deg, rgb(139, 144, 211), rgba(148, 197, 248, 1) 70.71%); + background-size: 600% 600%; + animation: gradient 5s ease infinite; +} + +.background-top-gradient.midday, .background-top-gradient.midday ~ .switch-section #switchBtn { + + background: linear-gradient(217deg, rgba(91, 131, 106, 0.5), rgba(6, 111, 168, 0.5) 70.71%), + linear-gradient(127deg, rgba(36, 111, 168, 0.8) , rgb(198, 160, 65, 0.5) 70.71%), + linear-gradient(336deg, rgba(36, 111, 168, 1), rgba(91, 131, 106, 1) 70.71%); + background-size: 600% 600%; + animation: gradient 5s ease infinite; +} + +.background-top-gradient.afternoon, .background-top-gradient.afternoon ~ .switch-section #switchBtn { + background: linear-gradient(217deg, rgba(30, 82, 142, 0), rgba(38, 88, 137, 0.5) 70.71%), + linear-gradient(127deg, rgba(157, 166, 113, 0.8), rgba(30, 82, 142, 0.5) 70.71%), + linear-gradient(336deg, rgba(38, 88, 137, 1), rgba(157, 166, 113, 1) 70.71%); + background-size: 600% 600%; + animation: gradient 5s ease infinite; +} + +.background-top-gradient.duskSunset, .background-top-gradient.duskSunset ~ .switch-section #switchBtn { + background: linear-gradient(217deg, rgba(55, 109, 167, 0), rgba(235, 178, 177, 0) 70.71%), + linear-gradient(127deg, rgba(89, 13, 12, 0.8), rgba(96, 22, 7, 0.5) 70.71%), + linear-gradient(336deg, rgb(31, 6, 1), rgb(2, 14, 28) 70.71%); + background-size: 600% 600%; + animation: gradient 5s ease infinite; +} + +.background-top-gradient.evening, .background-top-gradient.evening ~ .switch-section #switchBtn { + background: linear-gradient(217deg, rgba(57, 22, 3, 0), rgba(9, 75, 126, 0.5) 70.71%), + linear-gradient(127deg, rgba(22, 60, 82, 1) , rgba(65, 8, 116, 0.5) 70.71%), + linear-gradient(336deg, rgba(6, 98, 168, 1), rgba(239, 95, 6, 1) 70.71%); + background-size: 600% 600%; + animation: gradient 5s ease infinite; +} + +.background-top-gradient.midnight, .background-top-gradient.midnight ~ .switch-section #switchBtn { + background: linear-gradient(217deg, rgba(36, 14, 3, 0.8), rgba(22, 60, 82, 0) 70.71%), + linear-gradient(127deg, rgba(22, 60, 82, 0.8), rgba(84, 133, 159, 0.5) 70.71%), + linear-gradient(336deg, rgba(36, 72, 94, 1), rgba(7, 27, 38, 1) 70.71%); + background-size: 600% 600%; + animation: gradient 5s ease infinite; +} + +.background-top-gradient.dawnSunrise, .background-top-gradient.dawnSunrise ~ .switch-section #switchBtn { + background: linear-gradient(217deg, rgba(74, 73, 105, 0.1), rgba(205, 130, 160, 0) 70.71%), + linear-gradient(127deg, rgba(205, 130, 160, 0.8), rgba(112, 114, 171, 0.5) 70.71%), + linear-gradient(336deg, rgba(112, 114, 171, 1), rgba(74, 73, 105, 1) 70.71%); + background-size: 600% 600%; + animation: gradient 5s ease infinite; +} + +@keyframes gradient { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +.weather-forecast { padding: 20px; - width: 320px; - } -} \ No newline at end of file + text-align: center; + position: relative; +} + +.weather-forecast-section { + position: relative; +} + +.forecast-category { + width:125px; +} + +th, td { + padding:.25em .5em; + text-align:center; +} + +.forecast-category p { + height:27px; +} + +.weather-icons { + object-fit: cover; + height: 39px; + width: 56px; +} + + +footer { + text-align: center; + color: grey; + position: relative; +} + +footer a, +footer a:visited { + color: grey; + text-decoration: none; +} + +footer a:hover { + opacity: 0.5; + transition: 0.2s ease-in-out; +} + +/* To use when hiding something*/ +.hidden { + display: none; + transition: transform 1s ease 0s; +} + + + +/* For when we look at the app in desktop or tablet: */ +@media (min-width: 500px) { + + :root { + --top-background-bottom-position: 305px; + } + + .container { + box-shadow: 5px 8px 20px rgba(0, 0, 0, 0.3); + width: 100%; + max-width: 400px; + margin: 50px auto; + } + + .feature-image { /*Uses a background img placed over the gradient*/ + bottom: var(--top-background-bottom-position); + } + + .background-top-gradient { /*Uses a background gradient behind the transparent image*/ + bottom: var(--top-background-bottom-position); + } + + .search-bar { + font-size: 14px; + } + + .search-icon, + .x-icon { + height: 35px; + width: 35px; + padding: 25px; + } + + .nav { + margin-bottom: 10px; + } + + .mainWrapper .tempNumber { + font-size: 110px; + } + + .tempTextCelsius { + font-size: 40px; + } + + .mainWrapper .cityText { + font-size: 36px; + } + + .mainWrapper .describeText { + font-size: 18px; + } + + .local-time { + font-size: 18px; + } + + #sunriseText, + #sunsetText { + font-size: 18px; + } + + body { + background-color: #faf9f9; + } + + +} diff --git a/style3.css b/style3.css new file mode 100644 index 0000000..dd846ba --- /dev/null +++ b/style3.css @@ -0,0 +1,91 @@ +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVmZiArmlw.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; + } + /* cyrillic */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVmQiArmlw.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + } + /* greek-ext */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVmYiArmlw.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; + } + /* greek */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVmXiArmlw.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; + } + /* math */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVnoiArmlw.woff2) format('woff2'); + unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF; + } + /* symbols */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVn6iArmlw.woff2) format('woff2'); + unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF; + } + /* vietnamese */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVmbiArmlw.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; + } + /* latin-ext */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVmaiArmlw.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + /* latin */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVmUiAo.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + \ No newline at end of file diff --git a/style4.css b/style4.css new file mode 100644 index 0000000..e7e3080 --- /dev/null +++ b/style4.css @@ -0,0 +1,136 @@ +body { + font-family: 'Montserrat', sans-serif; + margin: 30px; + display: flex; + flex-direction: column; + align-items: center; + } + .cloudy { + background: #F4F7F8; + color: #F47775; + } + + .sunny { + background: #F7E9B9; + color: #2A5510; + } + + .rainy { + background: #A3DEF7; + color: #164A68; + } + + .unknown { + background: #dbf6e9; + color: #31326f; + } + + .todays-numbers { + margin-bottom: 30px; + } + + p { + font-size: 18px; + margin: 2px; + } + + .todays-description h2 { + font-size: 32px; + max-width: 400px; + } + + .todays-description img { + height: 70px; + } + + .forecast { + width: 100%; + max-width: 400px; + } + + .forecast div { + display: flex; + justify-content: space-between; + border-bottom: 1px dashed; + } + + footer { + width: 100%; + max-width: 400px; + } + + input { + background: #F4F7F8; + height: 20px; + width: 200px; + font-size: 16px; + border: 1px solid; + border-radius: 4px; + padding: 4px 8px; + margin: 30px 0; + } + + .cloudy input, .cloudy input::placeholder { + color: #F47775; + } + + .rainy input, .rainy input::placeholder { + color: #164A68; + } + + .sunny input, .sunny input::placeholder { + color: #2A5510; + border-radius: 4px; + } + + button { + color: white; + height: 30px; + font-size: 16px; + border-radius: 4px; + padding: 4px 8px; + border: none; + border-radius: 4px; + } + + .cloudy button { + background: #F47775; + } + + .rainy button { + background: #164A68; + } + + .sunny button { + background: #2A5510; + border-radius: 4px; + } + + .error { + font-size: 14px; + } + + @media (min-width: 668px) { + .todays-numbers p { + font-size: 20px; + } + + .todays-description img { + width: 150px; + } + + .todays-description h2 { + font-size: 38px; + max-width: 500px; + } + + .forecast { + max-width: 500px; + } + + footer { + width: 100%; + max-width: 500px; + } + } + \ No newline at end of file diff --git a/style5.css b/style5.css new file mode 100644 index 0000000..774b245 --- /dev/null +++ b/style5.css @@ -0,0 +1,271 @@ +/* cyrillic-ext */ +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUSjIg1_i6t8kCHKm459WRhyzbi.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; + } + /* cyrillic */ + @font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUSjIg1_i6t8kCHKm459W1hyzbi.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + } + /* vietnamese */ + @font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUSjIg1_i6t8kCHKm459WZhyzbi.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; + } + /* latin-ext */ + @font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUSjIg1_i6t8kCHKm459Wdhyzbi.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + /* latin */ + @font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + /* cyrillic-ext */ + @font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUSjIg1_i6t8kCHKm459WRhyzbi.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; + } + /* cyrillic */ + @font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUSjIg1_i6t8kCHKm459W1hyzbi.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + } + /* vietnamese */ + @font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUSjIg1_i6t8kCHKm459WZhyzbi.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; + } + /* latin-ext */ + @font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUSjIg1_i6t8kCHKm459Wdhyzbi.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + /* latin */ + @font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + /* cyrillic-ext */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3GUBGEe.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; + } + /* cyrillic */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3iUBGEe.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + } + /* greek-ext */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3CUBGEe.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; + } + /* greek */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3-UBGEe.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; + } + /* math */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMawCUBGEe.woff2) format('woff2'); + unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF; + } + /* symbols */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMaxKUBGEe.woff2) format('woff2'); + unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF; + } + /* vietnamese */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3OUBGEe.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; + } + /* latin-ext */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3KUBGEe.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + /* latin */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3yUBA.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + /* cyrillic-ext */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3GUBGEe.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; + } + /* cyrillic */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3iUBGEe.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + } + /* greek-ext */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3CUBGEe.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; + } + /* greek */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3-UBGEe.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; + } + /* math */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMawCUBGEe.woff2) format('woff2'); + unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF; + } + /* symbols */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMaxKUBGEe.woff2) format('woff2'); + unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF; + } + /* vietnamese */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3OUBGEe.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; + } + /* latin-ext */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3KUBGEe.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + /* latin */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v47/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3yUBA.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + \ No newline at end of file diff --git a/svg.xml b/svg.xml new file mode 100644 index 0000000..c220251 --- /dev/null +++ b/svg.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/weather.js b/weather.js new file mode 100644 index 0000000..6213441 --- /dev/null +++ b/weather.js @@ -0,0 +1,189 @@ +const API_KEY = "548773e920254208b83a2e2bdadb8f0e"; +const body = document.getElementById("body"); + +const shortDescription = document.getElementById("shortDescription"); +const temperature = document.getElementById("temperature"); +const sunrise = document.getElementById("sunrise"); +const sunset = document.getElementById("sunset"); +const description = document.getElementById("description"); +const forecast = document.getElementById("forecast"); +const icon = document.getElementById("icon"); +const errorMessage = document.getElementById("error"); + +const chosenCity = document.getElementById("chosenCity"); +const searchButton = document.getElementById("citySearchButton"); + +let city = "London"; + +//Change description and styling +//based on weather +const pickTodaysDescription = (todaysDescription) => { + body.classList.remove(...body.classList); + + if (todaysDescription === "Clouds") { + icon.src = "./assets/d2-cloud.svg"; + body.classList.add("cloudy"); + description.innerHTML = `Light a fire and get cosy. ${city} is looking grey today.`; + } else if (todaysDescription === "Clear") { + icon.src = "./assets/d2-sun.svg"; + body.classList.add("sunny"); + description.innerHTML = `Get your sunnies on. ${city} is looking rather great today.`; + } else if ( + todaysDescription === "Rain" || + todaysDescription === "Thunderstorm" || + todaysDescription === "Drizzle" || + todaysDescription === "Snow" + ) { + icon.src = "./assets/d2-rain.svg"; + body.classList.add("rainy"); + description.innerHTML = `Don't forget your umbrella. It's wet in ${city} today.`; + } else { + icon.src = "./assets/d2-unknown.svg"; + body.classList.add("unknown"); + description.innerHTML = `Be careful today in ${city}!`; + } +}; + +const capitalizeFirstLetter = (string) => { + return `${string.charAt(0).toUpperCase()}${string.slice(1)}`; +}; + +//Fetching the weather data for today +const fetchWeather = (city) => { + fetch( + `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&APPID=${API_KEY}` + ) + .then((response) => { + return response.json(); + }) + .then((json) => { + const sunriseTime = new Date((json.sys.sunrise + json.timezone) * 1000); //Gives us the time in "human" form (as a date), mult. by 1000 to get it in ms. + sunriseTime.setMinutes( + sunriseTime.getMinutes() + sunriseTime.getTimezoneOffset() + ); + + const sunsetTime = new Date((json.sys.sunset + json.timezone) * 1000); + sunsetTime.setMinutes( + sunsetTime.getMinutes() + sunsetTime.getTimezoneOffset() + ); + console.log(sunriseTime); + + if (json.cod === "404") { + errorMessage.innerHTML = + "Can't find what you're looking for. Try another city,
or add the country as well: 'Stockholm, Sweden'!"; + } else { + errorMessage.innerHTML = ""; + const todaysWeather = { + temperature: json.main.temp.toFixed(), + weather: json.weather[0], + sunrise: sunriseTime.toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + }), + sunset: sunsetTime.toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + }), + }; + shortDescription.innerHTML = todaysWeather.weather.description; + temperature.innerHTML = `${todaysWeather.temperature} °C`; + sunrise.innerHTML = `sunrise ${todaysWeather.sunrise}`; + sunset.innerHTML = `sunset ${todaysWeather.sunset}`; + + pickTodaysDescription(todaysWeather.weather.main); + } + }); +}; + +let dates = {}; + +const convertDate = (date) => { + //Get the correct day + const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + const wholeDate = new Date(date); + const dayName = dayNames[wholeDate.getDay()]; + return dayName; +}; + +//Fetching forecast +const fetchForecast = (city) => { + fetch( + `https://api.openweathermap.org/data/2.5/forecast?q=${city}&units=metric&APPID=${API_KEY}` + ) + .then((response) => { + return response.json(); + }) + .then((json) => { + if (json.list) { + json.list.forEach((weather) => { + const date = weather.dt_txt.split(" ")[0]; + if (dates[date]) { + dates[date].push(weather); + } else { + dates[date] = [weather]; + } + }); + + //Emptying the forecast before populating it + forecast.innerHTML = ""; + + //Getting weather values + Object.entries(dates).forEach((item, index) => { + dates = {}; + const date = item[0]; + const weatherValues = item[1]; + const temps = weatherValues.map((value) => value.main.temp); + + const sum = temps.reduce((a, b) => a + b, 0); + let averageTemp = sum / temps.length || 0; + + if (index === 0) { + return; + } + + let fixedTemp = averageTemp.toFixed(); + if (fixedTemp === "-0") { + fixedTemp = "0"; + } + + const day = convertDate(date); + + try { + forecast.innerHTML += ` +
+

${day}

+

${fixedTemp} °C

+
+ `; + } catch (error) { + console.log(`Next day of forecast will come soon`); + } + }); + } else { + console.log("No forecast available"); + } + }); +}; + +//Fetch again with new city input +const changeCity = () => { + city = capitalizeFirstLetter(chosenCity.value); + fetchWeather(city); + fetchForecast(city); + chosenCity.value = ""; +}; + +//Listening to enter press when search for city +chosenCity.addEventListener("keyup", (event) => { + if (event.key === "Enter") { + changeCity(); + } +}); + +searchButton.addEventListener("click", () => { + changeCity(); +}); + +//Fetch Stockholm data on page load +fetchWeather(city); +fetchForecast(city); diff --git a/weather.xml b/weather.xml new file mode 100644 index 0000000..5c51199 --- /dev/null +++ b/weather.xml @@ -0,0 +1,809 @@ + +http://api.openweathermap.org/geo/1.0/reverse?lat={lat}&lon={lon}&limit={limit}&appid={http://api.openweathermap.org/geo/1.0/reverse?lat={lat}&lon={lon}&limit={limit}&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +}} +[ + { + "name":"London", + "local_names":{ + "ms":"London", + "gu":"લંડન", + "is":"London", + "wa":"Londe", + "mg":"Lôndôna", + "gl":"Londres", + "om":"Landan", + "ku":"London", + "tw":"London", + "mk":"Лондон", + "ee":"London", + "fj":"Lodoni", + "gd":"Lunnainn", + "ky":"Лондон", + "yo":"Lọndọnu", + "zu":"ILondon", + "bg":"Лондон", + "tk":"London", + "co":"Londra", + "sh":"London", + "de":"London", + "kl":"London", + "bi":"London", + "km":"ឡុងដ៍", + "lt":"Londonas", + "fi":"Lontoo", + "fy":"Londen", + "ba":"Лондон", + "sc":"Londra", + "feature_name":"London", + "ja":"ロンドン", + "am":"ለንደን", + "sk":"Londýn", + "mr":"लंडन", + "es":"Londres", + "sq":"Londra", + "te":"లండన్", + "br":"Londrez", + "uz":"London", + "da":"London", + "sw":"London", + "fa":"لندن", + "sr":"Лондон", + "cu":"Лондонъ", + "ln":"Lóndɛlɛ", + "na":"London", + "wo":"Londar", + "ig":"London", + "to":"Lonitoni", + "ta":"இலண்டன்", + "mt":"Londra", + "ar":"لندن", + "su":"London", + "ab":"Лондон", + "ps":"لندن", + "bm":"London", + "mi":"Rānana", + "kn":"ಲಂಡನ್", + "kv":"Лондон", + "os":"Лондон", + "bn":"লন্ডন", + "li":"Londe", + "vi":"Luân Đôn", + "zh":"伦敦", + "eo":"Londono", + "ha":"Landan", + "tt":"Лондон", + "lb":"London", + "ce":"Лондон", + "hu":"London", + "it":"Londra", + "tl":"Londres", + "pl":"Londyn", + "sm":"Lonetona", + "en":"London", + "vo":"London", + "el":"Λονδίνο", + "sn":"London", + "fr":"Londres", + "cs":"Londýn", + "io":"London", + "hi":"लंदन", + "et":"London", + "pa":"ਲੰਡਨ", + "av":"Лондон", + "ko":"런던", + "bh":"लंदन", + "yi":"לאנדאן", + "sa":"लन्डन्", + "sl":"London", + "hr":"London", + "si":"ලන්ඩන්", + "so":"London", + "gn":"Lóndyre", + "ay":"London", + "se":"London", + "sd":"لنڊن", + "af":"Londen", + "ga":"Londain", + "or":"ଲଣ୍ଡନ", + "ia":"London", + "ie":"London", + "ug":"لوندۇن", + "nl":"Londen", + "gv":"Lunnin", + "qu":"London", + "be":"Лондан", + "an":"Londres", + "fo":"London", + "hy":"Լոնդոն", + "nv":"Tooh Dineʼé Bikin Haalʼá", + "bo":"ལོན་ཊོན།", + "ascii":"London", + "id":"London", + "lv":"Londona", + "ca":"Londres", + "no":"London", + "nn":"London", + "ml":"ലണ്ടൻ", + "my":"လန်ဒန်မြို့", + "ne":"लन्डन", + "he":"לונדון", + "cy":"Llundain", + "lo":"ລອນດອນ", + "jv":"London", + "sv":"London", + "mn":"Лондон", + "tg":"Лондон", + "kw":"Loundres", + "cv":"Лондон", + "az":"London", + "oc":"Londres", + "th":"ลอนดอน", + "ru":"Лондон", + "ny":"London", + "bs":"London", + "st":"London", + "ro":"Londra", + "rm":"Londra", + "ff":"London", + "kk":"Лондон", + "uk":"Лондон", + "pt":"Londres", + "tr":"Londra", + "eu":"Londres", + "ht":"Lonn", + "ka":"ლონდონი", + "ur":"علاقہ لندن" + }, + "lat":51.5073219, + "lon":-0.1276474, + "country":"GB", + "state":"England" + }, + { + "name":"City of London", + "local_names":{ + "es":"City de Londres", + "ru":"Сити", + "ur":"لندن شہر", + "zh":"倫敦市", + "en":"City of London", + "pt":"Cidade de Londres", + "fr":"Cité de Londres", + "uk":"Лондонське Сіті", + "he":"הסיטי של לונדון", + "hi":"सिटी ऑफ़ लंदन", + "ko":"시티 오브 런던", + "lt":"Londono Sitis" + }, + "lat":51.5156177, + "lon":-0.0919983, + "country":"GB", + "state":"England" + }, + { + "name":"London", + "local_names":{ + "el":"Λόντον", + "fr":"London", + "oj":"Baketigweyaang", + "en":"London", + "bn":"লন্ডন", + "be":"Лондан", + "ko":"런던", + "he":"לונדון", + "ru":"Лондон", + "lt":"Londonas", + "hy":"Լոնտոն", + "ga":"Londain", + "ja":"ロンドン", + "yi":"לאנדאן", + "cr":"ᓬᐊᐣᑕᐣ", + "iu":"ᓚᓐᑕᓐ", + "ar":"لندن", + "lv":"Landona", + "fa":"لندن", + "ug":"لوندۇن", + "th":"ลอนดอน", + "ka":"ლონდონი" + }, + "lat":42.9832406, + "lon":-81.243372, + "country":"CA", + "state":"Ontario" + }, + { + "name":"Chelsea", + "local_names":{ + "id":"Chelsea, London", + "uk":"Челсі", + "hi":"चेल्सी, लंदन", + "ga":"Chelsea", + "es":"Chelsea", + "de":"Chelsea", + "af":"Chelsea, Londen", + "vi":"Chelsea, Luân Đôn", + "pl":"Chelsea", + "pt":"Chelsea", + "da":"Chelsea", + "ko":"첼시", + "sv":"Chelsea, London", + "nl":"Chelsea", + "az":"Çelsi", + "it":"Chelsea", + "hu":"Chelsea", + "no":"Chelsea", + "fr":"Chelsea", + "he":"צ'לסי", + "eu":"Chelsea", + "ru":"Челси", + "ar":"تشيلسي", + "en":"Chelsea", + "el":"Τσέλσι", + "tr":"Chelsea, Londra", + "zh":"車路士", + "sh":"Chelsea, London", + "ja":"チェルシー", + "ur":"چیلسی، لندن", + "sk":"Chelsea", + "fa":"چلسی", + "et":"Chelsea" + }, + "lat":51.4875167, + "lon":-0.1687007, + "country":"GB", + "state":"England" + }, + { + "name":"London", + "lat":37.1289771, + "lon":-84.0832646, + "country":"US", + "state":"Kentucky" + } + [ + { + "name": "City of London", + "local_names": { + "ar": "مدينة لندن", + "ascii": "City of London", + "bg": "Сити", + "ca": "La City", + "de": "London City", + "el": "Σίτι του Λονδίνου", + "en": "City of London", + "fa": "سیتی لندن", + "feature_name": "City of London", + "fi": "Lontoon City", + "fr": "Cité de Londres", + "gl": "Cidade de Londres", + "he": "הסיטי של לונדון", + "hi": "सिटी ऑफ़ लंदन", + "id": "Kota London", + "it": "Londra", + "ja": "シティ・オブ・ロンドン", + "la": "Civitas Londinium", + "lt": "Londono Sitis", + "pt": "Cidade de Londres", + "ru": "Сити", + "sr": "Сити", + "th": "นครลอนดอน", + "tr": "Londra Şehri", + "vi": "Thành phố Luân Đôn", + "zu": "Idolobha weLondon" + }, + "lat": 51.5128, + "lon": -0.0918, + "country": "GB" + }, + { + "name": "London", + "local_names": { + "af": "Londen", + "ar": "لندن", + "ascii": "London", + "az": "London", + "bg": "Лондон", + "ca": "Londres", + "da": "London", + "de": "London", + "el": "Λονδίνο", + "en": "London", + "eu": "Londres", + "fa": "لندن", + "feature_name": "London", + "fi": "Lontoo", + "fr": "Londres", + "gl": "Londres", + "he": "לונדון", + "hi": "लंदन", + "hr": "London", + "hu": "London", + "id": "London", + "it": "Londra", + "ja": "ロンドン", + "la": "Londinium", + "lt": "Londonas", + "mk": "Лондон", + "nl": "Londen", + "no": "London", + "pl": "Londyn", + "pt": "Londres", + "ro": "Londra", + "ru": "Лондон", + "sk": "Londýn", + "sl": "London", + "sr": "Лондон", + "th": "ลอนดอน", + "tr": "Londra", + "vi": "Luân Đôn", + "zu": "ILondon" + }, + "lat": 51.5085, + "lon": -0.1257, + "country": "GB" + }, + { + "name": "Islington", + "local_names": { + "ascii": "Islington", + "az": "İslinqton", + "fa": "ایزلینتن", + "feature_name": "Islington", + "fr": "District londonien d'Islington", + "he": "איזלינגטון", + "ja": "イズリントン", + "ru": "Ислингтон" + }, + "lat": 51.5362, + "lon": -0.103, + "country": "GB" + }, + { + "name": "Lewisham", + "local_names": { + "ascii": "Lewisham", + "de": "London Borough of Lewisham", + "en": "Lewisham", + "feature_name": "Lewisham", + "fi": "Lewisham", + "fr": "Lewisham", + "hu": "Lewisham kerület", + "nl": "Lewisham", + "no": "Lewisham", + "ro": "Lewisham" + }, + "lat": 51.4535, + "lon": -0.018, + "country": "GB" + }, + { + "name": "Islington", + "local_names": { + "ascii": "Islington", + "de": "London Borough of Islington", + "en": "Islington", + "feature_name": "Islington", + "fr": "Islington", + "nl": "Islington", + "no": "Islington", + "ro": "Islington" + }, + "lat": 51.547, + "lon": -0.1094, + "country": "GB" + } +] + + + + + +Zocca + +IT +7200 + + + + + +0 + + + + + + + +... + + + +{ +"main":{ +"temp":306.15, //current temperature +"pressure":1013, +"humidity":44, +"temp_min":30.15, //min current temperature in the city +"temp_max":306.15 //max current temperature in the city +}, + + "dt":1406080800, +"temp":{ + "day":297.77, //daily averaged temperature + "min":293.52, //daily min temperature + "max":297.77, //daily max temperature + "night":293.52, //night temperature + "eve":297.77, //evening temperature + "morn":297.77}, //morning temperature + +} +api.openweathermap.org/data/2.5/forecast?q={city name}&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} + +api.openweathermap.org/data/2.5/forecast?q={city name},{country code}&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} + +api.openweathermap.org/data/2.5/forecast?q={city name},{state code},{country code}&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} +} +api.openweathermap.org/data/2.5/forecast?q=London,us&mode=xml&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} +} +api.openweathermap.org/data/2.5/forecast?q=München,DE&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} +} +api.openweathermap.org/data/2.5/forecast?id={city ID}&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} +} +api.openweathermap.org/data/2.5/forecast?id=524901&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} +} +api.openweathermap.org/data/2.5/forecast?zip={zip code},{country code}&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} +} +api.openweathermap.org/data/2.5/forecast?zip=94040,us&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} +} +api.openweathermap.org/data/2.5/weather?q=London&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} + + + +{ +"cod": "200", +"message": 0, +"cnt": 40, +"list": [ +{ + "dt": 1647345600, + "main": { + "temp": 287.39, + "feels_like": 286.38, + "temp_min": 286.69, + "temp_max": 287.39, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1018, + "humidity": 58, + "temp_kf": 0.7 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 71 + }, + "wind": { + "speed": 3.08, + "deg": 128, + "gust": 4.3 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-15 12:00:00" +}, +{ + "dt": 1647356400, + "main": { + "temp": 287.09, + "feels_like": 286.13, + "temp_min": 286.5, + "temp_max": 287.09, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1016, + "humidity": 61, + "temp_kf": 0.59 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 81 + }, + "wind": { + "speed": 3.28, + "deg": 168, + "gust": 3.96 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-15 15:00:00" +}, +{ + "dt": 1647367200, + "main": { + "temp": 285.44, + "feels_like": 284.6, + "temp_min": 284.47, + "temp_max": 285.44, + "pressure": 1020, + "sea_level": 1020, + "grnd_level": 1016, + "humidity": 72, + "temp_kf": 0.97 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 90 + }, + "wind": { + "speed": 2.7, + "deg": 183, + "gust": 5.59 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-15 18:00:00" +}, +..... + { + "dt": 1647766800, + "main": { + "temp": 282.42, + "feels_like": 280, + "temp_min": 282.42, + "temp_max": 282.42, + "pressure": 1036, + "sea_level": 1036, + "grnd_level": 1033, + "humidity": 60, + "temp_kf": 0 + }, + "weather": [ + { + "id": 802, + "main": "Clouds", + "description": "scattered clouds", + "icon": "03d" + } + ], + "clouds": { + "all": 39 + }, + "wind": { + "speed": 4.58, + "deg": 83, + "gust": 8.45 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2022-03-20 09:00:00" +} +], +"city": { +"id": 2643743, +"name": "London", +"coord": { + "lat": 51.5085, + "lon": -0.1257 +}, +"country": "GB", +"population": 1000000, +"timezone": 0, +"sunrise": 1647324902, +"sunset": 1647367441 +} +} +api.openweathermap.org/data/2.5/weather?q=London&mode=xml + + + + + +London + +GB +0 + + + + + +0 + + + + + + + +.... + + + + +"main":{ + "temp":306.15, //current temperature + "pressure":1013, + "humidity":44, + "temp_min":30.15, //min current temperature in the city + "temp_max":306.15 //max current temperature in the city +}, +"dt":1406080800, +"temp":{ + "day":297.77, //daily averaged temperature + "min":293.52, //daily min temperature + "max":297.77, //daily max temperature + "night":293.52, //night temperature + "eve":297.77, //evening temperature + "morn":297.77}, //morning temperature + + api.openweathermap.org/data/2.5/forecast?q={city name}&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} + +api.openweathermap.org/data/2.5/forecast?q={city name},{country code}&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} + +api.openweathermap.org/data/2.5/forecast?q={city name},{state code},{country code}&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} + + + +} +https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&cnt=3&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} +} +https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} +} +https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +}&units=metric +} +https://api.openweathermap.org/data/2.5/forecast?lat=57&lon=-2.15&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +}&units=imperial +} +http://api.openweathermap.org/data/2.5/forecast?id=524901&lang={lang} +} +http://api.openweathermap.org/data/2.5/forecast?id=524901&lang=zh_cn&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} +} +api.openweathermap.org/data/2.5/forecast?q=London,uk&callback=test&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={api.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid={548773e920254208b83a2e2bdadb8f0e} +} + }