mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-06-27 03:39:55 +00:00
Add new weather data provider UK Met Office (Datapoint)
This commit is contained in:
parent
b508a629e8
commit
c80e04fe8d
12
modules/default/weather/README.md
Normal file → Executable file
12
modules/default/weather/README.md
Normal file → Executable file
@ -35,9 +35,9 @@ The following properties can be configured:
|
||||
|
||||
| Option | Description
|
||||
| ---------------------------- | -----------
|
||||
| `weatherProvider` | Which weather provider should be used. <br><br> **Possible values:** `openweathermap` , `darksky` , or `weathergov` <br> **Default value:** `openweathermap`
|
||||
| `weatherProvider` | Which weather provider should be used. <br><br> **Possible values:** `openweathermap` , `darksky` , `weathergov` or `ukmetoffice`<br> **Default value:** `openweathermap`
|
||||
| `type` | Which type of weather data should be displayed. <br><br> **Possible values:** `current` or `forecast` <br> **Default value:** `current`
|
||||
| `units` | What units to use. Specified by config.js <br><br> **Possible values:** `config.units` = Specified by config.js, `default` = Kelvin, `metric` = Celsius, `imperial` = Fahrenheit <br> **Default value:** `config.units`
|
||||
| `units` | What units to use. Specified by config.js <br><br> **Possible values:** `config.units` = Specified by config.js, `default` = Kelvin, `metric` = Celsius, `imperial` = Fahrenheit, `ukunits` = Celsius (wind speed mph) <br> **Default value:** `config.units`
|
||||
| `roundTemp` | Round temperature value to nearest integer. <br><br> **Possible values:** `true` (round to integer) or `false` (display exact value with decimal point) <br> **Default value:** `false`
|
||||
| `degreeLabel` | Show the degree label for your chosen units (Metric = C, Imperial = F, Kelvin = K). <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
|
||||
| `updateInterval` | How often does the content needs to be fetched? (Milliseconds) <br><br> **Possible values:** `1000` - `86400000` <br> **Default value:** `600000` (10 minutes)
|
||||
@ -105,6 +105,14 @@ The following properties can be configured:
|
||||
| `lat` | The geo coordinate latitude. <br><br> This value is **REQUIRED**
|
||||
| `lon` | The geo coordinate longitude. <br><br> This value is **REQUIRED**
|
||||
|
||||
### UK Met Office options
|
||||
|
||||
| Option | Description
|
||||
| ---------------------------- | -----------
|
||||
| `apiBase` | The UKMO base URL. <br><br> **Possible value:** `'http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/'` <br> This value is **REQUIRED**
|
||||
| `locationId` | The UKMO API location code. <br><br> **Possible values:** `322942` <br> This value is **REQUIRED**
|
||||
| `apiKey` | The [UK Met Office](https://www.metoffice.gov.uk/datapoint/getting-started) API key, which can be obtained by creating an UKMO Datapoint account. <br><br> This value is **REQUIRED**
|
||||
|
||||
## API Provider Development
|
||||
|
||||
If you want to add another API provider checkout the [Guide](providers).
|
||||
|
9
modules/default/weather/current.njk
Normal file → Executable file
9
modules/default/weather/current.njk
Normal file → Executable file
@ -56,11 +56,18 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if config.showFeelsLike and not config.onlyTemp %}
|
||||
{% if (config.showFeelsLike or config.showPrecipitationAmount) and not config.onlyTemp %}
|
||||
<div class="normal medium">
|
||||
{% if config.showFeelsLike %}
|
||||
<span class="dimmed">
|
||||
{{ "FEELS" | translate }} {{ current.feelsLike() | roundValue | unit("temperature") | decimalSymbol }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if config.showPrecipitationAmount %}
|
||||
<span class="dimmed">
|
||||
{{ "PRECIP" | translate }} {{ current.precipitation | unit("precip") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
|
6
modules/default/weather/providers/README.md
Normal file → Executable file
6
modules/default/weather/providers/README.md
Normal file → Executable file
@ -91,9 +91,9 @@ A convenience function to make requests. It returns a promise.
|
||||
|
||||
| Property | Type | Value/Unit |
|
||||
| --- | --- | --- |
|
||||
| units | `string` | Gets initialized with the constructor. <br> Possible values: `metric` and `imperial` |
|
||||
| units | `string` | Gets initialized with the constructor. <br> Possible values: `metric`, `imperial` and `ukunits` |
|
||||
| date | `object` | [Moment.js](https://momentjs.com/) object of the time/date. |
|
||||
| windSpeed |`number` | Metric: `meter/second` <br> Imperial: `miles/hour` |
|
||||
| windSpeed |`number` | Metric: `meter/second` <br> Imperial: `miles/hour` <br> UKunits: `miles/hour` |
|
||||
| windDirection |`number` | Direction of the wind in degrees. |
|
||||
| sunrise |`object` | [Moment.js](https://momentjs.com/) object of sunrise. |
|
||||
| sunset |`object` | [Moment.js](https://momentjs.com/) object of sunset. |
|
||||
@ -104,7 +104,7 @@ A convenience function to make requests. It returns a promise.
|
||||
| humidity | `number` | Percentage of humidity |
|
||||
| rain | `number` | Metric: `millimeters` <br> Imperial: `inches` |
|
||||
| snow | `number` | Metric: `millimeters` <br> Imperial: `inches` |
|
||||
| precipitation | `number` | Metric: `millimeters` <br> Imperial: `inches` |
|
||||
| precipitation | `number` | Metric: `millimeters` <br> Imperial: `inches` <br> Ukunits: `percent` |
|
||||
|
||||
#### Current weather
|
||||
|
||||
|
263
modules/default/weather/providers/ukmetoffice.js
Executable file
263
modules/default/weather/providers/ukmetoffice.js
Executable file
@ -0,0 +1,263 @@
|
||||
/* global WeatherProvider, WeatherObject */
|
||||
|
||||
/* Magic Mirror
|
||||
* Module: Weather
|
||||
*
|
||||
* By Malcolm Oakes https://github.com/maloakes
|
||||
* MIT Licensed.
|
||||
*
|
||||
* This class is a provider for UK Met Office Datapoint.
|
||||
*/
|
||||
|
||||
|
||||
WeatherProvider.register("ukmetoffice", {
|
||||
|
||||
// Set the name of the provider.
|
||||
// This isn't strictly necessary, since it will fallback to the provider identifier
|
||||
// But for debugging (and future alerts) it would be nice to have the real name.
|
||||
providerName: "UK Met Office",
|
||||
|
||||
units: {
|
||||
imperial: "us",
|
||||
metric: "si",
|
||||
ukunits: "uk"
|
||||
},
|
||||
|
||||
// Overwrite the fetchCurrentWeather method.
|
||||
fetchCurrentWeather() {
|
||||
this.fetchData(this.getUrl("3hourly"))
|
||||
.then(data => {
|
||||
if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location ||
|
||||
!data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length == 0) {
|
||||
// Did not receive usable new data.
|
||||
// Maybe this needs a better check?
|
||||
return;
|
||||
}
|
||||
|
||||
this.setFetchedLocation(`${data.SiteRep.DV.Location.name}, ${data.SiteRep.DV.Location.country}`);
|
||||
|
||||
const currentWeather = this.generateWeatherObjectFromCurrentWeather(data);
|
||||
this.setCurrentWeather(currentWeather);
|
||||
})
|
||||
.catch(function(request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
})
|
||||
},
|
||||
|
||||
// Overwrite the fetchCurrentWeather method.
|
||||
fetchWeatherForecast() {
|
||||
this.fetchData(this.getUrl("daily"))
|
||||
.then(data => {
|
||||
if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location ||
|
||||
!data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length == 0) {
|
||||
// Did not receive usable new data.
|
||||
// Maybe this needs a better check?
|
||||
return;
|
||||
}
|
||||
|
||||
this.setFetchedLocation(`${data.SiteRep.DV.Location.name}, ${data.SiteRep.DV.Location.country}`);
|
||||
|
||||
const forecast = this.generateWeatherObjectsFromForecast(data);
|
||||
this.setWeatherForecast(forecast);
|
||||
})
|
||||
.catch(function(request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
|
||||
/** UK Met Office Specific Methods - These are not part of the default provider methods */
|
||||
/*
|
||||
* Gets the complete url for the request
|
||||
*/
|
||||
getUrl(forecastType) {
|
||||
return this.config.apiBase + this.config.locationID + this.getParams(forecastType);
|
||||
},
|
||||
|
||||
/*
|
||||
* Generate a WeatherObject based on currentWeatherInformation
|
||||
*/
|
||||
generateWeatherObjectFromCurrentWeather(currentWeatherData) {
|
||||
const currentWeather = new WeatherObject(this.config.units);
|
||||
|
||||
// data times are always UTC
|
||||
let nowUtc = moment.utc()
|
||||
let midnightUtc = nowUtc.clone().startOf("day")
|
||||
let timeInMins = nowUtc.diff(midnightUtc, "minutes");
|
||||
|
||||
// loop round each of the (5) periods, look for today (the first period may be yesterday)
|
||||
for (i in currentWeatherData.SiteRep.DV.Location.Period) {
|
||||
let periodDate = moment.utc(currentWeatherData.SiteRep.DV.Location.Period[i].value.substr(0,10), "YYYY-MM-DD")
|
||||
|
||||
// ignore if period is before today
|
||||
if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) {
|
||||
|
||||
// check this is the period we want, after today the diff will be -ve
|
||||
if (moment().diff(periodDate, "minutes") > 0) {
|
||||
// loop round the reports looking for the one we are in
|
||||
// $ value specifies the time in minutes-of-the-day: 0, 180, 360,...1260
|
||||
for (j in currentWeatherData.SiteRep.DV.Location.Period[i].Rep){
|
||||
let p = currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].$;
|
||||
if (timeInMins >= p && timeInMins-180 < p) {
|
||||
// finally got the one we want, so populate weather object
|
||||
currentWeather.humidity = currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].H;
|
||||
currentWeather.temperature = this.convertTemp(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].T);
|
||||
currentWeather.feelsLikeTemp = this.convertTemp(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].F);
|
||||
currentWeather.precipitation = parseInt(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].Pp);
|
||||
currentWeather.windSpeed = this.convertWindSpeed(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].S);
|
||||
currentWeather.windDirection = this.convertWindDirection(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].D);
|
||||
currentWeather.weatherType = this.convertWeatherType(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].W);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// determine the sunrise/sunset times - not supplied in UK Met Office data
|
||||
let times = this.calcAstroData(currentWeatherData.SiteRep.DV.Location)
|
||||
currentWeather.sunrise = times[0];
|
||||
currentWeather.sunset = times[1];
|
||||
|
||||
return currentWeather;
|
||||
},
|
||||
|
||||
/*
|
||||
* Generate WeatherObjects based on forecast information
|
||||
*/
|
||||
generateWeatherObjectsFromForecast(forecasts) {
|
||||
|
||||
const days = [];
|
||||
|
||||
// loop round the (5) periods getting the data
|
||||
// for each period array, Day is [0], Night is [1]
|
||||
for (j in forecasts.SiteRep.DV.Location.Period) {
|
||||
const weather = new WeatherObject(this.config.units);
|
||||
|
||||
// data times are always UTC
|
||||
dateStr = forecasts.SiteRep.DV.Location.Period[j].value
|
||||
let periodDate = moment.utc(dateStr.substr(0,10), "YYYY-MM-DD")
|
||||
|
||||
// ignore if period is before today
|
||||
if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) {
|
||||
// populate the weather object
|
||||
weather.date = moment.utc(dateStr.substr(0,10), "YYYY-MM-DD");
|
||||
weather.minTemperature = this.convertTemp(forecasts.SiteRep.DV.Location.Period[j].Rep[1].Nm);
|
||||
weather.maxTemperature = this.convertTemp(forecasts.SiteRep.DV.Location.Period[j].Rep[0].Dm);
|
||||
weather.weatherType = this.convertWeatherType(forecasts.SiteRep.DV.Location.Period[j].Rep[0].W);
|
||||
weather.precipitation = parseInt(forecasts.SiteRep.DV.Location.Period[j].Rep[0].PPd);
|
||||
|
||||
days.push(weather);
|
||||
}
|
||||
}
|
||||
|
||||
return days;
|
||||
},
|
||||
|
||||
/*
|
||||
* calculate the astronomical data
|
||||
*/
|
||||
calcAstroData(location) {
|
||||
const sunTimes = [];
|
||||
|
||||
// determine the sunrise/sunset times
|
||||
let times = SunCalc.getTimes(new Date(), location.lat, location.lon);
|
||||
sunTimes.push(moment(times.sunrise, "X"));
|
||||
sunTimes.push(moment(times.sunset, "X"));
|
||||
|
||||
return sunTimes;
|
||||
},
|
||||
|
||||
/*
|
||||
* Convert the Met Office icons to a more usable name.
|
||||
*/
|
||||
convertWeatherType(weatherType) {
|
||||
const weatherTypes = {
|
||||
0: "night-clear",
|
||||
1: "day-sunny",
|
||||
2: "night-alt-cloudy",
|
||||
3: "day-cloudy",
|
||||
5: "fog",
|
||||
6: "fog",
|
||||
7: "cloudy",
|
||||
8: "cloud",
|
||||
9: "night-sprinkle",
|
||||
10: "day-sprinkle",
|
||||
11: "raindrops",
|
||||
12: "sprinkle",
|
||||
13: "night-alt-showers",
|
||||
14: "day-showers",
|
||||
15: "rain",
|
||||
16: "night-alt-sleet",
|
||||
17: "day-sleet",
|
||||
18: "sleet",
|
||||
19: "night-alt-hail",
|
||||
20: "day-hail",
|
||||
21: "hail",
|
||||
22: "night-alt-snow",
|
||||
23: "day-snow",
|
||||
24: "snow",
|
||||
25: "night-alt-snow",
|
||||
26: "day-snow",
|
||||
27: "snow",
|
||||
28: "night-alt-thunderstorm",
|
||||
29: "day-thunderstorm",
|
||||
30: "thunderstorm"
|
||||
};
|
||||
|
||||
return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null;
|
||||
},
|
||||
|
||||
/*
|
||||
* Convert temp (from degrees C) if required
|
||||
*/
|
||||
convertTemp(tempInC) {
|
||||
return this.units === "imperial" ? tempInC * 9 / 5 + 32 : tempInC;
|
||||
},
|
||||
|
||||
/*
|
||||
* Convert wind speed (from mph) if required
|
||||
*/
|
||||
convertWindSpeed(windInMph) {
|
||||
return this.units === "metric" ? windInMph * 2.23694 : windInMph;
|
||||
},
|
||||
|
||||
/*
|
||||
* Convert the wind direction cardinal to value
|
||||
*/
|
||||
convertWindDirection(windDirection) {
|
||||
const windCardinals = {
|
||||
"N": 0,
|
||||
"NNE": 22,
|
||||
"NE": 45,
|
||||
"ENE": 67,
|
||||
"E": 90,
|
||||
"ESE": 112,
|
||||
"SE": 135,
|
||||
"SSE": 157,
|
||||
"S": 180,
|
||||
"SSW": 202,
|
||||
"SW": 225,
|
||||
"WSW": 247,
|
||||
"W": 270,
|
||||
"WNW": 292,
|
||||
"NW": 315,
|
||||
"NNW": 337
|
||||
};
|
||||
|
||||
return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null;
|
||||
},
|
||||
|
||||
/*
|
||||
* Generates an url with api parameters based on the config.
|
||||
*
|
||||
* return String - URL params.
|
||||
*/
|
||||
getParams(forecastType) {
|
||||
let params = "?";
|
||||
params += "res=" + forecastType;
|
||||
params += "&key=" + this.config.apiKey;
|
||||
|
||||
return params;
|
||||
}
|
||||
});
|
11
modules/default/weather/weather.js
Normal file → Executable file
11
modules/default/weather/weather.js
Normal file → Executable file
@ -68,13 +68,14 @@ Module.register("weather",{
|
||||
"moment.js",
|
||||
"weatherprovider.js",
|
||||
"weatherobject.js",
|
||||
"suncalc.js",
|
||||
this.file("providers/" + this.config.weatherProvider.toLowerCase() + ".js")
|
||||
];
|
||||
},
|
||||
|
||||
// Override getHeader method.
|
||||
getHeader: function() {
|
||||
if (this.config.appendLocationNameToHeader && this.weatherProvider) {
|
||||
if (this.config.appendLocationNameToHeader && this.data.header !== undefined && this.weatherProvider) {
|
||||
return this.data.header + " " + this.weatherProvider.fetchedLocation();
|
||||
}
|
||||
|
||||
@ -188,11 +189,11 @@ Module.register("weather",{
|
||||
|
||||
this.nunjucksEnvironment().addFilter("unit", function (value, type) {
|
||||
if (type === "temperature") {
|
||||
if (this.config.units === "metric" || this.config.units === "imperial") {
|
||||
if (this.config.units === "metric" || this.config.units === "imperial" || this.config.units === "ukunits") {
|
||||
value += "°";
|
||||
}
|
||||
if (this.config.degreeLabel) {
|
||||
if (this.config.units === "metric") {
|
||||
if (this.config.units === "metric" || this.config.units === "ukunits") {
|
||||
value += "C";
|
||||
} else if (this.config.units === "imperial") {
|
||||
value += "F";
|
||||
@ -203,9 +204,13 @@ Module.register("weather",{
|
||||
} else if (type === "precip") {
|
||||
if (isNaN(value) || value === 0 || value.toFixed(2) === "0.00") {
|
||||
value = "";
|
||||
} else {
|
||||
if (this.config.weatherProvider === "ukmetoffice") {
|
||||
value += "%"
|
||||
} else {
|
||||
value = `${value.toFixed(2)} ${this.config.units === "imperial" ? "in" : "mm"}`;
|
||||
}
|
||||
}
|
||||
} else if (type === "humidity") {
|
||||
value += "%"
|
||||
}
|
||||
|
9
modules/default/weather/weatherobject.js
Normal file → Executable file
9
modules/default/weather/weatherobject.js
Normal file → Executable file
@ -28,6 +28,8 @@ class WeatherObject {
|
||||
this.rain = null;
|
||||
this.snow = null;
|
||||
this.precipitation = null;
|
||||
this.feelsLikeTemp = null;
|
||||
|
||||
}
|
||||
|
||||
cardinalWindDirection() {
|
||||
@ -67,7 +69,7 @@ class WeatherObject {
|
||||
}
|
||||
|
||||
beaufortWindSpeed() {
|
||||
const windInKmh = this.units === "imperial" ? this.windSpeed * 1.609344 : this.windSpeed * 60 * 60 / 1000;
|
||||
const windInKmh = (this.units === "imperial" || this.units === "ukunits") ? this.windSpeed * 1.609344 : this.windSpeed * 60 * 60 / 1000;
|
||||
const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000];
|
||||
for (const [index, speed] of speeds.entries()) {
|
||||
if (speed > windInKmh) {
|
||||
@ -82,7 +84,10 @@ class WeatherObject {
|
||||
}
|
||||
|
||||
feelsLike() {
|
||||
const windInMph = this.units === "imperial" ? this.windSpeed : this.windSpeed * 2.23694;
|
||||
if (this.feelsLikeTemp) {
|
||||
return this.feelsLikeTemp
|
||||
}
|
||||
const windInMph = (this.units === "imperial" || this.units === "ukunits") ? this.windSpeed : this.windSpeed * 2.23694;
|
||||
const tempInF = this.units === "imperial" ? this.temperature : this.temperature * 9 / 5 + 32;
|
||||
let feelsLike = tempInF;
|
||||
|
||||
|
3461
package-lock.json
generated
3461
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -46,11 +46,11 @@
|
||||
"grunt-yamllint": "latest",
|
||||
"http-auth": "^3.2.3",
|
||||
"jsdom": "^11.6.2",
|
||||
"jshint": "^2.9.5",
|
||||
"jshint": "^2.10.2",
|
||||
"mocha": "^4.1.0",
|
||||
"mocha-each": "^1.1.0",
|
||||
"spectron": "^3.8.0",
|
||||
"stylelint": "^8.4.0",
|
||||
"stylelint": "^9.10.1",
|
||||
"stylelint-config-standard": "latest",
|
||||
"time-grunt": "latest"
|
||||
},
|
||||
|
3
translations/en.json
Normal file → Executable file
3
translations/en.json
Normal file → Executable file
@ -31,5 +31,6 @@
|
||||
"UPDATE_INFO_SINGLE": "The current installation is {COMMIT_COUNT} commit behind on the {BRANCH_NAME} branch.",
|
||||
"UPDATE_INFO_MULTIPLE": "The current installation is {COMMIT_COUNT} commits behind on the {BRANCH_NAME} branch.",
|
||||
|
||||
"FEELS": "Feels"
|
||||
"FEELS": "Feels",
|
||||
"PRECIP": "PoP"
|
||||
}
|
||||
|
30
vendor/package-lock.json
generated
vendored
30
vendor/package-lock.json
generated
vendored
@ -703,7 +703,6 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
|
||||
"integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-glob": "^2.0.0"
|
||||
}
|
||||
@ -717,8 +716,7 @@
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"optional": true
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"invert-kv": {
|
||||
"version": "1.0.0",
|
||||
@ -737,8 +735,7 @@
|
||||
"is-buffer": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
|
||||
"integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
|
||||
"optional": true
|
||||
"integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
|
||||
},
|
||||
"is-dotfile": {
|
||||
"version": "1.0.3",
|
||||
@ -764,8 +761,7 @@
|
||||
"is-extglob": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
|
||||
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
|
||||
"optional": true
|
||||
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
@ -779,7 +775,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
|
||||
"integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-extglob": "^1.0.0"
|
||||
}
|
||||
@ -808,8 +803,7 @@
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"optional": true
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"isobject": {
|
||||
"version": "2.1.0",
|
||||
@ -824,7 +818,6 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@ -890,7 +883,6 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
|
||||
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"remove-trailing-separator": "^1.0.1"
|
||||
}
|
||||
@ -1039,14 +1031,12 @@
|
||||
"remove-trailing-separator": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
|
||||
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
|
||||
"optional": true
|
||||
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
|
||||
},
|
||||
"repeat-element": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
|
||||
"integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
|
||||
"optional": true
|
||||
"integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo="
|
||||
},
|
||||
"repeat-string": {
|
||||
"version": "1.6.1",
|
||||
@ -1057,8 +1047,7 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
|
||||
"optional": true
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
|
||||
},
|
||||
"set-immediate-shim": {
|
||||
"version": "1.0.1",
|
||||
@ -1093,6 +1082,11 @@
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"suncalc": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz",
|
||||
"integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
1
vendor/package.json
vendored
Normal file → Executable file
1
vendor/package.json
vendored
Normal file → Executable file
@ -14,6 +14,7 @@
|
||||
"moment": "^2.17.1",
|
||||
"moment-timezone": "^0.5.11",
|
||||
"nunjucks": "^3.0.1",
|
||||
"suncalc": "^1.8.0",
|
||||
"weathericons": "^2.1.0"
|
||||
}
|
||||
}
|
||||
|
3
vendor/vendor.js
vendored
Normal file → Executable file
3
vendor/vendor.js
vendored
Normal file → Executable file
@ -13,7 +13,8 @@ var vendor = {
|
||||
"weather-icons.css": "node_modules/weathericons/css/weather-icons.css",
|
||||
"weather-icons-wind.css": "node_modules/weathericons/css/weather-icons-wind.css",
|
||||
"font-awesome.css": "css/font-awesome.css",
|
||||
"nunjucks.js": "node_modules/nunjucks/browser/nunjucks.min.js"
|
||||
"nunjucks.js": "node_modules/nunjucks/browser/nunjucks.min.js",
|
||||
"suncalc.js": "node_modules/suncalc/suncalc.js"
|
||||
};
|
||||
|
||||
if (typeof module !== "undefined"){module.exports = vendor;}
|
||||
|
Loading…
x
Reference in New Issue
Block a user