From b16bfdcaca455bd8b6120b6c279859547acfe45c Mon Sep 17 00:00:00 2001 From: Jens Lody Date: Sun, 20 Sep 2015 16:02:00 +0200 Subject: [PATCH] Partly revert commit 4085de619c1dbf740e3c561ccb587facc8dd4306 ("Add newest development version of gnome-shell (3.17.92) to metadata.json .") . Too many files/folders slipped in accidently. --- The Dark Sky Forecast API Docs.html | 666 ------ config/compile | 347 --- data/#weather-settings_2.ui# | 1185 ---------- data/weather-settings_2.ui | 1100 --------- ...ell-extension-openweather.cscope_file_list | 53 - search.txt | 104 - src/extension_test.js | 1426 ------------ src/fetch_data_base.js | 1979 ----------------- temp.txt | 937 -------- updateChangeLog.sh | 11 - zip-file/openweather.shell-extension.zip | Bin 125916 -> 0 bytes 11 files changed, 7808 deletions(-) delete mode 100644 The Dark Sky Forecast API Docs.html delete mode 100755 config/compile delete mode 100644 data/#weather-settings_2.ui# delete mode 100644 data/weather-settings_2.ui delete mode 100644 gnome-shell-extension-openweather.cscope_file_list delete mode 100644 search.txt delete mode 100644 src/extension_test.js delete mode 100644 src/fetch_data_base.js delete mode 100644 temp.txt delete mode 100755 updateChangeLog.sh delete mode 100644 zip-file/openweather.shell-extension.zip diff --git a/The Dark Sky Forecast API Docs.html b/The Dark Sky Forecast API Docs.html deleted file mode 100644 index 09a4220..0000000 --- a/The Dark Sky Forecast API Docs.html +++ /dev/null @@ -1,666 +0,0 @@ -The Dark Sky Forecast API - - - v2 Forecast API - -The Forecast API lets you query for most locations on the globe, and -returns: - - * Current conditions - * Minute-by-minute forecasts out to 1 hour (where available) - * Hour-by-hour forecasts out to 48 hours - * Day-by-day forecasts out to 7 days - -There are two main API calls. The first <#forecast_call> returns the -current forecast (for the next week): - -|https://api.forecast.io/forecast/APIKEY/LATITUDE,LONGITUDE| - -The second <#time_call> lets one query for a specific time, past or -future (for many places, 60 years in the past to 10 years in the future): - -|https://api.forecast.io/forecast/APIKEY/LATITUDE,LONGITUDE,TIME| - -*Note to Dark Sky API users*: The old docs can be found here . -Details on migrating to the new API can be found at the bottom of the -page <#migration>. - - - Changelog - - * *3 Dec 2014:* Added Russian to the list of supported languages. - * *23 Sep 2014:* Added Portuguese and Bosnian to the list of supported - languages. - * *14 Aug 2014:* Added Polish and Pig Latin (!?) to the list of - supported languages. - * *29 Jul 2014:* Added Italian to the list of supported languages. - * *11 Jun 2014:* Added Spanish to the list of supported languages. - * *29 May 2014:* Added the |lang| option <#options>. - * *7 Jan 2014:* Added the |moonPhase| property to data points. - * *10 Dec 2013:* Added the MADIS <#data-sources> data source. - * *5 Dec 2013:* Added the |nearestStormDistance| and - |nearestStormBearing| properties to data points. - * *15 Aug 2013:* Added the |apparentTemperature| properties to data - points. - * *17 Jul 2013:* Added the |description| property to severe weather - alerts <#alerts>. - * *15 Jul 2013:* Added the RTMA and SREF weather models - <#data-sources>, and the |X-Forecast-API-Calls| response header - <#response-headers>. - * *22 May 2013:* Added the |extend| option. - * *6 May 2013:* Added string date format to time machine requests. - * *17 Apr 2013:* Added |dewPoint| and |ozone| properties to data points. - * *9 Apr 2013:* Added the |ca| and |auto| unit options, and added - |precipIntensityMax| and |precipIntensityMaxTime| properties on - daily data points. - * *1 Apr 2013:* Added the |exclude| option. - * *29 Mar 2013:* Deprecated the |si| option, replacing it with the - |units| option. When upgrading, be advised that |windSpeed| is now - in meters per second, rather than in kilometers per hour. (*Edit 9 - Apr 2013:* one can now use |?units=ca| to precisely emulate the - functionality of |?si|. Please update any code using the deprecated - functionality at your earliest convenience.) - * *26 Mar 2013:* Initial version. - - - API Libraries - -Looking to include Forecast in your app? These wrapper libraries should -make it quick and easy to do so: - - * Official Ruby Wrapper Library - by David Czarnecki - - * Android Client Wrapper Library - by Christopher Brown - - * C++ Wrapper Library - by Todd Shore - - * C# Wrapper Library by - Charl Cilliers - * Portable C# Wrapper Library - by Jerome Cheng - - * CFML Wrapper Library by - Danny Cork - * Clojure Wrapper Library - by J. D. Hollis - - * Erlang Wrapper Library by - Derek Brown - * Go Wrapper Library by - Martin-Louis Bright - * Java Wrapper Library - by David Ervideira - * Java Wrapper Library - by Kushan Jayatilleke - * JavaScript Wrapper Library - (with a - PHP-based proxy) by Ian Tearle - * Node.JS Wrapper Library - by Matt Walters - - * Node.JS Wrapper Library by Chris - Jones - * Node.JS Wrapper Library - by Serhiy - Oplakanets - * Objective-C Wrapper Library - by Rob Phillips - - * Objective-C Wrapper Library by - Carl Jahn - * iOS XCode Project Template - by Brandon Emrich - - * Perl Wrapper Library - - by Martin-Louis Bright - * PHP Wrapper Library - by Tobias - Redmann - * PHP Wrapper Library by - Guilherm Uhelski - * PHP Wrapper Library - (supporting multiple, simultaneous calls) by Charlie Gorichanaz - - * Python Wrapper Library - by Ze'ev Gilovitz - * R Wrapper Library by Bob - Rudis - * Unofficial Ruby Wrapper Library - by Vicent Gozalbes - - * Scala Wrapper Library - by Garrett Thornburg - -Additionally, Gerard Davison has -provided a JSON Schema of -the API, and Alex Handy has provided a CodeEnvy IDE - for a Java API wrapper -of our API. - -Finally, please note that all of the above API wrappers (except for the -official Ruby wrapper) are unofficial: we cannot provide support for -them! If you have any questions about them, please contact the library's -author. - - - The Forecast Call - -|https://api.forecast.io/forecast/APIKEY/LATITUDE,LONGITUDE| - -|APIKEY| should be your Dark Sky API key. |LATITUDE| and |LONGITUDE| -should be the geographic coordinates of a location in decimal degrees. -/(Please note that the base domain for this API request is -|api.forecast.io|, not |api.darkskyapp.com|.)/ - -The response will be a JSON-formatted object with the following -properties defined: - - * |latitude|: The requested latitude. - * |longitude|: The requested longitude. - * |timezone|: The IANA timezone name for the requested location (e.g. - |America/New_York|). This is the timezone used for text forecast - summaries and for determining the exact start time of daily data - points. /(Developers are advised to rely on local system settings - rather than this value if at all possible: users may deliberately - set an unusual timezone, and furthermore are likely to know what - they actually want better than our timezone database does.)/ - * |offset|: The current timezone offset in hours from GMT. - * |currently|: A /data point/ (see below) containing the current - weather conditions at the requested location. - * |minutely|: A /data block/ (see below) containing the weather - conditions minute-by-minute for the next hour. /(This property’s - name should be read as an adjective—analogously to “hourly” or - “daily” and meaning “reckoned by the minute”—rather than as an - adverb meaning “meticulously.” Yes, we know that this is not proper - English. No, we will not change it. Complaints to this effect will - be deleted with utmost prejudice.)/ - * |hourly|: A /data block/ (see below) containing the weather - conditions hour-by-hour for the next two days. - * |daily|: A /data block/ (see below) containing the weather - conditions day-by-day for the next week. - * |alerts|: An array of /alert objects/ (see below), which, if - present, contains any severe weather alerts, issued by a - governmental weather authority, pertinent to the requested location. - * |flags|: An object containing miscellaneous metadata concerning this - request. (See /flags object/, below.) - -In general, to determine the weather at a given point in time, one -should examine the highest-precision data block defined (|minutely|, -|hourly|, and |daily| respectively), taking any data available from from -it and falling back to the next-highest precision data block for any -properties that are missing for the point in time desired. - - - Data Points - -A /data point/ object represents the various weather phenomena occurring -at a specific instant of time, and has many varied properties. All of -these properties (except |time|) are /optional/, and will only be set if -we have that type of information for that location and time. Please note -that |minutely| data points are always aligned to the nearest minute -boundary, |hourly| points to the top of the hour, and |daily| points to -midnight of that day. - -Data points in the |daily| /data block/ (see below) are special: instead -of representing the weather phenomena at a given instant of time, they -are an aggregate point representing the weather phenomena that will -occur over the entire day. For precipitation fields, this aggregate is a -maximum; for other fields, it is an average. - -Data point objects may contain the following properties: - - * |time|: The UNIX time (that is, seconds since midnight GMT on 1 Jan - 1970) at which this data point occurs. - * |summary|: A human-readable text summary of this data point. - * |icon|: A machine-readable text summary of this data point, suitable - for selecting an icon for display. If defined, this property will - have one of the following values: |clear-day|, |clear-night|, - |rain|, |snow|, |sleet|, |wind|, |fog|, |cloudy|, - |partly-cloudy-day|, or |partly-cloudy-night|. (Developers should - ensure that a sensible default is defined, as additional values, - such as |hail|, |thunderstorm|, or |tornado|, may be defined in the - future.) - * |sunriseTime| and |sunsetTime| (only defined on |daily| data - points): The UNIX time (that is, seconds since midnight GMT on 1 Jan - 1970) of the last sunrise before and first sunset after the solar - noon closest to local noon on the given day. (Note: near the poles, - these may occur on a different day entirely!) - * |moonPhase| (only defined on |daily| data points): A number - representing the fractional part of the lunation number - of the given day. - This can be thought of as the “percentage complete” of the current - lunar month: a value of |0| represents a new moon, a value of |0.25| - represents a first quarter moon, a value of |0.5| represents a full - moon, and a value of |0.75| represents a last quarter moon. (The - ranges in between these represent waxing crescent, waxing gibbous, - waning gibbous, and waning crescent moons, respectively.) - * |nearestStormDistance| (only defined on |currently| data points): A - numerical value representing the distance to the nearest storm in - miles. (This value is /very approximate/ and should not be used in - scenarios requiring accurate results. In particular, a storm - distance of zero doesn’t necessarily refer to a storm at the - requested location, but rather a storm in the vicinity of that - location.) - * |nearestStormBearing| (only defined on |currently| data points): A - numerical value representing the direction of the nearest storm in - degrees, with true north at 0° and progressing clockwise. (If - |nearestStormDistance| is zero, then this value will not be defined. - The caveats that apply to |nearestStormDistance| also apply to this - value.) - * |precipIntensity|: A numerical value representing the average - expected intensity (in inches of liquid water per hour) of - precipitation occurring at the given time /conditional on - probability/ (that is, assuming any precipitation occurs at all). A - /very/ rough guide is that a value of |0| in./hr. corresponds to no - precipitation, |0.002| in./hr. corresponds to very light - precipitation, |0.017| in./hr. corresponds to light precipitation, - |0.1| in./hr. corresponds to moderate precipitation, and |0.4| - in./hr. corresponds to heavy precipitation. - * |precipIntensityMax|, and |precipIntensityMaxTime| (only defined on - |daily| data points): numerical values representing the maximumum - expected intensity of precipitation (and the UNIX time at which it - occurs) on the given day in inches of liquid water per hour. - * |precipProbability|: A numerical value between 0 and 1 (inclusive) - representing the probability of precipitation occuring at the given - time. - * |precipType|: A string representing the type of precipitation - occurring at the given time. If defined, this property will have one - of the following values: |rain|, |snow|, |sleet| (which applies to - each of freezing rain, ice pellets, and “wintery mix”), or |hail|. - (If |precipIntensity| is zero, then this property will not be defined.) - * |precipAccumulation| (only defined on |hourly| and |daily| data - points): the amount of snowfall accumulation expected to occur on - the given day. (If no accumulation is expected, this property will - not be defined.) - * |temperature| (not defined on |daily| data points): A numerical - value representing the temperature at the given time in degrees - Fahrenheit. - * |temperatureMin|, |temperatureMinTime|, |temperatureMax|, and - |temperatureMaxTime| (only defined on |daily| data points): - numerical values representing the minimum and maximumum temperatures - (and the UNIX times at which they occur) on the given day in degrees - Fahrenheit. - * |apparentTemperature| (not defined on |daily| data points): A - numerical value representing the apparent (or “feels like”) - temperature at the given time in degrees Fahrenheit. - * |apparentTemperatureMin|, |apparentTemperatureMinTime|, - |apparentTemperatureMax|, and |apparentTemperatureMaxTime| (only - defined on |daily| data points): numerical values representing the - minimum and maximumum apparent temperatures (and the UNIX times at - which they occur) on the given day in degrees Fahrenheit. - * |dewPoint|: A numerical value representing the dew point at the - given time in degrees Fahrenheit. - * |windSpeed|: A numerical value representing the wind speed in miles - per hour. - * |windBearing|: A numerical value representing the direction that the - wind is coming /from/ in degrees, with true north at 0° and - progressing clockwise. (If |windSpeed| is zero, then this value will - not be defined.) - * |cloudCover|: A numerical value between 0 and 1 (inclusive) - representing the percentage of sky occluded by clouds. A value of - |0| corresponds to clear sky, |0.4| to scattered clouds, |0.75| to - broken cloud cover, and |1| to completely overcast skies. - * |humidity|: A numerical value between 0 and 1 (inclusive) - representing the relative humidity. - * |pressure|: A numerical value representing the sea-level air - pressure in millibars. - * |visibility|: A numerical value representing the average visibility - in miles, capped at 10 miles. - * |ozone|: A numerical value representing the columnar density of - total atmospheric ozone at the given time in Dobson units. - -All of the above numeric, non-time fields may, optionally, have an -associated |Error| value defined (with the property -|precipIntensityError|, |windSpeedError|, |pressureError|, etc.), -representing our system’s confidence in its prediction. Such properties -represent standard deviations of the value of their associated property; -small error values therefore represent a strong confidence, while large -error values represent a weak confidence. These properties are omitted -where the confidence is not precisely known (though generally considered -to be adequate). - - - Data Blocks - -A /data block/ object represents the various weather phenomena occurring -over a period of time. Such objects contain the following properties: - - * |summary|: A human-readable text summary of this data block. - * |icon|: A machine-readable text summary of this data block (see - /data point/, above, for an enumeration of possible values that this - property may take on). - * |data|: An array of /data point/ objects (see above), ordered by - time, which together describe the weather conditions at the - requested location over time. - -Ideally, the |minutely| data block will contain data for the next hour, -the |hourly| data block for the next two days, and the |daily| data -block for the next week; however, if we are lacking data for a given -time period, the data point sequence may contain gaps or terminate -early. Furthermore, if no data points for a time period are known, then -the data block will be omitted from the response in its entirety. -Developers are strongly encouraged, therefore, to check for the presence -of data before attempting to read it. - - - Alert Objects - -An /alert object/ represents a severe weather warning issued for the -requested location by a governmental authority (for a list of which -authorities we currently support, please see /data sources/, below). -Such objects contain the following properties: - - * |title|: A short text summary of the alert. - * |expires|: The UNIX time (that is, seconds since midnight GMT on 1 - Jan 1970) at which the alert will cease to be valid. - * |description|: A detailed text description of the alert from the - appropriate weather service. - * |uri|: An HTTP(S) URI that contains detailed information about the - alert. - - - Flags Objects - -The /flags object/ contains various metadata information related to the -request. Such objects may optionally contain any of the following -properties: - - * |darksky-unavailable|: The presence of this property indicates that - the Dark Sky data source supports the given location, but a - temporary error (such as a radar station being down for maintenace) - has made the data unavailable. - * |darksky-stations|: This property contains an array of IDs for each - radar station utilized in servicing this request. - * |datapoint-stations|: This property contains an array of IDs for - each DataPoint station utilized in servicing this request. - * |isd-stations|: This property contains an array of IDs for each ISD - station utilized in servicing this request. - * |lamp-stations|: This property contains an array of IDs for each - LAMP station utilized in servicing this request. - * |metar-stations|: This property contains an array of IDs for each - METAR station utilized in servicing this request. - * |metno-license|: The presence of this property indicates that data - from api.met.no was utilized in order to - facilitate this request (as per their license agreement). - * |sources|: This property contains an array of IDs for each data - source utilized in servicing this request. (For more information, - see /data sources/, below.) - * |units|: The presence of this property indicates which units were - used for the data in this request. (For more information, see - /options/, below.) - - - Forecast at a Given Time - -It is also possible to request a forecast for an arbitrary point in time: - -|https://api.forecast.io/forecast/APIKEY/LATITUDE,LONGITUDE,TIME| - -|TIME| should either be a UNIX time (that is, seconds since midnight GMT -on 1 Jan 1970) or a string formatted as follows: -|[YYYY]-[MM]-[DD]T[HH]:[MM]:[SS]| (with an optional time zone formatted -as |Z| for GMT time or |{+,-}[HH][MM]| for an offset in hours or -minutes). For the latter format, if no timezone is present, local time -(at the provided latitude and longitude) is assumed. (This string format -is a subset of ISO 8601 - -time. An as example, |2013-05-06T12:00:00-0400|.) - -If a time is provided in this way, only the conditions for the day on -which that time occurred (or will occur), midnight-to-midnight, are -provided; in all other ways, making such a request is equivalent to -getting in a time machine, going back or forward in time to the given -moment, and making a normal forecast request. (In fact, this is how it -is implemented behind-the-scenes.) Generally speaking, forecasted data -is more accurate the nearer you query to the present moment. (That is, -the present moment if you don’t have a time machine.) - - - Options - -The API request may optionally be modified through the use of query -parameters. It will respond to the following: - - * |callback=[callback]|: Return the API response as JSONP - . /Please use caution when - using this,/ since exposing your API key to the public is a security - hazard and, if abused, will result in the revokation of your API - key. However, if developing a personal- or internal-use app, this is - a convenient method of doing so. - * |units=[setting]|: Return the API response in units other than the - default Imperial units. In particular, the following settings are - possible: - o |us|: The default, as outlined above. - o |si|: Returns results in SI units. In particular, properties now - have the following units: - + |summary|: Any summaries containing temperature or snow - accumulation units will have their values in degrees Celsius - or in centimeters (respectively). - + |nearestStormDistance|: Kilometers. - + |precipIntensity|: Millimeters per hour. - + |precipIntensityMax|: Millimeters per hour. - + |precipAccumulation|: Centimeters. - + |temperature|: Degrees Celsius. - + |temperatureMin|: Degrees Celsius. - + |temperatureMax|: Degrees Celsius. - + |apparentTemperature|: Degrees Celsius. - + |dewPoint|: Degrees Celsius. - + |windSpeed|: Meters per second. - + |pressure|: Hectopascals (which are, conveniently, - equivalent to the default millibars). - + |visibility|: Kilometers. - o |ca|: Identical to |si|, except that |windSpeed| is in - kilometers per hour. - o |uk|: Identical to |si|, except that |windSpeed| is in miles per - hour, as in the US. (This option is provided because adoption of - SI in the UK has been inconsistent.) - o |auto|: Selects the relevant units automatically, based on - geographic location. - * |exclude=[blocks]|: Exclude some number of data blocks from the API - response. This is useful for reducing latency and saving cache - space. |[blocks]| should be a comma-delimeted list (without spaces) - of any of the following: |currently|, |minutely|, |hourly|, |daily|, - |alerts|, |flags|. (Crafting a request with /all/ of the above - blocks excluded is exceedingly silly and not recommended.) - * |extend=hourly|: When present on a forecast request, return hourly - data for the next seven days, rather than the next two. (This option - is ignored on time machine requests. When using this option, we - strongly recommend ensuring that your HTTP client supports compression.) - * |lang=[language]|: Return text summaries in the desired language. - (Please be advised that units in the summary will be set according - to the |units| option, above, so be sure to set both options as - needed.) |[language]| may be |bs| (Bosnian), |de| (German), |en| - (English, which is the default), |es| (Spanish), |fr| (French), |it| - (Italian), |nl| (Dutch), |pl| (Polish), |pt| (Portuguese), |ru| - (Russian), |tet| (Tetum), or |x-pig-latin| (Igpay Atinlay). (If a - different language is desired, please consider contributing to our - API translation module - on Github.) - - - Response Headers - -The API will set the following HTTP response headers to values useful to -developers: - - * |Cache-Control| and |Expires|: These headers are set to conservative - values for data caching purposes based on the data present in the - response body. - * |X-Forecast-API-Calls|: The number of API calls made by the given - API key for today. - * |X-Response-Time|: The server-side response time of the request. - - - Notes - - * Just about every object property in the response is optional. In - fact, a request with no data to return will return a nearly empty - object, rather than a failure. Robust code will check for the - presence of required parameters before using them, and will fail - gracefully if they are not present (or return an error if a minimum - functional set of data is not available). - * All numeric properties are real numbers, except for UNIX timestamps, - which are (signed) integers. - * Summaries on the |hourly| data block actually only cover up to a - maximum of 24 hours, rather than the full time period in the data - block. We found that covering the full 48 hours could be, in a - number of circumstances, far too wordy to be practical. - * Summaries and icons on |daily| data points actually cover the period - from 4AM to 4AM, rather than the stated time period of midnight to - midnight. We found that the summaries so generated were less awkward. - * The Forecast Data API supports HTTP compression. We heartily - recommend using it, as it will make responses much smaller over the - wire. To enable it, simply add an |Accept-Encoding: gzip| header to - your request. (Most HTTP client libraries wrap this functionality - for you, please consult your library’s documentation for details. Be - advised that we do not support such compression over HTTP/1.0 - connections.) - * JSON responses are in UTF-8 format (due to text summaries, which can - contain Unicode characters). Please ensure that your JSON parser - acts accordingly. - - - Data Sources - -This API is backed by a wide range of data sources, which are aggregated -together statistically to provide the most accurate forecast possible -for a given location. Any data sources used to service a given request -will be noted in the |flags| section of a forecast response. These -sources include: - - 1. Dark Sky’s own hyperlocal precipitation forecasting system - (id - |darksky|), backed by radar data from the following systems: - * The USA NOAA’s NEXRAD system (USA). - * The UK Met Office’s NIMROD system (UK, Ireland). - * (More coming soon.) - 2. The USA NOAA’s LAMP system - (USA, id |lamp|). - 3. The UK Met Office’s Datapoint API - (UK, id |datapoint|). - 4. The Norwegian Meteorological Institute’s meteorological forecast API - (global, id |metno|). - 5. The USA NOAA’s Global Forecast System - (global, id - |gfs|). - 6. The USA NOAA’s Integrated Surface Database - (global, id |isd|). - 7. The USA NOAA’s Public Alert system - (USA, id |nwspa|). - 8. The UK Met Office’s Severe Weather Warning system - (UK, id - |metwarn|). - 9. Environment Canada’s Canadian Meteorological Center ensemble model - - (global, id |cmc|). -10. The US Navy’s Fleet Numerical Meteorology and Oceanography Ensemble - Forecast System - - (global, id |fnmoc|). -11. The USA NOAA and Environment Canada’s North American Ensemble - Forecast System - - (global, id |naefs|). -12. The USA NOAA’s North American Mesoscale Model - (North - America, id |nam|). -13. The USA NOAA’s Rapid Refresh Model - (North America, id |rap|). -14. The Norwegian Meteorological Institute’s GRIB file forecast for - Central Europe - (Europe, - id |metno_ce|). -15. The Norwegian Meteorological Institute’s GRIB file forecast for - Northern Europe - (Europe, - id |metno_ne|). -16. Worldwide METAR weather reports - (global, id |metar|). -17. The USA NOAA/NCEP’s Short-Range Ensemble Forecast - (North America, id - |sref|). -18. The USA NOAA/NCEP’s Real-Time Mesoscale Analysis - model (North America, id |rtma|). -19. The USA NOAA/ESRL’s Meteorological Assimilation Data Ingest System - (global, id |madis|). - - - v1-to-v2 Migration Guide - -The v2 Forecast API is designed to be as close to a pure superset of the -v1 Forecast API as -possible, allowing for a straightforward upgrade path if you’re -currently using the v1 API and wish to upgrade. Below is a mapping of -all v1 response properties and how they map to v2 properties. - -v1 Property v2 Property Notes -|timezone| |timezone| and |offset| In v1, |timezone| was a string -containing the IANA timezone name, the timezone abbrevation, and the -timezone offset in hours. In v2, |timezone| contains the IANA timezone -name, while |offset| contains the timezone offset in hours. The timezone -abbreviation has no analogue in v2. -|currentSummary| |currently.summary| -|currentIntensity| |currently.precipIntensity| In v1, -|currentIntensity| was in dBZ. In v2, |precipIntensity| is in inches of -liquid water per hour. An equation for converting between the two is -available from the Wikipedia page for dBZ -. -|currentTemp| |currently.temperature| -|hourSummary| |minutely.summary| -|hourPrecipitation| |minutely.data| In v2, |minutely| may be omitted -entirely given a lack of data. -|hourPrecipitation[x].time| |minutely.data[x].time| -|hourPrecipitation[x].probability| |minutely.data[x].precipProbability| -|hourPrecipitation[x].intensity| |minutely.data[x].precipIntensity| In -v1, |intensity| was in dBZ. In v2, |precipIntensity| is in inches of -liquid water per hour. An equation for converting between the two is -available from the Wikipedia page for dBZ -. -|hourPrecipitation[x].error| |minutely.data[x].precipIntensityError| -Note the change in |precipIntensity| units outlined above. Additionally, -in v2, this value is a one-sigma value rather than a three-sigma value, -and if |precipIntensity| is zero, then this property will be omitted -entirely. -|hourPrecipitation[x].type| |minutely.data[x].precipType| In v2, there -is an additional type of precipitation: |hail|. Additionally, in v2, if -|precipIntensity| is zero, then this property will be omitted. -|daySummary| |hourly.summary| -|dayPrecipitation| |hourly.data| In v2, |hourly| may be omitted -entirely given a lack of data. -|dayPrecipitation[x].time| |hourly.data[x].time| -|dayPrecipitation[x].probability| |hourly.data[x].precipProbability| -In v2, |precipProbability| will be omitted if |precipIntensity| is zero. -It is also very uncommonly provided by our data sources; developers are -encouraged to use rely on |precipIntensity| whenever possible. -|dayPrecipitation[x].type| |hourly.data[x].precipType| In v2, there is -an additional type of precipitation: |hail|. Additionally, in v2, if -|precipIntensity| is zero, then this property will be omitted. -|dayPrecipitation[x].temp| |hourly.data[x].temperature| -|dayPrecipitation[x].cloudCover| |hourly.data[x].cloudCover| -|dayPrecipitation[x].relHumidity| |hourly.data[x].humidity| -|radarStation| |flags["darksky-stations"]| In v2, this property will -be omitted if we do not have radar coverage of the given location. -Additionally, v2 makes use of multiple radar sources, so this property -contains an array of station IDs, rather than a single ID. Finally, in -v1, radar stations were lower case and would have their first letter -omitted if they began with a "K". In v2, radar station IDs are always -four letters long and upper case. -|isPrecipitating| /not present/ In v2, simply check if -|currently.precipIntensity| is nonzero. -|minutesUntilChange| /not present/ In v2, iterate over |minutely.data| -and |hourly.data| in order, finding the first data point for which -|currently.precipIntensity !== 0| does not equal -|datapoint.precipIntensity !== 0|. Once that data point is found, -|minutesUntilChange| may be calculated as follows: |(datapoint.time - -currently.time) / 60|. -|checkTimeout| /not present/ Use either the |Cache-Control| or -|Expires| HTTP response headers. - -© 2013 The Dark Sky Company, LLC -Email Us Terms of Use -Privacy Policy - diff --git a/config/compile b/config/compile deleted file mode 100755 index 531136b..0000000 --- a/config/compile +++ /dev/null @@ -1,347 +0,0 @@ -#! /bin/sh -# Wrapper for compilers which do not understand '-c -o'. - -scriptversion=2012-10-14.11; # UTC - -# Copyright (C) 1999-2013 Free Software Foundation, Inc. -# Written by Tom Tromey . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -nl=' -' - -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent tools from complaining about whitespace usage. -IFS=" "" $nl" - -file_conv= - -# func_file_conv build_file lazy -# Convert a $build file to $host form and store it in $file -# Currently only supports Windows hosts. If the determined conversion -# type is listed in (the comma separated) LAZY, no conversion will -# take place. -func_file_conv () -{ - file=$1 - case $file in - / | /[!/]*) # absolute file, and not a UNC file - if test -z "$file_conv"; then - # lazily determine how to convert abs files - case `uname -s` in - MINGW*) - file_conv=mingw - ;; - CYGWIN*) - file_conv=cygwin - ;; - *) - file_conv=wine - ;; - esac - fi - case $file_conv/,$2, in - *,$file_conv,*) - ;; - mingw/*) - file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` - ;; - cygwin/*) - file=`cygpath -m "$file" || echo "$file"` - ;; - wine/*) - file=`winepath -w "$file" || echo "$file"` - ;; - esac - ;; - esac -} - -# func_cl_dashL linkdir -# Make cl look for libraries in LINKDIR -func_cl_dashL () -{ - func_file_conv "$1" - if test -z "$lib_path"; then - lib_path=$file - else - lib_path="$lib_path;$file" - fi - linker_opts="$linker_opts -LIBPATH:$file" -} - -# func_cl_dashl library -# Do a library search-path lookup for cl -func_cl_dashl () -{ - lib=$1 - found=no - save_IFS=$IFS - IFS=';' - for dir in $lib_path $LIB - do - IFS=$save_IFS - if $shared && test -f "$dir/$lib.dll.lib"; then - found=yes - lib=$dir/$lib.dll.lib - break - fi - if test -f "$dir/$lib.lib"; then - found=yes - lib=$dir/$lib.lib - break - fi - if test -f "$dir/lib$lib.a"; then - found=yes - lib=$dir/lib$lib.a - break - fi - done - IFS=$save_IFS - - if test "$found" != yes; then - lib=$lib.lib - fi -} - -# func_cl_wrapper cl arg... -# Adjust compile command to suit cl -func_cl_wrapper () -{ - # Assume a capable shell - lib_path= - shared=: - linker_opts= - for arg - do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as 'compile cc -o foo foo.c'. - eat=1 - case $2 in - *.o | *.[oO][bB][jJ]) - func_file_conv "$2" - set x "$@" -Fo"$file" - shift - ;; - *) - func_file_conv "$2" - set x "$@" -Fe"$file" - shift - ;; - esac - ;; - -I) - eat=1 - func_file_conv "$2" mingw - set x "$@" -I"$file" - shift - ;; - -I*) - func_file_conv "${1#-I}" mingw - set x "$@" -I"$file" - shift - ;; - -l) - eat=1 - func_cl_dashl "$2" - set x "$@" "$lib" - shift - ;; - -l*) - func_cl_dashl "${1#-l}" - set x "$@" "$lib" - shift - ;; - -L) - eat=1 - func_cl_dashL "$2" - ;; - -L*) - func_cl_dashL "${1#-L}" - ;; - -static) - shared=false - ;; - -Wl,*) - arg=${1#-Wl,} - save_ifs="$IFS"; IFS=',' - for flag in $arg; do - IFS="$save_ifs" - linker_opts="$linker_opts $flag" - done - IFS="$save_ifs" - ;; - -Xlinker) - eat=1 - linker_opts="$linker_opts $2" - ;; - -*) - set x "$@" "$1" - shift - ;; - *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) - func_file_conv "$1" - set x "$@" -Tp"$file" - shift - ;; - *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) - func_file_conv "$1" mingw - set x "$@" "$file" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift - done - if test -n "$linker_opts"; then - linker_opts="-link$linker_opts" - fi - exec "$@" $linker_opts - exit 1 -} - -eat= - -case $1 in - '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: compile [--help] [--version] PROGRAM [ARGS] - -Wrapper for compilers which do not understand '-c -o'. -Remove '-o dest.o' from ARGS, run PROGRAM with the remaining -arguments, and rename the output as expected. - -If you are trying to build a whole package this is not the -right script to run: please start by reading the file 'INSTALL'. - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "compile $scriptversion" - exit $? - ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) - func_cl_wrapper "$@" # Doesn't return... - ;; -esac - -ofile= -cfile= - -for arg -do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as 'compile cc -o foo foo.c'. - # So we strip '-o arg' only if arg is an object. - eat=1 - case $2 in - *.o | *.obj) - ofile=$2 - ;; - *) - set x "$@" -o "$2" - shift - ;; - esac - ;; - *.c) - cfile=$1 - set x "$@" "$1" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift -done - -if test -z "$ofile" || test -z "$cfile"; then - # If no '-o' option was seen then we might have been invoked from a - # pattern rule where we don't need one. That is ok -- this is a - # normal compilation that the losing compiler can handle. If no - # '.c' file was seen then we are probably linking. That is also - # ok. - exec "$@" -fi - -# Name of file we expect compiler to create. -cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` - -# Create the lock directory. -# Note: use '[/\\:.-]' here to ensure that we don't use the same name -# that we are using for the .o file. Also, base the name on the expected -# object file name, since that is what matters with a parallel build. -lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d -while true; do - if mkdir "$lockdir" >/dev/null 2>&1; then - break - fi - sleep 1 -done -# FIXME: race condition here if user kills between mkdir and trap. -trap "rmdir '$lockdir'; exit 1" 1 2 15 - -# Run the compile. -"$@" -ret=$? - -if test -f "$cofile"; then - test "$cofile" = "$ofile" || mv "$cofile" "$ofile" -elif test -f "${cofile}bj"; then - test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" -fi - -rmdir "$lockdir" -exit $ret - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/data/#weather-settings_2.ui# b/data/#weather-settings_2.ui# deleted file mode 100644 index 0c6f164..0000000 --- a/data/#weather-settings_2.ui# +++ /dev/null @@ -1,1185 +0,0 @@ - - - - - - - - - - - - - - - - - False - 14 - - - True - False - True - - - True - True - center - True - True - in - 200 - - - True - True - liststore - False - 0 - False - 12 - - - - - - - - 0 - 0 - 1 - 1 - - - - - True - False - - - False - True - False - list-add-symbolic - - - False - True - - - - - False - True - False - list-remove-symbolic - - - False - True - - - - - - 0 - 1 - 1 - 1 - - - - - False - True - 0 - - - - - True - False - - - True - False - 36 - 14 - 2 - 36 - 12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - True - 0 - - - - - False - True - 1 - - - - diff --git a/data/weather-settings_2.ui b/data/weather-settings_2.ui deleted file mode 100644 index 7d157c8..0000000 --- a/data/weather-settings_2.ui +++ /dev/null @@ -1,1100 +0,0 @@ - - - - - - - - - - - - - - - - - False - 14 - - - True - False - True - - - True - True - center - True - True - in - - - True - True - liststore - False - 0 - False - 12 - - - - - - - - 0 - 0 - 1 - 1 - - - - - True - False - - - False - True - False - list-add-symbolic - - - False - True - - - - - False - True - False - list-remove-symbolic - - - False - True - - - - - - 0 - 1 - 1 - 1 - - - - - False - True - 0 - - - - - True - False - - - True - False - 36 - 14 - 2 - 36 - 12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - True - 0 - - - - - False - True - 1 - - - - diff --git a/gnome-shell-extension-openweather.cscope_file_list b/gnome-shell-extension-openweather.cscope_file_list deleted file mode 100644 index c90f732..0000000 --- a/gnome-shell-extension-openweather.cscope_file_list +++ /dev/null @@ -1,53 +0,0 @@ -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/cs.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/zh_CN.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/ca.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/src/prefs.js" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/ChangeLog" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/sk.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/el.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/zh_TW.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/vi.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/aclocal.m4" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/COPYING" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/uk.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/data/Screenshot.jpg" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/configure.ac" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/AUTHORS" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/lt.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/it.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/src/convenience.js" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/data/openweather-search.ui" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/nl.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/data/org.gnome.shell.extensions.openweather.gschema.xml.in" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/fr.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/de.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/pl.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/NEWS" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/data/Makefile.am" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/Makefile.am" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/update.js" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/src/Makefile.am" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/da.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/pt.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/POTFILES.in" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/gnome-shell-extension-openweather.spec" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/sv.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/data/weather-settings.gif" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/LINGUAS" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/nb.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/gnome-shell-extension-weather.pot" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/bg.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/ru.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/README.md" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/ja.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/autogen.sh" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/fi.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/pt_BR.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/data/weather-settings.ui" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/data/metadata.json.in" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/he.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/data/stylesheet.css" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/hu.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/es.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/po/ro.po" -"/home/jens/sources/w/weather/gnome-shell-extension-openweather/src/extension.js" diff --git a/search.txt b/search.txt deleted file mode 100644 index 560014c..0000000 --- a/search.txt +++ /dev/null @@ -1,104 +0,0 @@ -https://open.mapquestapi.com/nominatim/v1/search.php?format=json&q=Sommerweg+2,+Neu-Eichenberg&addressdetails=1 - -[ - { - "place_id":"57218283", - "licence":"Data \u00a9 OpenStreetMap contributors, ODbL 1.0. http:\/\/www.openstreetmap.org\/copyright", - "osm_type":"way", - "osm_id":"26124984", - "boundingbox": - [ - "51.3747137", - "51.3755891", - "9.9164565", - "9.9192863" - ], - "lat":"51.3750768", - "lon":"9.9175961", - "display_name":"Sommerweg, Neu-Eichenberg, Werra-Mei\u00dfner-Kreis, Regierungsbezirk Kassel, Hessen, 37249, Deutschland, Europa", - "class":"highway", - "type":"residential", - "importance":0.51, - "address": - { - "road":"Sommerweg", - "village":"Neu-Eichenberg", - "county":"Werra-Mei\u00dfner-Kreis", - "state_district":"Regierungsbezirk Kassel", - "state":"Hessen", - "postcode":"37249", - "country":"Deutschland", - "country_code":"de", - "continent":"Europa" - } - } -] - - -[ - { - "place_id":"151244439", - "licence":"Data \u00a9 OpenStreetMap contributors, ODbL 1.0. http:\/\/www.openstreetmap.org\/copyright", - "osm_type":"relation", - "osm_id":"549411", - "boundingbox": - [ - "51.3462395", - "51.4210337", - "9.8500839", - "9.9327238" - ], - "lat":"51.3835891", - "lon":"9.8833684", - "display_name":"Neu-Eichenberg, Werra-Mei\u00dfner-Kreis, Regierungsbezirk Kassel, Hessen, Deutschland, Europa", - "class":"boundary", - "type":"administrative", - "importance":0.57579531509901, - "icon":"http:\/\/open.mapquestapi.com\/nominatim\/v1\/images\/mapicons\/poi_boundary_administrative.p.20.png", - "address": - { - "city":"Neu-Eichenberg", - "county":"Werra-Mei\u00dfner-Kreis", - "state_district":"Regierungsbezirk Kassel", - "state":"Hessen", - "country":"Deutschland", - "country_code":"de", - "continent":"Europa" - } - } -] - -http://open.mapquestapi.com/nominatim/v1/reverse.php?format=json&lat=51.3750768&lon=+9.9175961 - -[ - { - "place_id":"151244439", - "licence":"Data \u00a9 OpenStreetMap contributors, ODbL 1.0. http:\/\/www.openstreetmap.org\/copyright", - "osm_type":"relation", - "osm_id":"549411", - "boundingbox": - [ - "51.3462395", - "51.4210337", - "9.8500839", - "9.9327238" - ], - "lat":"51.3835891", - "lon":"9.8833684", - "display_name":"Neu-Eichenberg, Werra-Mei\u00dfner-Kreis, Regierungsbezirk Kassel, Hessen, Deutschland, Europa", - "class":"boundary", - "type":"administrative", - "importance":0.57579531509901, - "icon":"http:\/\/open.mapquestapi.com\/nominatim\/v1\/images\/mapicons\/poi_boundary_administrative.p.20.png", - "address": - { - "city":"Neu-Eichenberg", - "county":"Werra-Mei\u00dfner-Kreis", - "state_district":"Regierungsbezirk Kassel", - "state":"Hessen", - "country":"Deutschland", - "country_code":"de", - "continent":"Europa" - } - } -] diff --git a/src/extension_test.js b/src/extension_test.js deleted file mode 100644 index f822f00..0000000 --- a/src/extension_test.js +++ /dev/null @@ -1,1426 +0,0 @@ -/* jshint esnext:true */ -/* - * - * Weather extension for GNOME Shell - * - Displays a small weather information on the top panel. - * - On click, gives a popup with details about the weather. - * - * Copyright (C) 2011 - 2015 - * ecyrbe , - * Timur Kristof , - * Elad Alfassa , - * Simon Legner , - * Christian METZLER , - * Mark Benjamin weather.gnome.Markie1@dfgh.net, - * Mattia Meneguzzo odysseus@fedoraproject.org, - * Meng Zhuo , - * Jens Lody - * - * - * This file is part of gnome-shell-extension-openweather. - * - * gnome-shell-extension-openweather is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * gnome-shell-extension-openweather is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with gnome-shell-extension-openweather. If not, see . - * - */ - -const ExtensionUtils = imports.misc.extensionUtils; -const Me = ExtensionUtils.getCurrentExtension(); -const Config = imports.misc.config; -const Convenience = Me.imports.convenience; -const ForecastIo = Me.imports.forecast_io; -const OpenweathermapOrg = Me.imports.openweathermap_org; -const Clutter = imports.gi.Clutter; -const Gettext = imports.gettext.domain('gnome-shell-extension-openweather'); -const Gio = imports.gi.Gio; -const Gtk = imports.gi.Gtk; -const GLib = imports.gi.GLib; -const Lang = imports.lang; -const Mainloop = imports.mainloop; -const Soup = imports.gi.Soup; -const St = imports.gi.St; -const Util = imports.misc.util; -const _ = Gettext.gettext; - -const Main = imports.ui.main; -const PanelMenu = imports.ui.panelMenu; -const PopupMenu = imports.ui.popupMenu; - -// Settings -const OPENWEATHER_SETTINGS_SCHEMA = 'org.gnome.shell.extensions.openweather'; -const OPENWEATHER_DESKTOP_INTERFACE = 'org.gnome.desktop.interface'; -const OPENWEATHER_PROVIDER_KEY = 'weather-provider'; -const OPENWEATHER_UNIT_KEY = 'unit'; -const OPENWEATHER_WIND_SPEED_UNIT_KEY = 'wind-speed-unit'; -const OPENWEATHER_WIND_DIRECTION_KEY = 'wind-direction'; -const OPENWEATHER_PRESSURE_UNIT_KEY = 'pressure-unit'; -const OPENWEATHER_CITY_KEY = 'city'; -const OPENWEATHER_ACTUAL_CITY_KEY = 'actual-city'; -const OPENWEATHER_TRANSLATE_CONDITION_KEY = 'translate-condition'; -const OPENWEATHER_USE_SYMBOLIC_ICONS_KEY = 'use-symbolic-icons'; -const OPENWEATHER_USE_TEXT_ON_BUTTONS_KEY = 'use-text-on-buttons'; -const OPENWEATHER_SHOW_TEXT_IN_PANEL_KEY = 'show-text-in-panel'; -const OPENWEATHER_POSITION_IN_PANEL_KEY = 'position-in-panel'; -const OPENWEATHER_SHOW_COMMENT_IN_PANEL_KEY = 'show-comment-in-panel'; -const OPENWEATHER_SHOW_COMMENT_IN_FORECAST_KEY = 'show-comment-in-forecast'; -const OPENWEATHER_REFRESH_INTERVAL_CURRENT = 'refresh-interval-current'; -const OPENWEATHER_REFRESH_INTERVAL_FORECAST = 'refresh-interval-forecast'; -const OPENWEATHER_CENTER_FORECAST_KEY = 'center-forecast'; -const OPENWEATHER_DAYS_FORECAST = 'days-forecast'; -const OPENWEATHER_DECIMAL_PLACES = 'decimal-places'; -const OPENWEATHER_OWM_API_KEY = 'appid'; -const OPENWEATHER_FC_API_KEY = 'appid-fc'; - -// Keep enums in sync with GSettings schemas -const WeatherProvider = { - DEFAULT: -1, - OPENWEATHERMAP: 0, - FORECAST_IO: 1 -}; - -const WeatherUnits = { - CELSIUS: 0, - FAHRENHEIT: 1, - KELVIN: 2, - RANKINE: 3, - REAUMUR: 4, - ROEMER: 5, - DELISLE: 6, - NEWTON: 7 -}; - -const WeatherWindSpeedUnits = { - KPH: 0, - MPH: 1, - MPS: 2, - KNOTS: 3, - FPS: 4, - BEAUFORT: 5 -}; - -const WeatherPressureUnits = { - HPA: 0, - INHG: 1, - BAR: 2, - PA: 3, - KPA: 4, - ATM: 5, - AT: 6, - TORR: 7, - PSI: 8, - MMHG: 9 -}; - -const WeatherPosition = { - CENTER: 0, - RIGHT: 1, - LEFT: 2 -}; - -const OPENWEATHER_CONV_MPS_IN_MPH = 2.23693629; -const OPENWEATHER_CONV_MPS_IN_KPH = 3.6; -const OPENWEATHER_CONV_MPS_IN_KNOTS = 1.94384449; -const OPENWEATHER_CONV_MPS_IN_FPS = 3.2808399; - -let _httpSession; - -const OpenweatherMenuButton = new Lang.Class({ - Name: 'OpenweatherMenuButton', - - Extends: PanelMenu.Button, - - _init: function() { - log(new Error().fileName+':'+new Error().lineNumber+'11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'); - log(new Error().fileName+':'+new Error().lineNumber+' => Gio.NetworkConnectivity = '+Gio.NetworkConnectivity.toString()); - log(new Error().fileName+':'+new Error().lineNumber+' => Gio.NetworkConnectivity.full = '+Gio.NetworkConnectivity.full); - for (let i = 0; i < Gio.NetworkConnectivity.length; ++i) - { - log(new Error().fileName+':'+new Error().lineNumber+' => Gio.network_monitor_get_default()['+i+'] = '+Gio.network_monitor_get_default()[i]); - } -// log(new Error().fileName+':'+new Error().lineNumber+' => Gio.network_monitor_get_default().NETWORK_CONNECTIVITY_FULL = '+Gio.network_monitor_get_default().NetworkConnectivity.G_NETWORK_CONNECTIVITY_FULL); - log(new Error().fileName+':'+new Error().lineNumber+'22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222'); - this.owmCityId = 0; - - this.oldProvider = this._weather_provider; - this.oldTranslateCondition = this._translate_condition; - this.switchProvider(); - - this.currentWeatherCache = undefined; - this.forecastWeatherCache = undefined; - // Load settings - this.loadConfig(); - - // Label - this._weatherInfo = new St.Label({ - y_align: Clutter.ActorAlign.CENTER, - text: _('...') - }); - - this._weatherIcon = new St.Icon({ - icon_name: 'view-refresh' + this.getIconType(), - style_class: 'system-status-icon openweather-icon' - }); - - // Panel menu item - the current class - let menuAlignment = 0.25; - if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) - menuAlignment = 1.0 - menuAlignment; - this.parent(menuAlignment); - - // Putting the panel item together - let topBox = new St.BoxLayout(); - topBox.add_actor(this._weatherIcon); - topBox.add_actor(this._weatherInfo); - this.actor.add_actor(topBox); - - let dummyBox = new St.BoxLayout(); - this.actor.reparent(dummyBox); - dummyBox.remove_actor(this.actor); - dummyBox.destroy(); - - let children = null; - switch (this._position_in_panel) { - case WeatherPosition.LEFT: - children = Main.panel._leftBox.get_children(); - Main.panel._leftBox.insert_child_at_index(this.actor, children.length); - break; - case WeatherPosition.CENTER: - children = Main.panel._centerBox.get_children(); - Main.panel._centerBox.insert_child_at_index(this.actor, children.length); - break; - case WeatherPosition.RIGHT: - children = Main.panel._rightBox.get_children(); - Main.panel._rightBox.insert_child_at_index(this.actor, 0); - break; - } - if (Main.panel._menus === undefined) - Main.panel.menuManager.addMenu(this.menu); - else - Main.panel._menus.addMenu(this.menu); - - this._old_position_in_panel = this._position_in_panel; - - // Current weather - this._currentWeather = new St.Bin(); - // Future weather - this._futureWeather = new St.Bin(); - - // Putting the popup item together - let _itemCurrent = new PopupMenu.PopupBaseMenuItem({ - reactive: false - }); - let _itemFuture = new PopupMenu.PopupBaseMenuItem({ - reactive: false - }); - - _itemCurrent.actor.add_actor(this._currentWeather); - _itemFuture.actor.add_actor(this._futureWeather); - - this.menu.addMenuItem(_itemCurrent); - - this._separatorItem = new PopupMenu.PopupSeparatorMenuItem(); - this.menu.addMenuItem(this._separatorItem); - - this.menu.addMenuItem(_itemFuture); - - let item = new PopupMenu.PopupSeparatorMenuItem(); - this.menu.addMenuItem(item); - - this._selectCity = new PopupMenu.PopupSubMenuMenuItem(""); - this._selectCity.actor.set_height(0); - this._selectCity._triangle.set_height(0); - - this._buttonMenu = new PopupMenu.PopupBaseMenuItem({ - reactive: false, - style_class: 'openweather-menu-button-container' - }); - - this.rebuildButtonMenu(); - - this.menu.addMenuItem(this._buttonMenu); - this.menu.addMenuItem(this._selectCity); - this.rebuildSelectCityItem(); - this._selectCity.menu.connect('open-state-changed', Lang.bind(this, function() { - this._selectCity.actor.remove_style_pseudo_class('open'); - })); - - this.rebuildCurrentWeatherUi(); - this.rebuildFutureWeatherUi(); - - this._network_monitor = Gio.network_monitor_get_default(); - - this._connected = false; - this._network_monitor_connection = this._network_monitor.connect('network-changed', Lang.bind(this, this._onNetworkStateChanged)); - this._checkConnectionState(); - - this.menu.connect('open-state-changed', Lang.bind(this, this.recalcLayout)); - }, - - stop: function() { - if (_httpSession !== undefined) - _httpSession.abort(); - - _httpSession = undefined; - - if (this._timeoutCurrent) - Mainloop.source_remove(this._timeoutCurrent); - - this._timeoutCurrent = undefined; - - if (this._timeoutForecast) - Mainloop.source_remove(this._timeoutForecast); - - this._timeoutForecast = undefined; - - if (this._network_monitor_connection) { - this._network_monitor.disconnect(this._network_monitor_connection); - this._network_monitor_connection = undefined; - } - - if (this._settingsC) { - this._settings.disconnect(this._settingsC); - this._settingsC = undefined; - } - - if (this._settingsInterfaceC) { - this._settingsInterface.disconnect(this._settingsInterfaceC); - this._settingsInterfaceC = undefined; - } - - if (this._globalThemeChangedId) { - let context = St.ThemeContext.get_for_stage(global.stage); - context.disconnect(this._globalThemeChangedId); - this._globalThemeChangedId = undefined; - } - }, - - switchProvider: function() { - if (this._weather_provider == WeatherProvider.FORECAST_IO) - this.useForecastIo(); - else - this.useOpenweathermapOrg(); - }, - - useOpenweathermapOrg: function() { - this.parseWeatherForecast = OpenweathermapOrg.parseWeatherForecast; - this.parseWeatherCurrent = OpenweathermapOrg.parseWeatherCurrent; - this.getWeatherIcon = OpenweathermapOrg.getWeatherIcon; - this.refreshWeatherCurrent = OpenweathermapOrg.refreshWeatherCurrent; - this.refreshWeatherForecast = OpenweathermapOrg.refreshWeatherForecast; - - this.weatherProvider = "https://openweathermap.org/"; - }, - - useForecastIo: function() { - this.parseWeatherCurrent = ForecastIo.parseWeatherCurrent; - this.parseWeatherForecast = ForecastIo.parseWeatherForecast; - this.getWeatherIcon = ForecastIo.getWeatherIcon; - this.refreshWeatherCurrent = ForecastIo.refreshWeatherCurrent; - this.refreshWeatherForecast = function() {}; - - this.weatherProvider = "https://forecast.io/"; - - this.fc_locale = 'en'; - - if (this._translate_condition) { - let fc_locales = ['bs', 'de', 'en', 'es', 'fr', 'it', 'nl', 'pl', 'pt', 'ru', 'tet', 'x-pig-latin']; - let locale = GLib.get_language_names()[0]; - - if (locale.indexOf('_') != -1) - locale = locale.split("_")[0]; - - if (fc_locales.indexOf(locale) != -1) - this.fc_locale = locale; - } - }, - - getWeatherProviderURL: function() { - let url = ""; - if (this._weather_provider == WeatherProvider.FORECAST_IO) { - url = "https://forecast.io/#/f/"; - url += this.extractCoord(this._city); - } else { - url = "https://openweathermap.org"; - url += "/city/" + this.owmCityId; - if (this._appid) - url += "?APPID=" + this._appid; - } - return url; - }, - - loadConfig: function() { - this._settings = Convenience.getSettings(OPENWEATHER_SETTINGS_SCHEMA); - - if (this._cities.length === 0) - this._cities = "-8.5211767,179.1976747>Vaiaku, Tuvalu>-1"; - - this._settingsC = this._settings.connect("changed", Lang.bind(this, function() { - if (this._cities.length === 0) - this._cities = "-8.5211767,179.1976747>Vaiaku, Tuvalu>-1"; - this.rebuildCurrentWeatherUi(); - this.rebuildFutureWeatherUi(); - if (this.providerChanged()) { - this.switchProvider(); - this.currentWeatherCache = undefined; - this.forecastWeatherCache = undefined; - } - if (this.locationChanged()) { - this.currentWeatherCache = undefined; - this.forecastWeatherCache = undefined; - } - this.rebuildButtonMenu(); - this.parseWeatherCurrent(); - })); - }, - - loadConfigInterface: function() { - this._settingsInterface = Convenience.getSettings(OPENWEATHER_DESKTOP_INTERFACE); - this._settingsInterfaceC = this._settingsInterface.connect("changed", Lang.bind(this, function() { - this.rebuildCurrentWeatherUi(); - this.rebuildFutureWeatherUi(); - if (this.providerChanged()) { - this.switchProvider(); - this.currentWeatherCache = undefined; - this.forecastWeatherCache = undefined; - } - if (this.locationChanged()) { - this.currentWeatherCache = undefined; - this.forecastWeatherCache = undefined; - } - this.parseWeatherCurrent(); - })); - }, - - _onNetworkStateChanged: function() { - this._checkConnectionState(); - }, - - _checkConnectionState: function() { - log(new Error().fileName+':'+new Error().lineNumber+' => this._network_monitor.connectivity = '+this._network_monitor.connectivity); - this._connected = this._network_monitor.network_available; - - log(new Error().fileName+':'+new Error().lineNumber+' => this._connected = '+this._connected); - - if (this._connected) { - if (!this._timeoutForecast) - this.forecastWeatherCache = undefined; - if (!this._timeoutCurrent) - this.currentWeatherCache = undefined; - this.parseWeatherCurrent(); - } - }, - - locationChanged: function() { - let location = this.extractCoord(this._city); - if (this.oldLocation != location) { - return true; - } - return false; - }, - - providerChanged: function() { - let provider = this._weather_provider; - if (this.oldProvider != provider) { - this.oldProvider = provider; - return true; - } - if (provider == WeatherProvider.FORECAST_IO) { - let translateCondition = this._translate_condition; - if (this.oldTranslateCondition != translateCondition) { - this.oldTranslateCondition = translateCondition; - return true; - } - } - return false; - }, - - get _clockFormat() { - if (!this._settingsInterface) - this.loadConfigInterface(); - return this._settingsInterface.get_string("clock-format"); - }, - - get _weather_provider() { - if (!this._settings) - this.loadConfig(); - - let provider = this.extractProvider(this._city); - - if (provider == WeatherProvider.DEFAULT) - provider = this._settings.get_enum(OPENWEATHER_PROVIDER_KEY); - - return provider; - }, - - get _units() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_enum(OPENWEATHER_UNIT_KEY); - }, - - get _wind_speed_units() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_enum(OPENWEATHER_WIND_SPEED_UNIT_KEY); - }, - - get _wind_direction() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(OPENWEATHER_WIND_DIRECTION_KEY); - }, - - get _pressure_units() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_enum(OPENWEATHER_PRESSURE_UNIT_KEY); - }, - - get _cities() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_string(OPENWEATHER_CITY_KEY); - }, - - get _actual_city() { - if (!this._settings) - this.loadConfig(); - var a = this._settings.get_int(OPENWEATHER_ACTUAL_CITY_KEY); - var b = a; - var cities = this._cities.split(" && "); - - if (typeof cities != "object") - cities = [cities]; - - var l = cities.length - 1; - - if (a < 0) - a = 0; - - if (l < 0) - l = 0; - - if (a > l) - a = l; - - return a; - }, - - set _actual_city(a) { - if (!this._settings) - this.loadConfig(); - var cities = this._cities.split(" && "); - - if (typeof cities != "object") - cities = [cities]; - - var l = cities.length - 1; - - if (a < 0) - a = 0; - - if (l < 0) - l = 0; - - if (a > l) - a = l; - - this._settings.set_int(OPENWEATHER_ACTUAL_CITY_KEY, a); - }, - - get _city() { - let cities = this._cities; - let cities = cities.split(" && "); - if (cities && typeof cities == "string") - cities = [cities]; - if (!cities[0]) - return ""; - cities = cities[this._actual_city]; - return cities; - }, - - get _translate_condition() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(OPENWEATHER_TRANSLATE_CONDITION_KEY); - }, - - get _getIconType() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(OPENWEATHER_USE_SYMBOLIC_ICONS_KEY) ? 1 : 0; - }, - - get _use_text_on_buttons() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(OPENWEATHER_USE_TEXT_ON_BUTTONS_KEY) ? 1 : 0; - }, - - get _text_in_panel() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(OPENWEATHER_SHOW_TEXT_IN_PANEL_KEY); - }, - - get _position_in_panel() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_enum(OPENWEATHER_POSITION_IN_PANEL_KEY); - }, - - get _comment_in_panel() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(OPENWEATHER_SHOW_COMMENT_IN_PANEL_KEY); - }, - - get _comment_in_forecast() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(OPENWEATHER_SHOW_COMMENT_IN_FORECAST_KEY); - }, - - get _refresh_interval_current() { - if (!this._settings) - this.loadConfig(); - let v = this._settings.get_int(OPENWEATHER_REFRESH_INTERVAL_CURRENT); -// return ((v >= 600) ? v : 600); - return 30; - }, - - get _refresh_interval_forecast() { - if (!this._settings) - this.loadConfig(); - let v = this._settings.get_int(OPENWEATHER_REFRESH_INTERVAL_FORECAST); -// return ((v >= 600) ? v : 600); - return 30; - }, - - get _center_forecast() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(OPENWEATHER_CENTER_FORECAST_KEY); - }, - - get _days_forecast() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_int(OPENWEATHER_DAYS_FORECAST); - }, - - get _decimal_places() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_int(OPENWEATHER_DECIMAL_PLACES); - }, - - get _appid() { - if (!this._settings) - this.loadConfig(); - let key = this._settings.get_string(OPENWEATHER_OWM_API_KEY); - return (key.length == 32) ? key : ''; - }, - - get _appid_fc() { - if (!this._settings) - this.loadConfig(); - let key = this._settings.get_string(OPENWEATHER_FC_API_KEY); - return (key.length == 32) ? key : ''; - }, - - rebuildButtonMenu: function() { - if (this._buttonBox) { - if (this._buttonBox1) { - this._buttonBox1.destroy(); - this._buttonBox1 = undefined; - - } - if (this._buttonBox2) { - this._buttonBox2.destroy(); - this._buttonBox2 = undefined; - } - this._buttonMenu.removeActor(this._buttonBox); - this._buttonBox.destroy(); - this._buttonBox = undefined; - } - - if (this._buttonBox1) { - this._buttonBox1.destroy(); - this._buttonBox1 = undefined; - } - if (this._buttonBox2) { - this._buttonBox2.destroy(); - this._buttonBox2 = undefined; - } - - this._locationButton = Main.panel.statusArea.aggregateMenu._system._createActionButton('find-location-symbolic', _("Locations")); - if (this._use_text_on_buttons) - this._locationButton.set_label(this._locationButton.get_accessible_name()); - - this._locationButton.connect('clicked', Lang.bind(this, function() { - this._selectCity._setOpenState(!this._selectCity._getOpenState()); - })); - this._buttonBox1 = new St.BoxLayout({ - style_class: 'openweather-button-box' - }); - this._buttonBox1.add_actor(this._locationButton); - - this._reloadButton = Main.panel.statusArea.aggregateMenu._system._createActionButton('view-refresh-symbolic', _("Reload Weather Information")); - if (this._use_text_on_buttons) - this._reloadButton.set_label(this._reloadButton.get_accessible_name()); - this._reloadButton.connect('clicked', Lang.bind(this, function() { - this.currentWeatherCache = undefined; - this.forecastWeatherCache = undefined; - this.parseWeatherCurrent(); - this.recalcLayout(); - })); - this._buttonBox1.add_actor(this._reloadButton); - - this._buttonBox2 = new St.BoxLayout({ - style_class: 'openweather-button-box' - }); - - this._urlButton = Main.panel.statusArea.aggregateMenu._system._createActionButton('', _("Weather data provided by:") + (this._use_text_on_buttons ? "\n" : " ") + this.weatherProvider); - this._urlButton.set_label(this._urlButton.get_accessible_name()); - this._urlButton.style_class += ' openweather-provider'; - - this._urlButton.connect('clicked', Lang.bind(this, function() { - this.menu.actor.hide(); - let url = this.getWeatherProviderURL(); - - try { - Gtk.show_uri(null, url, global.get_current_time()); - } catch (err) { - let title = _("Can not open %s").format(url); - Main.notifyError(title, err.message); - } - })); - - this._buttonBox2.add_actor(this._urlButton); - - this._prefsButton = Main.panel.statusArea.aggregateMenu._system._createActionButton('preferences-system-symbolic', _("Weather Settings")); - if (this._use_text_on_buttons) - this._prefsButton.set_label(this._prefsButton.get_accessible_name()); - this._prefsButton.connect('clicked', Lang.bind(this, this._onPreferencesActivate)); - this._buttonBox2.add_actor(this._prefsButton); - - this._buttonMenu.actor.add_actor(this._buttonBox1); - this._buttonMenu.actor.add_actor(this._buttonBox2); - - this._buttonBox1MinWidth = undefined; - }, - - rebuildSelectCityItem: function() { - this._selectCity.menu.removeAll(); - let item = null; - - let cities = this._cities; - cities = cities.split(" && "); - if (cities && typeof cities == "string") - cities = [cities]; - if (!cities[0]) - return; - - for (let i = 0; cities.length > i; i++) { - item = new PopupMenu.PopupMenuItem(this.extractLocation(cities[i])); - item.location = i; - if (i == this._actual_city) { - item.setOrnament(PopupMenu.Ornament.DOT); - } - - this._selectCity.menu.addMenuItem(item); - // override the items default onActivate-handler, to keep the ui open while chosing the location - item.activate = this._onActivate; - } - - if (cities.length == 1) - this._selectCity.actor.hide(); - else - this._selectCity.actor.show(); - - }, - - _onActivate: function() { - openweatherMenu._actual_city = this.location; - }, - - extractLocation: function() { - if (!arguments[0]) - return ""; - - if (arguments[0].search(">") == -1) - return _("Invalid city"); - return arguments[0].split(">")[1]; - }, - - extractCoord: function() { - let coords = 0; - - if (arguments[0] && (arguments[0].search(">") != -1)) - coords = arguments[0].split(">")[0]; - - if ((coords.search(",") == -1) || isNaN(coords.split(",")[0]) || isNaN(coords.split(",")[1])) { - Main.notify("Openweathermap", _("Invalid location! Please try to recreate it.")); - return 0; - } - - return coords; - }, - - extractProvider: function() { - if (!arguments[0]) - return -1; - if (arguments[0].split(">")[2] === undefined) - return -1; - if (isNaN(parseInt(arguments[0].split(">")[2]))) - return -1; - return parseInt(arguments[0].split(">")[2]); - }, - - _onPreferencesActivate: function() { - this.menu.actor.hide(); - Util.spawn(["gnome-shell-extension-prefs", "openweather-extension@jenslody.de"]); - return 0; - }, - - recalcLayout: function() { - if (!this.menu.isOpen) - return; - if (this._buttonBox1MinWidth === undefined) - this._buttonBox1MinWidth = this._buttonBox1.get_width(); - this._buttonBox1.set_width(Math.max(this._buttonBox1MinWidth, this._currentWeather.get_width() - this._buttonBox2.get_width())); - if (this._forecastScrollBox !== undefined && this._forecastBox !== undefined && this._currentWeather !== undefined) { - this._forecastScrollBox.set_width(Math.max(this._currentWeather.get_width(), (this._buttonBox1.get_width() + this._buttonBox2.get_width()))); - this._forecastScrollBox.show(); - if (this._forecastBox.get_preferred_width(this._forecastBox.get_height())[0] > this._currentWeather.get_width()) { - this._forecastScrollBox.hscroll.margin_top = 10; - this._forecastScrollBox.hscroll.show(); - } else { - this._forecastScrollBox.hscroll.margin_top = 0; - this._forecastScrollBox.hscroll.hide(); - } - } - }, - - unit_to_unicode: function() { - if (this._units == WeatherUnits.FAHRENHEIT) - return '\u00B0F'; - else if (this._units == WeatherUnits.KELVIN) - return 'K'; - else if (this._units == WeatherUnits.RANKINE) - return '\u00B0Ra'; - else if (this._units == WeatherUnits.REAUMUR) - return '\u00B0R\u00E9'; - else if (this._units == WeatherUnits.ROEMER) - return '\u00B0R\u00F8'; - else if (this._units == WeatherUnits.DELISLE) - return '\u00B0De'; - else if (this._units == WeatherUnits.NEWTON) - return '\u00B0N'; - else - return '\u00B0C'; - }, - - hasIcon: function(icon) { - return Gtk.IconTheme.get_default().has_icon(icon + this.getIconType()); - }, - - toFahrenheit: function(t) { - return ((Number(t) * 1.8) + 32).toFixed(this._decimal_places); - }, - - toKelvin: function(t) { - return (Number(t) + 273.15).toFixed(this._decimal_places); - }, - - toRankine: function(t) { - return ((Number(t) * 1.8) + 491.67).toFixed(this._decimal_places); - }, - - toReaumur: function(t) { - return (Number(t) * 0.8).toFixed(this._decimal_places); - }, - - toRoemer: function(t) { - return ((Number(t) * 21 / 40) + 7.5).toFixed(this._decimal_places); - }, - - toDelisle: function(t) { - return ((100 - Number(t)) * 1.5).toFixed(this._decimal_places); - }, - - toNewton: function(t) { - return (Number(t) - 0.33).toFixed(this._decimal_places); - }, - - toInHg: function(p /*, t*/ ) { - return (p / 33.86530749).toFixed(this._decimal_places); - }, - - toBeaufort: function(w, t) { - if (w < 0.3) - return (!t) ? "0" : "(" + _("Calm") + ")"; - - else if (w >= 0.3 && w <= 1.5) - return (!t) ? "1" : "(" + _("Light air") + ")"; - - else if (w > 1.5 && w <= 3.4) - return (!t) ? "2" : "(" + _("Light breeze") + ")"; - - else if (w > 3.4 && w <= 5.4) - return (!t) ? "3" : "(" + _("Gentle breeze") + ")"; - - else if (w > 5, 4 && w <= 7.9) - return (!t) ? "4" : "(" + _("Moderate breeze") + ")"; - - else if (w > 7.9 && w <= 10.7) - return (!t) ? "5" : "(" + _("Fresh breeze") + ")"; - - else if (w > 10.7 && w <= 13.8) - return (!t) ? "6" : "(" + _("Strong breeze") + ")"; - - else if (w > 13.8 && w <= 17.1) - return (!t) ? "7" : "(" + _("Moderate gale") + ")"; - - else if (w > 17.1 && w <= 20.7) - return (!t) ? "8" : "(" + _("Fresh gale") + ")"; - - else if (w > 20.7 && w <= 24.4) - return (!t) ? "9" : "(" + _("Strong gale") + ")"; - - else if (w > 24.4 && w <= 28.4) - return (!t) ? "10" : "(" + _("Storm") + ")"; - - else if (w > 28.4 && w <= 32.6) - return (!t) ? "11" : "(" + _("Violent storm") + ")"; - - else - return (!t) ? "12" : "(" + _("Hurricane") + ")"; - }, - - getLocaleDay: function(abr) { - let days = [_('Sunday'), _('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday')]; - return days[abr]; - }, - - getWindDirection: function(deg) { - let arrows = ["\u2193", "\u2199", "\u2190", "\u2196", "\u2191", "\u2197", "\u2192", "\u2198"]; - let letters = [_('N'), _('NE'), _('E'), _('SE'), _('S'), _('SW'), _('W'), _('NW')]; - let idx = Math.round(deg / 45) % arrows.length; - return (this._wind_direction) ? arrows[idx] : letters[idx]; - }, - - getIconType: function(icon_name) { - if (!icon_name) - if (this._getIconType) - return "-symbolic"; - else - return ""; - - if (this._getIconType) - if (String(icon_name).search("-symbolic") != -1) - return icon_name; - else - return icon_name + "-symbolic"; - else - if (String(icon_name).search("-symbolic") != -1) - return String(icon_name).replace("-symbolic", ""); - else - return icon_name; - }, - - load_json_async: function(url, params, fun) { - if (_httpSession === undefined) { - _httpSession = new Soup.Session(); - } - - let message = Soup.form_request_new_from_hash('GET', url, params); - - _httpSession.queue_message(message, Lang.bind(this, function(_httpSession, message) { - - try { - if (!message.response_body.data) { - fun.call(this, 0); - return; - } - let jp = JSON.parse(message.response_body.data); - fun.call(this, jp); - } catch (e) { - fun.call(this, 0); - return; - } - })); - return; - }, - - checkPositionInPanel: function() { - if (this._old_position_in_panel != this._position_in_panel) { - switch (this._old_position_in_panel) { - case WeatherPosition.LEFT: - Main.panel._leftBox.remove_actor(this.actor); - break; - case WeatherPosition.CENTER: - Main.panel._centerBox.remove_actor(this.actor); - break; - case WeatherPosition.RIGHT: - Main.panel._rightBox.remove_actor(this.actor); - break; - } - - let children = null; - switch (this._position_in_panel) { - case WeatherPosition.LEFT: - children = Main.panel._leftBox.get_children(); - Main.panel._leftBox.insert_child_at_index(this.actor, children.length); - break; - case WeatherPosition.CENTER: - children = Main.panel._centerBox.get_children(); - Main.panel._centerBox.insert_child_at_index(this.actor, children.length); - break; - case WeatherPosition.RIGHT: - children = Main.panel._rightBox.get_children(); - Main.panel._rightBox.insert_child_at_index(this.actor, 0); - break; - } - this._old_position_in_panel = this._position_in_panel; - } - - }, - - formatPressure: function(pressure) { - let pressure_unit = 'hPa'; - switch (this._pressure_units) { - case WeatherPressureUnits.INHG: - pressure = this.toInHg(pressure); - pressure_unit = "inHg"; - break; - - case WeatherPressureUnits.HPA: - pressure = pressure.toFixed(this._decimal_places); - pressure_unit = "hPa"; - break; - - case WeatherPressureUnits.BAR: - pressure = (pressure / 1000).toFixed(this._decimal_places); - pressure_unit = "bar"; - break; - - case WeatherPressureUnits.PA: - pressure = (pressure * 100).toFixed(this._decimal_places); - pressure_unit = "Pa"; - break; - - case WeatherPressureUnits.KPA: - pressure = (pressure / 10).toFixed(this._decimal_places); - pressure_unit = "kPa"; - break; - - case WeatherPressureUnits.ATM: - pressure = (pressure * 0.000986923267).toFixed(this._decimal_places); - pressure_unit = "atm"; - break; - - case WeatherPressureUnits.AT: - pressure = (pressure * 0.00101971621298).toFixed(this._decimal_places); - pressure_unit = "at"; - break; - - case WeatherPressureUnits.TORR: - pressure = (pressure * 0.750061683).toFixed(this._decimal_places); - pressure_unit = "Torr"; - break; - - case WeatherPressureUnits.PSI: - pressure = (pressure * 0.0145037738).toFixed(this._decimal_places); - pressure_unit = "psi"; - break; - - case WeatherPressureUnits.MMHG: - pressure = (pressure * 0.750061683).toFixed(this._decimal_places); - pressure_unit = "mmHg"; - break; - } - return parseFloat(pressure).toLocaleString() + ' ' + pressure_unit; - }, - - formatTemperature: function(temperature) { - switch (this._units) { - case WeatherUnits.FAHRENHEIT: - temperature = this.toFahrenheit(temperature); - break; - - case WeatherUnits.CELSIUS: - temperature = temperature.toFixed(this._decimal_places); - break; - - case WeatherUnits.KELVIN: - temperature = this.toKelvin(temperature); - break; - - case WeatherUnits.RANKINE: - temperature = this.toRankine(temperature); - break; - - case WeatherUnits.REAUMUR: - temperature = this.toReaumur(temperature); - break; - - case WeatherUnits.ROEMER: - temperature = this.toRoemer(temperature); - break; - - case WeatherUnits.DELISLE: - temperature = this.toDelisle(temperature); - break; - - case WeatherUnits.NEWTON: - temperature = this.toNewton(temperature); - break; - } - return parseFloat(temperature).toLocaleString() + ' ' + this.unit_to_unicode(); - }, - - formatWind: function(speed, direction) { - let unit = 'm/s'; - switch (this._wind_speed_units) { - case WeatherWindSpeedUnits.MPH: - speed = (speed * OPENWEATHER_CONV_MPS_IN_MPH).toFixed(this._decimal_places); - unit = 'mph'; - break; - - case WeatherWindSpeedUnits.KPH: - speed = (speed * OPENWEATHER_CONV_MPS_IN_KPH).toFixed(this._decimal_places); - unit = 'km/h'; - break; - - case WeatherWindSpeedUnits.MPS: - speed = speed.toFixed(this._decimal_places); - break; - - case WeatherWindSpeedUnits.KNOTS: - speed = (speed * OPENWEATHER_CONV_MPS_IN_KNOTS).toFixed(this._decimal_places); - unit = 'kn'; - break; - - case WeatherWindSpeedUnits.FPS: - speed = (speed * OPENWEATHER_CONV_MPS_IN_FPS).toFixed(this._decimal_places); - unit = 'ft/s'; - break; - - case WeatherWindSpeedUnits.BEAUFORT: - speed = this.toBeaufort(speed); - unit = this.toBeaufort(speed, true); - break; - - } - - if (!speed) - return '\u2013'; - else if (speed === 0 || !direction) - return parseFloat(speed).toLocaleString() + ' ' + unit; - else // i.e. speed > 0 && direction - return direction + ' ' + parseFloat(speed).toLocaleString() + ' ' + unit; - }, - - reloadWeatherCurrent: function(interval) { - log(new Error().fileName+':'+new Error().lineNumber+' => this._timeoutCurrent = '+this._timeoutCurrent); - if (this._timeoutCurrent) { - Mainloop.source_remove(this._timeoutCurrent); - this._timeoutCurrent = undefined; - log(new Error().fileName+':'+new Error().lineNumber+' => this._timeoutCurrent = '+this._timeoutCurrent); - } - log(new Error().fileName+':'+new Error().lineNumber+' => this._timeoutCurrent = '+this._timeoutCurrent); - if (this._connected) { - this._timeoutCurrent = Mainloop.timeout_add_seconds(interval, Lang.bind(this, function() { - this.currentWeatherCache = undefined; - this.parseWeatherCurrent(); - return true; - })); - } - }, - - reloadWeatherForecast: function(interval) { - log(new Error().fileName+':'+new Error().lineNumber+' => this._timeoutForecast = '+this._timeoutForecast); - if (this._timeoutForecast) { - Mainloop.source_remove(this._timeoutForecast); - this._timeoutForecast = undefined; - log(new Error().fileName+':'+new Error().lineNumber+' => this._timeoutForecast = '+this._timeoutForecast); - } - log(new Error().fileName+':'+new Error().lineNumber+' => this._timeoutForecast = '+this._timeoutForecast); - if (this._connected) { - this._timeoutForecast = Mainloop.timeout_add_seconds(interval, Lang.bind(this, function() { - this.forecastWeatherCache = undefined; - this.parseWeatherForecast(); - return true; - })); - } - }, - - destroyCurrentWeather: function() { - if (this._currentWeather.get_child() !== null) - this._currentWeather.get_child().destroy(); - }, - - destroyFutureWeather: function() { - if (this._futureWeather.get_child() !== null) - this._futureWeather.get_child().destroy(); - }, - - rebuildCurrentWeatherUi: function() { - this._weatherInfo.text = _(' '); - this._weatherIcon.icon_name = 'view-refresh' + this.getIconType(); - - this.destroyCurrentWeather(); - - // This will hold the icon for the current weather - this._currentWeatherIcon = new St.Icon({ - icon_size: 72, - icon_name: 'view-refresh' + this.getIconType(), - style_class: 'system-menu-action openweather-current-icon' - }); - - this._sunriseIcon = new St.Icon({ - icon_size: 15, - icon_name: 'weather-clear' + this.getIconType(), - style_class: 'openweather-sunrise-icon' - }); - - this._sunsetIcon = new St.Icon({ - icon_size: 15, - icon_name: 'weather-clear-night' + this.getIconType(), - style_class: 'openweather-sunset-icon' - }); - - this._buildIcon = new St.Icon({ - icon_size: 15, - icon_name: 'view-refresh' + this.getIconType(), - style_class: 'openweather-build-icon' - }); - - // The summary of the current weather - this._currentWeatherSummary = new St.Label({ - text: _('Loading ...'), - style_class: 'openweather-current-summary' - }); - this._currentWeatherLocation = new St.Label({ - text: _('Please wait') - }); - - let bb = new St.BoxLayout({ - vertical: true, - style_class: 'system-menu-action openweather-current-summarybox' - }); - bb.add_actor(this._currentWeatherLocation); - bb.add_actor(this._currentWeatherSummary); - - this._currentWeatherSunrise = new St.Label({ - text: '-' - }); - this._currentWeatherSunset = new St.Label({ - text: '-' - }); - this._currentWeatherBuild = new St.Label({ - text: '-' - }); - - let ab = new St.BoxLayout({ - style_class: 'openweather-current-infobox' - }); - - ab.add_actor(this._sunriseIcon); - ab.add_actor(this._currentWeatherSunrise); - ab.add_actor(this._sunsetIcon); - ab.add_actor(this._currentWeatherSunset); - ab.add_actor(this._buildIcon); - ab.add_actor(this._currentWeatherBuild); - bb.add_actor(ab); - - // Other labels - this._currentWeatherCloudiness = new St.Label({ - text: '...' - }); - this._currentWeatherHumidity = new St.Label({ - text: '...' - }); - this._currentWeatherPressure = new St.Label({ - text: '...' - }); - this._currentWeatherWind = new St.Label({ - text: '...' - }); - - let rb = new St.BoxLayout({ - style_class: 'openweather-current-databox' - }); - let rb_captions = new St.BoxLayout({ - vertical: true, - style_class: 'popup-status-menu-item openweather-current-databox-captions' - }); - let rb_values = new St.BoxLayout({ - vertical: true, - style_class: 'system-menu-action openweather-current-databox-values' - }); - rb.add_actor(rb_captions); - rb.add_actor(rb_values); - - rb_captions.add_actor(new St.Label({ - text: _('Cloudiness:') - })); - rb_values.add_actor(this._currentWeatherCloudiness); - rb_captions.add_actor(new St.Label({ - text: _('Humidity:') - })); - rb_values.add_actor(this._currentWeatherHumidity); - rb_captions.add_actor(new St.Label({ - text: _('Pressure:') - })); - rb_values.add_actor(this._currentWeatherPressure); - rb_captions.add_actor(new St.Label({ - text: _('Wind:') - })); - rb_values.add_actor(this._currentWeatherWind); - - let xb = new St.BoxLayout(); - xb.add_actor(bb); - xb.add_actor(rb); - - let box = new St.BoxLayout({ - style_class: 'openweather-current-iconbox' - }); - box.add_actor(this._currentWeatherIcon); - box.add_actor(xb); - this._currentWeather.set_child(box); - }, - - scrollForecastBy: function(delta) { - if (this._forecastScrollBox === undefined) - return; - this._forecastScrollBox.hscroll.adjustment.value += delta; - }, - - rebuildFutureWeatherUi: function(cnt) { - this.destroyFutureWeather(); - - this._forecast = []; - this._forecastBox = new St.BoxLayout({ - x_align: this._center_forecast ? St.Align.END : St.Align.START, - style_class: 'openweather-forecast-box' - }); - - this._forecastScrollBox = new St.ScrollView({ - style_class: 'openweather-forecasts' - }); - - let pan = new Clutter.PanAction({ - interpolate: true - }); - pan.connect('pan', Lang.bind(this, function(action) { - - let[dist, dx, dy] = action.get_motion_delta(0); - - this.scrollForecastBy(-1 * (dx / this._forecastScrollBox.width) * this._forecastScrollBox.hscroll.adjustment.page_size); - return false; - })); - this._forecastScrollBox.add_action(pan); - - this._forecastScrollBox.connect('scroll-event', Lang.bind(this, this._onScroll)); - this._forecastScrollBox.hscroll.connect('scroll-event', Lang.bind(this, this._onScroll)); - - this._forecastScrollBox.hscroll.margin_right = 25; - this._forecastScrollBox.hscroll.margin_left = 25; - this._forecastScrollBox.hscroll.hide(); - this._forecastScrollBox.vscrollbar_policy = Gtk.PolicyType.NEVER; - this._forecastScrollBox.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC; - this._forecastScrollBox.enable_mouse_scrolling = true; - this._forecastScrollBox.hide(); - - this._futureWeather.set_child(this._forecastScrollBox); - - if (cnt === undefined) - cnt = this._days_forecast; - for (let i = 0; i < cnt; i++) { - let forecastWeather = {}; - - forecastWeather.Icon = new St.Icon({ - icon_size: 48, - icon_name: 'view-refresh' + this.getIconType(), - style_class: 'system-menu-action openweather-forecast-icon' - }); - forecastWeather.Day = new St.Label({ - style_class: 'popup-status-menu-item openweather-forecast-day' - }); - forecastWeather.Summary = new St.Label({ - style_class: 'system-menu-action openweather-forecast-summary' - }); - forecastWeather.Summary.clutter_text.line_wrap = true; - forecastWeather.Temperature = new St.Label({ - style_class: 'system-menu-action openweather-forecast-temperature' - }); - - let by = new St.BoxLayout({ - vertical: true, - style_class: 'openweather-forecast-databox' - }); - by.add_actor(forecastWeather.Day); - if (this._comment_in_forecast) - by.add_actor(forecastWeather.Summary); - by.add_actor(forecastWeather.Temperature); - - let bb = new St.BoxLayout({ - style_class: 'openweather-forecast-iconbox' - }); - bb.add_actor(forecastWeather.Icon); - bb.add_actor(by); - - this._forecast[i] = forecastWeather; - this._forecastBox.add_actor(bb); - } - this._forecastScrollBox.add_actor(this._forecastBox); - }, - - _onScroll: function(actor, event) { - let dx = 0; - let dy = 0; - switch (event.get_scroll_direction()) { - case Clutter.ScrollDirection.UP: - dy = -1; - break; - case Clutter.ScrollDirection.DOWN: - dy = 1; - break; - // horizontal scrolling will be handled by the control itself - default: - return true; - } - - this.scrollForecastBy(dy * this._forecastScrollBox.hscroll.adjustment.stepIncrement); - return false; - } -}); - -let openweatherMenu; - -function init() { - Convenience.initTranslations('gnome-shell-extension-openweather'); -} - -function enable() { - openweatherMenu = new OpenweatherMenuButton(); - Main.panel.addToStatusArea('openweatherMenu', openweatherMenu); -} - -function disable() { - openweatherMenu.stop(); - openweatherMenu.destroy(); -} diff --git a/src/fetch_data_base.js b/src/fetch_data_base.js deleted file mode 100644 index b8eeedd..0000000 --- a/src/fetch_data_base.js +++ /dev/null @@ -1,1979 +0,0 @@ -/* jshint esnext:true */ -/* - * - * Weather extension for GNOME Shell - * - Displays a small weather information on the top panel. - * - On click, gives a popup with details about the weather. - * - * Copyright (C) 2011 - 2015 - * ecyrbe , - * Timur Kristof , - * Elad Alfassa , - * Simon Legner , - * Christian METZLER , - * Mark Benjamin weather.gnome.Markie1@dfgh.net, - * Mattia Meneguzzo odysseus@fedoraproject.org, - * Meng Zhuo , - * Jens Lody - * - * - * This file is part of gnome-shell-extension-openweather. - * - * gnome-shell-extension-openweather is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * gnome-shell-extension-openweather is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with gnome-shell-extension-openweather. If not, see . - * - */ - -const ExtensionUtils = imports.misc.extensionUtils; -const Me = ExtensionUtils.getCurrentExtension(); -const Config = imports.misc.config; -const Convenience = Me.imports.convenience; -const Clutter = imports.gi.Clutter; -const Gettext = imports.gettext.domain('gnome-shell-extension-openweather'); -const Gio = imports.gi.Gio; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; -const Mainloop = imports.mainloop; -const Soup = imports.gi.Soup; -const St = imports.gi.St; -const Util = imports.misc.util; -const _ = Gettext.gettext; - -const Main = imports.ui.main; -const PanelMenu = imports.ui.panelMenu; -const PopupMenu = imports.ui.popupMenu; - -// Settings -const WEATHER_SETTINGS_SCHEMA = 'org.gnome.shell.extensions.openweather'; -const WEATHER_UNIT_KEY = 'unit'; -const WEATHER_WIND_SPEED_UNIT_KEY = 'wind-speed-unit'; -const WEATHER_WIND_DIRECTION_KEY = 'wind-direction'; -const WEATHER_PRESSURE_UNIT_KEY = 'pressure-unit'; -const WEATHER_CITY_KEY = 'city'; -const WEATHER_ACTUAL_CITY_KEY = 'actual-city'; -const WEATHER_TRANSLATE_CONDITION_KEY = 'translate-condition'; -const WEATHER_USE_SYMBOLIC_ICONS_KEY = 'use-symbolic-icons'; -const WEATHER_USE_TEXT_ON_BUTTONS_KEY = 'use-text-on-buttons'; -const WEATHER_SHOW_TEXT_IN_PANEL_KEY = 'show-text-in-panel'; -const WEATHER_POSITION_IN_PANEL_KEY = 'position-in-panel'; -const WEATHER_SHOW_COMMENT_IN_PANEL_KEY = 'show-comment-in-panel'; -const WEATHER_REFRESH_INTERVAL_CURRENT = 'refresh-interval-current'; -const WEATHER_REFRESH_INTERVAL_FORECAST = 'refresh-interval-forecast'; -const WEATHER_CENTER_FORECAST_KEY = 'center-forecast'; -const WEATHER_DAYS_FORECAST = 'days-forecast'; -const WEATHER_DECIMAL_PLACES = 'decimal-places'; -const WEATHER_OWM_API_KEY = 'appid'; - -//URL -const WEATHER_URL_HOST = ''; -const WEATHER_URL_PORT = 80; -const WEATHER_URL_BASE = 'http://' + WEATHER_URL_HOST; -const WEATHER_URL_CURRENT = WEATHER_URL_BASE + ''; -const WEATHER_URL_FORECAST = WEATHER_URL_BASE + ''; - -// Keep enums in sync with GSettings schemas -const WeatherUnits = { - CELSIUS: 0, - FAHRENHEIT: 1, - KELVIN: 2, - RANKINE: 3, - REAUMUR: 4, - ROEMER: 5, - DELISLE: 6, - NEWTON: 7 -}; - -const WeatherWindSpeedUnits = { - KPH: 0, - MPH: 1, - MPS: 2, - KNOTS: 3, - FPS: 4, - BEAUFORT: 5 -}; - -const WeatherPressureUnits = { - hPa: 0, - inHg: 1, - bar: 2, - Pa: 3, - kPa: 4, - atm: 5, - at: 6, - Torr: 7, - psi: 8, - mmHg: 9 -}; - -const WeatherPosition = { - CENTER: 0, - RIGHT: 1, - LEFT: 2 -}; - -const WEATHER_CONV_MPS_IN_MPH = 2.23693629; -const WEATHER_CONV_MPS_IN_KPH = 3.6; -const WEATHER_CONV_MPS_IN_KNOTS = 1.94384449; -const WEATHER_CONV_MPS_IN_FPS = 3.2808399; - -let _httpSession; - -const OpenweatherProviderBase = new Lang.Class({ - Name: 'OpenweatherProviderBase', - - _init: function() { - this.currentWeatherCache = undefined; - this.forecastWeatherCache = undefined; - // Load settings - this.loadConfig(); - - // Label - this._weatherInfo = new St.Label({ - y_align: Clutter.ActorAlign.CENTER, - text: _('...') - }); - - this._weatherIcon = new St.Icon({ - icon_name: 'view-refresh' + this.icon_type(), - style_class: 'system-status-icon openweather-icon' - }); - - // Panel menu item - the current class - let menuAlignment = 0.25; - if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) - menuAlignment = 1.0 - menuAlignment; - this.parent(menuAlignment); - - // Putting the panel item together - let topBox = new St.BoxLayout(); - topBox.add_actor(this._weatherIcon); - topBox.add_actor(this._weatherInfo); - this.actor.add_actor(topBox); - - let dummyBox = new St.BoxLayout(); - this.actor.reparent(dummyBox); - dummyBox.remove_actor(this.actor); - dummyBox.destroy(); - - let children = null; - switch (this._position_in_panel) { - case WeatherPosition.LEFT: - children = Main.panel._leftBox.get_children(); - Main.panel._leftBox.insert_child_at_index(this.actor, children.length); - break; - case WeatherPosition.CENTER: - children = Main.panel._centerBox.get_children(); - Main.panel._centerBox.insert_child_at_index(this.actor, children.length); - break; - case WeatherPosition.RIGHT: - children = Main.panel._rightBox.get_children(); - Main.panel._rightBox.insert_child_at_index(this.actor, 0); - break; - } - if (Main.panel._menus === undefined) - Main.panel.menuManager.addMenu(this.menu); - else - Main.panel._menus.addMenu(this.menu); - - this._old_position_in_panel = this._position_in_panel; - - // Current weather - this._currentWeather = new St.Bin(); - // Future weather - this._futureWeather = new St.Bin(); - - // Putting the popup item together - let _itemCurrent = new PopupMenu.PopupBaseMenuItem({ - reactive: false - }); - let _itemFuture = new PopupMenu.PopupBaseMenuItem({ - reactive: false - }); - - if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) { - _itemCurrent.addActor(this._currentWeather); - _itemFuture.addActor(this._futureWeather); - } else { - _itemCurrent.actor.add_actor(this._currentWeather); - _itemFuture.actor.add_actor(this._futureWeather); - } - - this.menu.addMenuItem(_itemCurrent); - - this._separatorItem = new PopupMenu.PopupSeparatorMenuItem(); - this.menu.addMenuItem(this._separatorItem); - - this.menu.addMenuItem(_itemFuture); - - let item = new PopupMenu.PopupSeparatorMenuItem(); - this.menu.addMenuItem(item); - - this._selectCity = new PopupMenu.PopupSubMenuMenuItem(""); - this._selectCity.actor.set_height(0); - this._selectCity._triangle.set_height(0); - - this._buttonMenu = new PopupMenu.PopupBaseMenuItem({ - reactive: false, - style_class: 'openweather-menu-button-container' - }); - - this.rebuildButtonMenu(); - - this.menu.addMenuItem(this._buttonMenu); - this.menu.addMenuItem(this._selectCity); - this.rebuildSelectCityItem(); - this._selectCity.menu.connect('open-state-changed', Lang.bind(this, function() { - this._selectCity.actor.remove_style_pseudo_class('open'); - })); - - this.rebuildCurrentWeatherUi(); - this.rebuildFutureWeatherUi(); - - this._network_monitor = Gio.network_monitor_get_default(); - - this._connected = false; - this._network_monitor_connection = this._network_monitor.connect('network-changed', Lang.bind(this, this._onNetworkStateChanged)); - this._checkConnectionState(); - - this.menu.connect('open-state-changed', Lang.bind(this, this.recalcLayout)); - if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) { - this._needsColorUpdate = true; - let context = St.ThemeContext.get_for_stage(global.stage); - this._globalThemeChangedId = context.connect('changed', Lang.bind(this, function(){this._needsColorUpdate = true;})); - } - }, - - stop: function() { - if (_httpSession !== undefined) - _httpSession.abort(); - - _httpSession = undefined; - - if (this._timeoutCurrent) - Mainloop.source_remove(this._timeoutCurrent); - - this._timeoutCurrent = undefined; - - if (this._timeoutForecast) - Mainloop.source_remove(this._timeoutForecast); - - this._timeoutForecast = undefined; - - if (this._network_monitor_connection) { - this._network_monitor.disconnect(this._network_monitor_connection); - this._network_monitor_connection = undefined; - } - - if (this._settingsC) { - this._settings.disconnect(this._settingsC); - this._settingsC = undefined; - } - - if (this._settingsInterfaceC) { - this._settingsInterface.disconnect(this._settingsInterfaceC); - this._settingsInterfaceC = undefined; - } - - if (this._globalThemeChangedId) { - let context = St.ThemeContext.get_for_stage(global.stage); - context.disconnect(this._globalThemeChangedId); - this._globalThemeChangedId = undefined; - } - }, - - loadConfig: function() { - this._settings = Convenience.getSettings(WEATHER_SETTINGS_SCHEMA); - this._settingsC = this._settings.connect("changed", Lang.bind(this, function() { - this.rebuildCurrentWeatherUi(); - this.rebuildFutureWeatherUi(); - this.rebuildButtonMenu(); - if (this.locationChanged()) { - this.currentWeatherCache = undefined; - this.forecastWeatherCache = undefined; - } - this.parseWeatherCurrent(); - })); - }, - - loadConfigInterface: function() { - let schemaInterface = "org.gnome.desktop.interface"; - if (Gio.Settings.list_schemas().indexOf(schemaInterface) == -1) - throw _("Schema \"%s\" not found.").replace("%s", schemaInterface); - this._settingsInterface = new Gio.Settings({ - schema: schemaInterface - }); - this._settingsInterfaceC = this._settingsInterface.connect("changed", Lang.bind(this, function() { - this.rebuildCurrentWeatherUi(); - this.rebuildFutureWeatherUi(); - if (this.locationChanged()) { - this.currentWeatherCache = undefined; - this.forecastWeatherCache = undefined; - } - this.parseWeatherCurrent(); - })); - }, - - _onNetworkStateChanged: function() { - this._checkConnectionState(); - }, - - _checkConnectionState: function() { - this._connected = this._network_monitor.network_available; - if (this._connected) - this.parseWeatherCurrent(); - }, - - locationChanged: function() { - let location = this.extractId(this._city); - if (this.oldLocation != location) { - return true; - } - return false; - }, - - get _clockFormat() { - if (!this._settingsInterface) - this.loadConfigInterface(); - return this._settingsInterface.get_string("clock-format"); - }, - - get _units() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_enum(WEATHER_UNIT_KEY); - }, - - set _units(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_enum(WEATHER_UNIT_KEY, v); - }, - - get _wind_speed_units() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_enum(WEATHER_WIND_SPEED_UNIT_KEY); - }, - - set _wind_speed_units(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_enum(WEATHER_WIND_SPEED_UNIT_KEY, v); - }, - - get _wind_direction() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(WEATHER_WIND_DIRECTION_KEY); - }, - - set _wind_direction(v) { - if (!this._settings) - this.loadConfig(); - return this._settings.set_boolean(WEATHER_WIND_DIRECTION_KEY, v); - }, - - get _pressure_units() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_enum(WEATHER_PRESSURE_UNIT_KEY); - }, - - set _pressure_units(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_enum(WEATHER_PRESSURE_UNIT_KEY, v); - }, - - get _cities() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_string(WEATHER_CITY_KEY); - }, - - set _cities(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_string(WEATHER_CITY_KEY, v); - }, - - get _actual_city() { - if (!this._settings) - this.loadConfig(); - var a = this._settings.get_int(WEATHER_ACTUAL_CITY_KEY); - var b = a; - var cities = this._cities.split(" && "); - - if (typeof cities != "object") - cities = [cities]; - - var l = cities.length - 1; - - if (a < 0) - a = 0; - - if (l < 0) - l = 0; - - if (a > l) - a = l; - - return a; - }, - - set _actual_city(a) { - if (!this._settings) - this.loadConfig(); - var cities = this._cities.split(" && "); - - if (typeof cities != "object") - cities = [cities]; - - var l = cities.length - 1; - - if (a < 0) - a = 0; - - if (l < 0) - l = 0; - - if (a > l) - a = l; - - this._settings.set_int(WEATHER_ACTUAL_CITY_KEY, a); - }, - - get _city() { - let cities = this._cities; - let cities = cities.split(" && "); - if (cities && typeof cities == "string") - cities = [cities]; - if (!cities[0]) - return ""; - cities = cities[this._actual_city]; - return cities; - }, - - set _city(v) { - let cities = this._cities; - cities = cities.split(" && "); - if (cities && typeof cities == "string") - cities = [cities]; - if (!cities[0]) - cities = []; - cities.splice(this.actual_city, 1, v); - cities = cities.join(" && "); - if (typeof cities != "string") - cities = cities[0]; - this._cities = cities; - }, - - get _translate_condition() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(WEATHER_TRANSLATE_CONDITION_KEY); - }, - - set _translate_condition(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_boolean(WEATHER_TRANSLATE_CONDITION_KEY, v); - }, - - get _icon_type() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(WEATHER_USE_SYMBOLIC_ICONS_KEY) ? 1 : 0; - }, - - set _icon_type(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_boolean(WEATHER_USE_SYMBOLIC_ICONS_KEY, v); - }, - - get _use_text_on_buttons() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(WEATHER_USE_TEXT_ON_BUTTONS_KEY) ? 1 : 0; - }, - - set _use_text_on_buttons(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_boolean(WEATHER_USE_TEXT_ON_BUTTONS_KEY, v); - }, - - get _text_in_panel() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(WEATHER_SHOW_TEXT_IN_PANEL_KEY); - }, - - set _text_in_panel(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_boolean(WEATHER_SHOW_TEXT_IN_PANEL_KEY, v); - }, - - get _position_in_panel() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_enum(WEATHER_POSITION_IN_PANEL_KEY); - }, - - set _position_in_panel(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_enum(WEATHER_POSITION_IN_PANEL_KEY, v); - }, - - get _comment_in_panel() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(WEATHER_SHOW_COMMENT_IN_PANEL_KEY); - }, - - set _comment_in_panel(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_boolean(WEATHER_SHOW_COMMENT_IN_PANEL_KEY, v); - }, - - get _refresh_interval_current() { - if (!this._settings) - this.loadConfig(); - let v = this._settings.get_int(WEATHER_REFRESH_INTERVAL_CURRENT); - return ((v >= 600) ? v : 600); - }, - - set _refresh_interval_current(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_int(WEATHER_REFRESH_INTERVAL_CURRENT, ((v >= 600) ? v : 600)); - }, - - get _refresh_interval_forecast() { - if (!this._settings) - this.loadConfig(); - let v = this._settings.get_int(WEATHER_REFRESH_INTERVAL_FORECAST); - return ((v >= 600) ? v : 600); - }, - - set _refresh_interval_forecast(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_int(WEATHER_REFRESH_INTERVAL_FORECAST, ((v >= 600) ? v : 600)); - }, - - get _center_forecast() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_boolean(WEATHER_CENTER_FORECAST_KEY); - }, - - set _center_forecast(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_boolean(WEATHER_CENTER_FORECAST_KEY, v); - }, - - get _days_forecast() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_int(WEATHER_DAYS_FORECAST); - }, - - set _days_forecast(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_int(WEATHER_DAYS_FORECAST, v); - }, - - get _decimal_places() { - if (!this._settings) - this.loadConfig(); - return this._settings.get_int(WEATHER_DECIMAL_PLACES); - }, - - set _decimal_places(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_int(WEATHER_DECIMAL_PLACES, v); - }, - - get _appid() { - if (!this._settings) - this.loadConfig(); - let key = this._settings.get_string(WEATHER_OWM_API_KEY); - return (key.length == 32) ? key : ''; - }, - - set _appid(v) { - if (!this._settings) - this.loadConfig(); - this._settings.set_string(WEATHER_OWM_API_KEY, v); - }, - - createButton: function(iconName, accessibleName) { - let button; - - if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) { - button = new St.Button({ - reactive: true, - can_focus: true, - track_hover: true, - accessible_name: accessibleName, - style_class: 'popup-menu-item openweather-button' - }); - button.child = new St.Icon({ - icon_name: iconName - }); - button.connect('notify::hover', Lang.bind(this, this._onButtonHoverChanged)); - } else - button = Main.panel.statusArea.aggregateMenu._system._createActionButton(iconName, accessibleName); - - return button; - }, - - _onButtonHoverChanged: function(actor, event) { - if (actor.hover) { - actor.add_style_pseudo_class('hover'); - actor.set_style(this._button_background_style); - } else { - actor.remove_style_pseudo_class('hover'); - actor.set_style('background-color:;'); - if (actor != this._urlButton) - actor.set_style(this._button_border_style); - } - }, - - _updateButtonColors: function() { - if (!this._needsColorUpdate) - return; - this._needsColorUpdate = false; - let color; - if (ExtensionUtils.versionCheck(['3.6'], Config.PACKAGE_VERSION)) - color = this._separatorItem._drawingArea.get_theme_node().get_color('-gradient-end'); - else - color = this._separatorItem._separator.actor.get_theme_node().get_color('-gradient-end'); - - let alpha = (Math.round(color.alpha / 2.55) / 100); - - if (color.red > 0 && color.green > 0 && color.blue > 0) - this._button_border_style = 'border:1px solid rgb(' + Math.round(alpha * color.red) + ',' + Math.round(alpha * color.green) + ',' + Math.round(alpha * color.blue) + ');'; - else - this._button_border_style = 'border:1px solid rgba(' + color.red + ',' + color.green + ',' + color.blue + ',' + alpha + ');'; - - this._locationButton.set_style(this._button_border_style); - this._reloadButton.set_style(this._button_border_style); - this._prefsButton.set_style(this._button_border_style); - - this._buttonMenu.actor.add_style_pseudo_class('active'); - color = this._buttonMenu.actor.get_theme_node().get_background_color(); - this._button_background_style = 'background-color:rgba(' + color.red + ',' + color.green + ',' + color.blue + ',' + (Math.round(color.alpha / 2.55) / 100) + ');'; - this._buttonMenu.actor.remove_style_pseudo_class('active'); - }, - - rebuildButtonMenu: function() { - if (this._buttonBox) { - if (this._buttonBox1) { - this._buttonBox1.destroy(); - this._buttonBox1 = undefined; - - } - if (this._buttonBox2) { - this._buttonBox2.destroy(); - this._buttonBox2 = undefined; - } - this._buttonMenu.removeActor(this._buttonBox); - this._buttonBox.destroy(); - this._buttonBox = undefined; - } - - if (this._buttonBox1) { - this._buttonBox1.destroy(); - this._buttonBox1 = undefined; - } - if (this._buttonBox2) { - this._buttonBox2.destroy(); - this._buttonBox2 = undefined; - } - - this._locationButton = this.createButton('find-location-symbolic', _("Locations")); - if (this._use_text_on_buttons) - this._locationButton.set_label(this._locationButton.get_accessible_name()); - - this._locationButton.connect('clicked', Lang.bind(this, function() { - if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) - this._selectCity.menu.toggle(); - else - this._selectCity._setOpenState(!this._selectCity._getOpenState()); - })); - this._buttonBox1 = new St.BoxLayout({ - style_class: 'openweather-button-box' - }); - this._buttonBox1.add_actor(this._locationButton); - - this._reloadButton = this.createButton('view-refresh-symbolic', _("Reload Weather Information")); - if (this._use_text_on_buttons) - this._reloadButton.set_label(this._reloadButton.get_accessible_name()); - this._reloadButton.connect('clicked', Lang.bind(this, function() { - this.currentWeatherCache = undefined; - this.forecastWeatherCache = undefined; - this.parseWeatherCurrent(); - this.recalcLayout(); - })); - this._buttonBox1.add_actor(this._reloadButton); - - - this._buttonBox2 = new St.BoxLayout({ - style_class: 'openweather-button-box' - }); - - this._urlButton = new St.Button({ - label: _("Weather data provided by:") + (this._use_text_on_buttons ? "\n" : " ") + WEATHER_URL_BASE, - style_class: 'system-menu-action openweather-provider' - }); - if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) { - this._urlButton.connect('notify::hover', Lang.bind(this, this._onButtonHoverChanged)); - } - this._urlButton.connect('clicked', Lang.bind(this, function() { - this.menu.actor.hide(); - let title = ; - Main.notifyError(_("Not implemented"), - _("Opening the website of the weatherprovider is not (yet) implemeted !")); - })); - - this._buttonBox2.add_actor(this._urlButton); - - - this._prefsButton = this.createButton('preferences-system-symbolic', _("Weather Settings")); - if (this._use_text_on_buttons) - this._prefsButton.set_label(this._prefsButton.get_accessible_name()); - this._prefsButton.connect('clicked', Lang.bind(this, this._onPreferencesActivate)); - this._buttonBox2.add_actor(this._prefsButton); - - if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) { - this._buttonBox = new St.BoxLayout(); - this._buttonBox1.add_style_class_name('openweather-button-box-38'); - this._buttonBox2.add_style_class_name('openweather-button-box-38'); - this._buttonBox.add_actor(this._buttonBox1); - this._buttonBox.add_actor(this._buttonBox2); - - this._buttonMenu.addActor(this._buttonBox); - this._needsColorUpdate = true; - } else { - this._buttonMenu.actor.add_actor(this._buttonBox1); - this._buttonMenu.actor.add_actor(this._buttonBox2); - } - this._buttonBox1MinWidth = undefined; - }, - rebuildSelectCityItem: function() { - this._selectCity.menu.removeAll(); - let item = null; - - let cities = this._cities; - cities = cities.split(" && "); - if (cities && typeof cities == "string") - cities = [cities]; - if (!cities[0]) - return; - - for (let i = 0; cities.length > i; i++) { - item = new PopupMenu.PopupMenuItem(this.extractLocation(cities[i])); - item.location = i; - if (i == this._actual_city) { - if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) - item.setShowDot(true); - else - item.setOrnament(PopupMenu.Ornament.DOT); - } - - this._selectCity.menu.addMenuItem(item); - // override the items default onActivate-handler, to keep the ui open while chosing the location - item.activate = this._onActivate; - } - - if (cities.length == 1) - this._selectCity.actor.hide(); - else - this._selectCity.actor.show(); - - }, - - _onActivate: function() { - openweatherMenu._actual_city = this.location; - }, - - extractLocation: function() { - if (!arguments[0]) - return ""; - - if (arguments[0].search(">") == -1) - return _("Invalid city"); - return arguments[0].split(">")[1]; - }, - - extractCity: function() { - if (!arguments[0]) - return ""; - let city = this.extractLocation(arguments[0]); - if (city.indexOf("(") == -1) - return _("Invalid city"); - return city.split("(")[0].trim(); - }, - - extractId: function() { - if (!arguments[0]) - return 0; - - if (arguments[0].search(">") == -1) - return 0; - return arguments[0].split(">")[0]; - }, - - updateCities: function() { - let cities = this._cities; - - cities = cities.split(" && "); - if (cities && typeof cities == "string") - cities = [cities]; - if (!cities[0]) - cities = []; - - if (cities.length === 0) { - this._cities = "2516479>Eivissa (CA)"; - this.updateCities(); - return; - } - - for (let a in cities) { - if (!this.extractCity(cities[a])) { - let params = { - q: cities[a], - type: 'like' - }; - if (this._appid) - params.APPID = this._appid; - - this.load_json_async(WEATHER_URL_CURRENT, params, Lang.bind(this, this._updateCitiesCallback)); - return; - } else - continue; - } - }, - - _updateCitiesCallback: function() { - let city = arguments[0]; - - if (Number(city.cod) != 200) - return; - - let cityText = city.coord + ">" + city.name; - - if (city.sys) - cityText += " (" + city.sys.country + ")"; - - cities.splice(a, 1, cityText); - - cities = cities.join(" && "); - if (typeof cities != "string") - cities = cities[0]; - this._cities = cities; -// this.updateCities(); - }, - - _onPreferencesActivate: function() { - this.menu.actor.hide(); - Util.spawn(["gnome-shell-extension-prefs", "openweather-extension@jenslody.de"]); - return 0; - }, - - recalcLayout: function() { - if (!this.menu.isOpen) - return; - this._updateButtonColors(); - if(this._buttonBox1MinWidth === undefined) - this._buttonBox1MinWidth = this._buttonBox1.get_width(); - this._buttonBox1.set_width(Math.max(this._buttonBox1MinWidth, this._currentWeather.get_width() - this._buttonBox2.get_width())); - if (this._forecastScrollBox !== undefined && this._forecastBox !== undefined && this._currentWeather !== undefined) { - this._forecastScrollBox.set_width(Math.max(this._currentWeather.get_width(), (this._buttonBox1.get_width() + this._buttonBox2.get_width()))); - this._forecastScrollBox.show(); - if (this._forecastBox.get_preferred_width(this._forecastBox.get_height())[0] > this._currentWeather.get_width()) { - this._forecastScrollBox.hscroll.margin_top = 10; - this._forecastScrollBox.hscroll.show(); - } else { - this._forecastScrollBox.hscroll.margin_top = 0; - this._forecastScrollBox.hscroll.hide(); - } - } - }, - - unit_to_unicode: function() { - if (this._units == WeatherUnits.FAHRENHEIT) - return '\u00B0F'; - else if (this._units == WeatherUnits.KELVIN) - return 'K'; - else if (this._units == WeatherUnits.RANKINE) - return '\u00B0Ra'; - else if (this._units == WeatherUnits.REAUMUR) - return '\u00B0R\u00E9'; - else if (this._units == WeatherUnits.ROEMER) - return '\u00B0R\u00F8'; - else if (this._units == WeatherUnits.DELISLE) - return '\u00B0De'; - else if (this._units == WeatherUnits.NEWTON) - return '\u00B0N'; - else - return '\u00B0C'; - }, - - get_weather_icon: function(code) { - // see http://bugs.openweathermap.org/projects/api/wiki/Weather_Condition_Codes - // fallback icons are: weather-clear-night weather-clear weather-few-clouds-night weather-few-clouds weather-fog weather-overcast weather-severe-alert weather-showers weather-showers-scattered weather-snow weather-storm - /* -weather-clouds-night.png -weather-freezing-rain.png -weather-hail.png -weather-many-clouds.png -weather-showers-day.png -weather-showers-night.png -weather-showers-scattered-day.png -weather-showers-scattered-night.png -weather-snow-rain.png -weather-snow-scattered-day.png -weather-snow-scattered-night.png -weather-snow-scattered.png -weather-storm-day.png -weather-storm-night.png - -weather-severe-alert-symbolic.svg - - -weather-clear-night.png = weather-clear-night-symbolic.svg -weather-clear.png = weather-clear-symbolic.svg -weather-clouds.png = weather-overcast-symbolic.svg -weather-few-clouds-night.png = weather-few-clouds-night-symbolic.svg -weather-few-clouds.png = weather-few-clouds-symbolic.svg -weather-mist.png = weather-fog-symbolic.svg -weather-showers-scattered.png = weather-showers-scattered-symbolic.svg -weather-showers.png = weather-showers-symbolic.svg -weather-snow.png = weather-snow-symbolic.svg -weather-storm.png = weather-storm-symbolic.svg - -*/ - switch (parseInt(code, 10)) { - case 200: //thunderstorm with light rain - case 201: //thunderstorm with rain - case 202: //thunderstorm with heavy rain - case 210: //light thunderstorm - case 211: //thunderstorm - case 212: //heavy thunderstorm - case 221: //ragged thunderstorm - case 230: //thunderstorm with light drizzle - case 231: //thunderstorm with drizzle - case 232: //thunderstorm with heavy drizzle - return ['weather-storm']; - case 300: //light intensity drizzle - case 301: //drizzle - case 302: //heavy intensity drizzle - case 310: //light intensity drizzle rain - case 311: //drizzle rain - case 312: //heavy intensity drizzle rain - case 313: //shower rain and drizzle - case 314: //heavy shower rain and drizzle - case 321: //shower drizzle - return ['weather-showers']; - case 500: //light rain - case 501: //moderate rain - case 502: //heavy intensity rain - case 503: //very heavy rain - case 504: //extreme rain - return ['weather-showers-scattered', 'weather-showers']; - case 511: //freezing rain - return ['weather-freezing-rain', 'weather-showers']; - case 520: //light intensity shower rain - case 521: //shower rain - case 522: //heavy intensity shower rain - case 531: //ragged shower rain - return ['weather-showers']; - case 600: //light snow - case 601: //snow - case 602: //heavy snow - case 611: //sleet - case 612: //shower sleet - case 615: //light rain and snow - case 616: //rain and snow - case 620: //light shower snow - case 621: //shower snow - case 622: //heavy shower snow - return ['weather-snow']; - case 701: //mist - case 711: //smoke - case 721: //haze - case 741: //Fog - return ['weather-fog']; - case 731: //Sand/Dust Whirls - case 751: //sand - case 761: //dust - case 762: //VOLCANIC ASH - case 771: //SQUALLS - case 781: //TORNADO - return ['weather-severe-alert']; - case 800: //sky is clear - return ['weather-clear']; - case 801: //few clouds - case 802: //scattered clouds - return ['weather-few-clouds']; - case 803: //broken clouds - return ['weather-many-clouds', 'weather-overcast']; - case 804: //overcast clouds - return ['weather-overcast']; - default: - return ['weather-severe-alert']; - } - }, - - get_weather_icon_safely: function(code, night) { - let iconname = this.get_weather_icon(code); - for (let i = 0; i < iconname.length; i++) { - if (night && this.has_icon(iconname[i] + '-night')) - return iconname[i] + '-night' + this.icon_type(); - if (this.has_icon(iconname[i])) - return iconname[i] + this.icon_type(); - } - return 'weather-severe-alert' + this.icon_type(); - }, - - has_icon: function(icon) { - return Gtk.IconTheme.get_default().has_icon(icon + this.icon_type()); - }, - - get_weather_condition: function(code) { - switch (parseInt(code, 10)) { - case 200: //thunderstorm with light rain - return _('thunderstorm with light rain'); - case 201: //thunderstorm with rain - return _('thunderstorm with rain'); - case 202: //thunderstorm with heavy rain - return _('thunderstorm with heavy rain'); - case 210: //light thunderstorm - return _('light thunderstorm'); - case 211: //thunderstorm - return _('thunderstorm'); - case 212: //heavy thunderstorm - return _('heavy thunderstorm'); - case 221: //ragged thunderstorm - return _('ragged thunderstorm'); - case 230: //thunderstorm with light drizzle - return _('thunderstorm with light drizzle'); - case 231: //thunderstorm with drizzle - return _('thunderstorm with drizzle'); - case 232: //thunderstorm with heavy drizzle - return _('thunderstorm with heavy drizzle'); - case 300: //light intensity drizzle - return _('light intensity drizzle'); - case 301: //drizzle - return _('drizzle'); - case 302: //heavy intensity drizzle - return _('heavy intensity drizzle'); - case 310: //light intensity drizzle rain - return _('light intensity drizzle rain'); - case 311: //drizzle rain - return _('drizzle rain'); - case 312: //heavy intensity drizzle rain - return _('heavy intensity drizzle rain'); - case 313: //shower rain and drizzle - return _('shower rain and drizzle'); - case 314: //heavy shower rain and drizzle - return _('heavy shower rain and drizzle'); - case 321: //shower drizzle - return _('shower drizzle'); - case 500: //light rain - return _('light rain'); - case 501: //moderate rain - return _('moderate rain'); - case 502: //heavy intensity rain - return _('heavy intensity rain'); - case 503: //very heavy rain - return _('very heavy rain'); - case 504: //extreme rain - return _('extreme rain'); - case 511: //freezing rain - return _('freezing rain'); - case 520: //light intensity shower rain - return _('light intensity shower rain'); - case 521: //shower rain - return _('shower rain'); - case 522: //heavy intensity shower rain - return _('heavy intensity shower rain'); - case 531: //ragged shower rain - return _('ragged shower rain'); - case 600: //light snow - return _('light snow'); - case 601: //snow - return _('snow'); - case 602: //heavy snow - return _('heavy snow'); - case 611: //sleet - return _('sleet'); - case 612: //shower sleet - return _('shower sleet'); - case 615: //light rain and snow - return _('light rain and snow'); - case 616: //rain and snow - return _('rain and snow'); - case 620: //light shower snow - return _('light shower snow'); - case 621: //shower snow - return _('shower snow'); - case 622: //heavy shower snow - return _('heavy shower snow'); - case 701: //mist - return _('mist'); - case 711: //smoke - return _('smoke'); - case 721: //haze - return _('haze'); - case 731: //Sand/Dust Whirls - return _('Sand/Dust Whirls'); - case 741: //Fog - return _('Fog'); - case 751: //sand - return _('sand'); - case 761: //dust - return _('dust'); - case 762: //VOLCANIC ASH - return _('VOLCANIC ASH'); - case 771: //SQUALLS - return _('SQUALLS'); - case 781: //TORNADO - return _('TORNADO'); - case 800: //sky is clear - return _('sky is clear'); - case 801: //few clouds - return _('few clouds'); - case 802: //scattered clouds - return _('scattered clouds'); - case 803: //broken clouds - return _('broken clouds'); - case 804: //overcast clouds - return _('overcast clouds'); - default: - return _('Not available'); - } - }, - - toFahrenheit: function(t) { - return ((Number(t) * 1.8) + 32).toFixed(this._decimal_places); - }, - - toKelvin: function(t) { - return (Number(t) + 273.15).toFixed(this._decimal_places); - }, - - toRankine: function(t) { - return ((Number(t) * 1.8) + 491.67).toFixed(this._decimal_places); - }, - - toReaumur: function(t) { - return (Number(t) * 0.8).toFixed(this._decimal_places); - }, - - toRoemer: function(t) { - return ((Number(t) * 21 / 40) + 7.5).toFixed(this._decimal_places); - }, - - toDelisle: function(t) { - return ((100 - Number(t)) * 1.5).toFixed(this._decimal_places); - }, - - toNewton: function(t) { - return (Number(t) - 0.33).toFixed(this._decimal_places); - }, - - toInHg: function(p /*, t*/ ) { - return (p / 33.86530749).toFixed(this._decimal_places); - }, - - toBeaufort: function(w, t) { - if (w < 0.3) - return (!t) ? "0" : "(" + _("Calm") + ")"; - - else if (w >= 0.3 && w <= 1.5) - return (!t) ? "1" : "(" + _("Light air") + ")"; - - else if (w > 1.5 && w <= 3.4) - return (!t) ? "2" : "(" + _("Light breeze") + ")"; - - else if (w > 3.4 && w <= 5.4) - return (!t) ? "3" : "(" + _("Gentle breeze") + ")"; - - else if (w > 5, 4 && w <= 7.9) - return (!t) ? "4" : "(" + _("Moderate breeze") + ")"; - - else if (w > 7.9 && w <= 10.7) - return (!t) ? "5" : "(" + _("Fresh breeze") + ")"; - - else if (w > 10.7 && w <= 13.8) - return (!t) ? "6" : "(" + _("Strong breeze") + ")"; - - else if (w > 13.8 && w <= 17.1) - return (!t) ? "7" : "(" + _("Moderate gale") + ")"; - - else if (w > 17.1 && w <= 20.7) - return (!t) ? "8" : "(" + _("Fresh gale") + ")"; - - else if (w > 20.7 && w <= 24.4) - return (!t) ? "9" : "(" + _("Strong gale") + ")"; - - else if (w > 24.4 && w <= 28.4) - return (!t) ? "10" : "(" + _("Storm") + ")"; - - else if (w > 28.4 && w <= 32.6) - return (!t) ? "11" : "(" + _("Violent storm") + ")"; - - else - return (!t) ? "12" : "(" + _("Hurricane") + ")"; - }, - - get_locale_day: function(abr) { - let days = [_('Sunday'), _('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday')]; - return days[abr]; - }, - - get_wind_direction: function(deg) { - let arrows = ["\u2193", "\u2199", "\u2190", "\u2196", "\u2191", "\u2197", "\u2192", "\u2198"]; - let letters = [_('N'), _('NE'), _('E'), _('SE'), _('S'), _('SW'), _('W'), _('NW')]; - let idx = Math.round(deg / 45) % arrows.length; - return (this._wind_direction) ? arrows[idx] : letters[idx]; - }, - - icon_type: function(icon_name) { - if (!icon_name) - if (this._icon_type) - return "-symbolic"; - else - return ""; - - if (this._icon_type) - if (String(icon_name).search("-symbolic") != -1) - return icon_name; - else - return icon_name + "-symbolic"; - else - if (String(icon_name).search("-symbolic") != -1) - return String(icon_name).replace("-symbolic", ""); - else - return icon_name; - }, - - load_json_async: function(url, params, fun) { - if (_httpSession === undefined) { - if (ExtensionUtils.versionCheck(['3.6'], Config.PACKAGE_VERSION)) { - // Soup session (see https://bugzilla.gnome.org/show_bug.cgi?id=661323#c64) (Simon Legner) - _httpSession = new Soup.SessionAsync(); - Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault()); - } else - _httpSession = new Soup.Session(); - } - - let message = Soup.form_request_new_from_hash('GET', url, params); - - _httpSession.queue_message(message, Lang.bind(this, function(_httpSession, message) { - - try { - if (!message.response_body.data) { - fun.call(this, 0); - return; - } - let jp = JSON.parse(message.response_body.data); - fun.call(this, jp); - } catch (e) { - fun.call(this, 0); - return; - } - })); - return; - }, - - parseWeatherCurrent: function() { - if (this.currentWeatherCache === undefined) { - this.refreshWeatherCurrent(); - return; - } - - if (this._old_position_in_panel != this._position_in_panel) { - switch (this._old_position_in_panel) { - case WeatherPosition.LEFT: - Main.panel._leftBox.remove_actor(this.actor); - break; - case WeatherPosition.CENTER: - Main.panel._centerBox.remove_actor(this.actor); - break; - case WeatherPosition.RIGHT: - Main.panel._rightBox.remove_actor(this.actor); - break; - } - - let children = null; - switch (this._position_in_panel) { - case WeatherPosition.LEFT: - children = Main.panel._leftBox.get_children(); - Main.panel._leftBox.insert_child_at_index(this.actor, children.length); - break; - case WeatherPosition.CENTER: - children = Main.panel._centerBox.get_children(); - Main.panel._centerBox.insert_child_at_index(this.actor, children.length); - break; - case WeatherPosition.RIGHT: - children = Main.panel._rightBox.get_children(); - Main.panel._rightBox.insert_child_at_index(this.actor, 0); - break; - } - this._old_position_in_panel = this._position_in_panel; - } - - let json = this.currentWeatherCache; - // Refresh current weather - let location = this.extractLocation(this._city); - - let comment = json.weather[0].description; - if (this._translate_condition) - comment = this.get_weather_condition(json.weather[0].id); - - let temperature = json.main.temp; - let cloudiness = json.clouds.all; - let humidity = json.main.humidity + ' %'; - let pressure = json.main.pressure; - let pressure_unit = 'hPa'; - - let wind_direction = this.get_wind_direction(json.wind.deg); - let wind = json.wind.speed; - let wind_unit = 'm/s'; - - let sunrise = new Date(json.sys.sunrise * 1000); - let sunset = new Date(json.sys.sunset * 1000); - let now = new Date(); - - let iconname = this.get_weather_icon_safely(json.weather[0].id, now < sunrise || now > sunset); - - if (this.lastBuildId === undefined) - this.lastBuildId = 0; - - if (this.lastBuildDate === undefined) - this.lastBuildDate = 0; - - if (this.lastBuildId != json.dt || !this.lastBuildDate) { - this.lastBuildId = json.dt; - this.lastBuildDate = new Date(this.lastBuildId * 1000); - } - - switch (this._pressure_units) { - case WeatherPressureUnits.inHg: - pressure = this.toInHg(pressure); - pressure_unit = "inHg"; - break; - - case WeatherPressureUnits.hPa: - pressure = pressure.toFixed(this._decimal_places); - pressure_unit = "hPa"; - break; - - case WeatherPressureUnits.bar: - pressure = (pressure / 1000).toFixed(this._decimal_places); - pressure_unit = "bar"; - break; - - case WeatherPressureUnits.Pa: - pressure = (pressure * 100).toFixed(this._decimal_places); - pressure_unit = "Pa"; - break; - - case WeatherPressureUnits.kPa: - pressure = (pressure / 10).toFixed(this._decimal_places); - pressure_unit = "kPa"; - break; - - case WeatherPressureUnits.atm: - pressure = (pressure * 0.000986923267).toFixed(this._decimal_places); - pressure_unit = "atm"; - break; - - case WeatherPressureUnits.at: - pressure = (pressure * 0.00101971621298).toFixed(this._decimal_places); - pressure_unit = "at"; - break; - - case WeatherPressureUnits.Torr: - pressure = (pressure * 0.750061683).toFixed(this._decimal_places); - pressure_unit = "Torr"; - break; - - case WeatherPressureUnits.psi: - pressure = (pressure * 0.0145037738).toFixed(this._decimal_places); - pressure_unit = "psi"; - break; - } - - switch (this._units) { - case WeatherUnits.FAHRENHEIT: - temperature = this.toFahrenheit(temperature); - break; - - case WeatherUnits.CELSIUS: - temperature = temperature.toFixed(this._decimal_places); - break; - - case WeatherUnits.KELVIN: - temperature = this.toKelvin(temperature); - break; - - case WeatherUnits.RANKINE: - temperature = this.toRankine(temperature); - break; - - case WeatherUnits.REAUMUR: - temperature = this.toReaumur(temperature); - break; - - case WeatherUnits.ROEMER: - temperature = this.toRoemer(temperature); - break; - - case WeatherUnits.DELISLE: - temperature = this.toDelisle(temperature); - break; - - case WeatherUnits.NEWTON: - temperature = this.toNewton(temperature); - break; - } - - let lastBuild = '-'; - - if (this._clockFormat == "24h") { - sunrise = sunrise.toLocaleFormat("%R"); - sunset = sunset.toLocaleFormat("%R"); - lastBuild = this.lastBuildDate.toLocaleFormat("%R"); - } else { - sunrise = sunrise.toLocaleFormat("%I:%M %p"); - sunset = sunset.toLocaleFormat("%I:%M %p"); - lastBuild = this.lastBuildDate.toLocaleFormat("%I:%M %p"); - } - - let beginOfDay = new Date(new Date().setHours(0, 0, 0, 0)); - let d = Math.floor((this.lastBuildDate.getTime() - beginOfDay.getTime()) / 86400000); - if (d < 0) { - lastBuild = _("Yesterday"); - if (d < -1) - lastBuild = _("%s days ago").replace("%s", -1 * d); - } - - this._currentWeatherIcon.icon_name = this._weatherIcon.icon_name = iconname; - - let weatherInfoC = ""; - let weatherInfoT = ""; - - if (this._comment_in_panel) - weatherInfoC = comment; - - if (this._text_in_panel) - weatherInfoT = parseFloat(temperature).toLocaleString() + ' ' + this.unit_to_unicode(); - - this._weatherInfo.text = weatherInfoC + ((weatherInfoC && weatherInfoT) ? ", " : "") + weatherInfoT; - - this._currentWeatherSummary.text = comment + ", " + parseFloat(temperature).toLocaleString() + ' ' + this.unit_to_unicode(); - this._currentWeatherLocation.text = location; - this._currentWeatherTemperature.text = cloudiness + ' %'; - this._currentWeatherHumidity.text = parseFloat(humidity).toLocaleString() + ' %'; - this._currentWeatherPressure.text = parseFloat(pressure).toLocaleString() + ' ' + pressure_unit; - this._currentWeatherSunrise.text = sunrise; - this._currentWeatherSunset.text = sunset; - this._currentWeatherBuild.text = lastBuild; - - // Override wind units with our preference - switch (this._wind_speed_units) { - case WeatherWindSpeedUnits.MPH: - wind = (wind * WEATHER_CONV_MPS_IN_MPH).toFixed(this._decimal_places); - wind_unit = 'mph'; - break; - - case WeatherWindSpeedUnits.KPH: - wind = (wind * WEATHER_CONV_MPS_IN_KPH).toFixed(this._decimal_places); - wind_unit = 'km/h'; - break; - - case WeatherWindSpeedUnits.MPS: - wind = wind.toFixed(this._decimal_places); - break; - - case WeatherWindSpeedUnits.KNOTS: - wind = (wind * WEATHER_CONV_MPS_IN_KNOTS).toFixed(this._decimal_places); - wind_unit = 'kn'; - break; - - case WeatherWindSpeedUnits.FPS: - wind = (wind * WEATHER_CONV_MPS_IN_FPS).toFixed(this._decimal_places); - wind_unit = 'ft/s'; - break; - - case WeatherWindSpeedUnits.BEAUFORT: - wind_unit = this.toBeaufort(wind, true); - wind = this.toBeaufort(wind); - } - - if (!wind) - this._currentWeatherWind.text = '\u2013'; - else if (wind === 0 || !wind_direction) - this._currentWeatherWind.text = parseFloat(wind).toLocaleString() + ' ' + wind_unit; - else // i.e. wind > 0 && wind_direction - this._currentWeatherWind.text = wind_direction + ' ' + parseFloat(wind).toLocaleString() + ' ' + wind_unit; - - this.parseWeatherForecast(); - this.recalcLayout(); - }, - - refreshWeatherCurrent: function() { - if (!this.extractId(this._city)) { - this.updateCities(); - return; - } - this.oldLocation = this.extractId(this._city); - - let params = { - id: this.oldLocation, - units: 'metric' - }; - if (this._appid) - params.APPID = this._appid; - - this.load_json_async(WEATHER_URL_CURRENT, params, function(json) { - if (json && (Number(json.cod) == 200)) { - - if (this.currentWeatherCache != json) - this.currentWeatherCache = json; - - this.rebuildSelectCityItem(); - - this.parseWeatherCurrent(); - } else { - // we are connected, but get no (or no correct) data, so invalidate - // the shown data and reload after 10 minutes (recommendded by openweathermap.org) - this.rebuildCurrentWeatherUi(); - this.reloadWeatherCurrent(600); - } - }); - this.reloadWeatherCurrent(this._refresh_interval_current); - }, - - reloadWeatherCurrent: function(interval) { - if (this._timeoutCurrent) { - Mainloop.source_remove(this._timeoutCurrent); - } - this._timeoutCurrent = Mainloop.timeout_add_seconds(interval, Lang.bind(this, function() { - this.currentWeatherCache = undefined; - if (this._connected) - this.parseWeatherCurrent(); - else - this.rebuildCurrentWeatherUi(); - return true; - })); - }, - - parseWeatherForecast: function() { - if (this.forecastWeatherCache === undefined) { - this.refreshWeatherForecast(); - return; - } - - let forecast = this.forecastWeatherCache; - let beginOfDay = new Date(new Date().setHours(0, 0, 0, 0)); - - // Refresh forecast - for (let i = 0; i < this._days_forecast; i++) { - let forecastUi = this._forecast[i]; - let forecastData = forecast[i]; - if (forecastData === undefined) - continue; - - let t_low = forecastData.temp.min; - let t_high = forecastData.temp.max; - - switch (this._units) { - case WeatherUnits.FAHRENHEIT: - t_low = this.toFahrenheit(t_low); - t_high = this.toFahrenheit(t_high); - break; - - case WeatherUnits.CELSIUS: - t_low = t_low.toFixed(this._decimal_places); - t_high = t_high.toFixed(this._decimal_places); - break; - - case WeatherUnits.KELVIN: - t_low = this.toKelvin(t_low); - t_high = this.toKelvin(t_high); - break; - - case WeatherUnits.RANKINE: - t_low = this.toRankine(t_low); - t_high = this.toRankine(t_high); - break; - - case WeatherUnits.REAUMUR: - t_low = this.toReaumur(t_low); - t_high = this.toReaumur(t_high); - break; - - case WeatherUnits.ROEMER: - t_low = this.toRoemer(t_low); - t_high = this.toRoemer(t_high); - break; - - case WeatherUnits.DELISLE: - t_low = this.toDelisle(t_low); - t_high = this.toDelisle(t_high); - break; - - case WeatherUnits.NEWTON: - t_low = this.toNewton(t_low); - t_high = this.toNewton(t_high); - break; - } - - let comment = forecastData.weather[0].description; - if (this._translate_condition) - comment = this.get_weather_condition(forecastData.weather[0].id); - - let forecastDate = new Date(forecastData.dt * 1000); - let dayLeft = Math.floor((forecastDate.getTime() - beginOfDay.getTime()) / 86400000); - - let date_string = _("Today"); - if (dayLeft == 1) - date_string = _("Tomorrow"); - else if (dayLeft > 1) - date_string = _("In %s days").replace("%s", dayLeft); - else if (dayLeft == -1) - date_string = _("Yesterday"); - else if (dayLeft < -1) - date_string = _("%s days ago").replace("%s", -1 * dayLeft); - - forecastUi.Day.text = date_string + ' (' + this.get_locale_day(forecastDate.getDay()) + ')\n' + forecastDate.toLocaleDateString(); - forecastUi.Temperature.text = '\u2193 ' + parseFloat(t_low).toLocaleString() + ' ' + this.unit_to_unicode() + ' \u2191 ' + parseFloat(t_high).toLocaleString() + ' ' + this.unit_to_unicode(); - forecastUi.Summary.text = comment; - forecastUi.Icon.icon_name = this.get_weather_icon_safely(forecastData.weather[0].id); - } - }, - - refreshWeatherForecast: function() { - - if (!this.extractId(this._city)) { - this.updateCities(); - return; - } - - this.oldLocation = this.extractId(this._city); - - let params = { - id: this.oldLocation, - units: 'metric', - cnt: '13' - }; - if (this._appid) - params.APPID = this._appid; - - this.load_json_async(WEATHER_URL_FORECAST, params, function(json) { - if (json && (Number(json.cod) == 200)) { - if (this.forecastWeatherCache != json.list) - this.forecastWeatherCache = json.list; - - this.parseWeatherForecast(); - } else { - // we are connected, but get no (or no correct) data, so invalidate - // the shown data and reload after 10 minutes (recommendded by openweathermap.org) - this.rebuildFutureWeatherUi(); - this.reloadWeatherForecast(600); - } - }); - this.reloadWeatherForecast(this._refresh_interval_forecast); - }, - - reloadWeatherForecast: function(interval) { - if (this._timeoutForecast) { - Mainloop.source_remove(this._timeoutForecast); - } - this._timeoutForecast = Mainloop.timeout_add_seconds(interval, Lang.bind(this, function() { - this.forecastWeatherCache = undefined; - if (this._connected) - this.parseWeatherForecast(); - else - this.rebuildFutureWeatherUi(); - return true; - })); - }, - - destroyCurrentWeather: function() { - if (this._currentWeather.get_child() !== null) - this._currentWeather.get_child().destroy(); - }, - - destroyFutureWeather: function() { - if (this._futureWeather.get_child() !== null) - this._futureWeather.get_child().destroy(); - }, - - rebuildCurrentWeatherUi: function() { - this._weatherInfo.text = _('Loading current weather ...'); - this._weatherIcon.icon_name = 'view-refresh' + this.icon_type(); - - this.destroyCurrentWeather(); - - // This will hold the icon for the current weather - this._currentWeatherIcon = new St.Icon({ - icon_size: 72, - icon_name: 'view-refresh' + this.icon_type(), - style_class: 'openweather-current-icon' - }); - - this._sunriseIcon = new St.Icon({ - icon_size: 15, - icon_name: 'weather-clear' + this.icon_type(), - style_class: 'openweather-sunrise-icon' - }); - - this._sunsetIcon = new St.Icon({ - icon_size: 15, - icon_name: 'weather-clear-night' + this.icon_type(), - style_class: 'openweather-sunset-icon' - }); - - this._buildIcon = new St.Icon({ - icon_size: 15, - icon_name: 'view-refresh' + this.icon_type(), - style_class: 'openweather-build-icon' - }); - - // The summary of the current weather - this._currentWeatherSummary = new St.Label({ - text: _('Loading ...'), - style_class: 'openweather-current-summary' - }); - this._currentWeatherLocation = new St.Label({ - text: _('Please wait') - }); - - let bb = new St.BoxLayout({ - vertical: true, - style_class: 'openweather-current-summarybox' - }); - bb.add_actor(this._currentWeatherLocation); - bb.add_actor(this._currentWeatherSummary); - - this._currentWeatherSunrise = new St.Label({ - text: '-' - }); - this._currentWeatherSunset = new St.Label({ - text: '-' - }); - this._currentWeatherBuild = new St.Label({ - text: '-' - }); - - let ab = new St.BoxLayout({ - style_class: 'openweather-current-infobox' - }); - - ab.add_actor(this._sunriseIcon); - ab.add_actor(this._currentWeatherSunrise); - ab.add_actor(this._sunsetIcon); - ab.add_actor(this._currentWeatherSunset); - ab.add_actor(this._buildIcon); - ab.add_actor(this._currentWeatherBuild); - bb.add_actor(ab); - - // Other labels - this._currentWeatherTemperature = new St.Label({ - text: '...' - }); - this._currentWeatherHumidity = new St.Label({ - text: '...' - }); - this._currentWeatherPressure = new St.Label({ - text: '...' - }); - this._currentWeatherWind = new St.Label({ - text: '...' - }); - - let rb = new St.BoxLayout({ - style_class: 'openweather-current-databox' - }); - let rb_captions = new St.BoxLayout({ - vertical: true, - style_class: 'openweather-current-databox-captions' - }); - let rb_values = new St.BoxLayout({ - vertical: true, - style_class: 'openweather-current-databox-values' - }); - rb.add_actor(rb_captions); - rb.add_actor(rb_values); - - rb_captions.add_actor(new St.Label({ - text: _('Cloudiness:') - })); - rb_values.add_actor(this._currentWeatherTemperature); - rb_captions.add_actor(new St.Label({ - text: _('Humidity:') - })); - rb_values.add_actor(this._currentWeatherHumidity); - rb_captions.add_actor(new St.Label({ - text: _('Pressure:') - })); - rb_values.add_actor(this._currentWeatherPressure); - rb_captions.add_actor(new St.Label({ - text: _('Wind:') - })); - rb_values.add_actor(this._currentWeatherWind); - - let xb = new St.BoxLayout(); - xb.add_actor(bb); - xb.add_actor(rb); - - let box = new St.BoxLayout({ - style_class: 'openweather-current-iconbox' - }); - box.add_actor(this._currentWeatherIcon); - box.add_actor(xb); - this._currentWeather.set_child(box); - }, - - scrollForecastBy: function(delta) { - if (this._forecastScrollBox === undefined) - return; - this._forecastScrollBox.hscroll.adjustment.value += delta; - }, - - rebuildFutureWeatherUi: function() { - this.destroyFutureWeather(); - - this._forecast = []; - this._forecastBox = new St.BoxLayout({ - x_align: this._center_forecast ? St.Align.END : St.Align.START, - style_class: 'openweather-forecast-box' - }); - - this._forecastScrollBox = new St.ScrollView({ - style_class: 'openweather-forecasts' - }); - - let pan = new Clutter.PanAction({ - interpolate: true - }); - pan.connect('pan', Lang.bind(this, function(action) { - - let[dist, dx, dy] = action.get_motion_delta(0); - - this.scrollForecastBy(-1 * (dx / this._forecastScrollBox.width) * this._forecastScrollBox.hscroll.adjustment.page_size); - return false; - })); - this._forecastScrollBox.add_action(pan); - - this._forecastScrollBox.connect('scroll-event', Lang.bind(this, this._onScroll)); - this._forecastScrollBox.hscroll.connect('scroll-event', Lang.bind(this, this._onScroll)); - - this._forecastScrollBox.hscroll.margin_right = 25; - this._forecastScrollBox.hscroll.margin_left = 25; - this._forecastScrollBox.hscroll.hide(); - this._forecastScrollBox.vscrollbar_policy = Gtk.PolicyType.NEVER; - this._forecastScrollBox.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC; - this._forecastScrollBox.enable_mouse_scrolling = true; - this._forecastScrollBox.hide(); - - this._futureWeather.set_child(this._forecastScrollBox); - - for (let i = 0; i < this._days_forecast; i++) { - let forecastWeather = {}; - - forecastWeather.Icon = new St.Icon({ - icon_size: 48, - icon_name: 'view-refresh' + this.icon_type(), - style_class: 'openweather-forecast-icon' - }); - forecastWeather.Day = new St.Label({ - style_class: 'openweather-forecast-day' - }); - forecastWeather.Summary = new St.Label({ - style_class: 'openweather-forecast-summary' - }); - forecastWeather.Temperature = new St.Label({ - style_class: 'openweather-forecast-temperature' - }); - - let by = new St.BoxLayout({ - vertical: true, - style_class: 'openweather-forecast-databox' - }); - by.add_actor(forecastWeather.Day); - by.add_actor(forecastWeather.Summary); - by.add_actor(forecastWeather.Temperature); - - let bb = new St.BoxLayout({ - style_class: 'openweather-forecast-iconbox' - }); - bb.add_actor(forecastWeather.Icon); - bb.add_actor(by); - - this._forecast[i] = forecastWeather; - this._forecastBox.add_actor(bb); - } - this._forecastScrollBox.add_actor(this._forecastBox); - }, - - _onScroll: function(actor, event) { - let dx = 0; - let dy = 0; - switch (event.get_scroll_direction()) { - case Clutter.ScrollDirection.UP: - dy = -1; - break; - case Clutter.ScrollDirection.DOWN: - dy = 1; - break; - // horizontal scrolling will be handled by the control itself - default: - return true; - } - - this.scrollForecastBy(dy * this._forecastScrollBox.hscroll.adjustment.stepIncrement); - return false; - } -}); - -let openweatherMenu; - -function init() { - Convenience.initTranslations('gnome-shell-extension-openweather'); -} - -function enable() { - openweatherMenu = new OpenweatherMenuButton(); - Main.panel.addToStatusArea('openweatherMenu', openweatherMenu); -} - -function disable() { - openweatherMenu.stop(); - openweatherMenu.destroy(); -} diff --git a/temp.txt b/temp.txt deleted file mode 100644 index 9bc8967..0000000 --- a/temp.txt +++ /dev/null @@ -1,937 +0,0 @@ -{ - "cod":"200", - "message":0.0227, - "city": - { - "id":2807184, - "name":"Witzenhausen", - "coord": - { - "lon":9.86667, - "lat":51.333328 - }, - "country":"DE", - "population":16055 - }, - "cnt":10, - "list": - [ - { - "dt":1382526000, - "temp": - { - "day":18.21, - "min":15.06, - "max":18.39, - "night":15.06, - "eve":17.24, - "morn":17.89 - }, - "pressure":990.22, - "humidity":75, - "weather": - [ - { - "id":804, - "main":"Clouds", - "description":"overcast clouds", - "icon":"04d" - } - ], - "speed":7.59, - "deg":216, - "clouds":88 - }, - { - "dt":1382612400, - "temp": - { - "day":12.78, - "min":10.18, - "max":13.3, - "night":10.18, - "eve":10.8, - "morn":12.04 - }, - "pressure":999.55, - "humidity":100, - "weather": - [ - { - "id":501, - "main":"Rain", - "description":"moderate rain", - "icon":"10d" - } - ], - "speed":2.28, - "deg":328, - "clouds":88, - "rain":6 - }, - { - "dt":1382698800, - "temp": - { - "day":14.51, - "min":11.29, - "max":14.95, - "night":14.95, - "eve":14.45, - "morn":11.29 - }, - "pressure":997.12, - "humidity":99, - "weather": - [ - { - "id":500, - "main":"Rain", - "description":"light rain", - "icon":"10d" - } - ], - "speed":5.02, - "deg":166, - "clouds":92, - "rain":1 - }, - { - "dt":1382785200, - "temp": - { - "day":18.32, - "min":15.21, - "max":18.32, - "night":15.81, - "eve":17.21, - "morn":15.21 - }, - "pressure":991.83, - "humidity":89, - "weather": - [ - { - "id":500, - "main":"Rain", - "description":"light rain", - "icon":"10d" - } - ], - "speed":6.92, - "deg":211, - "clouds":20, - "rain":1 - }, - { - "dt":1382871600, - "temp": - { - "day":11.91, - "min":10.7, - "max":13.76, - "night":10.7, - "eve":11.4, - "morn":13.28 - }, - "pressure":991.86, - "humidity":90, - "weather": - [ - { - "id":501, - "main":"Rain", - "description":"moderate rain", - "icon":"10d" - } - ], - "speed":9.27, - "deg":256, - "clouds":24, - "rain":7 - }, - { - "dt":1382958000, - "temp": - { - "day":12.72, - "min":9.59, - "max":13.11, - "night":13.11, - "eve":12.94, - "morn":9.59 - }, - "pressure":983.93, - "humidity":0, - "weather": - [ - { - "id":501, - "main":"Rain", - "description":"moderate rain", - "icon":"10d" - } - ], - "speed":7.39, - "deg":205, - "clouds":85, - "rain":9.48 - }, - { - "dt":1383044400, - "temp": - { - "day":12.55, - "min":10.99, - "max":12.55, - "night":10.99, - "eve":11.32, - "morn":11.08 - }, - "pressure":974.35, - "humidity":0, - "weather": - [ - { - "id":501, - "main":"Rain", - "description":"moderate rain", - "icon":"10d" - } - ], - "speed":11.04, - "deg":222, - "clouds":78, - "rain":4.04 - }, - { - "dt":1383130800, - "temp": - { - "day":13.45, - "min":11.12, - "max":13.45, - "night":11.12, - "eve":12.01, - "morn":11.28 - }, - "pressure":974.2, - "humidity":0, - "weather": - [ - { - "id":501, - "main":"Rain", - "description":"moderate rain", - "icon":"10d" - } - ], - "speed":7.86, - "deg":214, - "clouds":96, - "rain":3.98 - }, - { - "dt":1383217200, - "temp": - { - "day":12.61, - "min":10.44, - "max":12.61, - "night":10.44, - "eve":11.22, - "morn":10.67 - }, - "pressure":983.29, - "humidity":0, - "weather": - [ - { - "id":501, - "main":"Rain", - "description":"moderate rain", - "icon":"10d" - } - ], - "speed":7.34, - "deg":228, - "clouds":4, - "rain":5.07 - }, - { - "dt":1383303600, - "temp": - { - "day":10.96, - "min":8.19, - "max":10.96, - "night":8.19, - "eve":9.54, - "morn":9.71 - }, - "pressure":996.06, - "humidity":0, - "weather": - [ - { - "id":501, - "main":"Rain", - "description":"moderate rain", - "icon":"10d" - } - ], - "speed":3.4, - "deg":268, - "clouds":98, - "rain":6.79 - } - ] -} - - - -{ - "coord": - { - "lon":9.86667, - "lat":51.333328 - }, - "sys": - { - "country":"DE", - "sunrise":1382507949, - "sunset":1382544624 - }, - "weather": - [ - { - "id":804, - "main":"Clouds", - "description":"overcast clouds", - "icon":"04d" - } - ], - "base":"global stations", - "main": - { - "temp":17.885, - "temp_min":17.885, - "temp_max":17.885, - "pressure":990.17, - "sea_level":1019.55, - "grnd_level":990.17, - "humidity":77 - }, - "wind": - { - "speed":7.17, - "deg":205.505 - }, - "clouds": - { - "all":92 - }, - "dt":1382514022, - "id":2807184, - "name":"Witzenhausen", - "cod":200 -} - -{ - "coord": - { - "lon":1.43296, - "lat":38.908829 - }, - "sys": - { - "country":"ES", - "sunrise":1382508754, - "sunset":1382547866 - }, - "weather": - [ - { - "id":800, - "main":"Clear", - "description":"sky is clear", - "icon":"02d" - } - ], - "base":"global stations", - "main": - { - "temp":23.453, - "temp_min":23.453, - "temp_max":23.453, - "pressure":1028.28, - "sea_level":1028.37, - "grnd_level":1028.28, - "humidity":100 - }, - "wind": - { - "speed":7.96, - "deg":225.5 - }, - "clouds": - { - "all":8 - }, - "dt":1382545727, - "id":2516479, - "name":"Ibiza", - "cod":200 -} - - English - en, Russian - ru, Italian - it, Spanish - sp, Ukrainian - ua, German - de, Portuguese - pt, Romanian - ro, Polish - pl, Finnish - fi, Dutch - nl, French - fr, Bulgarian - bg, Swedish - se, Chinese Traditional - zh_tw, Chinese Simplified - zh_cn, Turkish - tr , Czech - cz - - -https://api.forecast.io/forecast/b251335276b56396cc98b7c79b282971/51.3750768,9.9179173?exclude=minutely,hourly&units=si - -{ - "latitude":51.3750768, - "longitude":9.9179173, - "timezone":"Europe/Berlin", - "offset":1, - "currently": - { - "time":1426481725, - "summary":"Clear", - "icon":"clear-night", - "precipIntensity":0, - "precipProbability":0, - "temperature":1.07, - "apparentTemperature":-3.68, - "dewPoint":-0.08, - "humidity":0.92, - "windSpeed":5.19, - "windBearing":98, - "cloudCover":0.01, - "pressure":1026.57, - "ozone":424.04 - }, - "daily": - { - "summary":"Drizzle on Friday and Saturday, with temperatures peaking at 16C on Wednesday.", - "icon":"rain", - "data": - [ - { - "time":1426460400, - "summary":"Mostly cloudy starting in the afternoon, continuing until evening.", - "icon":"partly-cloudy-day", - "sunriseTime":1426484069, - "sunsetTime":1426526784, - "moonPhase":0.85, - "precipIntensity":0, - "precipIntensityMax":0, - "precipProbability":0, - "temperatureMin":0.94, - "temperatureMinTime":1426478400, - "temperatureMax":11.72, - "temperatureMaxTime":1426518000, - "apparentTemperatureMin":-3.93, - "apparentTemperatureMinTime":1426478400, - "apparentTemperatureMax":11.72, - "apparentTemperatureMaxTime":1426518000, - "dewPoint":4.12, - "humidity":0.85, - "windSpeed":5.33, - "windBearing":104, - "cloudCover":0.17, - "pressure":1026.07, - "ozone":420.3 - }, - { - "time":1426546800, - "summary":"Partly cloudy starting in the afternoon.", - "icon":"partly-cloudy-night", - "sunriseTime":1426570332, - "sunsetTime":1426613285, - "moonPhase":0.89, - "precipIntensity":0, - "precipIntensityMax":0, - "precipProbability":0, - "temperatureMin":1.35, - "temperatureMinTime":1426568400, - "temperatureMax":13.86, - "temperatureMaxTime":1426604400, - "apparentTemperatureMin":-1.95, - "apparentTemperatureMinTime":1426568400, - "apparentTemperatureMax":13.86, - "apparentTemperatureMaxTime":1426604400, - "dewPoint":5.29, - "humidity":0.86, - "windSpeed":2.7, - "windBearing":105, - "cloudCover":0.24, - "pressure":1025.65, - "ozone":391.18 - }, - { - "time":1426633200, - "summary":"Partly cloudy in the morning.", - "icon":"partly-cloudy-night", - "sunriseTime":1426656595, - "sunsetTime":1426699785, - "moonPhase":0.93, - "precipIntensity":0, - "precipIntensityMax":0, - "precipProbability":0, - "temperatureMin":2.74, - "temperatureMinTime":1426654800, - "temperatureMax":15.66, - "temperatureMaxTime":1426687200, - "apparentTemperatureMin":2.74, - "apparentTemperatureMinTime":1426654800, - "apparentTemperatureMax":15.66, - "apparentTemperatureMaxTime":1426687200, - "dewPoint":5.94, - "humidity":0.83, - "windSpeed":0.49, - "windBearing":49, - "cloudCover":0.21, - "pressure":1025.06, - "ozone":387.11 - }, - { - "time":1426719600, - "summary":"Mostly cloudy throughout the day.", - "icon":"partly-cloudy-day", - "sunriseTime":1426742858, - "sunsetTime":1426786286, - "moonPhase":0.97, - "precipIntensity":0, - "precipIntensityMax":0, - "precipProbability":0, - "temperatureMin":3.92, - "temperatureMinTime":1426744800, - "temperatureMax":9.96, - "temperatureMaxTime":1426770000, - "apparentTemperatureMin":2.91, - "apparentTemperatureMinTime":1426744800, - "apparentTemperatureMax":8.87, - "apparentTemperatureMaxTime":1426770000, - "dewPoint":5.89, - "humidity":0.91, - "windSpeed":1.7, - "windBearing":308, - "cloudCover":0.6, - "pressure":1024.53, - "ozone":401.06 - }, - { - "time":1426806000, - "summary":"Drizzle until evening, starting again overnight.", - "icon":"rain", - "sunriseTime":1426829121, - "sunsetTime":1426872786, - "moonPhase":0.01, - "precipIntensity":0.1041, - "precipIntensityMax":0.2184, - "precipIntensityMaxTime":1426863600, - "precipProbability":0.68, - "precipType":"rain", - "temperatureMin":3.6, - "temperatureMinTime":1426831200, - "temperatureMax":6.87, - "temperatureMaxTime":1426863600, - "apparentTemperatureMin":1.98, - "apparentTemperatureMinTime":1426831200, - "apparentTemperatureMax":4.71, - "apparentTemperatureMaxTime":1426863600, - "dewPoint":4.37, - "humidity":0.91, - "windSpeed":2.48, - "windBearing":290, - "cloudCover":0.89, - "pressure":1020.38, - "ozone":387.87 - }, - { - "time":1426892400, - "summary":"Light rain until afternoon.", - "icon":"rain", - "sunriseTime":1426915383, - "sunsetTime":1426959286, - "moonPhase":0.04, - "precipIntensity":0.1321, - "precipIntensityMax":0.2438, - "precipIntensityMaxTime":1426906800, - "precipProbability":0.8, - "precipType":"rain", - "temperatureMin":0.57, - "temperatureMinTime":1426975200, - "temperatureMax":5.71, - "temperatureMaxTime":1426892400, - "apparentTemperatureMin":-2.42, - "apparentTemperatureMinTime":1426975200, - "apparentTemperatureMax":3.27, - "apparentTemperatureMaxTime":1426892400, - "dewPoint":2.03, - "humidity":0.91, - "windSpeed":3.17, - "windBearing":357, - "cloudCover":0.86, - "pressure":1015.43, - "ozone":410.38 - }, - { - "time":1426978800, - "summary":"Partly cloudy overnight.", - "icon":"partly-cloudy-night", - "sunriseTime":1427001646, - "sunsetTime":1427045786, - "moonPhase":0.08, - "precipIntensity":0.0305, - "precipIntensityMax":0.0356, - "precipIntensityMaxTime":1427025600, - "precipProbability":0.01, - "precipType":"snow", - "precipAccumulation":0.602, - "temperatureMin":-2.46, - "temperatureMinTime":1427000400, - "temperatureMax":4.5, - "temperatureMaxTime":1427036400, - "apparentTemperatureMin":-5.86, - "apparentTemperatureMinTime":1427000400, - "apparentTemperatureMax":1.8, - "apparentTemperatureMaxTime":1427036400, - "dewPoint":-3.39, - "humidity":0.75, - "windSpeed":2.65, - "windBearing":59, - "cloudCover":0.05, - "pressure":1020.27, - "ozone":356.07 - }, - { - "time":1427065200, - "summary":"Mostly cloudy throughout the day.", - "icon":"partly-cloudy-day", - "sunriseTime":1427087908, - "sunsetTime":1427132286, - "moonPhase":0.12, - "precipIntensity":0.0356, - "precipIntensityMax":0.0914, - "precipIntensityMaxTime":1427133600, - "precipProbability":0.1, - "precipType":"rain", - "temperatureMin":-2.33, - "temperatureMinTime":1427086800, - "temperatureMax":6.96, - "temperatureMaxTime":1427119200, - "apparentTemperatureMin":-4.58, - "apparentTemperatureMinTime":1427090400, - "apparentTemperatureMax":4.99, - "apparentTemperatureMaxTime":1427119200, - "dewPoint":-3.86, - "humidity":0.65, - "windSpeed":1.13, - "windBearing":216, - "cloudCover":0.73, - "pressure":1019.58, - "ozone":334.74 - } - ] - }, - "flags": - { - "sources": - [ - "isd", - "madis", - "metno_ce", - "metno_ne", - "fnmoc", - "cmc", - "gfs" - ], - "isd-stations": - [ - "094490-99999", - "104380-99999", - "104440-99999", - "104480-99999", - "104490-99999" - ], - "madis-stations": - [ - "D8965", - "E0831", - "E0954", - "E4790", - "EDVK", - "ETHF" - ], - "metno-license":"Based on data from the Norwegian Meteorological Institute. (http://api.met.no/)", - "units":"si" - } -} - -https://api.forecast.io/forecast/b251335276b56396cc98b7c79b282971/51.3750768,9.9175961?units=si&exclude=currently,minutely,hourly,alerts,flags - -{ - "latitude":51.3750768, - "longitude":9.9175961, - "timezone":"Europe/Berlin", - "offset":1, - "daily": - { - "summary":"Light rain today through Friday, with temperatures rising to 13C on Monday.", - "icon":"rain", - "data": - [ - { - "time":1426892400, - "summary":"Light rain until afternoon, starting again in the evening.", - "icon":"rain", - "sunriseTime":1426915383, - "sunsetTime":1426959286, - "moonPhase":0.04, - "precipIntensity":0.0914, - "precipIntensityMax":0.2388, - "precipIntensityMaxTime":1426960800, - "precipProbability":0.88, - "precipType":"rain", - "temperatureMin":-0.01, - "temperatureMinTime":1426903200, - "temperatureMax":7.6, - "temperatureMaxTime":1426950000, - "apparentTemperatureMin":-2.87, - "apparentTemperatureMinTime":1426910400, - "apparentTemperatureMax":6.66, - "apparentTemperatureMaxTime":1426950000, - "dewPoint":2.58, - "humidity":0.92, - "windSpeed":1.95, - "windBearing":287, - "cloudCover":0.79, - "pressure":1016.81, - "ozone":418.83 - }, - { - "time":1426978800, - "summary":"Mostly cloudy until afternoon.", - "icon":"partly-cloudy-day", - "sunriseTime":1427001646, - "sunsetTime":1427045786, - "moonPhase":0.08, - "precipIntensity":0.0203, - "precipIntensityMax":0.0864, - "precipIntensityMaxTime":1426982400, - "precipProbability":0.03, - "precipType":"rain", - "temperatureMin":-0.59, - "temperatureMinTime":1427004000, - "temperatureMax":6.78, - "temperatureMaxTime":1427036400, - "apparentTemperatureMin":-5.62, - "apparentTemperatureMinTime":1427004000, - "apparentTemperatureMax":3.92, - "apparentTemperatureMaxTime":1427036400, - "dewPoint":-0.18, - "humidity":0.82, - "windSpeed":3.97, - "windBearing":77, - "cloudCover":0.5, - "pressure":1025.36, - "ozone":364.7 - }, - { - "time":1427065200, - "summary":"Partly cloudy until afternoon.", - "icon":"partly-cloudy-day", - "sunriseTime":1427087908, - "sunsetTime":1427132286, - "moonPhase":0.12, - "precipIntensity":0, - "precipIntensityMax":0, - "precipProbability":0, - "temperatureMin":-3.18, - "temperatureMinTime":1427086800, - "temperatureMax":13.21, - "temperatureMaxTime":1427119200, - "apparentTemperatureMin":-5.2, - "apparentTemperatureMinTime":1427079600, - "apparentTemperatureMax":13.21, - "apparentTemperatureMaxTime":1427119200, - "dewPoint":-1.16, - "humidity":0.71, - "windSpeed":1.21, - "windBearing":169, - "cloudCover":0.33, - "pressure":1018.13, - "ozone":319.54 - }, - { - "time":1427151600, - "summary":"Mostly cloudy starting in the afternoon.", - "icon":"partly-cloudy-night", - "sunriseTime":1427174171, - "sunsetTime":1427218786, - "moonPhase":0.15, - "precipIntensity":0.0203, - "precipIntensityMax":0.0635, - "precipIntensityMaxTime":1427212800, - "precipProbability":0.02, - "precipType":"rain", - "temperatureMin":-1.47, - "temperatureMinTime":1427169600, - "temperatureMax":12.66, - "temperatureMaxTime":1427205600, - "apparentTemperatureMin":-1.47, - "apparentTemperatureMinTime":1427169600, - "apparentTemperatureMax":12.66, - "apparentTemperatureMaxTime":1427205600, - "dewPoint":2.52, - "humidity":0.83, - "windSpeed":1.1, - "windBearing":230, - "cloudCover":0.3, - "pressure":1007.38, - "ozone":368.29 - }, - { - "time":1427238000, - "summary":"Light rain overnight.", - "icon":"rain", - "sunriseTime":1427260433, - "sunsetTime":1427305285, - "moonPhase":0.19, - "precipIntensity":0.0483, - "precipIntensityMax":0.0864, - "precipIntensityMaxTime":1427274000, - "precipProbability":0.05, - "precipType":"rain", - "temperatureMin":0.86, - "temperatureMinTime":1427252400, - "temperatureMax":8.93, - "temperatureMaxTime":1427295600, - "apparentTemperatureMin":0.86, - "apparentTemperatureMinTime":1427252400, - "apparentTemperatureMax":7.97, - "apparentTemperatureMaxTime":1427295600, - "dewPoint":2.88, - "humidity":0.89, - "windSpeed":0.95, - "windBearing":335, - "cloudCover":0.93, - "pressure":1005.42, - "ozone":384.05 - }, - { - "time":1427324400, - "summary":"Light rain throughout the day.", - "icon":"rain", - "sunriseTime":1427346696, - "sunsetTime":1427391785, - "moonPhase":0.22, - "precipIntensity":0.3023, - "precipIntensityMax":0.5588, - "precipIntensityMaxTime":1427360400, - "precipProbability":0.8, - "precipType":"rain", - "temperatureMin":1.57, - "temperatureMinTime":1427349600, - "temperatureMax":7.74, - "temperatureMaxTime":1427385600, - "apparentTemperatureMin":-2.31, - "apparentTemperatureMinTime":1427349600, - "apparentTemperatureMax":5.8, - "apparentTemperatureMaxTime":1427385600, - "dewPoint":4.02, - "humidity":0.93, - "windSpeed":3.08, - "windBearing":1, - "cloudCover":0.99, - "pressure":1004.17, - "ozone":383.65 - }, - { - "time":1427410800, - "summary":"Overcast throughout the day.", - "icon":"cloudy", - "sunriseTime":1427432959, - "sunsetTime":1427478284, - "moonPhase":0.25, - "precipIntensity":0.0686, - "precipIntensityMax":0.1829, - "precipIntensityMaxTime":1427410800, - "precipProbability":0.42, - "precipType":"rain", - "temperatureMin":1.35, - "temperatureMinTime":1427436000, - "temperatureMax":7.37, - "temperatureMaxTime":1427472000, - "apparentTemperatureMin":-1.55, - "apparentTemperatureMinTime":1427436000, - "apparentTemperatureMax":5.62, - "apparentTemperatureMaxTime":1427472000, - "dewPoint":3.51, - "humidity":0.93, - "windSpeed":2.32, - "windBearing":331, - "cloudCover":1, - "pressure":1009.45, - "ozone":351.61 - }, - { - "time":1427497200, - "summary":"Overcast throughout the day.", - "icon":"cloudy", - "sunriseTime":1427519221, - "sunsetTime":1427564784, - "moonPhase":0.29, - "precipIntensity":0.0432, - "precipIntensityMax":0.0813, - "precipIntensityMaxTime":1427554800, - "precipProbability":0.08, - "precipType":"rain", - "temperatureMin":0.93, - "temperatureMinTime":1427518800, - "temperatureMax":8.17, - "temperatureMaxTime":1427554800, - "apparentTemperatureMin":0.93, - "apparentTemperatureMinTime":1427518800, - "apparentTemperatureMax":6.77, - "apparentTemperatureMaxTime":1427554800, - "dewPoint":3.03, - "humidity":0.9, - "windSpeed":1.51, - "windBearing":311, - "cloudCover":0.96, - "pressure":1011.46, - "ozone":349.29 - } - ] - } -} - -https://api.forecast.io/forecast/b251335276b56396cc98b7c79b282971/51.3750768,9.9175961?units=si&exclude=daily,minutely,hourly,alerts,flags - -{ - "latitude":51.3750768, - "longitude":9.9175961, - "timezone":"Europe/Berlin", - "offset":1, - "currently": - { - "time":1426944648, - "summary":"Mostly Cloudy", - "icon":"partly-cloudy-day", - "precipIntensity":0.1245, - "precipProbability":0.1, - "precipType":"rain", - "temperature":6.17, - "apparentTemperature":4.28, - "dewPoint":4.68, - "humidity":0.9, - "windSpeed":2.51, - "windBearing":295, - "cloudCover":0.71, - "pressure":1015.34, - "ozone":448.84 - } -} diff --git a/updateChangeLog.sh b/updateChangeLog.sh deleted file mode 100755 index de3266b..0000000 --- a/updateChangeLog.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -COM_LAST=`head -1 ChangeLog | cut -d " " -f 2` - -echo "Downloading git log from commit $COM_LAST (excluded) to HEAD (included)" - -git log --decorate=no --date=rfc $COM_LAST...HEAD > ChangeLog.new - -cat "ChangeLog" >> "ChangeLog.new" - -mv "ChangeLog.new" "ChangeLog" diff --git a/zip-file/openweather.shell-extension.zip b/zip-file/openweather.shell-extension.zip deleted file mode 100644 index 8134683b0ae0d233e70fdbdc17e06cf8f866a8d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125916 zcmaf*Ly#^?w57|oZQHh8b;`DF`!Cx(W!uIn+qP{ReP7Ssq&qS)Cz+9>6|wgEV#ijJ z1qDL`0s?{pstRV2Y?4KL^+o~$GTH?KLIuJD@-Q=UwKQ|4cQJEywX(NxVQ{ljQ-uZs zJ;47``=9OR2@3=ab_NOr1a|e`ajmE0vdMwrKU>##QP9MzBh%pGw6JkQVU={fBG1yW zsF25n1T9@I6et^*wj9vx;J0;pL#Pvo8JQ%6QcRwhvYgq95$OVj=gY-~sXOzp>k+D5 z9C$QF|4HE^-UsMUct=JYqql+mjuxZ$uATtTZ?sv^YeXRs%uz5l1}YQ9ocNyf?~(W~ zbUmFGluA%AvMZ8fCS=1AXX%tEMjnv}ohv1hT3$m&{281uv#{{(12WJl@P|hP=n!zf zs5Dt=z%BhH*+0h(T(RS|JI*7hJ*2UB@!Ot^pWuo~bN;~XXaeVkdh<1WQe>yp<8L8< z8YCB?f^Y_JgyNS7ZsJ?LUO-6Eqp-G+!Hx+7S!3Rj0v&Lc9&}cN*KA$ z<)F}y-bkOgE|{%7?feFFgns{qpa6U2I)jHUpO@PPR;6KvU7(mA7Sgzr-FsA6h z2rk$R7%JzF&MIu(x?U-4*n@_)`=d!)#v!rrN7nK=8~$_xI78AvUv0({LtbV=J&<0N97$jbDpkJifw)7QY3Qy@zF4T7mNa;<9|QAtm)O#>N)F;doTk@_s0EFi7W8Ye zQ|b}dK!_@tR%Q68m;74!?YkkoBL$GJtT@wbjP&z63Y-LBSUpSAx^U+>*@9bbOTfD- zVR?X95}}9z?t~*PV6B0Pq=O5rzwf}sVGPPWri;06Cm7citT(n_4;@~MLw7nhNkxsq z#tt`~0~9mXPzp?H%ZTWGS04y^_JQDqqziZLI7HByHawNp? zk#R0FI_oJ({OQ`3&?B+H7#n1@dN``6x{6009yf1K#C z@isCn@p9B~%P-8T484V8Si&2pKx2=MU@l*>Z6%T>(ia{(n?5T|Ss0rbIYzG)Bf=`? zAweySy)J|YiYMkOIi@i+XtF02?Wg zxf0d1Ehtq=7!f`iM?<22x2ltyb=cLko~%>vq)eE~E&bH47Jle-V>91pu1|~Yia%{zgDj4UOEYISs+yr-8{V2k%!s~1BYB$v zvnfd;c&Xe{`Kgl)BTE@#!ZNis&r31LW*VLjCo3_+jPH&Vcgu|5TIQ;G?WV}SXtXL& zidNEU@Ibo%2T#@aqmZotaOX)k%PDppJF%*jYT{*Z7#U1KX|ZpiUT*R zz-d0^jF*oACzRS6$IfWxjoCj0`Oyc4!@?0;atUcUM4u(FStF}zRpC!Yt@-W} zL4!kWB={stC2#j{$x2QQ&phof{2XR=#oz665LI z(@2kZak0ilLLHo;Tvd`!#s)%>NEFX3ka&}EhX}1P%I9Bq+dH(*1#mtJl+b%k z$)L!vaTBpQdXiQ=|H=6P5q4Sz=`y`&k1Y&KptP%2-~Nau-41g-6!b83ZyH4CLsPtl6{vgW zR5D?6?8AtT6p+Ky$|q2lRW+*ugQm%Id5K=j@7uO@`%m$L%tzq#)x$NAHn#XoFSQf6 zpo5=ad@5aQ)56Vd@IQ_E81n%x8qEOBYN9rRYsRZ#EH6oU&>OH1PKYWXl8~J-H2; z3I4L&t#6IA3^XHCDEH=#H@Ft!Or~lp1l{Z!-`j_|SpB4e-j zL}qS2Vuo>qVL!LCw&gyb+1Tpq1`EYoiMYUawr#_$3JYVR`4S67+slcOQIK>6aQD>l zv_k#3bk4taNn4gz)m$v)`x8{LSobEi&NU_ejSSZ<6LQhy_daYn&GY26YqZm-9$Fno z98zQTZ%s+Ds~|PM)};1Ruym!fN}ZYp0=Aku-%XLam9jcvIm{`dfcOm$6dn?3d!rP! zF%>`K^_kGE)l9>0{5ADzoZrpN=6gKBxIaGk2=G8wByiih?h4>D$Pqz?fbuOclfB)r z#BG`GQ}8q)oK9dq~<80D3KV5*|Y&0L{^c^#fRI{Y1?9A$LE268K)%8i9HvL zRVPF+nyIL&8lDp1VW))%wNRfbUV?{>(cW{hWqa!}?r^h(YxVAznQa3MoeiNB&9)XFB6zy@guBT#YT%BVCq z0aO$X7$~ym0g0#Tee>JEaGPGL5{g?$I+WjtNNNSgQ86Nw-L3|7A*N^oVD@C`9$tF#mxR7oP?f7;FZd zQ6t>k5(s3W`Jzm>GPi8nETxt0Kc12S$eQBbnmXn4DXvq&rht#DaUrgs;b665k3lL* zS-_t;EQePqd7v?H=QQ>7SyQe*#lLp#X?}i@fae@N1z`ivbdMoOJ`o!>aS?Vcy7Y38 zYmJ*)ufEMmUJ;Rj;3ZEr(EeR~g`7Bhr zAe|yq)%VG8z#P5|hE0?jA$OC01|2J=L?nVP&{X;Cr>M~+V$1)-C>vKBhHvI?)b#;G zv1ho9WE-KLcnf3Fp?;?i->dAy98z7F*wR3Dmj!m8-N&)s* ziQ=)J`@{~hx$FG|fE=aj8MmFH!~3>B?$_kV5U*%b;g%sbpo+^6E-16IPxYo7(;BGM_~?=sgL$^rT; z1cX)DtI~FK5^;1OkjS&}U)p16lE zXOltpj2Y^C5v)%s@k7$hJ&fzNqR(6STSOeI07Z_rC;XBcI?=Xi^VF#e&uR*7`HLlR zxV1@qP<%TOV|uc2a_p>(SpZkR8;M)_Or`cE8#~gwz4@vUT+Dr@7G28HzXIlY;p;9Z zKBy?;yYj7Qc&J;9b%&LgWS#ve$Htp#Gu_2;g_+PF432{Lzl5_@uAeE5=lC6B!3I~CzD6gt)-*JWm&lF&{N)OBZw`pzvVLrxDrnt zEj_(sXDAp*PBtV*8`o!qh{}cr!<{}C$_j=H;Ay1EC&T_L#*e?FKWL4XU?M9dz;vaZ zhTFl-NHw46L|T9f*b2z}adCh7I*(qoAdh})wL1liFl4*XQaIp4ZzyLr71gD^8D`Hm! zyF!A%ki@~ck4REm@0X)g*08Artz%I8Z<<{M{KGmxwzE)8P)~3E*}A4H zcDl71U7J3^tHakxpijmwCLh2+_)Vzvzc9w(#>B@UFc6UPe@p`YKa62#=4xbWiOHKc&}h6Qg~Ph>m!R{@`q#67FfhTyb2o% zvEy58i#cUs_TB6oMq;CQw7rVe{m;Ta`kF zJX)k+J9uA@4OapXiQr|Y85QDCw&Lc(6J(Pb{=67y$fqZ^D*w=tE6onB1Dsn+$RWK- z3{D>-`FS*^L5~Cd1HCnNx2yab5S#o2HxZu)mwkM@Iz3?gVKl?sNq|meZAZrBBiR~O zW0DONyiC(+(@w8U|V%Vwixl(y~R6)8(}()^9?DG8s?d-3UWd< zRhG24Mu|GhB_BDbn^`t_r3&j=CKGz^36A0GoIFc`$bd0Y_6M~sng*4Bi_M$rkim9#=@&%AopBat9|m2uoZ zvifJl7aUp;Z*#Fb9ia*8Gjp{1Feb^|vl#R6fbr)bZP7NbgjkL+UM4jgOTU5^CNoe> zv`CuK8YXlQTA5`i=Y1>JTi_U9utx|}Or#o)>167l+ES@oF>@K1!i5xVyQm6hvyv7! zV8e5_3?&r3k~aS-s8cgMKd3TWnRE{#7MQ|gJ-nG(mCm>m6%5KF#?p4ZVkgfI8B*Qu zM^vd^RxqNEXkKGM29q>0v|+Rzx>Mr4K*G;xHq-Ht0dXb+`N3gZk-&WMlm)(SXqEbs z`Ju||p+HV3Wmj=dI)vK$#eZ<8M&1^&9WaZb^X}ko0`%Wp@POs5c&m=6^gjbowZN7* z6#ZL>4r@yQ@Hv?)P@Uow-OtB&3%?Rsh{3N(ZkM%aURcy7B6bD1G9YAt{3A5EEJnyl zpTDVNfBY>41x$p-z)uedY6RP}!xy$J5XVQf5)p1cjXCFtf@fYeLo%D326d4Zn!H^g zDn+u42H>@Pqbm50%74I zL-PCp1!`jC0WYYHvC*JF!KO{v=Nj0;O0WY+Vm?LiQvy8BAChxgMXP@EN5>HiVAiLx zy{#~4TvA0NV=R%fx0UdfRJSct$g~a)(X>R~;G_C7!_ zF}1AMt=43v6S(^KQ80T=sB~qhF|_N&>~*e27AXRp>4HZv(Pcbki5rT0k38p1tP`yypHj|;5Lbr7sH@HPX7laK zceNp_PgPqv_NK%;@}1&K7X%it{>c=WiY&VBu+9tDIGZqo-4-pfXVS(mE;S8BTN8w; zxaBQK6tIJ4Q3L4p=ogMn`*ySzdQL~)Qps~k9ybnj($te5L!P6<<8r5$4KF0X}s zs1-HxwF3JimnEaQ`TJ9VqOuIQE)M@i@tO~H;Y?0 zQT%p6XS!d2{)L?1E@AJSY~I>R4bdKP`KQIGKpNt!R1bnrb%fEk9y}K0)l7FIqu2rAl`Np0TZ#KQ-U&`$Ks4h_= z@Dxc2}W95li81SZ9R3^9Jo0={iA2)LuYmFVJc_~`gbkA zCwpykiZ!U78@6LVR@i?r5Kp!=d^-BS&2_3MgS&<o~+5Jr`>76&H zY#up_Yn*w>!f;r=@?K(BTUj`P2385r6d*tv6ikM;y?tFmC=b1a^<5vy-6 z`w4!(*lVQ;UX6V*{%_|Je~c-dq5uL)9tHw}`_H+|JYCJ~U924J|3AKU#c$)XG1j>I zNK3KR3G5)`PnI2?V=Btj%H6+ac6V}eR7`~pF{dq+Lg2pU^RVmi%2%8@4|TWEwchEb zs{>Yilly;{*Y%6yQJd!pICO!N&_D7|=@jLM#h0S%JObpe_yolzd2=?ByEKRfObAmH ziKBK8_YI0~>}NlSWukEX?z?R>IbD=lyl zug91_;etHc5*jJp`@aIQm^WYFt_Wf|f4BlP(hWf!awU#Tj)tYVh#l-Lg--WBz3|Qq z?RN2#O9h<{*TA#xF26(K2FLWo_8nYPxQy7Q3qE)7ifI+g6<{ZT6;e_+; zgFw*t?L6k3*Cw2w68`PW3-ycV))fqYsyjoDFAwF-V_yO~$lm0D)3|v`!n`TgQ5ba4 zdIf}JSz3%ba!}g&Qo=QlZZIV#--U!H%s#5SiY;ga^#J0~?k>uU>xDv=3}JS`5RNUQ zW6_d;)Zy*0-9tJ~_&xD5`SA&+I@h%axmh6+R(TI~&q}Tq3x9}9gy16>(isiJ=tSO4 zgn#4|J~qQdAlVKo*bPNOs`!Lr%u8$l{J;*lOZK2kI?kIi=cq8gze5Ya3KYaRhXCb& z8T1P1Dq+qk7GQ+|qR8U`BsWb0TfGP*D^5p8n>*aS2YPXJvV%LA6nDQ5yauvB;dTf& zf@LNQSbY|{fly5&=Ga@@VUv+c<_Onq-zFC|!7h-UPDcxuxvksjCp=C@KQ{Sq0-qL* zVTgm!J_#7MOI8Z%(M2L9ehi~hd8-rUr=yFk-(-aJh?y!Hs5yq1iYFhZg%rl;1Yz@pzRq!^@% z%;~_4$E)n&N8&0&+jAAOkV#g@5oeQX#B8CDoPz;Ga zlU2p~8Nv=n+6~rrvpZE|CCB$E*jaO87z1u;^3c1T@Pt-8+N{Mbk9ys=Sc&Z` zARNfAe2VrY6aFyjoU=MizOpm!mSxFRx)O-h3S{o|tL#p`vlOM!g_%A2B<@C=NTU(( zERHDHD0?8ki7 z1_@BOZ5O<1Q`jhzCsF~oK{=#h4cy9R>#8EqEXQyCB!sj$9aM0b>*ca;-QekAj;$lc zcP4@?njgadL!0;*-DJQUes^s0$$AhCfy<=1>v@=z#^{q1BqjyQ*Z|^p@q`fm{pkLw z1o-zH>_n=s#A9DA!GEROtOJOIV0VYg-L&XDpD^ zZ)^r(*8xnLYXICNr7u2Wl~aJ>#J}xb<_KD6yuyz^2QngiadKLAd3gElUS%``@sJlr*>y8a z4P71Dvc83}$+?v^BlVi&`&Ja%AHSpAoxGfYLlTw5h&!S!;7`0bEs1=WHe(V@CuOY2 z6>B&asK&qtc?|0$_-*}fZ0O?)_Ot;D_HGJ6yN?VZxdMX)q=+!h5UMt$)|@3xie-Z* zUX(8R!vnZF!13DP?IWhD$HXtBC9ojCn9c?fm-j4K_iSgHBl;-u=B_srSadYgF35|4 z2fqRX)_e7SOWjupFVZG$GXzw4e>rAf#}NYlS~a`0D!LQ;&5oc8zoCH0{{3Uu()B%K zCOB%J8)){onRhP1^3Sg z)7FFcn<4Pu-ansf#l4l!BeTRNMI_cwEL%4W!Q4F4tDJ*Zz4x9x=H~_vjx!57{C(X1 z8AwA!Rgi-(UE6zIF`b_NDvLVcuS7*+ z_5oKx*|IfM%I-wr=ly0|^-`WEuxglME)r}4=+?BbNJx!( z8%tKl5Qlv($esJMA%09tPyH-faA>yJcdhjtempc8XKuW9G$s>@&^R{AZdX);Qs635 zGcij@TTtPN@-T5#aiuHDt#Cj!n9GYL)s-0)>nZ?bLg+-7KGWH3OpAwOYJnM4Fbvt8 zExD%ft#WC54qw!ao+SW&K3t=_ot~&eV`(+01TDu91%~jP5&^XO+^-X_vzHV8#SHm^ zO;Q?*{XTQ>P+RZT;BN@|p!Tv8-mp@yLuTi+CYG5!4BZ|h0Cb8w9N1$GH-3jhtW}v@ zk(<1H0LiXicWxtXM*c6I-yFNQfZ^yQSHYvi-*#!7CfziuVMHIL78f{e(?5Yz4Rnuz zFjh?AX!o)86fBN#W>DixY^QM@hgaX#yhTe?cY9BbreQalP$yk+ri2H5bjQf(S zdSOo93q;N9T~7(?0y;#t%V|aT37cV}wOl=yfEh!jO})-XjK; z;o)O~PUH{1!1LlA!vu23#;CQ+!2YC?{@QZs10|~E!*7GN<1IQwNnB_Z#VG=;SeoW~ zf{7nK411JFIyO}4^h>tX>hUh?&|)d0vSmhANN;E~!*DATXkE7ud4J4U9 z{0in^0QP{731Jao6NC!02(s&6P%I>1dHcaLZ!Sbo#E`*MT1MBHGSQNsddI#~LWv~~ zq1#MT!ftS2r0l>@yoW<33(%!yVP3iJYujfb4(G=UV(T7xQU zyBZeEelDaS7QC|Piz8Tzi%WCoHS#&}`l+}euvTeSQTI(a9ODg(6*3wMvl3LR4?d-J zG{mah?(vZ0-0`W*H{uviORVs{@b`3jDt_7QjR7<_AVy%@?5mrrj0$p=32iUZ6k3^| z0^R&Eu;pZ_;eU=iVr-N;bu|UxbS6bB*pzy1odLg@S&KT}K*P|R8)6QH*DNjL74hiW zO%lY}T{uKuF_?_%V4mlG{0NZ>QlW?#_y`xcJe~Gta7<@O4Y&4(F-p5*&yv0*!Xs6; z&Yf#eNE1^HQ0OOL4ai^YI!9Doyr%GD-Q;C1Yj&GOsYJ0|#qqW{*r5^gSs6{>0e~Odbv(%%9j61PSVOXd zbpU>YVf4qR{5w~pM6W#7IMXCoB9M(%Lrk|j>txt|1Ey>M4W*G5H5K*|`it{n3zIg1 z_tjUHQ+eMDOfbidMp&d4+B`12zk)_CR!DRC1de6RBj?;#;r%s4e^M4F z0P@PXhMCn@DkD~Q!{ubgr##H7b&hb%91L6&5+OAtWma;Jdhym)Dj5mMd!ae;>?V%Q z{ngsqdhLJYVxJIP)$)zN>1u;biM;6a`ojqf8lz}} zK`j1_l*v$nJz#>Mgo2n~$^4PZUvgBR_caZ7rSO*Pu$2agF!1Jo5A97b8l4=RV1%=3 za7SBe7W{qU=Et0j}G>7pKiW_vQ;~FWz6uR$viq)~zWu#7d#>O6ZOX$%$ zg950dKRTc%dV9Oi(%#T7sA3(B3YED%1Bv_3T!c5wEq+`0*K6_6^7EoX2qC7%@X6`R zLq?rP^zx{_W*}0R;V}U5J>wG`D7&>|exU0=e~sa%y^J=2qxs3lzZdufZ}EDk&zwAU z@bTu!VnM`~0LHx*CTe0+&O}Js+*yHP44fn@>bAc-jUO!K1E7aTHYv77_M9_uF{I5JU$->@;ALm^o_QcJWk)?@^6RH&?Fqaef z6pptP$X8cH=bc)kz@#z^=RWFk%eX z+%C=DFEi;3AgG13P~x)e%sbDPwdNZWeJtj1KfLx0!_3Zyl=)KCEMM=3e?5nPN$c9H zdNwHyG_rix*{UU0AeuP_nVmiUtANdfJU#eE_>YYL$Vtr|A$A~ySsg70+U9g`FegYd zc$VIFY4F{Gfz*6OqRwp|@R*;)>r6!DG=#PFALv6M(bpt16oEVsGs+ma)hErl|g+ z?{O$t4hQk^uav39Q0I(dunTw@PuL%FKsgLwkQ*3LznPs+%p_BS6At>xryb*39w=OL z9BpTz<20%z4Q^4>RO>%{4j$AP%+aPZ>e$nw-q{1&7A2U)%xVMaBP)}Ut+(rs7xHCT zX&4LoXa8ZDR#Am$b;CMtK>;d88i{BZi5NcNT~oVhq6XX37ts#)^Go(kJcBSc?h2@X zGo3#}v~TAWZ?)YD_*xO^aqVN+{xa~?#Otb|Sy*n4)RSAUz-4N?Bqa!(*4i5-f6puV zXd-K@)R2yoeUSbezF($IR3a9J<11BetHs4(=ZwEe+d+R-$)P9o=9ETmUEAHD7G>hc zLksROX|1;eNkCDZniH+QiP5>-BfW@~%My26Q<~~$WucYp)#^^V1S9Hx@iBUD!HuLp zQR%&KFl+uq1Lt=EA+Fzodd8uCJpMpfwm1;vft&4Xf6Qp8D2Bc{?~QBl^~UFN3u$sQ z5*uOj>LlfAO^fh^D|XilrxB1c{l}_F$9M!=Wk<$H#-SsBUyNiRLk+s_4xu=TK~drj z_P10)*JMyr@Z7};zR`y5IEnM*D$C}tgQ?1;IMXi3iAdHNX2tuk)Y%0-ZZ`gsCInco!-8YiC=vA6TxGdfqU>BR}FW1Y@`w#&J!JVyIEtlLLcf6sN5QOG~fZ(FPz z@;3K#jFR`10OaAZL2%=O4ij}fW0*JmM@D@bVU9t#k!6gL3+Dkg&L1p%BS&^63#N^S zul!kmv1HqyemU2i5Z`v3!i8d<$NYuE(EJu*>T27{Pn8>#Iu4d2)#YD@GW{jm z`zFf`Ts^O?JHu_Ie3z9QCOUhg^sMa$ZT9n+M-xrzCC$2<;sid>SBxBMVeO$p8FG#Y z|1gi;7-MjdakAdv65cVI^)j^nFV(m?C!zXf`wF#&>p_$^4zmWJB&*)8av{?kyk)j_ zr=fSGd_PXYQ~P-0lo!V)Em8i@{ zJ8DMyJ<-Bxh#p}_xx3;cO;Qdc~coXgO1<7DFgQm*5_;b!z@B8O^CXGn{ zM02_sM{Dp-5B!zFUuh+#?XPKb_bR1{<%v39751tv zab20c9ralUX+sV8seI-|EY9t*VpIlOsDXcnM;rZJ=Iaa;-Ex%*Yx)#U5s}*{L;S(l zm;d!Q##j#%5RF%w5h7W;P9qR~nQ%bg?U=5QOai~9<$I5-6OF{*q?F94-Az=#R;T02 z9fUukl1Y+oHDhxgnYm~er!$bfy6iCa(r#h;iutu=rk7*kW^hZw03LPCRY%~d%*3bY zUg8#Pwd!(D1Wb%+rR#d8H zMv-8VLGA2^5-}scb|x?-%&cd0^sklu!S}G%KZIX}%JJrN+?~1mm0-;ZZRm!Tvo0-X z)liy>VR9&LR%MU3PSDdaq}`e@K}dZ`E={Y-G5neglQsL-c+@l`EBdW(ShHHvtjy?5 z$5d@Uj5cM$nN@0uNQ;Tdj)o2zGZib*qyJBT=j%`BNjZ=%5)8h*XZB_q+1dmj1q zxjPi?W6ub>Z+a0kHL==d0NeGPDpsmKAHSl0QTbES&qr}8FnmeCYzImhvH;kHxF%OP z{+;M*Ep1ID`||e>MNspxMMdfbf@u6(lh6m9?O3rUO~92RJ0hb*qN6{KkU;n+A4ZnHilLDV#mD&!{`vcnUkJoKBh1Hx`MGc zFBD^mnR9{{(UT$xHqA1^5vr4RpCAO`1WRB(oel4|fZu&0Tw?;* z^+ywYTp!@DUnba0ODD9wwDy^W^GFfqU7nrsMSoNt`^uu9q%`}4yIg>L`_n_$pE?nx zyvFK>!-o@eT%|nU-1pdTlwE>O{o3Tuox6z-;bDa`YM82KTpA5dFJ9c9YYc~5gRih} zzY?K!L;q|CW9{{)5Tm9=9S}3q=BuR^@0Fn4s3$WBeO$yS4ocr@=*VD?oG2R{(AX%!crZmsEKw=;YeIFOe>`I7uqvzha7b=Vf0!~ zx--^_b40LE3!8T2JaqN?^=n37oP#iU-Ggntnq=X|Xms~h;}{cS z@|?vj-Dc5-)EzyO>?}6@0V%_kcPFlG6Qbk8UyZyM`j9GmGIh;L6d^2_e%?&YJbizV zq+*V#H4((8CrWO{!r`3=&Beh2wWgHAgAbqascQA|9rDws$35V+o}>zOiDd3-__Y#p zNH*7zpf70s)(R56ISX7eB9=oy%~Avk!8SOq?9JDxXxJeq8u<$NZzhtoW-Rf==$qc! zm~2frnYCujBGVUknv-w}EQ1fZt~W^fzqtu&1pM_YJFghU zUBTvub@Vsgd~|UbUL8(_2reI1yMGSH&6JKj02MV!4xy}j;hMDx3xhpY&Ef>O)kNgN zX{=|zo=^&lrPZn%8>Dnrk!DzlZI)?#OSaR2lF7@OE}ew~1UGLNdwaD0nsna^Lk8&OCYISkS(uVa7)>Hk+=*1 zCz{Rez6xZyhaz(mp!b$M9Qt|zb_SFiqjosfmnZJOQ*WpH-z>)jvkMXYa3Eyh{;Cel zK$o~+=j#0kR>09Q;&?yOZ)zii#a0i2pWpnqgx_Co4Q>77rhFLR7-p|20B>2sA>L33`-uMJ zCuC|oPOloLAd6F!2TDOtf;DHv6TLMD8o$44N=}_=i5rW+jY^F073QFR4r#gm;w=2q z@Odd3ne;iBFZp_<-T-3MoUS9BtI@Iv~epO_O=|GfcQ z91i0fp>gvt5v}t6r7iN7->GArRO3GWuktdwN@q>+Z6Z|j)<7N<-G@bPGo5n|}g zcgG)`NqW)LKVmBgYFg(mQWk$~XC%sC$WO79m6R?@gxb2?mC0gjdP`l`k^VsW`nWzf43>cO;J;`m=Fda#ENWauWXz{ znh9UZ3u~&W$`0yr;up}JWl=-JC!OCosVeM_MnH?QJGoA=COxXNeWc8bNrY3f0ATK#2cy8G(z^CwzFtVfu%o&vn^x zU9{rlSs$==?S`+YT>S&Jvb1}`#3WCiVpREYwayNGkR&%H*rCoH zmaaE+As7&;u3mZqDP0SL43Y+~J@|={`xtcOffViGx@BBz`|_oqxhz@ixY8-O$UGc8 zadEe$-z)zqh5lVFyM;U@ge;j_S6SA$3$|3&N=*%0_5%~zbwRsME;7?$*5|yE69ksd)G&#hh!BWbh`}WQ+ zw$63}p(8BSt_R&eP;CDkR2`5|zC3LD1KJ?IZWnWK?nsHuzuta3M{Tr%(ltb3L!8k? zzL!(EbPPf*IMCA$BwI8je$9xV#?kNd@*|I~E&%4hiLk z{b4Hj{|+QulXSs>UG6m&A09@#*{V~1c^r zGR_%E+t)Kgk!YA{Q~vB5bLi$|4=d`6*1PU9Q?-K)CM$)ALLvmQyp+X~P1wc~qa z8RC)yU(ih=5wHS=F96o^yo`8=x8VxmnF}{c=Qn5>Z>r*GBU!(KxsH`pwXt>l&~0hO zprjOZv~?@JCF|Vc=rA*p` zhK`n*_uH4{1+cEL7_pM+H|h(Q(L)-?QHPZmzakAcc;pSCIwxcEz3ew~@g1%Ip<;lpdDFK#P{6SU&n>2+)y${+ zz$WnezDfH)9rHdSsnpbf+Ytd3?wjtq4y1#5vk5?Z;9zQ&a2-!;Vw)JC5pjE&5<&ku zWRj|q9gY@C^0hG>zk=LeV!wj2xHO$_(-)G$!5*ytLY5`j&I5qQ+iO{OhcB?x$p zr%&)(3sqq_{~INi6zezQ;szlcf3?I0HUjhAb>Nase1(i!z}S`@ddUrSbOe@UG!g`x zFPvYvgpDCRbn>dFU;}0(X-*LwaM6V~0Z!e<+Op+S56(Pu`%{A8*JkaK9=$(vQ+Pbm z`nid_*Q>#~jCzJrg@nE#v^NJaf$JJls_n8=E9A$&6*wDNL0#@A{6b?(Rx5?G+_*{w zF-jA1@592rVn_#Xtl{|`SA=i2vii%TkY))+qV+Se2^6C;BY%1Aj3Y0_myktm(6rc; zMGeriWUmwnkg_>Pte<6$a}1e2W5_u4%yx_GcZnElk_YikOvDODYZTg=G16=h>D{YW zFOF*xk4plYGm(2o7^YrP4oNuN<=2R(yVFqveZ}m9WFR1!Mq?h-;pcAfv>+CuHj@|--}2`n?e!%A?T1Cv5XT$mg}W& z0!MHQ(*YCP7}9K3houH*3;$JUR)6FGD@d}oGUS$s@5$CdeLzibz2|~CIJ>-}3Sc!Z z1idv-dPPsUQ)Jxrl)Q3c@_jZs>pUMnPYrWh?rzrwd03`w&T+Nh;cl5?S)T>?Npvw{P1s! z=rZY|=}eYFyKfH5*RI=3pPFjMJJ(s+dvwd!aeFO>1z2O++2JVp2 zkh`yd;i`Ac1%Y;9LS`joTE~iPg6+D$feJT?J(02N)gPhM&Gcu2!$$#f2InttZaRvJ z)b>k-hO?Z>@KxRki@&&}BwgBbA+tfCB%EUj`=SmFa{YO}_omh*&X-5`mxrtN-!Gl5 z_u(GAix7Z;&7jTdNAYA^JxQ@>dUciR6`RJ#g~BKUMTG{i{{vPXCa>p1a`bR@cwB4` zKhVp~`yvHvn8!z_|7I7;iO}z5YkV|u%=b6>*A{-e3sVt)XzU=Ou*I5x`*)kz-o_ex zp=CH4Xt2WhRe_=GV>Jd2O-)^u69^KFwW@(8{*fjVA-gIKlIseHUe>R{SrRjB?IJX2-KtFZX1elhiNu4_j1 z_FFOGR-eR0qqy#GnabH}nCea>^M0S~o}+5{ND(ZaCZ^`WH!FF|YP-I+?>mlDwkGc+ zR&uS_kimtb9_z>r$0(A*gdJ}z$N#mR{HAyF9s!+DES~|MN3VVPo57d>T}W~l`g^ba z+&v)ozE?7A^XIl!EAn5*NAbp;OxTc!~URU-x)E(&)uPI_x4%k2BaKPP|a*?-@N|I-l%^WSg+ zp#M9Zpw4FN|B&|0LAHL$mSx+vZQC|)*;Th}TeobRw`{xWmTlX%In_OH=KcD`n|>4B zC(b_KA77jm=Q|OZD>L`X+(H`Q004hm@ZX9!c{>vu_5VGffX>dw?4OCb!xZGiVWF`8 zh6O7rA)@qsW%%2I_?CtPr~|!(0sw&HONt1pm~URBYRPC1VGj8oWp>t}C+jSNq0yuN z2?32{3<;c*_u?eAjJ+V?d6K5b}M~5clu`CFo!_2rq6yF`$W~3!do5Ad!u? z{<^u~=35GW-j=Kl^TI~BiKu_L*g33n%?X@R(_~{YApEKUCLdxesZ@MeV0zvJmZUIz z`GHg&!o>YrHpG(I!Lgcq(9;dfkU_?Jcat}B$rhCnw^6po!S(p|4}_Y4SwMFgQ`3vd zx#VNsV`wb?TqKcg$4{PuR{`U@@y^ey^i+Z8HA0pF*QJm-i_5R1ntmtk379OfDxjvO z+qbM;D7b{`U|knIDANEkzl8HKcWo^EbhvX50Tmp-yWi@5CFT#$ zRK{9@CO|dY{L#R;8paR=d||T5jO&%JAOR#Kt%tvE(*ZdvL#p3W0dL}Ib@5O_bR{$Z z8i1mM&97(RfceADI7Mp*`HXtatWUQ=Tex}j7KVfFOQQ`wz(+v~q~64`DZ%J-<899x z-)*^lEuc?qwGIHP>m-gw56~^^dbU0WuFX_d1uPXb*_4SxF)YnNvRKF}rCUAU7LNjk zI(@XgYtr&ec&{Ul9EM}jd0(rzjZ;&D1VZH>*dy#`OBgco6Udcq*;-Q0a=rI@9)cL@ zj++z6>=W`^fKI0a>sMSwY91e?RE$$@`Me+=!cL{7fIOvi{{TQXE=gE|Fq{XeBP|w zmexYRr^4;A_x3kLTfzOXO^xyj{U+QA$wVpoN)dR2rtv1)_0*ZthS(073BqwQP z>O(-)xPeEyA-AJbj>pr4cweWNo>ID^qM$y$h#MQ|7}(em!0N_mv1ov(Zg6f`<{G~Y z99DZR+T{TSZc;a`QW->DH!m7fRM;qNrw3ijLTFS#>7LHRs9Juz`` zoWu%dAh(^`K_)j)O3a}oJi&=rU+q|kVC#(W=f&$-cfM)fxn*7Id~qt zu2#%Swv_5vL>Vo{r=}bqP8ZJe@(7WypZbr-)blL#V`L6P{N3E*@x7*p5HnB>Z-OFi z%7XF?+&*xh2c+#j$T%|Tq@<))7Jo=fOJi&OEKfdgoS2xHpP#pTJYP}UuI?%1*~kKj z9(f`iF}HOfLqDVc{KKY~u=#@KynN2N{jHZkZS( zQqa&C_6G*HC)>S*ik?q)&?n+LW9s-{zq42bUpD1Lt#Ur;A3lR`8_ z?n~05_PM<)Fx0n`sz5QUO~t^+N6%A`z~S{!adL9{)z>Ek=tZ(O5O0v;$q1JT^s|Br zyh!TTYTLywJAD@w5woExBQGy)TU(n50RqBpy#AGvu@j?q(x~=<=ynI)FmPAEu7k4+ zUvD!!fAF8CwkHm?@+1KQzha9Zp}dC~b0?7JF(u!eGXE^U<(Fw2``i6DLs~{gM#9I7 zHF6rXG00pU9U}jEuZ>a*G&~#YJX6Pm^vx1?9=z4nRS2*^z->j=3450I4KV_R!B^*O z)^0Q_E33km77qLp*{3#ouz=dyjQjh01#P9izCIui?I8vyr;Q#4Cz!qNJ8QyE_9r!z zgJ|pU{9FsHvaHT{%4RT zDzfG}qA1z#Un^wRSh6Uj6pJadZ`tw<76?W+;J_|B`SS#Hnd|KIu3k@5+>XdOV)lwU zP;}a2qUddkAbGScBYn9}MG_mYz)58&Ac$>YOIPFL?N_9o*Bg$P>_?NCj)$3d&)M+Co(U$F0;Ku5*5XGk`<_?!h$!hT<0c74)#!y#bCt>Q{l&PucQw zA9`gPVbl1@_*3UpeaP^fBy4X5cws+>eYFenoYZgg2fV|yJdWIM^(XKFelqRD?L@JY zQ^*&>`+vdR;%|$5$ONBD=78~Y4KEYwKV@xL?@IE+_~708=lDwMV=q= ztrKP63tm&lcEh_|g*vt6oW;r$x<9<>TE_F94C!}6y?`QoI6M&D6w3Q=`QzZ5o_9+7 z^4Z?Pe#l*;O2BKh-QMi=C&>9^`)dQ@J;Y?RNbm!Fk`BZBp%1$Fl4jovZ+8cEz^vc( zybb!!j(p(`WB1^D2I?WpzfwGB#Ci(6Z9eMsC-|Ve&qEk7_vp#%wu$kaH28wv5?x;` z`nG>R9q^~;aCuKy7qlLtJlBOI?k(8$-s5^9r)&S_lI$>VZX2uTXePJemA6Y`ZM*+g zbZ3_^&xr~-yigakaef*ksvFZH(b{(2k_^+1Mg zRW^J0(g$P&Y(s}*;KDX@o?6)D$ZWDck!Zp0dfXbQIJJx^>=~of*_y@z2-E&jM;Fg< z!&x*SU2iPRCL+eE&V?)_&ZEl9$=NbJ0?T%j5JGVmu%PZBh^i!$Y~P|qBi|c&u}S;M zVJCMb_eD^(CeuI^BRY}SF|P|RE% z0dVMNQP$|tXd`WA^HUmF>L8>GrIcLWA91DfD@eEoJ&iCQarh=zyBu?`^ncTlivbS!rD^$iq$^`oNhpONw^8?u4uU{#dJ`T|L~!siah z*yMWs2*H?a$_bqA2{)T4VnV`PDNmWiWazEwPH0D9B1FIi(}_LBq+|dr$prwakReln z_JyLxK7p@;-20L85ze`fdq9%#1L0-FDAH?;R6K$$p*o|EjpIPp_(WUGD~i6MRVef9 z!@7-AWouG`V7LNmOBA5X`$FQK#>U;6rGOmmJDC8bRuI>g=bLail%Z`jUf5WsI=r1BeBPmH;C)>Js;oA*8y*^c3WvR zQtd6YI1s-nfjTks`lmCw{24_d5GRm3GdpqG>w|5-YLlttm8syze5Hu%$_#0}-sB-K zh##;&7gxBfVR`pn9=M{JTg`C0arb1kqzQ56ma%`#8S_pq;!TQ6FvqIwX%ot0n4#>A zNwUB;S%+84Hdsk5IMhj5|Ts7(}=>9OIYEg)E^&EKUDhF{bGpXBgQa3 z4)rq5JU%pD2|6DN1Kr}1o+NS+lA9M7rDUG=M}X9)ansnF;3>EvrfirmLW*Bm{yD7*{mn4Q1D1Av|6xsI0$eT`;kE!Y*;5b*Q@mA(yx!-23jZ5O}@ZgASp5=%q|{$mItvL?^E?g`bs?RDrebsRX0t&5c> z#OWp3@A8M*MlgntKA3?Fa!M)%77SEqZ}A~JCHXkJk^b>G z?0?|L7)rBO}RDJm{8VpLN(;Pf`_*$#?3CeAa0ldc+07o>;?`wXy%Ig3{? zWk*Oi85&fsPV>bzKB@j7V28Y`NTHM_Ki`F^Y{-5v#EpqziK|@I)xq=P2(NWqlP~(x zW_MbULY@dd6n3A>eVAoeF*g4C6=v`#$ztQ!P3GrUv<@}#8@o!h~Z?9=(Yh++$@;^q3|2+WIe*)MT{)-rB|9~MQtS2j~tSl%l zs{B9V{pa*diGIG;-#`EW#@}@CH!Ap#hx-0af5rPdDbW6%6lni1DbW6v6Rd6j85QWn zb=x8{q72E#3qf|T&ieaHZDNG~AypOid{+>aT#$l{TD7Dm6mW2?MrTLozI|CW6)-e1 z+}GQ-EdfCiCNVA6goO*l;o7D<1Lb@PZ1#h5iFgudq z<0Fn3HrjXJN8cCSXCJ~JmLArl`vi9f)uhq*a_c=Ujx8A00xiFbH5zUQ)$&{!$RQSw z<+i~mrYBHNIVy_i7GtV-DAs@T)N63(CmI`;7cJ*@d8?-L3BVEmq*?Xq*6}JdK8xhs zq*(bZ-LpQ*pa5j7!b2zyA zJCNy$8|Rv>R&=FCDW`&b$C_fCM> z;qOkWQ!E}vnrUq^Ms}$;r`iHhLy(jPP55lKQ_K48t zH~6*J=BLtiI(GH+hwtGKZfT;Vuo4x_#|8a8{;hK{t+7w$?SGts4tvFF`VT|eDsphA zE9lm!-nernt)Z34$g4NwaA65!hLu)XiBA1)M#?T7BP;R#oGyp ze~F5)F>*%*GZw~OVibUHRLSoa2xpBX6#RK#zSjF-w)Dy-k(a)R|r-pwqSMz_>-xz;2uYYDb{}{Q&_NfkCK>`5GeOvHf%=N$E{k!HGrD|!V zEsmO<+|amGif`G>gEdN06w7jMdcl)!70*_6=TM7FzS$2esvvmH*-*%&D{OQay(F6aQy+^fY3n;_S7i1H*gYL{1 z7~Ai`S*j7}3V0K6U18{m9Y`IR9gw(3$Jy%>;96H7zb1PZ0SECz8~2Tu_-$(BQ~hjt ztKz&HL=t^su~js8x%=+r9-l5Ek0X<>3|O2k zS8R^YB`l6;c9Bo&72kUQy)R4PryJbmcZh+;^raZUD{#Kf^pEErdOyD-HAmm7pT=Eh ze)zy_tV}U$e&07Yhn+D&d~i5uZqY%YqsE6sYwx1O4o^^5x~a}`SRFdLt@gWK12ex; zDz>cm-?1~6x7x@SV}Rk6Ix{q`+SU3B9<@FBW3`#*i*=X-pC;Nw0_lYPP5 z@E7vZ4)knHv+39!arl28-YuoCe69ufCfqG$v}Tw8aNC&g^R90Sc9&?X@iBv5bFT}& z^C%16lWVT=Z4SQk!g~g=gL+onZWg&pUv`&1{{($z*uahxFTlAz1j?W8!m6Yk9sTiK$|UkA4h-#Bx)fUDWxs4bnYa{upo#e60pI${5a8c+U{n!W-yNt_*YaaC8Zed_B({PYAfjj*EX0 ziPcG2dBh%Xy+oRizUSr_20x@^|w z4m7-c5?k=uf*ZV#wO#vdtr__PGo8!AQV7>?CQ>I3A7_fIhB>Z({3**|S#jf1l6tT3 zf#Fd#hBscFck)<6S1X#HnR9(l6T(bI8IO0f#-vZNbFp4-an#(Ehdb!F6EVw0EXymm z5^S6m*4_;dPPEVLTw1axz?kB zECyMb@xz+WcB|cNn&UmBr%=qZ?jnQNXcIzEPNReU6u#;Q<{Ffh_o##2Ff>f*SmtA3 zkN$e|gJQ~lom3gI3)sq;U{g`M4#y-G7{RCqx%Ipve^oSsUdsaT+kDSXK^8A>DqI=h zn5^w8H{SlkcIuuPkk$T>x0E9RJoEFF=eFu|Y?6VI{(21~Lmcic(`3yh9@(gJX!O1F zC2ygU3!C`7>R#nWNpT_;_7iYj{Oz;v;+^+ZqSQ+=w(+m$gF~fK`?X^{?)kZem8Fd$ zZg99Vqv#Yt?2{f5?h+~*nB^B9ETR&d!pe>!$1c}d$u$e!AU5oVIXW#Ir}c)-vs~?v zn>@%3NdpiXjNugygZNx$CERA<26$YY+fL*b@;^@4KuKUxKl}MqHDfe$t;U<=5! z&{lgy(ipSOw4$|`7bt?@v`MBsS?5qg>)|qUOZXbq1`=$eqKO7k!vSH+0Mr3%g~-x- z!yqp}G**(U18Dlx2j{{I8lk;MM`BJIt}^+e^0#Pq-es8Bp*cU-@T&}VP4ia7@{t?) zUcImCDU>U?ak;^)6RAs)ZytvcxsP66G;A483ytI>W58+?Q|9A7g-bP3Y%|sn)*?cr zPNPNM7BvjTE4@DY`i>#wS${(aKf;mE-;??A=%zj75C z3DL~PZ>Tdz-Op)5?m~)?P$Hi7NCY7fb%@qP`cyci+LzMMs<3~`gIHqIno+o_;Ew)l0g0vf54DOnQ+t1RTs%3Bd`1C!c>>mIG6N#e z&!E0-A}@MFTe*zS^tGVG-+g2AV#-bdKb=a8O(PgoE!67E7H#5Pq#4-1mFOYz>oAu! zOm(Tn#Z`H`9i`%$`@!iMPJ#PibW!XDd}EZz>?Wi2RyO{UR|j^dYV36$pA}5i01gBr zIN?nK!Ld%|?rQE-JuLOjg)+UAVWKS(YO-?FEOQmL?7nl%3`WbTMRt}H6lo;;T&Sr= zd0di!bZKK8L-x}LY3fO@*T^Kia_Y9}l?h9w*Oo~tkq1l-2YlLocIovT5mwurdS<4@|Uw{%5I7%AWJzh_q!?n2FODT`OyRZJ8_GnN0dH21Gzuk-(y zRsQ#x?q9=R=YKKmb%4dH$of9xp@sM#!`^?y`**|MMh#CZttEGUi`VeF!NoDj2cG=X z1#98cxaDNbHAvc-CZcdP((fj}!U;lm5#1ZUR8P9nSlP8A=?qTU#kSsXL)>W!jb?X0 zXeV9Rin}J8Ooj?AHUdFztDa=E4`QuwAe~U!jT*zZtT$XG6l$aDK zFM7=H>M&dQ=Y*c!u&*}LSLq*1k=edLSs>ny@GqYF^p#WRq^;yn@p=)tw!pkb$8|ee zptt}N{?YzEK=%O05uTD)Ie{*LK10{tT`BipXS#Jq-QzE=uE<|*>;q=`8TWYSWZt2I zTcB9%cgPz-j&&LPnHOYV{HwAq`%#%wP6?Ywk?(pJWZgam8Mg=D-JBD{Z*w+%FWehJ zL)c=Uz8LP!kJIl>c)MpOd3RS=j4n?Im*AemQ^>r9{0qXLnOB6oF@9a@Lo?$!j1FDK zlbsMA=*PBCvAD3rU#j(A&0?4EHNCI4)Hh3ww(2{)_A+4ZW(IZwMH?+(^< zo#@zzLso333{88e9(edu z{H5Js_U(_s?49y7d_b3D(0c|}URN9rA&)X~AwRFs&FeM9%FQsu&h;|HiYDXz9vEj`s#Xcji#B*L2DVOo+bRS-+_lSa^ zP#n^AcCnFaa&gMdsp$Am^zoPKNG0!Xkk`95IPub$E}Q+$!LUnE(bIZv&I7YVDeSjF(Q|$i?47 zC30p%5Y^&C61oPF`>I33U%!VSQs~oPmLfB4qY$&{v0pnGZ;$jMGqs3=jO2svH!ul( z;Y29tFT)VNDC@h>2;1vTyUmXiOuz0B>z>9CXTPE#2KMB~KlLzPb%>ANOurr=4rXGA zgRbO>Ri<1c=iUSN=40?M$TRV9$=d_$Pu1mP5^%fufr~sK7j^dAvjX^SgHO%d(>m6rMG?E;qd&!_X+9Y04E}3CcKl4uuxY6V_k9kS-6}>?} z<0(dtK8o_k94D7~wk>-@zzs{mXOiiB47}ky!)S=vw-|;oyUz_{&l`hL?4i^bI`ZeJ z**r1F;1R|~@55C=cL)kmsr7M)G6%(!7k`UKSjP2d63xL7%;pktuia%Fxh&G zR)pRFaP*f|hZDi`%x2Sg9sOlb6VY zF7>TrPBD&R>Zawl?X&l$WB}eQt|3@dHu!mNJcuMzLe;fjUbV?y&yg*&pHc+-?pCjI ztFd7JE13uisiWEZ7?+8>qi&D&(Pp<4M&kUM9X!Vn(L073r6Dp?tgDq$T4f8Ym=| ztN2sad9s}PSS-Q-0p`35)rMN7WCT=?>LYs>IV$5izSM_Kq*rCRCzJu1i~0`Rg)_fJ zh06jq4Ln9;CbeHT^?gW1qZ>TRf=Oyl9r?_)fpf~rq42m}o~PGw%kzjl8=k3vs(M_9 z?``W=ra5LDoRYYx(j~g!wM+>+V{{_=be~GfkPH z2J$t$H~7-yu0`|w*3H@bXfEO#*5HE4ixny*i0rTw#l(<Bz8dh;y*|hQz3%>4_qO{mYge_9re56wORb*G zSPj(Oy???p1Qjk;VR^d(2jgT-iEDinZ0`o3tBP8z%`B=?t}dRoC!4I?1s>;9X}lbV zNePNF>t?#rW{rrLJ+v#`O%cNHdU-gU>O0+j&pHT^mm7qa^EG$ya6pQjG0|*PA>Wd5 zIwi>ALg_w&xG9R|oiW9~f9K%8S^>P|8dFodF5vqdJlz=u1_ifm#jq(JvLB{ZnXb#n zq{Pu!$Q*L7oo(dkPF=roqGDSKK7>NgD^>%O1_&j$!*5uBbE~58A`LVuPfM6d!{xJ{ zY`ZUzWIsAV_s*O$uFO5lqu5Xu=1$=$z2a7`OC;8%^{6rMvUnsDlcM zRrja1(i(cbW`z2V>-NIViyDG%IOtPt7!w3Z%X{vgT#jFy|Gn3gjW(qQkSj8DmZ5N& zho8~T_+8q~M^vTe+|C6> zI)h~d#YTi@peahlS@-FdG8J5Wt&)NCGIqLl0f9>|Ko;V&JqE2(cDfZ#(i!?Wj-O-s zFuabIYTG|v>-B5xOLGhVNJW)z2V-0LX9Ku2-pE!dkE95IT85KaDK7d+uL&lD3X)H^ zpTqBwu^elKXZb}6$wKc4?v>f@0kXSTpf}SmVyg!V^hUQVUa(iK$nC{zC6Gpa(S2w# z*`hO(tO3MaEPN!5tHk|H~5J7K4k;Yx=^cOcjfw8HkHT|X*fp{6F9ML}PW zEc^s)?Xt~Nb_*|tahRc$I#-cx1GPX)i4APAdZDnI%9~11G8$t|%0#`8kAn75^~5n( zXRV3ds9hcf_o^Ux*3@Vtblc0o?%HO6WzWl3cdf*bUgbj)3IUveT0^HfS-e&REDqRP zfacP+8*#Q=(_4yNfdJeMtyv+IYpcw(p;~hf@PzIQtz9MUNf4YGkyaIp*+&)WKd6Dw z_<7ZglLcERG9_e|2Tvi5gzp2^BZ^t_`Y0NxiU?QnCvp(z~`)a6g&8|>N(Q=we#d$MA}N$8)aXu5hfQ3Y{p`6@`o3(~OdkGa9?mj@hO zEYLO-Qi&p)<(?&p&Zm7XdoC^lHJaB0i@13&Zo$$W$(VH^Nf#RLmEMu8beuS-rSK`n zs%EH^W@i!rq7ov19zapi{=pitQ7Nj-AL`JI_5v5lBVXqC0OqbV*Dsb7y2>C5{zXj^(wp9 zz&fTNw|MvPm3m?a-UihmX>E$ok8(48#|G^Lu0I=ssqW<+!Pc=3aC8xH?i*~m7k<{b zJ9A51a~+SG7uGM3%v!YrT{|#;KReA<3I(~TeIXP1*oj+T=3w^FhS7x2n2}|c?kLS^ z?&t5*i>CmzBo^hUnZmI?IFwM1ymZiBcisJW1=oLHVEIdt#@OKBFVcKt{A+uY`m}Do zci&QitACUd{1?1`w@9NJKV^v`i87RP_G~$?<9ikmdP_hd9hJpsc#aWa+q-+Zr`>aq!rmccoJRG7d8x@ zV;4%UJ&t#FEAP3z&{v{Oyk9l5i5Opb)2zYAe?7oU_N+T@E!LJ|$~W9ke+ro8Yg;a*J>aEM2LrTVQ!EexUttfz&*91eDIWrDygKafn&|`!{B5F3z0IX!Jmy- zEKzhOwC1e2tkAT3X&Q)B=#H&HC)!ZtE6#a5GFm6v1|~4p=Ipt=(AGQ9T42o)KGDW` zHC0!s46ad)hg>AV=eARQ6*8T$ipNw& zeQBA7kdf<8?^XJSDp2r>-s7*COdrg*VPYn4{0Y%SZ_-}r6?wxIhRycF9kxzRd9e0p zG|{r63+e^gDKn44P*)H7u(9il)AbOT%$WO}p^pkpkJ?A0i~FFh+gNEoK);25giIsI zlx>XdBn=MG=kJ5Pueyz#Gge+&KU8p;SEZw_&S?wA$FM)=9q1DAOrLen3h`ffF^`0? z+iusYq{hAv8%%6QtIy*+D4%mT5S<)~x@b#1IryB7nh({q6PG(SA_gW8Ew6b5@Dwa2 z3cMk@qtc3fK1$eBE!bh|5?q}I7fL}o2cB={VyJB(NmF-kdJLU3u3|dQO|6uO>bi?v z-c;&FRoJ}j*D57>%yG z#%$EtY+T2hYG(RV>$B=Fj>j`SCS?p}Qe&S9#Jm}>_Mj0N2?^8n{m_x|CAMVT7!i<= zqni6uB_inuul3)j-oIQ@B+a@UU+A}d&tl3`eEYXoV6Qyfs%ed^aIQDFHD9$gCR25M zKq2^DF!?ZhssXQnJAfdl&bjpYw_ydqui4|@ps(qAd;uK&#@-OFE`?tjz0F;bvuum* zbo{6RLr*$@+~Bum@K-G#^F9jUKe_?kz_&Ak$R#gn>+S%zse0y&uYk7yu)(!;!$I&r zGOxU4oxck{lj|=I3Ojtoe|$-F^9On@_8r;u!1_G_9Re-^Tu$Zs@CLrp&vXes0d7N$ zaR<7{o5T(c86PFU-15P>o=)QWC``!@f{aP1zn=R~I@Rm^c)fLFY=UBs+GxtH-1Iw1<7qiOe z$iUA=*~CY!mcNM%kA8W~fVXbRLlW72#9nuVNB^Sb4^WcuKNiOLFz4J4K_X(o?V+HJrpc1z)3g&2P zuxsov!@wup>5C(8Vg}$(W@SD2i&u8kF9Ks?rtl(DVyfHsW%alnpZ;>9ctGlUMq1g3 zsh^bc600nt`YB!HhbxY`*u%kZ!ji{s083tC;Vs`ogJKR7;gp~3P|KqCGhnu+ifJ{~j2fBB zCu-7vAzOPd8ODZGtMz0_%+eKUNGpXmzSyaO`UJ+XTWL6BHd*5c_~D27ZO;bc4S7({ z4E|g~^${*=EPPR^9Xds+@q)+Z}v6++vunqUv}!fLlIO2M@!j)(uy zXjRynmUZ-Jv8y-Yhn5ul%8GYbCjl%=xN61E2Plfxy=+gFpTMJ}UCesJ=vfvkYFsYV z#V4MZy@eL*ZB+KZxl~=n8)WKFqk-;_@F`HhH~N@u?BVHAqymB0pn!vcAll~Y_A=J? z!Pfh7wbn<#!KB)u)}TaVGZ4sJ&~I~{!eSa4Yz_59I+UuqITW)G--t?8*SYMpyQn(7 zgoCF7)aGSGl-rys`;e-E77Ejxrm(wGV#0@00IQ$%=aIc~(05M-n1iCF9-5zE65Y66 zsP>X>4c`a6di@>xV?CSsw!q>v@M2sWfOo__-3v$?;%=tnUQ^r66eqzL$Q!kyu|{2d z!>-aEjDBO0`~bPcP?=72o0n@gHP@#fI+#8*-&3$3)BVjpK!s~mX&2dk)Rt1T6Sr%9 zoeg&@C=s(gy;^H5E{KwkS^)+V%uP->3kpb!1q80?#(-nAT{XiC?J@^^JR$c4GhVN6 za`(fq-5=IcLPFxz|6GEgu+d8BR>d~mTNucIt0&h~l7dJjL6)1WA7scqTsA=O@};;k z|1t#^JJ=sHjt8<=%6wt2HAG*~hH=rUZf97|1vt%oJ4=q0lq|7U9L&k|iW%49`UAwtx%F7O1nu1Nez7y7OcCa zvowA5m#`fgOz(!0IHAb=r>aK?FgVz7-^asbH{M;5l6y^HM+|@ww|UwKdc{#+ZGZXe zD>tzpzLU8TCjAMU=7ndok|9m3OaMzwZ3vle-etQ~fL_SO9Wj)WvVy|mHvR(s|5D{S z*#7(U_l@zd(ccY0vz-Q%IX<;^OM!8sGjz_hc|6T`Hi6h$_LO5+ns&LJ1K>B~bF~lR_y1 zSk_ks0zqLuG!{XEheXOB{}<8C1g{x>v~{C;_Q&OSzu36@#QL6kg1VRFwmrjUp#9f@ zkVfB_mdJZyH4+dBBTxrW3v>%=D&UW}0v>*_a}X+h`kK)*KFD(*K8SMwpSUG&)MeOr zFa+OS@JRXk_bIn-y_T#fG?%NSr! zzb&IyGj55iDa}t;nkV}0BsPT94%`~hXE^=*gyX=hhR;>G_^lbqw=FOkfTz1Qoa>+4 zL^bdlrzGwCgRgvlUhxiJ)HN>cb-z@|2X-(wuRs@{kgj!lx}D=cv6jwNY%sP4TaazIgZ@;2VCXeD@PO>Zs7myToO61Ly+3BVYg6 zHrYVYTaon;^OxM#V6V)%D1Jz?`SJ8Ur*={H;SQwQH{_&y|DoC`0k_&YLFem|jGtZ} zp_^UsteNyzj%4h69LNB5N^Zw`My{7CvhkEu!22iAT=(GJ6$yn8zu`OMnU=}t0LZ}C zQqL3MS2jU+lTFdfgq8&#C=Nh+rSTQ{bwZ2GuPNIi$J+=?Uw9-Fe|kl@?flrm z^dY(UHAk}YVi^DKODg&Jt+WHoc+w5ulIeZcPUy*)bUy`=xSdn(dx{t@rG4X0i zIp-ZZ>spX@zW(?gFH2r=#9s0BMDsNDy{!wo=&Oo9VS+!vKEN?6Zoj-B?(uZv)fRJ4 z&y>zrceLkSc-70ddW3WR(PR6lh?8^l(0x(R(y=Q3@DR#Zcjr9Fp4wfM^L}~$`+@yl zxkK#DqWj}xe+gu7f6-%-vPIXAx1JK^44$0h3E((6d}7&yh$2w?ct1F%X; zDd4QDli$8PTrBP;z(w=;z5Ly~;^H01nY)MI)k9!^cbGkS&DLRq=UF>-MMe$e4vp}t5|~^(e}iH6N_Rq9>t7x0bR7%ypPz>po`S!syY}E_EupVrwF98tD&hN z23qz+MfXk#hJV>l(WXzk*$_lgnk^iW=+)&6F6E)GxiNPHeTS97rlLT(x zR-{$gugeb1T>jDHn8%~VeA}QKN4ix$IHSD?mGP#kiv9Rrm+IUA)u62g7STZfr%&xu z5223m@`J7|d8$4#bq=m0nOq_z)2Y^;^%19{thq3b*?u? z`e6Y>q`Ep0f6Whcp4Uo`t}EIIP`y@vqrLSq{91$)jmPKlc{dji2W``%m|uH?jtbOF zzbb88_^SUPtiY!S#AZZDonwqmSP)jk}whz zCEP}>OjbjvR%jo74Y#7$2%4m(H?Wa_q1t2uni;e#kN}lmx*S;V5#>sq^?;?O07G%a zaU$n)J+s~nk|Wa|{oW*TOX(OS8ze*c-Xtk*&|O+qXB`%7w6`;ATY=Lb>n({T(UC0)xanoDb-T!H#AMh#+ci{imDRT*EsLf+L>R@K8s}f? zVe`7Evhq;Ig{so9S7;Y$RqJLGZaWsusdM+vkOVzioXUlf6gVG{5{FyQ3|(rkH^i=Y ziV&Y2S8x)iQ+l60KWvjGXXX-hDG^gVhafX?LW*1whb>#=S|sK&Ix{m~d4hX_I4ql| zq7=nFa>wk@v0G3A!x!562l`0{H#^}?`@+-U;F0;YfesG6jsm}A4=6K>NWB?${e=-EShLeS}PR7mv2A8rT@olL1+%V9A+{!uw}BfzZN z3A2^kwl7+f{5B~eU0^sc(#i6M1!JvMefDhGMLjxd1kqifnAzdYMaDMqTJbW4*fV7R z<7o^H(&2=#)j9*@fa{HqCCH?J!Oh(KO7iJ7x?QP0d+;IiXDi#0YEnc`gWI0&e#j@3 z1~aGj+6tQ4X2g2{9{Cp&6O^=F&4RUzIMP;6x|zJSB6u*=<)zrtjyTAV1^UcJbZ)4k zs{V#a@o07SJXx{_Jal|ku_~XXB-R5Dm!!7mn3TQJZg*Y!S|TJSBTzR0VmzPJsuOyugN`Ey(s!6sHKjzNpV9sd0VMF(A7?PK= zKr#&{n`0eCVpnAkoR_JZX5H=4n2RIoBjgtSscbu3II1ILJYmecdT!ePpch_NOW!Q8 zDJ2k2lDy$y4yE4GEwQ5|S<-N6s0mXypKicz>&ED$HeKZ1Iw5$BpIk$jtS^*kSN~o1 zOG<>4=`xAR6Sv?`DXJ9!lk0SWlN}8|X6Xv28Z;nE-9c31nS;Xm(lqvW0q|REbrGI! z<9vcJ_8Y>197|D0-$)E{D2`nfIUsuXo`;ggaddJ>YFTRWrdyOK-k%ViaQtAkx=!wp zLntCGL#2=|ftzDkdrG`Fr4dm<92w{E;~T+dC-HHJ%4iwD7k46Jqk0QRF*}4}lAOWd zEJEhgj^J4G*y>=D--#mQ05g$8!?~|&j@lRFb3#c z&4rMLr!3pL;mDZ058Za|Z;rbCNy=-+Vs+fvf#yrlf2rhmv;X%?{tu0Rt>ho&RjtB9 zfq=Ls{HK!tKk5CuC4Yprp99e#KB*ktKm&13?j|$wSjqGr(JGaTYcE0!=|GI}QUVG> z-PPHnlUt|2;(E8+B(p}LoFbB~>U`)*EF$gH}?>0xy_c?w`N-OCHfgCpz{ujlRfhI#>7$+#Bh8VWin0vP^923?{j4gB%=x3PeBl!!9V6wHiTLR zz$VP2IX|g|tV2j4H%u>;n$Af~1g2q)Py}JSARpbCN1w3k(H}E(!D7s#Z_}r%I?^Y# zutspFm6Sf6$1;;nTl>Get=5dC-wB|Or~fP@ulY^9!=K1Z()T~i@Hg&u{`TF%@4pz1 zoRat0YcpO*e!IZy3F3Jb=G+}Wwlxe8Is*doUw^ga@151sc1In@T#%dO+-nOh6GG^R zJj|!&N}t4lACTYh`$0baLCcpxE%`f-0wxB-Q-2nn09`h#3NN+m3Man7%=|!Zb&^D9 znr>nf_)EyG;gCdUKzoTWCb3Nd?##rS4P=udmx}w0^70O&B{Cv5R9HXe&+-Z$HNnjCZ@tU zJ5vRE5&AYJ?_gMMU#>cDQ-1dZcVj<>a`bZxAD z4SZY08A}{DA1Ei6@*FUy3Nns=B#B9WbNe!uY7qZg|C!PUZBXXIIp<9o@A+eMGac{g zWFBu691y?P}G)TS$u|U3FJR9NYLI9nG$O^+X}e<@D}~*s;lS zDT>&+G(oz0D=rEej4yB?7ZGvX%d;o%4%+y7Y)uhto6oiW?X*>))wpZG_;fR`)p&zeQ+i?i=P^vH@*=T$hJQoqW_6WL z*~ykt=$!oq$?>3zb60xR2K+GLJ$U)#NSJ3F#Qg#`Kdd=x1`m1uEosYJ*j!WcaV^a| z&2prDBMy6LOMOdhRu2%gx?J|W?vKR>E+{>B%_==L7lrM$xPJzp@c(4#6tLNxMBV8G zhV6Wr6Z0fJDSWZ&jR#r{iJX!J7#$VzcFmZclS*w0>d}_y@eODN6(!^((3c3f!&B;e zthrBaRNa{mfSsgV<~D`H&K%wr)#rhmTQDWr_!6uAGC_{3O3n0V_EJ478Z8fQHne#A z&F`-9ld5lga3cCGM#I-EQo_@ld2oDsDOsJUjv_0~MV811`19ey@I%x0>|?NRj@DQr zZ}iRN&HB?!Qdb>ljwz}R9tIxghi-em&6GB7Ru^m~ye~GxGoB>@7-w`V6e~hDDKmzg z37&Y&y+7{}Z2}?_d&Y&oXGnD-oZ+o-*)&B4VmJcESfMooa2-qSUb8CSxx?DnE79JF zB~Gl<61%O=J*Dn|CPTVXpg~9}XXQ5^8~WL{ned~NXQb(Kw%t|aW49zjYZrN}b{YCv zl;S{ZYuXdsggDYfKZZR9Mxj8%-_K>Za+?qZ+C2)fWEO7;Si-}l#-hgiOslD4NhWV& zO{ddZM!y{s(b9j^W#@m+cTWO@W$wzB`JdtxA=~s})>?=&3`Y9nmp zjNCZYlJT;L38Vw9EE&oaf?hl^D3;imq8+Mlq1-tybiFiX(BMnm zoxv!f5l>3ekiE(-iR;TZ2Q@#e@~JtpoQ|`@kYsds>*ch|>NDtHWP44vt6oqF;e5sd zW{9@w64OX)Usyn6#_5#mrdZehudbs7{tp*0~X|x^`l%;o7&mfK*RkPyAZ{fJ|rUIKXRc>N4fC}lkthS zq@CcpxZVl?zRoce2TQ_t9HM)Ot_3|)pak+tL04m7tJ z5g(iqf8qS6Xtwn9C3O66kP02&+56-9WS-FadUvO9o5#cX(dkCmMuHI>?bBbb7tsFK7;qPAY;A6I z63!dPW2*>N9j|NM;t?DX}TBZEE#IKAx%lJJo{zrOiEC!a>!urxvV6<)17^ zPFtDIre4Kcvp^}D2umkSg{DQI6)8Q6Fwew#aG64%kVanB$~Zz63dvitlttb-qJpEU zU7;nkh2)vZ;%2N|g!eAuTYBwF!S}e6Qx)2lkEhuG5MhUp*~1?q_Z?0D3cp%vkmgY_ z&yXvXz3P=sn4r{wF_7&C;?68XuRYCB`R-d!{AAZ7#MkUCA;WcnT|>W}^-dpcZ8Phs zh1&dD7N&URu`c3j!#2u|rZBGy1$R?Jo`vsZ=sRVYa!&}tN&32dXMqw-EBJwKIMP09 z5!6rBR1sQ!2T4gSw@LAb2+cUkfAGQhDVG?#?Gelh`1Q!a2 zDSoy;jN0lmt~%owbApH7;DAtS@u>Z=(PUep4Z7OZ$xhjf%;CMu(PSn z&3Ym{^(F#ySiTPhV{KfjzwiRko!b$>;~fyN&U5|N6-WDsveDB+68Ltv*7?ghD*trI zVrqjRz(sck(_}x*wMx3LWfAo*B1nbh!18dlJ-kfQU?*gY;Sb}ck&hfO*6Lf5d1`#C zm8$2s@t_CLUk|2r>j}dJuoatrgMlSolRLGy^q5PTq3p+??mTh`aiNnto-;(z534WDpd?s=n{Nf4fY>mbHjwUe@oO`$!OBrSnl zC?4E#Dd-c*TF@GiSYkGpA*@9(IU}Qy6a9k6nie1E`=`FboIjr7lbfy%ve|%9PQ%#4 z{^!Ok(Fxm4i;Rzt$y|`Ip%Pb>uZ?TuQUpq`3*FK6BILxycY)f@Rf(I%jDh;z^xSPq ziG@S5j^8T|@5P!k;CU8PJJJWKQH|D@RxXI!&@@OhsU$&mZ=>Y+^2M$Ga;k}cm{#q)sMUdcm;T*^hey% zzLeyjWs(!)>7%+IndNhT-ZM*=hQ?0^>M0yr1DZ|Z@6$2xpQVf z(tMeLSA!NSVk^tdM0KKP02sS{PE>&m&7uMvJw{DFyv&pGJAHI%G}Qd`8(v)~r-LME z(9nPYLOHaLNc!z#(en|%Z{<*6Wz`;WMHsb ztaLN(y4{&g<)6M&shG0l!cUVc2rQL4gl1c#&11$kgmk>hzk>8cp{)pa}g(;1wMQomB8DU3{z#9aln$PbrNIgSSfQt*`43+WNZo7_UN;CV6XNF{D0pMQT|VciLZ^ZxYECP zMf^vQ-~Wt4`5!X>+AZ<74+00uhi|Qi3<5&v|0ntHUKDGz{Jv>?Sl1F}hce8=U>?bh z7O9+0vkisV$VP)H!|QFsOUWRIWX+9j>pbh0*BLiE?Hg=Rd*J-NA=sw8?2e=yJejS8d6#wMKh~T)8RiE_;d<$T~-KJ%C z1ODE{Cd37F;J^)VFCgW&|5ngsp?5*9>~(RLh1Z!vti8}B(r<<#lM~kTLgB5OvOR>JP;imI=UH1~d?c$u!V|d;gbU z&Z)x~;L&)JM#SI2TABOIFZirr1kgTdtqwG>>@0D(kX}v$6$WG>Kan&O8{_WZTW2vw%AR@F28K-LU^Ct-8MCERdQ#=^6!ja6eszE$=NR zTC1;-Ucb_Iy^DAY+oK+d@JC(q1fkB)3Pc@uxuQNbIiU{LGz$KCz2{4t;vPb6eZZOW znkag{g~WxTJy021$jv93qxuihcxMdrx5|r~qA}zZC6J1_}SpIgw zA2y%+0sj3MH$0Ls@p^$51jf4??EaOu>GR8?jqb;DvEYw`D%Yb8#Jy{w5#Ja5PVXMp zAE)opckdZbXm}!Ko!~$Ixlcis??BfIl7jsdAX;BV-Kg)MvM1Le#36#A9|vmd8V8C) z2fy}=#|>gj!uCP0s5dwF}WA3&gw)c!H^#!1{@YCII z{~gi-<#!>Wf@@XIg4bu7sh5Mm|9AF!A)N@TGR!TtLzm{DidjhJ6&`ozc-l>W4s31-<<8uB#q zioT*cF+O+_8$!EgB6fg@SL2AI)(lt|l!)`aB}v^af1FJ> zEF3fsbG@#fa}WcfER^e@&Y)^=Z|%`jMHCn0?z8?xWIm^E+WTZ^DWw9Te4%b5$&B-% zxD;lu5PZ=_3vNLtg&@%~_8+0=bJicG(jWxi5D(*At8&rlZsv=8M=~U=&$r)GHe;Nd z^1J$RL+*p^VAf}@z1aE}ti*n)WjRk|B7J#}D7>&ae!#F{wuvb8%Jj#?3gHfk6@wRz z602+K`7#moRKtRM`+Wtm63P*h8M4MSPsBX!ZUcz{(h)vDd74M&eUHbPC6Ux5KGZYp z9ZLg24^9u!4vwpF5^Bg=R6ukSDgb*Ad(Qd#0Yyy64$;?*zEDZb`P-A9?lh13dp>*( zbT@)8K^i;*=53@6=4}mFN$T~ikWB_&GwdA(3$h#T`15UKnuw35)=fLA2IR9-WFC!5 zQK7Sg%JgcT*0f<0=^p$W-^rNQxsup}(s3K41}l7AemxGoDP=Jy-b}r+;I_KIT~qNh z3W?tN(#c&cwpIy&7E?fHt7|g0T3D}Sl^t|P8E1CnriQp&H~L?uGTB6!w7>IQn%IQ) z6&8)e^ChK8137adG*)ZU0vYn&9G$RAHH8Z}%9J~aw~(5rMu!no-NT39SmlW|+ z{k9PmdA|FEY93adRo$Un<)ul0!i05#vM24^-&y9v!+fHO9Ii*tFfO@or5cm3(zZ?Y z(<8GwcTJqcOM`J8WBy}!A6`xx_wkrkO%}gMiO5B<3rO{IZWoPaly1N4$Fz5jO4YB7 zc6MV!^|{uyFqE~gaLm!K^c5u?PS>1f3>FTv)0<;%W?_GLg}u4RFu?u|U>tqC8d_(f&*izQMid!S2wgRI?@24sbC9yGpEH6~gKm@V1HcpD-{8)6ZxpZDH>^%y3 zmNQ$TrXrHrr-nXNT47F#OItg;Z2(Xi+xU0P!&1(60?7>1Fp4^MsgzKR2zk)8WSL2A zw0edD-5rpQ^Eels&F|hwEdQ6|D79U;%3kA*U>X-t!?WwaVDH`>nImS=r15M&BcWIV zr|xu{!iuiXiIm5LyO1@cwWfS`t<(Th5U|a0cea|WCp9>*{8@NT#l{GzyHyl`k% z#vQ9pkbZZKETaWSOg z`a*nY`-4iUuI#UGxO{cF+)uy0GMaFb`{BFcW5BNSIkM)r^!?*{AUqcq;|K zWXd+Ptt7>f>g%(W#1u?I zo^sZ!mfRcHVHidk8_=YJ7PzFYQo0BF!Nly(4`dS|jm<|{;a<?pLj@XG*hdQSSIoQRn2by)^WF=%13v3V7>-S1EpCY6n<#`29r>KbnfpLJWdC2e~^rMo5v%Z@8O zIkfq)4mzE+tqPpqJ9+um4zQlLMG2UT6Dxs=mb|?jEU36W2bMPpa(EFKbv;3o0};ev z5wtst@tDU|+_MEn&yza|aMHRDvy0>K*$ng*qqbQ;{LYzQUbl4KdGDTpq3fEPq_D3! zWkAEWPz(}?&GaEZI`LHYbQNJ3(6eSP-tT!bxHLWUm<;W?dh}s|QSytMoppLZ9`M?5 z?HJna?w=g(kyzaazqk=kzOineTw!*qLRxQ~Ee+sX4|CNky->eACnG-nX63;5;d{2_*7goMATM>(#}1JMbEa~)2)gnYkF%Qec#@4Rfd>3M$Y1esm$>4Nqo z9BfGG6|)jh?xG(LX9gZkU-rmB?)tHObLc=eGCIKlA6#RlyCP}HM!z)=B*@in+_m;j zB|f2YvwmkJzphQ}we0$+DS7Es(1t6l%|&Ve;$3r2Ii;VauQG9Slqb9LV2@A-rOO#W z=o`DsnM`9%KM8&UO3Oeb%Q&Se+F4^=+ozX^OWV}uqMcN^$HR9TQ@zeXB*_ehe z4~|L)YM)8*-S6*c^z_Qq??ubqBx29R;q&rwB+v;@f+d!mNs?N3q=z~B2>KG>6GrD` zWo{KeFNVAiyKFVO*8P@}!W~5oJ!#lBEo=78Gc#UI^>0#MTdpsti{cz$^;}{eF2~ZW zOz;>OeulL(CtY*)B7&TXUnMy5B@d91vO9^@!+XcSF%Y#60ohn;y&3`fek7>hADaLQd_$G&LvMha+5MJcFo%$_76!p>?}M zmT!5T*^KgKP56YLj$HUlO1r1`7@v&CDP-@<2p z+b;W+KT85KFY((5hZA*M1t2fuacTQeVAx!oa+HJTZ_ONwnK|ZRwzo)axEM$@M{p2? zx)Oy-c>$lwT)sri=KhDZ12R`Ax`g#m0}-Uh^PaMfODi4Iz{nC*LVAbMaP@Zol-Hgq z;*`uxNZ51jGA@gSu#PsGV&?4f{&(kfhdK@kF~jEv7A}(y;3pozHRpJe=?Dog6HoI) zybQ}S2TL5^FK3#5{qdY&s}w^XK>X=sfVx)4-|^oHC# z+j>9eU!L9>QuNkgzxSHBf(~#k#&?QJ1B&aN5<0?F?@n zti_EECiwR><7Z~!J)vzGA3|Y>Q~e`zHhds-U0fZ93WK?~A;@i&_6k5F#HU5H24o(Bln>PH~wHx1>Sg{9z zlY}Gc6lr9^+HC*g(+yGM7uw|RxKVpM_B-VguvD3v7-Ouod$d*)Nn$(6vkCp+ssc*_eW4Z7p0{j&&sMxZJ$kTg&?nl_l>8%{myqpk_Z zrJ)JorO*~y55)i|7*-_`K@}z!&H&+6@EfK%^*9hM7k&-$72^`Zd=ax*ne`joCF&)| zZy>x9{5!Nt$35%sI%tu-xBN`0zzK*x>MKnXxJ$xWn@s~U11$OSndg>x%MbJ@-^Bu9 z0JAoD!lFp|qOA*tJ6X?@dVeSWz?H@~ukc;UP?_+ryPUCJ+wLj2inN_4nu`8Nm`pkQtutDUuZe#YvZ!!SfL%f;?KHMWqkrg zQm?PbSHa4y56etDz)VSBUESvQET(&bxa%IOxE+H$$(J8is)C#2#Q{ce!qg`t{v4}( zlP8l91u#aF6e91DXTaebpk?QS&pIg{IP3xZ2l`NfL(9ie)?sxRc|qVI2c_=r_q;%scSYicA9T zqI5RKPv9Fz6Wf|b>prmS+QrptfD!mYu;5GT?FapR$`MFCKFXK%Fyc#nUFJ>Q(b6Tc z2wYScv*s{|Ulr)P8MamnV1WQZUrdy?3!A(HGpDj7AAYkBUF+_(;d+z6))h!z9SF*L zt}Fk2GDdwxxrE(n?}E=S?s?_f6%mp2EdCQT@OY&@hnqM7c%95r^hC103HXw8Fz&q} zkaNE}?mH3h{0HE7cIwdh!hP}<`ee-BGwvBQ{u*!~V)0(GtdW=)!m|e0Grz`>mqOKnxRUm~; zfB?|+b1~6z)jVG*FnxbM{+(!ScarG3>EoxNV5}%$ieq#5mFvLy@)>=|OXt0cC>9iO z@PT4!hm>`|H*WNavmgxc#0NJe8P}eq1~Pj0c(T;gnOB3J7Jc5?#yhhvEKjYUYJTm3 z4L3k_Ahk7Mw)|6E!)s#K`Nw~l-~quD5st)D!KwCK7p`5YA=ibvZ0Q%DU`f$U!A8G~ zyIM9Q>uv$TATN@q8>Dr8$l{fDD9BQwK5vsFaNt^GqTE{~ zOZhFS>@!e>Jdp2ZQ`3eNZM+|`Mx=1sOJ*ahO4Ls*2j-1na6mcL`s)hhn~cKy=tYa5 zJY)Gt&?jGlTXQj?Yo?!`u?f=CelqW+BAamCWH)I1REJ82EN?JxFt-#ZJ)DC|J%xVy z`4f3$n0uK29cKQ}Ro>V}5`7WF4n4Pd63Dcwl2e(~ILP^X02LoZeJGIq8i3YJ()@K= zK%oc0Lc|%G8M-A5HO$C7z&sXwt>3LQ&0_~|!(k&}^Tmew!|Yv5lK+Y7pN8ZXPlqN%~;Jaa}bs0c|P$|9|?OsXwPsX%s)5xE(Ah-d8iI2%7Xb} zyLn1NK0VVP@~N=cd@tmYXexAmL;Jhq3=1p9|C8ueQ3dao;ivdCq1yZ2 zvcbfzoeKRS>+I=V7$Qu7`CI5lV0x%85M>Yc4fY=}lSIXI<(avVfKTVL`IjgHfoa)7 zG>p)WZQ_n9A=bS8<+S^dQ=5J@+sRy^*>PucI?|uu;|Eq9&7)bxG8PMOaXZn9FHqSP zb0?++YKbubTekHJLJtt77 z1oj^^^H+|}E{6gNeWfPl`!@zB4X^U^M%)rSQgBm{D+MXXDqgj`MG?R~M^)PrXhthQdc{Q2qo2%DQ}_*+i?~!k<#!-TP7-0n&{XZZ zV>bItC3^*TDLy$Hsju0MTy&r;#-V6NpyUl@klgi8r(E9enTU7-T(@o4p-U7T31~)x z{Hj;$HPmHgcv>-tT!*8EguPD{*GJ?)1TkKW6#NPmFS}x>?}lMcb~5vN`7^gHHJ{9R zUZaq)k~se4rf$YYf2>H+7V?YY?_7DB8@3@xI0Oi~Oz?qUqE>Ft474u-@C zQF-${G9zhPj401&ctuI7tPJ9I(`k#@>@EWmmJ)96Wj^W-s|Fo_QiolFveF&NhVQlg zW|9uGC?cqlX8bc6F&6BM&EN3yYymJNT-7vac@D!na|*{)TDJ2ZmD^R$Wq8lh13Q;V5^B$kUU_Kr8GkoVcX#o znjIZy+hUD_x`&6fMY0-xFa7rs-(Rt7@`%?rNI!5`##jvwCXFL!ZX%#`QEVZNjH~8p zA1cx{(?By>mlZ#MDyw^O7m`g1VL7R!un2ygWGq(*ten2ZzZ)@HG02t>^HN%lvz{P3 zo=Ax?U5auNSIuL1&SN|54#ja1*j{{os87=IOo8Ma4NUbAsdG>+rr>MS%80yOwkppz1H3 z7W){FcE`eqbJ?76oG_gh;`Q~9_Unva*KuiGT|3mUQ~TI^`(iUKlB*Rt>UXgQaW`q9 zgM+X>ANyi;SnIoT8(~sE@w#^x!;%-%umjg`D!+i)`lo2w}txF~5oAw~0uO zH0Z*(+j1=%DvwlP?sB!?_tl;W&v$RsLi)7;YmfZ&#HtlrdG}4~mq=)N6;fSUux>TX z3DJT<7SNz*d#r08pY_*a#L35$w_HSR`fse`Ubt2t9IkPl->C(e;Tk;%=#uE)s1MqV zPcW+26Ck;>YV&(G4{%)2v376oKNrLzzDP(&kh&mgN$f)J_CnNRub%9VsVxE*Nc$FF zS)6_suBzCyBWOfxU3!B*-B9-gKZZ5j>jVY4mkKScn6r`)TW#(U-|iu<7#o~kHZ4w5{q=r+6{K8zSN{{WdwLJp+1O7SF##^;47 z6}k5#v<_XSSuP8Wc(557%+*f2!)VvC`ZVeZHERbq#x5QVrFrI)b`B7MvK>!Z2%t z+ktM|{jT_z)xLgKm>;=;YlEd~Wj0!;*h_#6Ye9K6PtEgtIV?{+@oM5Ij9j#FJ8eiM zakn2DC^T-I7@EVjd+%1&T;JV7f}Vc!r_SO%Eh<`U)aw20T~dsWan!uGS#k4pSW`o% zHY|fho`9K$A?#FqymPUgOu;&rOiWR%8aQUDO!YS1-(KXy%qP`NK5Oft5+5vap-HPm z|0}SM|0N^fn#Q`{j^Oh`&&k4Xmk@dKh8MCjJW$-qnD88C=Q5+2qhBrye&^YqoAbDY z@R>Pod)ThHb5zQGd)yUfxujWF|M54RB}(mSNurgsS^!^Kt2_x5h6mT~kgV_0 zI&*OeyhYpcFdDz2moumEH^*z+tsY0*E?I{MYLyM2r6J;m}SmNm@LTNE8_ zW%jVItI|rvZOL{9&`S1-eB2HCi{{!&5>e8a)}G}Z6`CrG1GT7BlgLYF6YTLD!Y9+F zd)=%v-u(EU&IP*zSHiTB8)5AbFvQBH#wSYd4_^jyoMqrFF=no~Pj*Pw#vTY)cPA)q z=3c%N|3uLvO$ntw?<%H_c#?dQ$Jxi->-@nK5a?pMZT53ymx#3EG!tKtiKj7Jfa=E~ z{twB$x9W!EQT-i^LjXeoFORK-2Z>A#`Hbb?p3_eqA8xo5+T`?Wd$2$#gU%0ae><|eIS78iq zW@BYi_E0Wiz6>aKf->vx(d1045omG#&cR_6o2%F=)+%8tQhBGOr3lET$t__WX(Z1Q z3H>lHXBEV=?~TH2qf>egYtZV|e0TnTH+TJqq$@Yqf02g#M||n}FQSk&M?sM-^pBxg z4F7EY`DeXSIXy+ zI$zQrJgFttG|1p>Fa)?0!jQS~cH8qNODSQHVquE2X!2ysZ8ugtte+E8WdXB8w)|(! zF2j!H=ND^kUM1&MT4t=QFeUbR1;ZE*uQBFekZX}N%Tr@ELfG-oeWWH1vjWIP?qlJ((Ste zYxfJ7Ejx`EExY`s$GeO61Au97uU7OgyN=9YU~?DRkE_R8_5()7-M2eSy$kmH7XW*! zn>K#IrtZ+apxzM3ALn)#OIk>{Vqf7XfHiCb{<++;df3?J$@%aOxab;G`|y?nxH!HM zY5uy4GAHe=-+SZ8i05p`=nW>Hz=i9^Rlnd~3>xt8F&2$Grt7C!`)=iWWuxGtQ)?>jsY`o4jD!2-VB z7SuPJZ7FYUp47v$z?9v!j+DD2ol#FhUtz$ow05J2vfXo9#zU@Af!^rV6Zawiv_9i< zZNcFc`0y%Q(*VBJZlx*q4mIrkGbE}0;9Uty?;7&+V?Zw0TC~mVjpz`Ju^~Kp|919v z`XdOc2J-FUMYrHZt0|zRu%(bt?BR31Xi;o?ef9&b81??To$$lid@ie(*s||*V(m7s z6AUpx(5T-#-?$$X7=$u>Hf*o6!Fu=V=W9Hwm$6x&ad)gUez*Hu&qyRDi2Qn0FF{@w zcHG#o_v&YbNzWN}^+O5vAD-f)2E^7IP8*T!y3n_`gbkn_@oq0L;ml5d*k!fEc9=gw zf06%wmhF&Mv;fW#E^qcF2v(0eoIUcfih8$E^V*lk=CiwKV?L|weLwanh($*D!Y}3S zSzag*sX5`2VOfMa-C?S`&`<1yL073cWlBhG6qH|U@vhCdyfN-;ESDIhH|mj|M$^5h z-2mjT(%ArU64#pja>5?>tBidMYK?shtcbmO5}No?Y33KGI|zD}$9_2?G0@8y0nR&Y z>Tr#N;cPHRtE`A#J-9&gb(K%KURA%|H&pvQx&e`QYr6fQySaKpV~BMG{*RaS;)Jq$ zHbHRzz-q^fdNI$|Gxqrpb780bGMaJa{>#O@-jGLS#+^@F##tvYVP9Bf_~jwgiCW;; zdvl*(7*xZ*@E~%`yQwwbM6!D96XYed8ql8q#-=yrDQGzL_?+r140b;LWzz7DFOVwA!D%8V z$e><1|Fgf>w#}EcVeytCy@$~rWyB#d!WE8C`(y6ry5cwTmHzC9WI?`gvC36<-1y>O zp(psJxv!796Vg4@BDta`m0>w{ff^SE)PPp+E{Wj}1QPU(?28%~8X@Kxq_0W?U)n-^v zlOm>#GGc(QRbXB?qd7r6c+GY>DJn*<441mrV402F`>to=B51siAH=H@f#=bUoyWuP5jR9J@Bg5`J=rdbGUOo=5KxdbBG) z8u#K6YPB`QDMQ_|&QU5Mjm42l0+eplhS*AdC?IPjxv$) zF1F#0>mHh$7Y}h~=h5h?wH|X0HLfL6RBA0HK})Xt(dJRalnn4^Kaa+~FbXrRdfs_> zonJU#2vT)+?Dw{AY_!(Ci@&D`&!%0Osyp%Q)tjTXXrT=6QaaT)xHvfcAx)ruZN+qo z*9o)w!?i9YfN^aJx1Ahaw@iA8HeAB{SXBFVP0nG(FC}qL1^1g;Aj>U`h>Li!(Y#T2 zB_STqWp;VP<}^4U0XfU1Keqk-?7PJ{D!1*h*le&`0%zg?c}VM!BYxvr@+ZMB0Nffp z7>Vz^%xHX`&C_sx1M#-!Kfe?!RIJS8aa3T1kihzpuM%;twQn|7d0L>bXA>s>JR1_D zU^hc!;4(NY?c%c%NLCpFv_cA?<90Scg3TD3OS7syYz1wk2AnwH%55lS%VXC2TkZQK z#ib}Prk1`RCg_oyC1%3;W5o&V9fCuSbqMPaHU zeYiJg+=%QycSNJ|N^JWzfQkj|B&w5$VBD;dJiW?JL*Tc_d4nOK1c(o<{L>L9*WpoqHZJGHUp{1gz%hbvwFX-m~6zLrCb;_`Kp{9tqpfT2lBQ5a| zLM$$)+_ab463J4UPZ)F;-A@3RfT)Ihc?Ct+EDOKv1M;X8yK+DY=Yv+>ubHfKS86Lsce zywaq5uLsYTvm=~0EBElw!DpyKu*>t zd>6_*cbH)lE9%r3_=ym7N{7%$Gyhw$J;0hdB*9qNr4`}P$@SOGXav$pv z+udMuQmFuf((E0?ycdc+9qGirmTWorU*un-i`d>wfr2JFL)!yz%LSqtG;~HiIAFj5 z0KlBn=3ukZIKSD9-Thr3rt3IUwL55pNWOqWLbcRi1F0X5g5QClWcO2arTCRgmX>LZ zPdA5i!(pj_Lt?L=uDvb?#^E0U`MQoT1Nu`;p1b{`grSwic&gL@6%h4-Zp7=L!<{#C zU6qCg!=*uMps!U!PKoi{*MZ_Av(f$=`t5eBE{`Cvk?}YM=@E|wf6x6=p(3uIN-MI?RZ6}LRH7Q`hL|c3 zojIl5VXJVvqH9|Vxz;L{jiY0Vhet|B$k+ma=9fC0h01rYX72JIt!+-FwJYdL8(2xo zg1!2`F?AA!6qjbZ0`*5Jg#(cpo$r=tgetRNncojEu9{+QTF$3vjM6p~z3s>3)vWnF zR^&rjK3(9vW|rc9?rb&b%VFVe8MuJF=;DFiR#$V>y{z2=H+zW#5@vpBcSp=M%(?ve zQ)+YxD0`@W=<<^CRo~FPz;B*C4AA$TGQDJ9k>9Y-?LluBuMWE9FncwmvT%Xs9O{^o?~ z4L8S?AI+m~oLKB?Is}ih@n$_V^>>O2%jNZvwDWjm7?idqU0BH$dl5s!b-S(-)v$;n ztZc2T*eRyCl?S~TQ?3M~-N#8B#kheAMH~vxkt>vS((D~DfJnmPDS<&mzAe07Dn3aS|h zdt7k?3u}YgJM@*Kg!kqyYr>LDK!%uK@Mt163=ka_>`GuYSz7ZICQZNjtkg)gM>i6w z#z?1cWSN4dhxC;>lpFpJmUJaY{VCkN+PxBzRG8QI{mH|%LcF|@>g49}3fXMQBU2n_ zB|2q;-D~4^{6TZ0A~692hLYO;>CrjuuA@Se5EXH3J~h6ogMH+qrBDQZA{Q+yrKbMU z$cyoCyvG=M;{jV8x&Wv+#hD_bE-W4y02|y zY5UqbWlU9W2mg(=cM7jFezU(DHBK7aw!LG!X>7Z(x#Ki$Y}-y_+qN1u+_84>=709i z9L+VqIeSi?b$DOjb>p+5JkJw?E}gi;$)zN>1X3&A-X#)x75}vjgF_z4C1E3{Dp+T3 zol;dX{L5PaW3UafAIrABXV3a|q{^jNsSM_Cby|VQHa> z8D9}N#9NyV{!m~r!!e0zZB9Q4-v`y^@v-AZ&z|VH^->>}a+D>ln`L}qMXP-Bl^j?~ z=?gub89mmstT&`{glbNIh_`)RzO4E+)?V`IGahfIn>G%nVn2BWAD>!Z&byb3WIa!E zO$gqiIaw?xh0%hpn*o$a@(!O=Nxjve=JxZ@u1Zrq2pbhX-3+}RM+rv~f^FLA zL^Y}m!V#u;Rb7cobhf~UlPjLN9RIAfVYK61_(CBl*dzH%e0MS}Q@xWYpBHnr*C((I zzE7|+=O>P6Y1zDB?YfuFls8*GN@bL^tcneDdsd#KF4ze+U^D#ZH9rbb(u&dKIJ{wLTn(`fVte|^svw(@dcSLJGm@%jUqZ`()}S> z4F8q0*qM!Pk?u4w(4eG%@gL4Ge1)96kZwqYVbcX;>Qff{UV&L!F{122Q6}U)6aC&e z#!2eBdZ!Ibfd`*{G;cn){oNlwz*yY4@}!;wi&26^FU(4U)0fP-KE|tbcd*0X#*K?fu5m@HFPas<+!X)>Dq7$m)TJE_GHZC4OupGcP83L+W%koQ5%KK76X` z&QrxZmuu?>VJxseO~yo3aF5zj{qO1g{iDy?TU_DTdrpfo+7zhDe|>Qij~KF(1pHtf zsx9*kC9{y#Q2O=)@!aPTD2N;!y3<>IeGf4+S~Lb0poj{6b(8P0WH3||yHCW^0yWvO#Fj-RI=pPiI> zD4EH4&;E8pcwk6o)v~(XzDL(c|ROpyAU!~7-qYwA|D%F4Px4`yFBmC z*GrKl!CrWhKC=P~-K;1!Oa08$lrG;>nG~4YnDi!LrhoJ?CZRzs?om&>Xp4qx=SpaA z=wotm2~IYYM+lp$VW$Uk6wJ8Gso9dMH^Aa)}omVI{epCo;0g z4pT~}@AuzwGQ)KY{?au|kzBPN3qeU_F1lcTwVpSgxJg|sI zT6+RxjFo_OR$(s3pHU~vqrz!r{_76*7yHsq85qIuv?}(^#~1THS8A9q)`9Vag~goj zX(`5r%wS<RcKdLx?quh1NT&>@gV_T!=l)UgLjHHR9R`&(vC}0 z6h6wE7WfY_e2=W%2IQ%!P1MswnP)?~o|0GiL&eG54?2KARfQqTCT?!6u*SB!I*}AI zkUOoM-hsVU3o*=Q9NggaoEhdJ>-8szr=*i(9E?>&>&c1jxlrcR!YwR-*M(f894;PA zTebsF5<4jp=Q%|Fc%Iy4P?>J&8cax4F$fkIn_cc* zwogoz8?i6~A*2utBSg>FPH4}J$6Sb`Ko$s>-rTGAmB1&A9&_KQmA9A~fr;CXzt0mc zu1a*$w*mp`yHk97*WVmhZzkg36F)z_c6}I?hetfOFnVnRXX>_b0%3MhwcZhhjuj0a zEqBd(<-=q^SmH$>xnaPSU$32b(`5$Pyvx?NlOFS5o)-|YUqD}UG-se{A!{I|1DTdx zBJTmy`!w3`oFE_nU$4#?&zLhCd#XP&a2NF>q#5F7PP-r z+5?EVIQZn79ACqbCRcl?$ zFh(yM!H3m}YdR0_aex)HCyJc+YQ`uMKLhF7bI*B%XWp);y>!&14| zoFrOimXy(HP0x45Wseq#=bIh$>kii>&$!rxtqtk1I1(bN4-Kg?2e4GcM^|Cdu`#jj zaAN1XEHTh6>2eFP&~@52x`%|Sr)O&41223cWMcvoB$xi`?2|tIc?(QidzLgtl6!b< z+6g*ge?BIN-eFqs5@t%&cSwpj)-~UIR!TqjpTRv8^^e{OWovMG#2tI&*cKcHp-*Uf zy~BYV;^Mb*2?||ui3%SN1WX5Sk2~LE*cy(NO)*DG@<66muye861Wc%zg;u$kW;@|_ zNVAtXt_Cmq4yIubr0Y}M4zu>7qbsu|v-W5>@9z0i+V6lCKJ$w^=);k%pqn>{l#LFR zJ^$qT;a1uwyT8}cv-qDKTKnU+aF{J0uwSGTDEG)K6T|KD5AJD>#00p1vPInut?5R(Cy{@GK+#30yVV*b=0TB z9-E_F{IL28Lpct1ff5w zwck~A<)wKNsr2_>;?p={QPhf5n=|)A{t+rb&3Um2GaaEudGSi!C!Ljl4Y>{GP!q2A zTM&%O(a2AsNs8)*#{eN^HNq)}IOQF_btm7JQKvM)79JQ^_j3H^5V~_i9~eyFBC>7- zFr}bInPUwFQne5o!@R?O%`rmsOu90R#dx21QyTEJSDogpPSn6oIYL!p`h~T1qGQTa zZbrksR@1ak+N7g_^ae^JWu+OE%X^(|tih)Y(28(taCb9q@ptquVMb-%31(DK)LB*u z$qUWIh>c7-|5|d)zaEcV)Ng$8RJ31rCg40CDv$BV^>ULZ$V=JhtZ6DOwh?Q)CrU&< z=x$2EIuhTdm|2+b2(fP%eYGFq+9^-P-)*)Jr(^6OSvOu!kb!hFAc&BP}s zj9nRX8q4A&{yfWGj4fZpMcW_1@z4J6iW6F}lJ^dJb4e+bPvE=^bj6ZbQX{3OO;kxW zK2TanUeMQ7T8sw$wGBEFdc5DOPJTcu8_wJACsA<-VH<4&sFs^X&x zen$Tc4@{&$(9&k(O4rrXDqn=k?$k=AgKnm#sl@1DSlVE~@G)!F*$`}N@=e6tXYCv&YzfE#D=yuz0t?*I{_jpj>NOK}W z;a)C6`HVnyS%B)G8Ls35xU^!CE`m&CLss^eYha}>lBZe_#E33>fQR4BXN!UztryLi7F9DeI0SuWa94Ey^&)|Jo>cDSkC5q7%W*87p1SvLMPS-K#{ z)%3!u96yktsG0A3Y<>I<&vY-FB8Bz5xSLJh74P_8$gL0}{v=PF=0Dn>*T$PFPoOZl zy`_O-QS3akysuH}ny{Ec_?K^!!F%r9c4~G zV_|i5d#oCQF(lZch^Z4r_v`kqgRjFAL{$pNR-tt~}FEx}CxECewMMSz4 znaep}lw=|~?fytF32Kp*I6^lBF+2omZF|-jr*ANXbMW{PpOMZ(A$kGK`DJh@eztMv z>$wZW#Bh}DP&Xm?R$6_pP-hZYHRh%hKp>P~V8i9L-huA@WOAd~UJ3 z110W0+Hyad#O!mo+T?G>Mnk>u$Z&eqi7Yaz9ovW?mdoYvt?0t45j6~8i(ZpXxK5_V zYgyd*^jQ7%$-0EN)I2DU8s*^{V=<0k)R4ehPwxB{kkyKkIIl$8K7583y`O_9O}V5G zf7omSXWk%;)nD&<3MkT~_1(JKtRiLxrgO9?P$76SVj4tK-!SP1enT#y&B{NYfEaO| zUisWZav8A>3u(RbjQ{idD#0;FfH*6493#xV*DobN+8coaw91dqYE+I0TdsC-)OU-kae2YB}XJLy@%>d~-eI}pDSg_PYbUwWBCh7a0>r2jg*>YEN7^fsS* zK5;a5>2v1OVKnOm_q&MSh#^$;n-r~;Fg4lN)v%Dk*L}n6>5b)+5rtCqjdUelyAj~} z+y45STi%28bhK1&eqsB{RGLHL2TS=7C)Lc&)g%f<&f{<1W+N!fH!@WHNgbePx7fx7nH%+XjJc-ej9E(fzw+Ud#RbOYS}hWz?wEKK}F)1ol8NfAP;d zcrU*L7Tht>nsrPB4)vajExTBfP1HiCKoKBn&pe1N7gqXzpOQ}6{7!c3UibTv&tTO3 zUFHM~?+Ab8Oa^|mHNv{u5<9vzEe49B&EVkF=Twj{19j2PY8m!Ct5x4%BYC%(Y~I|t zc3`WZFKPEWH#7$yav(LJJ{Kre3EVaT;GUOj6G1kKE!-rUxt| zwck5zUYim~m@EX2BG+pEM6S*JS$fS)dhJK318VTtQWL z0-#ntlThvdE`PBWG^G+-Y(c`Ylx*i*TKJ6=pnpcVt}n{Q0yW(60zfrpS+=TH|e! zTH~IaYGXf&-poK#uB_6YGUIOHGGpOpoto17X5Ves<%U<)=JSun=Bz)kw&{OJ7M%?S z18vKuKSRhWQ=EFBRz;k2hQZT}ro!9$!^cd52P{LU#N+Z!$u?OxNv{VsFb~Qn!e3L=C;(w)R`}b^e}G<2jqn!PM&*R1Vj% z%=c660unJvuxa>J2uIrStc%-xI`PU!_a>>n`(~&Mv_22n+Fb#8aUV6u_j&Q>c@|zJ z%*=q@3=l?EurAEVFwK)fad@jg(gi`#O!`#Neu{7ZClrnY=9uL0+ab*1Y)O-wnyG88 zB+T)npACSTJ=X!gyY%El4BX;f`vVuv*MK^gW`6sma~URgLU$4Olhk3QSOE<0hlO70 zd*JjMpV4Tt3vyw3{=U7CE_zRXdU`5RNQ|&QGS4Vbv4%D;AaA?EL;)@KXH~R*h;7rqdW0={E9?~d{##cDgr5ii zx|ocD@57Ptr`SvYi9@XEgIJtZgZn8NN8Y`O9w&jH%G}Sd;KB@h{!>MGo(=v^P(-ONJlesRDiWd9Ljm~EQ_6M`u{Rm-dlk3_m zK?~8yHdQ;}mb19TtFLoJO&ZyXy{)bN=IZ)lnccas)=!R$Z}T!P#m!sfV`8OfG2~>M ziy|U%r#gf69vKi6dH1AK?J)sE_#KK2d3Nk*%wwK20WI;9j$Q>ECL&_|qJBM|laBF1 zl&kxz0^e!6)R1f7c#kf(jHL39{*_Qc?rPvFOA}F4Nxekt%SH$lB;RN#-JRvN?#z0i z1mu?)lRkF+4mJ_LV! zHpx0Xis$cMlPJGY@sDCxN?94r^th`c2C{))k*+$O>basAgjIiJU6sd;-Gb*^f%k_LADN&Vv7NBq&7k8Kg2T8z1DW^1?fH4Rt3 z&l*eoq&c;93byEdG-CYs(*CnYV|IJ_(AE{nYxJ3$tjyoe+;70f@U5#mtXape3wS@? zajLnzVwzt&uxj0occ$@tT7O5}`9h#^-EL77#Nu_j8cXsRXuF%xZ(S#J{~|IO>gI+$ zeJ^8`hr%NZtSYTpLD_-zV!&Mp4y&D*9bjc$d$g4*%PTH7zwIO>ku zr9z0xKu*S5uXJ{?LbUSBes#Th=#RTUk@m7BZ}*f&ts+jgq3(vM6ymx#n>6ZkOMt;j ztv1@48&8#9>GfIIMs+4P=VpD4Q3q-&Q?c;#vONK>s`2P)yE@Fx>0^#ElDCt?aHjk@ z*0%ii(4eTpa;D7r;}PfceoTSzv7#4FomG$!Qs@458c*gbY9HUDL0*(kWtMvQ52xBY!dm3qGuj4w_oYl&~PHm?85ds=SRw0PskVpE5Y`JL9 zR16kxoGw}RTUP5Kd#82X0iDj?X=?|1(`f-|m&WrP5BQv+u8F7MZB<97Z+5wx{-Xk^ zQW7csE1ifoC#^gX6EoCd=mT}3T0u-SyBvC5yNag1zu{J)gqVF2S&851PSVt9Iw_j? zLSQ4HeJY8$WYQQLye&3tYGRy3YMIuO0| z=-sH}$?+tH9vI?HiTUA46LCdW4kBMxE~C|>7Rpl%b2vqiIW|dn) zhBzgc{XHWKgdsY}8Vu^Ei^>qo)(cA5NMz)L;M(VvtJw^rzk^JOs|2!BDdGt*l?R5W z#Z$pj=b5QBbZYKz#Ht1FbkjwN$bcWeJHym;Eb-zZvIq=LYd7 zbMo0KtOUf4 zac5RFVLYj>ji;W9DVL)Z&ZoVMbGXEo(!g+Sas$9z3p-$}cx~~|fgI)MIGVqh!5OxG z{wr>o{dxJFc&9Kba!D0hm?zCI7&3D$I)#X|l! zz5mogc4_(iG+WUYrljI5neZNon;Nd&A1UdWntqBe=@07ib6Zc7QSFsmp?3;bO1N{K$ zFg#J+i_vQct;EhuMBPRL-2wr%I|D%i(E=$9zgXdq#tZj4Zk+J(YCL}nL#l?&0;wAS z1g0JId<_}jGYq`w{V)+K*XY00$mpp~e#nJFfv^lL4X|gpeh$`1cr@RB#9a7rVmSFw z+}#KSj-9bICv2t$QuLBEClIyA&c0qq{{pR1xK2MpI($)LRpQt>M{8KYuOsm!xq`l8 z+r8+um6mz86?w&Qxa!XQQ6%jXd3UOamg`aS%b#4*Ur!E>ILiDP zn8@{V#p^9hY5g;0@-uEQ;@y>I4dhGn?2@1O`kJpaUpg;){Ej;V4BP2hm3{ae4_O~Q zA{zip5?^nRdxdrxvR!LFjvi|Y@BA-mm%@E;-wKN!DS9g%pKxLmwh>2UNX~GVLYa0y zQ9qD9h_AiXMI%-?e@~bTdS)fv&Yf|d{eo9abAWkKch7n_C$}{ElpnPnqusTxbA0}* zlJA}MnR{0$_VbU+_5~y`#IUg*s{TnGvau_Q53%iI4kVxwUa&9E8u;3N56oo%jD74{ zRD5}3s{O$A%uIn@l&=SED_DX2CE@eUfwR=JS*tTNj(<_wYkf`nZorT7!6v`(o_R_X;y>P?8WW_p{`gJ#woOIXEk%`Ws+91GHTFCJ!jgT) zk>Q^iNZ32UNH~2*wlyA>1=Ietgn{-9sz8CzwS@peT{Abtxri<=WoaKV|WMM3v7{(Y**DdWCs z@*)j8wquB2)cR5=nqYW*pNjk8^!xnYGzFX}dUFOuNzk_^EO-Nb>4({S`sQcJf*fyH zMOHC`iX5MvgInPH^tGplcW?(NdN23Exg*WyFA0|XZ2(%}#x&a)2JHu#35V5_$;7@3 zj(WoG*PihzoZsSN4TIq4bw6CUo~j7cQOFJ^W^6~$hb^BI zIDe(z!ptU%tQP1u%|PPbR_R$H3&?%@XeQB?Ff#Io|tRnXlYjZPVUHSfmgr; zFY~`x@VDVw6W{OOiJoYO`JxjQN^M&oW=h$%XIx%_0F$4gnj?7kTW-YrpVP3e*m8QQ zuco@Q+1HFxcoc)J82kRwki#(1hS&#>*hi(H5TRkt;aaMnE>e0Q9wdd+$*v~b2i(Iy zOq5ol=%P{K#;@ThXlVU`!Pc%9K0L!T(1(HVhj{Y1Ngo{==+Gcwmz;4&-jQH zre^>T`2E|U%hQ)f;%MdT+pcJk*}0i7Z{NZ&@61d}oX16+JwxGX*C|fD%E?HTz8U4o1hb1jd0X3J>`@l#0xE7*YQ=}A3g>-4;I}R(SKc= z6;;r9{odzD#o%60!nJ#=*ikk%<*faTT#YUt+hC-|g3xkxJ|elHYMh3Z*sa-=3ER4e z*<|azc9XZzlr~Iw_Xu?!#vq#}xCN^xiAh>` z9nLvWE0SdcBbv~BeWP5!cB}bF$wSEE%I+W-N<4hQ& zE6F5cc>%cnDHLMT*C2QhSQ^RR6Z!{iXV!RU!h^c-Ocmn47W?~=iU^LsH?qP=rb382 z5{BexcD=6YsDtevk-&;5gR}y{bKmTQzi^B+WLbPH4C*YD;QIa~( zPu%<`_9B8!U;xzxKh=J>Ws?U|t?a1DuzICx&29H>8M*0Hb${GEy#k0=hAIxR!b?qx z?!AXlvc6%c5L%s8>txDRWrzeuWjN)_OS9u>P{<7I^oBRC5xiRX*5eZxR@t|C8K#c5 z1-S$5t<9Z$ZDbFUbeCdnb6EK1I7Ly^Rm5C{V#ymj&|&kBGHy?5&tL-$G1_`>#PsbB zmB^zA&#THg!QZQxrj%n@rWMDpm$d7p)cF~PGA;yUgz+*Ks-nW!G}ST5A_tB_#>l3n ziQ3nWqq9SvhVi)@Ji(|^k6i3Jn>@X3!ynCISqTpX)B26y>v!iO8@T`Mep9_DU|ReBH^6JV&GNcE z(Riq~&pV=dFj~U(GJdEs9~O8!Ic=&Y+SFG*92H9^4R#YU%28YGNK=bjegNQO#UOB| zF2-596MLK-uV1BY(CURTC2-9am;872yvdovPqK28nI`1h?uy=PY+mRFMKxk$qPNqD`7((GDWs(uJYu(m z*tyvu`|l#xn+BjxE=k+HB$V4#VBbg?c3{m9It@1yjxk<39}N@)(xxz%B!AwFv&m`j zmooA&l&TSimc2N1kwq!%O!RN|-^J2NaZoUob=N`MtyTn421$lF#Wi=iG<>fQ`YwsX ze9T-tb3SYBCr>Y<>;q%CgWqtYupO(Dl8u{s##v)&pO$Q})ER~|JT2?p>DZt6hI8<5 z%!TQ(=!D*W8i2utOgh4DDa}!;+d5K*2p7~qfAZyO5P#XpbX@yzkm3mSA7{zWP-YQk z)!M(~$UANnZJZsvOvf4)B{-!e$5*@@H3Ttj)~@(16|cf~__hLFUkh}+>Fr$!?rj6J zTDt5G)sm3qL1%ml5pXu%Y`;{l{_Kmy25&Pnw85uH#9IkmvCZFpJa&uQKJ}af?&y?~ zSY3YnA(mr?p-t6@1`~KH!b&ayG~S#x&mF;aMADmfUhR!Wsg#ub93Ramps^+L|mTIPnTG!wc_%7mq##2f8a6yb~@E+NysPo?i4!A zN%cznY$;iA66bhftN?fx;>?|n!RK|4_C3|4!ymMtm>P}1JvZo-EmjfroBf&RZA*)j zSCI|$F-zsCV`4}NLY~+clC;#ng}-6(Ieg)wnWqU2Cqwu6I5@z}#kL@gnG4L9Nk1|V zXPnIhABH>>ob*RvmeXEDmL@{wwqC5Nd`m}@|CO4c3Pk7pXV4k*jVUG;QRu>5&tBn* z@3^{vohgQmiQfBG^kl;fnOGxU35^Y7v35E4*XGMoLm`Foak9FT!V9CAlRn_v!js9r zyh>qhpcqMmvAcOHKDIPRA#$vR#TX|CwY?Mjfh1oXh~;)kYO$}dD-(`%D}1rmTPn2I zmFX%=wFi5T!qRnZW9wC64+=l~fOz4;Y8@(r=tf}*!8PF0RUl?H2VoD=WT-ODa}G^y zkwbefy5c&9R;m>LH0dXF3kovZMW2O1;f5&petR6TCHzq|6pvv~1xFA+F(2dKKfENT zSd*>!5hoSpXn{(U5-Bwt#OhUM-6|64(6d9THRy4p2;BJ0`*b@TIhkRmU11gZC&9m0 z{dct`h1Wo{`4}8oPmAyWf_VDgW|H1}l6wCEq8ys-J)yG2;B7}=xCXg}nrRJ9#woj1 zh6-5%wW5fM3W_-d=Dw!ChS(~Q&(SU4Q)85tVeQ(Ev%#-ZDFgYJY3c7%Kcl0F6A`uR zI}FG#C@#ur7u(Y!b#D=|7T%!wJGp{Qst9Hd6B<-*oVG;VZjfMj2kt!c3Y@#z7*FHv z^8v6 zj}#Nl_p2d^N6t#f(GoO>$7U6wBy)rVqv!;d1(5h-Xy=5wb+V&-Sc-1(S>tw4NN5LV>P_S1514jaQKLN$jyC04QanH z$TQx$;JZOFvuX)SUShkF+W&A}-{SuOOYy1kziY(E(ZANkBYycZhx=a|G5<~PKW)T> zYTEwPlg7%Kg)QHgHm$w5h*E;HTW>mBRT7_{Ds);t8?5efKX=PY>8^R4zTAEiYVo*i z-p9O#Qv1e2cAt;%J&?R;7=|7~3?{J52n?nED^>0HZz~8D_-6FiFA^l^dzn7dH7o9n zH30BbR=Ug4q}L>2&$8dMDx_hwyWsjnD*QFltY42zx3E4Hw9MX2??j-(XLhUuWG!^} z#J-)K*!h=B=!Y*3U+ke!n$bS|jRdYpzX45}VxCF^hYd*e_5 zCOrD2oa}r>fi(O{;rBl5ymRDNvnl%G`eg_9+~j;)^vpYO1=0h`0fKl#^oHSS4Suon zvYx1E2cz>H&)^a2RnPc*1l-ww1BBo#dButYqITjx!S1^6>P|kgqY-}remj-0_ zo~_GHZ@cf2d@TuRb5C$-$v)5m)Li+-JQLf}bog~=KRo{sIPr=<6h!U(`c&x7zf;-E zd3EpJaJ<0?^nso7aQ~g<3Om-*7JPu}`nw0^_Q@0W*(YHo_wbp$j-+)})afw-W&Y8& z_bgxscKge#BJA1+38N)J^c?a}5am08K*Wa;%{7*QwSINt-qoDa-UsADuKBxzTLLkQ zTY>?L$2=c!;udK94!nI;*Kg|Xi8^=l!+EA!kbLK#mwd@OEpQQ@bd4Kf&^PN*X7`Uh z6r8?Q_K1J$f#^hgN@V6=u?6_YjjR~o3hm}s%I?tZE;t^DYpUkFS<;LF9cZdImKB|n zzCPglxFv4G26QM8yQ>l=b&LtA=d5g*g~xfQ0tA;7z5Rik6rYfaF{7J52JQ1<-+;dM>L92J{ ziLk<4x3GM?zJX%=+XvjH-Hm|cvHT)bJZfy*;(c>#ogNCsecO3TOPqb; zVTFvlom^_cTkCcYVi{G!nxZjOzl%7dyFI~5-EXD?#Vj}D-VS61&AhT zh1X0yiA)LIZ)Q=2RN9qli65~Kzt?|T4tQNOYFOpB9XBtDP_EpSvkPyL>-5yJ&0b$I{thFJFdz zCs8lYme8F+O^6Gm^*-zu#h^=8j9e2VBas8fm4P^xH_`-A#pfGpCg<@uwNcUu(K5M| zScz$5la1@-W$k!G-;Ic@-j(_5!=^(9oUcTP^d^jI?esWe#muzCYK$wcL>oG2G-QkF zG0&>?$0E~m*j=oya=$5t->4?seriMNE0j4?QfJ9=C8S_D$EDLiBA%)h@r_7)Z$Nh& zEOOhvX4HJC|MTS{xS=UK62sa$dCIz=BB6zzO5P@LU)qGdPTfjUF*{>l;zE`X(*{R^ zj0NGg;0uSge9FEKVj5%Bg>f}yiWR=CPALCX{g}*De3Xr3%0RC?V`mj3Et#ag?&dyMwDrS3v$Raz zhjiieN-0O=hYyCz)B8vNCDGE?S}3e6{z;w%{HVtdUzef#dUpn6jLR5hV)eYv6=sOY ztP-u>@G!Y3VPC|WlSt86I*3Q(h$i)eW_>y;49nuvK$5y98tHy|eB-)<)$tTWxJEB? zFs0M>wH@DSuYSZ3j>f?+74e0^pNfGLd?9$2LtSzdzDWCGxQyh=a?}J(b>heUFj`?M zVJZ8F1T9#nzL@lJbmq;QyR-z28Lf)c71#=T>dW&8jF@yJ5Ow4PVt?{Dj>E>}KVe{6 zVPrZ-I<)9cb;c|?OG1SGNzL|Zpk=gEqr=d2B<;6$>+S8yFS5;G8!7Rp6lY15oYe$Hq}sV=MqaLcT*e(10OuOWu0CLNS$0RQMcU6 z)Ml&x#cpvYti0iy6VVcl7iljCnt!BFCM92M9hDi%L92?bopYyK&)jgGgRl$%iF zR2(EsME93#^8t8WNjW?%E&lx`B%CD1?Y49Dbo_?M!C^BtcecD0kH;y0c=i3ES5${5 z@cSsIeKzUjxE`0pEUzar&Fv7F`iA2sB?uw7%)1h>N0YsOyj0KtD;Ma2bnZ{pLQk)% zmXexm`b`Zu9kd@?HZRwj7pn>A#5h~AxJGJHj8#5bnFesOu7)9^;z5{e*l3~uJzCXt zF)kWtP-_;eE+}*vs-Mhnc9S}3K;ZD|!A#>}Wk6-(RoQ4F2v5nx3qEwycxg5(i$ftv zSrqh+>N)#2TOGbJZE=N?ImtSbgMwM3OY3a38{1-`9uU4-38N$6`LC#p=2xm1%}+Jh zd=t20Tl>`)`ZZn5(@Mm8+noBB3O!Bg-K~V*nCamQk=I`*LP?ucIJ4k_SDo|`gE8uQ zf+DJ35R2(s;Px`KTg{k#z7sJ`)9y&E^LZLl(0DcW&CyaMFqJyaMjr0RJL=z_QVxZn z(^RkiVhp>F(rLe6l6x~*HOkczp6olq+T2`S#H9fB;S`%yUBCNyVi%7{eobOf&t|W2 zUBux^up6VIsT!2Q;77U4d!c7+dIy+5YVSGfv%$0ponq=E`qI!bS`kzU;_NmLiXWXJ zr%eC-=4|Gzx11mc#ZsBcs#h^6GM%P#8MNp_sL2ddFD24D%7it7eaXf``p{QrVT0Ou z&FN88E+!XIjZ{eo%#i$*V&I1r4M88K!{iFU`XS1W|J9K|ol=#9g68&LzGE*L&MwQq zuj(ch6GLPhn~^7&`v^;4`|*gETO;WJ9zTbdhDDn-mDXXNY3?QXyLq*0K+umM`DEXT zHgXEr=M1N%^Vt?0pFj)xqZ^Is~5=>*8y)+1_)tE(+d8bb=?twiw?I8v53 zjS05t3og8XRQ9Scz75PxEFFV46SE+M%>D~x)7btQxS|p_75m|QP{8*_u_se>kZuBz zty>I{>Ps4oRAqy158TE-Y(&OB3jDxvdBs@CZ|>uLA75ZxY^}8oVS1!QM#?@2X7@<- z0I>-rd*#BP=_g4saf2sXZNpczBQc}~zy9O}J^4)ckHv7-k|nlTEgkvqd6?lpafRr6 zYgG)RX-{h^N!m%~^m9RwP~;|HT)oF+8ZUT;a9g9_tyimX;710<)2j~-uuV`ptF~dg zdF~~=kVd!$Fu9&p%V2AH#E4ieszqq!&3#29;GBPDnV=#ZPss2@|4d1@i*qKTF9}Bq)7dp6>)$qm!9ZOv1I|WnOAj4X*dc^DL1=b=J?r6+m=Y@{SNy- zx+AuB{m&=FpBn!=W3t@e#iaUaOkV!0G5K$L{|Cn8^U4paMm@ybo%rYD-QB++Opqn& zR!4)tT|-?XN8|ZuXW9q~DZ_tK`1kGthvc!V|(H$ugiGV>c5Sr{!fdckkf z47i?j=Vq(Z>X!=)AlzVB&&#<3ySVF7bVX=fp5KY_6;tUJZmbOpV5j# zw@Mxu4yf)6{Fd!wGb3x;kAWnxLK}+LZz!MhX;q%XE2;2>eWbZR6x%O+53*MfPje9*VQfgTb9e> zXIO9RZ84S@+xs6x{@tlZz?j3h&+t+2vAEpF1Vfg)A6Y%-Z)bpy+$!OoxZz{)uUbSf zEla4-_{x;u!A!kSBv>egr>$pQ`qeM}y7DK8pz1@323eH9Z|`5X`A35K{cj#4{cm~(ZwB55Hzb6IoOrH&7=>PQ#`$#S-n^R$uf53% zFI~7)eTWMW-SY2uyd503@l{M@^F>-J$L=v4kG}I>=@?N+yOWI1@mo3{fIM6VcTjP2 zr{Z&2oIef;uWwffhwf3A1%B+`S_M3ae|(AQ@eX*!BPQ*3u8y-K$)xS$K z0s}8P*+uSekG>p&gaN{trB5s~s#)M$N|Lcepi7lzv~kXP*0k!Y<&7C=4p9AwwBg03 ze18iDRDYnvfmxOPQILKR>G8|F>d$DIJim*smxc$XwgOOpWcvn!En7cSi9b$BF9v#$ ze-LlYEM44Br)(Hn`DpudtSbf$qvi_+Xn54;E4JyNV-Aot5zN^idTFw6@1B0H%pY?A z4Tn9MOl!41wkCKZ9_U1y4?KB)x%ZIT6A8NjrlmW=dqD2bQVW|NZhX-#A?^edo9X7y zKG=3@-*RbYg_wR7R^+XxT6w@#h(EeKdWp}zJ7z7<#^y00win{S9Cnian{*LQ4epo~ z3g(XEW~TiZtBr6M$UsYy_W0WFvzc9QTJ8jfUIP9R^ieJ0q~X-Y@fBh? zL7THZtGt1*DrlWr>&wODVc|bF#f6A>tqyA=%jW1>QdadrGi8wEuTGMq$j zKJ>(r?O#Rg5WwpL*~(od{dQhzJN2Q`lF}nBJqwnoA_C615J$`Gw%wO}vERmHO zMBYQ~h{X5^il-_)L=zT^w-OB}6054!2)GN=xdob~hZ2@doq^05cS$`Vqcy}Y`d7K> z&bqXD{QOjDV`;f(jTS5xAl3OQ^8>{#>LXmezmG2tOn$?ABL}4XsRJE%Rvb}{{Sx$S zGCRSDB9}eETm-$apWx^n%mf>et7&$_))Uq2G)pY1T#7D93=V2QS22bZrW|e=o(>7!77JNuphq6!Jn5=$ zXwe$#8^~3s+4r~j1RItrtT9LzIa+MH3?dK7=A%N7mKp`tWtCQjR_NZSoReZ>ZOpMWn`pb>%|tbs$BFjg>Vlem(#(9+v9J{ z+#$XSYTEoIT$s%p3@!-XeQ=mcHo-$3`Y3bZ(9(og*Y{Ymf*7O01Q#|h>$LKbocyX@T7(~O~Rh@lobV{&&$NJ{TEx~Aot=Fcf zmEqv{hr@@8MX^Wqb@DKOo4t9zSUoi^776^G@3%qr>8w|17QS8VMn5(Lt-JyUL4m|P z#!84r`Ednf2QqNA=QhfGPbg6Yb7s1p?O%m#i)O@K%;JlUtC^LFlTN@F zBHkC3X6ZFlX|s`^=g5_eE>AWsJ1CvE2N}um$f$&qCXGC~$rLHlgSU$h1vx&GnU}|N z9c=SElDiswk*XVRE*f>y6ft>xMW)ksqYQeqN4Ko8+_b!H5C-Y06{=u=e%}e@?wPog z4$%)eRXdL&q%V?ZOKKLJnu5Ld+)#|wU5okxOPeL_D#acFR*J^3AU_%M?`eo(s7kq~ z6?&D_l|+f8De}4rQywVEyDQj>MQfl)LzL*n`J29SZhh*A&XvpjXgNBRQQRn)4cPmNK zq!R7MLNH4kh!>a(t+{nF!%=-!1CdJJC1DW&^Cm`)_GGsP8Xh^r>=kKt=FGhS<<_pb zVtX#AS8FSa*V{S4UNNS9)xa+geU?4{$j}z-TEo`OsCFtbrCxoAG3Vl@MQ2O%NTee_ z%jvPVB>;zoGL>Vx?CqL}#R`$IU;4GNTCYXM5;7R#Kcfjdp889@mNKWJPbMG0Lxcp52muQlr1nVNq7 zhE(YVZn39Kc87ETB7#RHg2#0qK$d{4>H)r0AR~njL)lXZw{sneL86)TWdR5ry%Deo z*yw&y_qsvulSkRnlYDQU3)~65c2yK2^4lP${?|a&z+DJI)Gx5^U^g&-K;Ng%J|H(B z-@($rJ}qtu%DZjD5M@Reg-!j&<5stUae=Su-}ZaT{f9%Nx?hO)zwYC>x}iI8DQUsg zH)iS97oxRpPpK0Gxy5{zN$X5O?T zx1hPR-N5fOa>qo~=1yY1iC?@r&>Z)`^~eonbsJvhj$?LJgEWI|kED5f8-9439BzY5 z_uafjl`fweC?oi-3{Ztee@6C9_Na%zZ8wKbwqC>GY!QG|L-^W0`2lVHJ?FH3)~$0* zuP9v}s;FI0Ve?o?WP9OHV>`|o$>8NnVe7Ee?B}Ryu|AwOmepneZU)ku&gk&|(E0a$;dKQ*yrOrG*}Z=GsuuZ%+Yg8vEQs0VIK_O+U-ar@@-C0zYPPvG86J3xF}k}6 zFuHqUxCLFntu+JR&(YeO}f5 z_1eMaS?ft&~kboGl$ z!#!!!7MCG7v5Os)MR(C|MzCLrbm*C?M|YW;^VYu@UJ0%RC9yl?p*z!#F|?*Awv(h! zB|+hhY9&Ttz89r6##BU_BZl$#Sv&$7AQSAY6(nU%DQU61OQ0n zgxJg>nuZ%MC%!B`A>c1jD%U33tdX&`iZLNC_vI1eCn^NCA9)*ceJC=PnE_V0L}%l24% zwBDAVPsevtymnG(?e&VP&sVpF*sUg-f8=g=>v;0qGeq5xWni3X1w3aaxA$XW=DoY@ z?XB&6X>&vKd8SiE?+H4Y+*q%#rsrpG`##&Bj>Pjg`tw&V2kBG;(1W9p@+ueLfL-0e172m9OXSPv$}MRN` z!NsmuE5WYF0SKpT*{PWjrK5C|YDhnCqOBToRtNeC|KWvoivjN#Ol7oy+9EExf-b+u z^U8MJu&q_FciKI7C*z*b+A{`zEQ5FRK_5=Po#vOAe~|bYwAlH234iKmN3Bz}1)lZ3Y{X_)386GQcbt?gwu`29?g+D7-Dc z7BK}%heqLsjwCj0tI)fMwzN8TdBSb4nYO<+1vr+-58oH151`)OB5mGSG#`5&o2 zN*LN+k}`~e>9*AOs(3m_;W;;XD(TDLgaQ|s;y%`MrGT^lL%iodrCHei546y4jDN3% zp7z%zR)2@_djHoj-haXSPh05!6UOWK6G}jfx>jM-(BLmFeJSAELOcx2>m5z%tb}TQ5^I zfPAW%)6AZqPx$T@SX0bbBuCg+NcX2N)ia(4(o22IS9C`dZR*C0@#v{(9LmT#SqUJ1 zInGUb%B!)(FN8O8gXR(Hj+dF{u7mPQj~L6dle+bFD=GU5&k^~h>%yBqRcE7l?^AsB z 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 G@BabX>!;uV