PageSourceSearch

https://www.meteotaranto.org/ajaxWDwx3.js

js meteotaranto.org collected 2026-10-04 02:48:01 UTC 134,505 bytes, 2,690 lines download raw bytes

1/*
2Version 2.24 - 13-Dec-2011 -- Dashboard -- for Ken True's Template Update Tool
3*/
4var ajaxVersion  = "3.07";
5var ajaxVersDate = "24-NOV-2013"; /* Release date
6+------------------------------------------------------------------------------+
7|    Project: Cartelake/TNET/Saratoga PWS Website templates (WD)               |
8|     Module: ajaxWDws.js   (packed version is: ajaxWDwx-packed.js)            |
9|    Purpose: Ajax update from WD clientraw.txt for weather station websites.  |
10|Description: This alternative ajaxWDwx.js script has been heavily modified    |
11|             and has many new ajax tags. Setup has been simplified and many   |
12|             new features have been added (see Version History below).        |
13|Discussions: For a discussion and new releases go to the Weather-Watch forum: |
14|             http://www.weather-watch.com/smf/index.php/topic,43859.0.html    |
15|    Authors: Matthew Romer ..       http://wawaweather.net                    |
16|             Kevin Reed .....       http://www.tnetweather.com                |
17|             Pinto ..........       http://www.joske-online.be                |
18|             Tom ............       http://CarterLake.org                     |
19|             Ken True ....... v2.00 http://Saratoga-weather.org               |
20|             Mike Challis ...       http://www.carmosaic.com/weather/         |
21|             FourOhFour .....       http://skigod.us (at wxforum.net)         |
22|             Jim ............       http://jcweather.us                       |
23|             Scott .......... v3.00 http://www.BurnsvilleWeatherLIVE.com      |
24|             Rainer ......... v9.00 http://www.bashewa.com                    |
25| Modifid by: Rainer Finkeldeh, [email protected], www.bashewa.com            |
26|  Copyright: (c) 2006-2010 Copyright Bashewa Weather Station and those above. |
27|Source code: http://www.bashewa.com/downloads/bws-script-ajaxWDwx.zip         |
28| ---------------------------------------------------------------------------- |
29| NOTES: This version of "ajaxWDwx.js" has been modified by www.bashewa.com    |
30|        To see how changes to this script have been implemented go to:        |
31|           http://www.bashewa.com/ajax-dashboard.php?sce=view                 |
32|        For available "ajax tags" and descriptions go to:                     |
33|           http://www.bashewa.com/wxclientrawparser.php                       |
34| ---------------------------------------------------------------------------- |
35| JS SIZE REDUCTION:                                                           |
36| If you want to pack this script after you have made changes, go here:        |
37|     http://dean.edwards.name/packer/                                         |
38| ... make a "ajaxWDwx-packed.js" file and change this line in "top.php" to:   |
39|     <script type="text/javascript" src="ajaxWDwx-packed.js"></script>        |
40| ... This will reduce the size to ±34% of it's original size (±38kb).         |
41| ---------------------------------------------------------------------------- |
42| SCRIPT DOWNLOADS:                                                            |
43|       Cloud base graphic:  http://www.bashewa.com/download-cloud-base.php    |
44|     Gradient thermometer:  http://www.bashewa.com/download-thermometer.php   |
45|   Dynamic condition icon:  (not yet implemented)                             |
46+------------------------------------------------------------------------------+
47| USAGE and WARRANTY:                                                          |
48| ---------------------------------------------------------------------------- |
49| You may copy/modify/use this script as you see fit.                          |
50| No warranty is expressed or implied.                                         |
51|                                                                              |
52| This program is free software; you can redistribute it and/or modify it      |
53| under the terms of the GNU General Public License as published by the Free   |
54| Software Foundation; either version 2 of the License, or (at your option)    |
55| any later version.                                                           |
56|                                                                              |
57| This program is distributed in the hope that it will be useful, but          |
58| WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY   |
59| or FITNESS FOR A PARTICULAR PURPOSE.                                         |
60| See the GNU General Public License for more details.                         |
61|                                                                              |
62| You should have received a copy of the GNU General Public License along      |
63| with this program; if not, write to the:                                     |
64|    Free Software Foundation, Inc.,                                           |
65|    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA                  |
66+------------------------------------------------------------------------------+
67
68
69+--------------------------------------------------------------------------------------------+
70| ICON & GRAPHIC DOWNLOADS:                                                                  |
71| ... unzip in root folder with "use folder names" when unziping                             |
72| All of the below icons  :  http://www.bashewa.com/downloads/bws-iconsets.zip        (2.5mb)|
73| -------------------------------------------------------------------------------------------|
74| Current conditions icons:  http://www.bashewa.com/downloads/bws-icons-current.zip   (269kb)|
75|            Forcast icons:  http://www.bashewa.com/downloads/bws-icons-forecast.zip  (1.1mb)|
76|  Sun/Moon bg, Moon ph x4:  http://www.bashewa.com/downloads/bws-icons-moonphase.zip ( 19kb)|
77|        Moon pictures x28:  http://www.bashewa.com/downloads/bws-icons-moon.zip      (188kb)|
78|       Fire Weather Index:  http://www.bashewa.com/downloads/bws-icons-fire.zip      (291kb)|
79|                 UV icons:  http://www.bashewa.com/downloads/bws-icons-uv.zip        ( 20kb)|
80|          Wind Rose icons:  http://www.bashewa.com/downloads/bws-icons-wind.zip      (822kb)|
81+--------------------------------------------------------------------------------------------+
82
83
84--------------------------------------------------------------------------------
85VERSION HISTORY v2.00 - Saratoga Weather ........... http://saratoga-weather.org
86--------------------------------------------------------------------------------
87Updates available at: http://saratoga-weather.org/scripts-WD-AJAX.php
88Special thanks to: Kevin Reed http://www.tnetweather.com/
89Kevin was the first to decode the clientraw in PHP
90Special thanks to: Pinto http://www.joske-online.be/
91Pinto wrote the basic AJAX code for this page!
92Cheerfully borrowed from Tom at CarterLake.org and adapted by Ken True - Saratoga-weather.org  21-May-2006
93Announcements of new versions will be on weather-watch.com and wxforum.net
94--------------------------------------------------------------------------------
95Version 1.00 - 24-Nov-2006 -- added flash-green on data update functions - Ken True
96Version 2.00 - 13-Dec-2006 -- --------------------------------------------------
97   Ken True -repackaged AJAX function, added metric/english units also included
98   Mike Challis' counter script to display seconds since last update and error.
99   Handling for the fetch to fix to fix random error: NS_ERROR_NOT_AVAILABLE
100   Mike's site: http://www.carmosaic.com/weather/index.php
101   Thanks to FourOhFour on wxforum.net ( http://skigod.us/ ) for replacing all the
102   x.responseText.split(' ')[n] calls with a simple array lookup.. much better speed and
103   for his streamlined version of getUVrange.
104Version 2.01 - 17-Dec-2006 -- Corrected cloud height calculation
105Version 2.02 - 20-Dec-2006 -- added unescape to set_ajax_obs comparison for lastobs
106Version 2.03 - 07-Jan-2006 -- added wind m/s or km/h for metric variables
107Version 2.04 - 08-Jan-2006 -----------------------------------------------------
108  Added use epoch time for get (thanks to johnnywx on WD forum)
109        so a numeric time without HTMLencoded characters is used
110Version 2.05 - 30-Jan-2006 -----------------------------------------------------
111  Added new 'anti-NaN' check from johnnywx to make sure full clientraw.txt is
112        read by looking for '12345' at start and '!!' at end of record
113Version 2.06 - 24-Jun-2007 -- added '/' as delimiter for currentcond
114Version 2.07 - 21-Sep-2007 -- added support for dynamic thermometer.php display refresh
115Version 2.08 - 07-Nov-2007 -----------------------------------------------------
116  Added useMPH to force wind display in Miles-per-hour and
117  Added optional Wind-Rose, optional new current icon display graphics
118Version 2.09 - 23-Dec-2007 -- added maxupdates feature, new ajax variables from K. Reed www.tnetweather.com
119Version 2.10 - 18-Jan-2008 -- fixed icon=34 for ra1.jpg
120Version 2.11 - 21-Feb-2008 -- added icon=35 for windyrain.gif/.jpg
121Version 2.12 - 07-Mar-2008 -- added fix for 'flashing icon/thermometer' from Jim at jcweather.us
122Version 2.13 - 11-Mar-2008 -- changed Wind-rose defaults to .png type (Carterlake/AJAX/PHP templates)
123Version 2.14 - 29-Mar-2008 -- fixed UV words with  color: black; for display on dark/black template (MCHALLIS)
124Version 2.15 - 28-Apr-2008 -- added ajaxFixConditions() and translation capability
125Version 2.16 - 20-May-2008 -- added headcolorword processing V1.0 from MCHALLIS
126Version 2.17 - 25-Jun-2008 -- added gizmo-specific ajax variables
127Version 2.18 - 20-Mar-2008 -- added fix for 'green-flash' issue with Internet Explorer 8
128Version 2.19 - 03-Jul-2009 -- additional gizmo-specific ajax added, and useHpa variable for pressure
129--------------------------------------------------------------------------------
130
131
132--------------------------------------------------------------------------------
133VERSION HISTORY v3.xx - Burnsville Weather LIVE...... http://www.BurnsvilleWeatherLIVE.com
134                        Formerly: Webster Weather Live
135--------------------------------------------------------------------------------
136Updates available at: www.BurnsvilleWeatherLIVE.com or [email protected]
137Version 2.80 - 15-Apr-2009 -- added Lightning ajax variables
138Version 3.00 - 14-May-2009 -- added many additional ajax variables
139Version 4.10 - 25-Sep-2009 -- added support for Nexstorm Lightning distance and direction
140Version 4.20 - 11-Oct-2009 -- added support for UV reading 0 during the day - shows "updating..." if so.
141Version 6.00 - 30-Oct-2010 -- Totally new format and new version of AjaxWDwx with additions and
142                              corrections to Version 9.11 from Bashewa Weather's version, now
143                              labeled 3.00 and dated 30-Oct-2010
144Version 6.50 - 09-Oct-2011 -- Modified to allow animated icons and several minor changes
145Version 6.70 - 16-May-2012 -- Added new SI code and minor changes
146Version 6.71 - 07-Jul-2012 -- Added additional Heat Index and Wind Chill ajax tags for dashboard update
147Version 6.72 - 29-Sep-2012 -- Added Bashewa's version 9.14 mods as listed below
148Version 6.80 - 25-Oct-2012 -- Added Soil Moisture, UOM Conversion
149version 3.01 - 17-Mar-2013 -- Added Wind Run ajax Code, finished UOM Conversions, made compatible with style-switching (Thanks Jerry)
150                              Filename Changed to put the version back to the 3.xx that it was supposed to be at and prevent being in
151                              conflict with Ken's version!
152Version 3.02 - 07-Apr-2013 -- Fix for FWI Image display - Thanks Jerry.  More changes to FWI (for 6 images and scale for 0-232) and 
153                              re-named images for FWI Only.
154Version 3.04 - 15-Sep-2013 -- Added utc_offset for local time zone to correct cloud-level graphic day-night switch times. Plus other minor fixes/additions.
155Version 3.05 - 22-Oct-2013 -- Added support for version 6.90 of the alternative Dashboard.  Only minor changes here.
156Version 3.06 - 03-Nov-2013 -- Added support to split out last Lightning Strike Date and Time
157Version 3.07 - 24-Nov-2013 -- Syntax updates for java script.Stefan
158--------------------------------------------------------------------------------
159
160
161--------------------------------------------------------------------------------
162VERSION HISTORY v9.00 - Bashewa Weather ................. http://www.bashewa.com
163--------------------------------------------------------------------------------
164Updates available at: http://www.bashewa.com/downloads.php
165
166Version 9.00 - 15-Apr-2009 -----------------------------------------------------
167Overhaul.... major ovehaul of script.
168Added....... fetching of "clientrawextra.txt" for history data (e.g. rain etc.).
169Added....... tag "ajaxrainSun" ...... for last Sunday's rain
170                   ..thru..
171                 "ajaxrainSat" ...... for last Saturday's rain
172Added....... tag "ajaxwinddeg" ...... for wind in degrees e.g. 334°
173Added....... tag "ajaxsnowDepth" .... for current snow depth
174                 "ajaxsnowToday" .... for todays snow
175                 "ajaxsnowMonth" .... for this months snow
176                 "ajaxsnowSeason" ... for this seasons snow
177Added....... tag "ajaxwebcamimg" .... for webcam image support
178Added....... tag "ajaxmoonimg" ...... for moon image support
179Added....... tag "ajaxmoonphase" .... for current phase e.g. "First Quarter"
180Added....... tag "ajaxmoonpct" ...... for current moon illumination e.g. 24%
181Added....... tag "ajaxcloudheightimg" for cloud height graphic
182Added....... tag "ajaxuvimg" ........ for UV graphic (current UV)
183Added....... tag "ajaxuvburnrate" ... for UV skin burn rate (in minutes)
184Added....... "REFRESH" hyperlink to "Updates paused" for restarting ajax script.
185Added....... window.onload function to prevent early ajax loading.
186Added....... support for UOM switching [ metric | english ].
187Added....... support for UOM switching on static field values.
188Modified.... [url=http://www.weather-watch.com/smf/index.php/topic,43750.0.html][color=blue]thermometer.php[/color][/url] to support UOM switching and different styles.
189Modified.... UV color words to official web colors as specified by WHO, WMO & UNEP
190Modified.... overall settings setup for easier configuration.
191Modified.... UOM conversions and added functions convertSnow & convertDist.
192
193Version 9.01 - 05-Jan-2010 -----------------------------------------------------
194Fixed....... problem with Moon Phase.
195
196Version 9.02 - 07-Jan-2010 -----------------------------------------------------
197Added....... Burnsville Weather modifications (v2.80, v3.00, v4.10)
198Version 9.03 - 10-Jan-2010 -----------------------------------------------------
199Added....... tag "ajaxRcdRain" ......... rain record (record all-time daily rain)
200Added....... tag "ajaxRcdRainTime" ..... rain record time
201Added....... tag "ajaxRcdRainDate" ..... rain record date
202Added....... tag "ajaxRcdRainHr" ....... rain record Hr (record all-time daily rain in 1 hour)
203Added....... tag "ajaxRcdRainHrTime" ... rain record Hr time
204Added....... tag "ajaxRcdRainHrDate" ... rain record Hr date
205Added....... tag "ajaxDaysRain" ........ rain days (MTD)
206Added....... tag "ajaxDaysNoRain" ...... rain absent days
207
208Version 9.04 - 10-Jan-2010 -----------------------------------------------------
209Implemented. Webcam support for useCamAtNight and delayDayNight
210
211Version 9.05 - 10-Jan-2010 -----------------------------------------------------
212Fixed....... problem with "number_format" function not showing correct decimal value.
213Added....... ALERT when "clientraw.txt" file can not be found (error 404)
214Removed..... ajaxLoaderInBody - can no longer be supported i.e. <body onload="ajaxLoader(...)">
215Added....... ClientExtra will now always be loaded as well.
216Implemented. external "ajaxWDwx-settings.js" for separate setup outside of this script.
217
218Version 9.06 - 11-Jan-2010 -----------------------------------------------------
219Fixed....... problem with incorrect language translations.
220Added....... modified "language-??.js" files to installation zip.
221Added....... tag "ajaxVPleaf" ... VP leaf wetness
222Added....... alert to your visitors if you have Weather Station problems.
223Simpilfied.. the setup in the external settings file "ajaxWDwx-settings.js".
224
225Version 9.07 - 13-Jan-2010 -----------------------------------------------------
226Added....... support to use English Windrose images only (for Multilingual Systems).
227Simpilfied.. the setup in the external settings file "ajaxWDwx-settings.js" even more.
228             Your external settings file will now be compatible with all future versions of the script.
229
230Version 9.08 - 17-Jan-2010 -----------------------------------------------------
231Fixed ...... problem with dates when set to AM/PM in WDisplay.
232
233Version 9.09 - 17-Jan-2010[/color][/url]
234Fixed ...... problem with JS Date function showing 00:15pm instead of 12:15pm
235
236Version 9.10 - 19-Jan-2010 -----------------------------------------------------
237Fixed ...... problem with dates showing 19:00pm instead of 07:00pm when switching UOM.
238
239Version 9.11 - 19-Jan-2010 -----------------------------------------------------
240Fixed ...... added code for displaying JavaScript errors on page.
241
242Version 9.12 - 19-Jan-2010 -----------------------------------------------------
243Added ...... classes "convDate" and "convTime" for static field UOM switching.
244Removed .... Bashewa icon nameing convention function i.e. ajax_getIconName2().
245Implemented. Icon Nr specification on icon names eg. "{0NR}-{PIC}
245.gif" = "01-nskc.gif"
246
247Version 9.13 - 16-Jan-2011 -----------------------------------------------------
248Fixed ...... fixed Moon Phase data (Thanks to Ken True, Ken True - Saratoga-weather.org)
249
250Version 9.14 - 29-Sep-2012 -----------------------------------------------------
251Fixed ...... fixed UOM conversions/switching for static fields. 
252Fixed ...... tags "convTime" and "convDate" and conversion functions.
253Added ...... tags "ajaxLiveFWI10" and "ajaxLiveFWI" for live FWI.
254Added ...... tag  "ajaxVPforecast" 
255Fixed ...... "ajax_getUVrange" function.
256Fixed ...... "date" prototype function.
257--------------------------------------------------------------------------------
258
259
260
261
262================================================================================
263                       HOW TO IMPLEMENT UOM SWITCHING                          .
264================================================================================
265for implementation see:  http://www.bashewa.com/ajax-dashboard.php?sce=view
266Add the following code somewhere into your "ajax-dashboard.php":
267    ----------------------------------------------------------------------------
268    <div onClick="javascript:ajax_changeUnits();" style="cursor: pointer"><b>
269         <span id="uomM" style="color: gray;">METRIC</span> |
270         <span id="uomE" style="color: blue;">IMPERIAL</span></b>
271    </div>
272    ----------------------------------------------------------------------------
273For static field that don't have an "ajaxtag" you need to add one of the
274following classes to your fields:
275    ----------------------------------------------------------------------------
276    <span class="convTemp">82.7&deg;F</span>   ...for temp
277    <span class="convDdif"> +1.1&deg;F</span>  ...for temp variation
278    <span class="convWind">   2.7 mph</span>   ...for wind
279    <span class="convBaro">30.30 inHg</span>   ...for temp
280    <span class="convRain">   1.04 in</span>   ...for rain
281    <span class="convSoil">      4 in</span>   ...for soil sensor depth
282	<span class="convMoist">	 1 cb</span>   ...for soil moisture
283    <span class="convSnow">   12.4 in</span>   ...for snow
284    <span class="convAlti">   2793 ft</span>   ...for altitude
285    <span class="convDist">  15 miles</span>   ...for distance
286    <span class="convDate">20-10-2009</span>   ...for dates
287    <span class="convTime">  15:32:27</span>   ...for times
288    ----------------------------------------------------------------------------
289NOTE: the value in the span must include the units-of-measure for them be converted.
290You'll also need the modified "thermometer.php" script that supports UOM switching.
291Get it here:  http://www.weather-watch.com/smf/index.php/topic,43750.0.html
292================================================================================
293*/
294
295
296
297//============================================================================\\
298//                             S E T I N G S                                  \\
299//             P L E A S E   R E A D    T H I S   F I R S T                   \\
300// You can have seperate settings in "ajaxWDwx-settings.js" so that you don't \\
301// have to redo them each time a new version of this script is released.      \\
302// I suggest strongly that you do so and also to use the packed version of    \\
303// this script i.e. ajaxWDwx-packed.js.                                       \\
304// -------------------------------------------------------------------------- \\
305// If you have seperate settings in a file "ajaxWDwx-settings.js" then you    \\
306// need to add the following line to your "top.php" file:                     \\
307//     <script type="text/javascript" src="ajaxWDwx-settings.js"></script>    \\
308// below this line in "top.php":                                              \\
309//     <script type="text/javascript" src="ajaxWDwx.js"></script>             \\
310//============================================================================\\
311
312//==============================================================================
313// Settings (required ... should be done in ajaxWDwx-settings.js)              .
314//==============================================================================
315var clientrawFile = './clientraw.txt'; // location of clientraw.txt relative to this page on website
316
317var useUOM = 'M';   // [ E | M ] ... Units Of Measure:
318                    //               E = English/Imperial
319                    //               M = Metric
320                    // NOTE: You can change individual units below in UNITS-OF-MEASURE.
321
322var showUOM = true; // set to FALSE if no units should be displayed inside "ajaxtags".
323                    // i.e. if your UOM's are outside the of the "ajaxtag" spans.
324                    // Note: If you have implemented UOM switching this needs to
325                    //       be TRUE and all your UOM's need to be on the inside
326                    //       of your "ajaxtags".
327
328//==============================================================================
329// Settings (optional ... should be done in ajaxWDwx-settings.js)              .
330//==============================================================================
331
332var wxStation =   // Your Weather Station status
333   {problemNr : 0 // Pick a problemMsg number from below
334   ,problemMsg:   // Problem reports ... the selected message below by "problemNr" will be reported in the wxStation.useTag box
335      {0:'No problems'
336      ,1:'<b style="color:red">...your msg here...</b><br />...your msg here...<br />'
337      } // you can add as many problem messages as you like to the above ... just number them properly
338   ,stopUpdates: false // Stop the ajax updates for the problem reported ... you should do so if your station is out-of-order
339   ,showAlert  : false // Show an alert box instead of a msg in wxStation.useTag box. Use "\n" for line breaks.
340   ,useTag     : "ajaxindicator" // you can specify a different "ajaxtag" here to suit your requirements
341   };
342
343var update = // for ajax update interval
344   {reloadtime: 10000   // fetch clientraw.txt file every 5 seconds (1000 ms = 1 second )
345   ,maxupdates: 0    // Maximum number of updates/fetches allowed (set to zero for unlimited)
346                       // maxupdates * reloadtime / 1000 = (number of seconds to update)
347                       // i.e. 36 x 5000 / 1000 = 180 seconds (3 minutes)
348                       // Note: if you upload your clientraw.txt file every 30 seconds
349                       //       then the visitor will see (180/30) = (6 updates in total).
350   ,showRefresh: true  // show REFRESH hyperlink after "maxupdates" have been exceeded.
351   };
352
353var flash = // for update indicator
354   {color: '#00CC00'   // color to flash for changed observations (RGB) (def #00CC00 = green)
355   ,red  : '#FF0000'   // color to flash red for warnings/alarms  (RGB) (def #FF0000 = red)
356   ,time : 3000        // milliseconds to keep flash color on (2000 = 2 seconds);
357   };
358
359var utc_offset = +1;	   // Set your local TZ offset from UTC Time ('America/Chicago' = -6, 'America/Los Angeles = -8, etc.)
360
361//==============================================================================
362// STATIC IMAGES                                                               .
363//==============================================================================
364// IMAGE LOCATION: default root folder for graphic images & icons
365// ... (for root folder specify "./")
366
367var imgDir = './ajax-images/'; // with trailing slash
368
369// NOTE: do not delete any of the words enclosed in {} in the src parts eg. {PIC}
370//       They'll get replaced by their corresponding values later in the script.
371
372//------------------------------------------------------------------------------
373// DASHBOARD ICONS: optional settings for current conditions graphic for dashboard
374// tag: "ajaxconditionicon" or "ajaxconditionicon2" ... specify it below in wxIcon.useTag
375// e.g. graphic name: "./ajax-images/bkn.gif"
376// .... grab the animated icons for set 2 here: http://www.bashewa.com/downloads/bws-icons-current.zip
377var wxIcon =
378   {src    : imgDir+"{PIC}.gif" // where {PIC} will = picname from function specified in wxIcon.useName below
379   ,width  : 74 ,height: 74 ,hspace: 0 ,vspace: 0 ,border: 0
380   ,style  : ""  // eg. "border: 2px solid silver"
381   ,align  : ""  // [ left | right | top | bottom | middle | texttop | absbottom | absmiddle ]
382   ,useTag : "ajaxconditionicon2" // [ ajaxconditionicon | ajaxconditionicon2 ] ... ajax tagname to use
383   ,useName: 1   // [ 0| 1 | 2 | 9 ] function for getting icon names ...
384   };            //                  0 = Anole's icon names ............ see ajax_getIconName0()
385                 //                  1 = NWS icon names ................ see ajax_getIconName1()
386                 //                  9 = Dynamic current icons ......... NOT IMPLEMENT
386ED
387
388
389//------------------------------------------------------------------------------
390// WIND ROSE: optional settings for the Wind Rose graphic
391// tag: "ajaxwindiconwr"
392// e.g. graphic name: "./ajax-images/wr-SSE.gif"  or  "./ajax-images/wr-nl-SSE.gif"
393// .... grab the wind rose icons here: http://www.bashewa.com/downloads/bws-icons-wind.zip
394var wrImg =
395   {src   : imgDir+"wind/4/wr-#LANG##DIR#.gif"  // where #DIR# will = wind dir (e.g. NNW), #LANG# = wrImg.lang
396   ,width : 58 ,height: 58 ,hspace: 0 ,vspace: 0 ,border: 0
397   ,style : ""
398   ,align : "" // [ left | right | top | bottom | middle | texttop | absbottom | absmiddle ]
399   ,useTag: "ajaxwindiconwr" // ajax tagname to use where the windrose icon should be placed
400   ,lang  : ""     // with trailing dash (e.g. "nl-" will result in graphic name: "./ajax-images/wr-nl-SSE.gif")
401   ,calm  : "calm" // substitution for #DIR# (e.g "wr-calm.gif") ... specify "" if not to be shown or not available
402   };
403   
404
405
406
407
408//------------------------------------------------------------------------------
409// UV: optional settings for the UV graphic
410// tag: "ajaxuvimg"
411// e.g. graphic name: "./ajax-images/uv/1/uv12.gif"
412// .... grab UV pics here: http://www.bashewa.com/download/bws-icons-uv.zip
413var uvImg =
414   {src   : imgDir+"UV{INDEX}.gif" // where {INDEX} will = UV index (0 to 11)
415   ,width : 34 ,height: 65 ,hspace: 0 ,vspace: 0 ,border: 0
416   ,style : ""
417   ,align : ""
418   ,useTag: "ajaxuvimg"
419   };
420
421//------------------------------------------------------------------------------
422// SI: optional settings for SI graphic
423// tags:  ajaxsiimg, ajaxsiimg2
424// e.g. graphic name: "./ajax-images/si/1/si1.gif"
425var siImg =
426   {src   : imgDir+"SI{INDEX}.gif" // where {INDEX} will = SI index (0 to 10)
427   ,width : 34 ,height: 65 ,hspace: 0 ,vspace: 0 ,border: 0
428   ,style : ""
429   ,align : ""
430   ,useTag: "ajaxsiimg"
431   };
432var siImg2 =
433   {src   : imgDir+"SI{INDEX}.gif" // where {INDEX} will = SI index (0 to 10)
434   ,width : 34 ,height: 65 ,hspace: 0 ,vspace: 0 ,border: 0
435   ,style : ""
436   ,align : ""
437   ,useTag: "ajaxsiimg2"
438   };
439
440
441//------------------------------------------------------------------------------
442// MOON: optional settings for the moon phase graphic
443// tag: "ajaxmoonimg"
444// e.g. graphic name: "./ajax-images/moon/w/NH-moon07.gif"
445// .... grab the Moon images here: http://www.bashewa.com/downloads/bws-icons-moon.zip
446var moonImg =
447   {src   : imgDir+"moon/{BG}/{NS}-moon{AGE}.gif" // {BG} = [ w | b ] from moonImg.bg, {NS} = [ NH | SH ] from latitude, {AGE} = 2 digit moonage (0 to 28) from getMoonInfo
448   ,bg    : "w" // [ w | b ] moon background (w=white, b=black)
449   ,width : 50 ,height: 50 ,hspace: 0 ,vspace: 0 ,border: 0
450   ,style : ""
451   ,align : ""
452   ,useTag: "ajaxmoonimg"
453   };
454
455
456//------------------------------------------------------------------------------
457// FIRE INDEX: optional setting for the fire risk graphic
458// tag: "ajaxfireimg"
459// e.g. graphic name: "./ajax-images/fire/fire3.gif"
460// .... grab the FWI icons here: http://www.bashewa.com/downloads/bws-icons-fire.zip
461var fireImg =
462   {src   : imgDir+"FWIFire{IMGNR}.gif" // where {IMGNR} will = fire index (0=very low, 1=low, 2=moderate, 3=high, 4=extreme) from fireImg.imgNrs below
463   ,width : 74 ,height: 74 ,hspace: 0 ,vspace: 0 ,border: 0
464   ,style : ""
465   ,align : ""
466   ,imgNrs: // we all have different numbering systems for our FWI icons it seems ... specify the 6 icon numbers below
467      {0:"0"  ,1:"1"  ,2:"2"  ,3:"3" ,4:"4" ,5:"5"}
468   ,useTag: "ajaxfireimg"
469   };
470
471//------------------------------------------------------------------------------
472// FIRE INDEX: optional setting for the fire risk graphic
473// tag: "ajaxfireimg"
474// e.g. graphic name: "./ajax-images/fire/fire3.gif"
475// .... grab the FWI icons here: http://www.bashewa.com/downloads/bws-icons-fire.zip
476var fireImg2 =
477   {src   : imgDir+"Fire{IMGNR}.gif" // where {IMGNR} will = fire index (0=very low, 1=low, 2=moderate, 3=high, 4=extreme) from fireImg.imgNrs below
478   ,width : 74 ,height: 74 ,hspace: 0 ,vspace: 0 ,border: 0
479   ,style : ""
480   ,align : ""
481   ,imgNrs: // we all have different numbering systems for our CBI icons it seems ... specify the 5 icon numbers below
482      {0:"0"  ,1:"0"  ,2:"16"  ,3:"25"  ,4:"31" ,5:"32"}
483   ,useTag: "ajaxcbiimg"
484   };
485
486//------------------------------------------------------------------------------
487// WEBCAM IMAGE: optional setting for the webcam graphic
488// tag: "ajaxwebcamimg"
489// e.g. picture name: "./ajax-images/webcam/snap00.jpg"
490var webcamImg =
491   {src   : "htzwwlcam.gif" // full path and image name of your current webcam picture
492   ,srcNgt: "htzwwlcam.gif" // full path and image name of your current nightcam picture (after/before "delayDayNight")
493   ,width : 320 ,height: 240 ,hspace: 0 ,vspace: 0 ,border: 0
494   ,style : ""
495   ,align : ""
496   ,webcamUpdate      : 5     // Webcam update interval in minutes (set to 0 for no updates i.e. visitor must reload page for updates)
497   ,swapIconWithWebcam: false // swap current conditions icon (tag "ajaxconditionicon2") with webcam image during day and night unless useCamAtNight=false;
498   ,useCamAtNight     : true // use current conditions icon at night time instead of webcam image
499   ,delayDayNight     : 15    // day starts given minutes before sunrise and night starts given min after sunset - for night icon switch
500   ,useTag: "ajaxwebcamimg"
501   };
502
503
504//==============================================================================
505// DYNAMIC SCRIPT IMAGES                                                       .
506//==============================================================================
507
508// THERMOMETER: optional setting for the dynamic thermometer graphic
509// tag: "ajaxthermometer"
510// ... you'll need the new thermometer.php script from www.bashewa.com for UOM switching.
511// ... read here  : http://www.weather-watch.com/smf/index.php/topic,39180.0.html
512// ... get it here: http://www.bashewa.com/download-thermometer.php
513var thermometerImg =
514   {src   : "./thermometer.php" // path and script for dynamic thermometer PNG image (optional)
515   ,width : 54 ,height: 170 ,hspace: 0 ,vspace: 0 ,border: 0
516   ,style : ""
517   ,align : ""
518   ,useTag: "ajaxthermometer"
519   };
520
521// CELLTHERMOMETER: optional setting for the dynamic thermometer graphic
522// tag: "ajaxthermometer"
523// ... you'll need the new thermometer.php script from www.bashewa.com for UOM switching.
524// ... read here  : http://www.weather-watch.com/smf/index.php/topic,39180.0.html
525// ... get it here: http://www.bashewa.com/download-thermometer.php
526// ... suppresses style switching for cell.php display
527var cellthermometerImg =
528   {src   : "./cell-thermometer.php" // path and script for dynamic thermometer PNG image (optional)
529   ,width : 54 ,height: 170 ,hspace: 0 ,vspace: 0 ,border: 0
530   ,style : ""
531   ,align : ""
532   ,useTag: "ajaxcellthermometer"
533   };
534
535
536//------------------------------------------------------------------------------
537// CLOUD BASE: optional setting for the dynamic cloud height graphic
538// tag: "ajaxcloudheightimg"
539// ... you'll need the cloud-base.php script from www.bashewa.com
540// ... get it here: http://www.bashewa.com/download-cloud-base.php
541var cloudImg =
542   {src   : "./cloud-base.php" // path and script for dynamic cloud height image (optional)
543   ,width : 90 ,height: 200 ,hspace: 0 ,vspace: 0 ,border: 0
544   ,style : ""
545   ,align : ""
546   ,stationAlt: 22 // your station altitude in meters for cloud height graphic if you want ASL (meters = ft / 3.2808399)
547   ,useTag: "ajaxcloudheightimg"
548   };
549
550
551//------------------------------------------------------------------------------
552// DYNAMIC CURRENT ICON: settings for the dynamic current conditions graphic
553// tag: "ajaxconditionicon2"
554// ... you'll need the dynamic-icon.php script from www.bashewa.com
555// ... get it here: (NOT YET IMPLEMENTED)
556// Set this up in wxIcon in DASHBOARD ICONS above:  { src: "./dynamic-icon.php" ,width: 170 ,height: 127, useName: 9 }
557
558
559
560//==============================================================================
561// UNITS-OF-MEASURE / UOM (optional)
562// ... change to your desired UOM's and decimal places
563//==============================================================================
564// ENGLISH (Imperial)
565var imperialUOM =
566   {Temp: '&deg;F' // [ &dec;C | &dec;F ] ......................... Temp
567   ,Wind: 'mph'    // [ kts | mph | kph  | m/s  ] ................. Wind
568   ,Baro: 'inHg'   // [ hPa | mb  | inHg | mmHg ] ................. Baro
569   ,Rain: 'in'     // [ mm  | in  ] ............................... Rain
570   ,Soil: 'in'     // [ cm  | in  ] ............................... Soil Sensor Depth
571   ,Moist:'cb'	   // [ kp  | cb  ] ............................... Soil Moisture
572   ,Snow: 'in'     // [ cm  | in  ] ............................... Snow
573   ,Alti: 'ft'     // [ m   | ft  ] ........................... Altitude
574   ,Dist: 'miles'  // [ m   | km  | miles] .................... Distance
575   ,Deg : '&deg;'  // [ deg | &deg; ] ..................... Direction/UV
576   ,dateFmt: "m/j/Y"   // 04/26/2009 ... same format as "date" function in php ( eg. for US use "m/j/Y", for GB use "d/M/Y" )
577   ,timeFmt: "g:i:s a" // 3:27:01 pm ... same format as "date" function in php ( for 24h clock use "H:i:s" )
578   ,timeHM : "g:i a"   // 3:27 pm ...... same format as "date" function in php ( for 24h clock use "H:i" )
579   };
580var imperialDP = // decimal places
581   { Temp:1 ,Wind:1 ,Baro:2 ,Rain:2 ,Soil:0 ,Moist:0 ,Snow:2 ,Alti:0 ,Dist:2 ,UV:0 };
582//----------------------------------------------------------------------
583// METRIC
584var metricUOM =
585   {Temp: '&deg;C' // [ &dec;C | &dec;F ] ..........................Temp
586   ,Wind: 'kph'    // [ kts | mph | kph  | m/s  ] ................. Wind
587   ,Baro: 'hPa'    // [ hPa | mb  | inHg | mmHg ] ................. Baro
588   ,Rain: 'mm'     // [ mm  | in  ] ............................... Rain
589   ,Soil: 'cm'     // [ cm  | in  } ............................... Soil Sensor Depth
590   ,Moist:'kp'	   // [ kp  | cb  ] ............................... Soil Moisture
591   ,Snow: 'cm'     // [ cm  | in  ] ............................... Snow
592   ,Alti: 'm'      // [ m   | ft  ] ........................... Altitude
593   ,Dist: 'km'     // [ m   | km  | miles] .................... Distance
594   ,Deg : '&deg;'  // [ deg | &deg; ] ........................ Direction
595   ,dateFmt: "j-M-Y" // 26-04-2009 ... same format as "date" function in php (eg. for DE use "j.M.Y", for NL use "j-M-Y)
596   ,timeFmt: "H:i:s" // 15:27:01 ..... same format as "date" function in php  ( for 12h clock use "g:i:s a" )
597   ,timeHM : "H:i"   // 15:27 ........ same format as "date" function in php  ( for 12h clock use "g:i a" )
598   };
599var metricDP = // decimal places
600   { Temp:1 ,Wind:1 ,Baro:0 ,Rain:1 ,Soil:0 ,Moist:0 ,Snow:2 ,Alti:0 ,Dist:2 ,UV:0 };
601
602
603//==============================================================================
604//                            I M P O R T A N T                                .
605//                          LANGUAGE TRANSLATION                               .
606//           No need to change if you're using the Multilingual Templates:     .
607//           (af, de, dk, el, en, es, fi, fr, it, nl, no, pl, pt, se, us)      .
608// =========================================================================== .
609// You don't need to customize this area if you're using English or if you're  .
610// using the Canada/World Mutilingual templates. Instead change your language  .
611// in "Settings.php" i.e. $SITE['lang']='nl';                                  .
612// If translations are incorrect then edit the "language-??.js" files.         .
613//==============================================================================
614var langRestart  = 'Restart live updates';
615var langRefresh  = 'REFRESH'; // RESTART
616var langPauseMsg = 'Updates paused';
617
618var langMonths   = new Array ("January","February","March","April","May","June","July","August","September","October","November","December");
619var langDays     = new Array ("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
620var langDaySuf   = new Array ("st","nd","rd","th"); // day suffix as in 1st, 2nd, 3rd, 4th
621var langAM_PM    = new Array ("am","pm","AM","PM");
622var langWindUOM  = new Array ("kts", "mph", "km/h", "m/s");
623
624var langBaroTrend = new Array (
625    "Steady", "Rising Slowly", "Rising Rapidly", "Falling Slowly", "Falling Rapidly");
626
627var langUVWords = new Array (
628    "None", "Low", "Medium", "High", "Very&nbsp;High", "Extreme", "Unknown" );
629
630var langBeaufort = new Array ( /* Beaufort 0 to 12 in array */
631    "Calm", "Light air", "Light breeze", "Gentle breeze", "Moderate breeze", "Fresh breeze",
632    "Strong breeze", "Near gale", "Gale", "Strong gale", "Storm", "Violent storm", "Hurricane");
633
634var langWindDir = new Array( /* used for alt and title tags on wind dir arrow and wind direction display */
635    "N", "NNE", "NE", "ENE",
636    "E", "ESE", "SE", "SSE",
637    "S", "SSW", "SW", "WSW",
638    "W", "WNW", "NW", "NNW");
639
640var langWindCalm = 'Calm';
641var langGustNone = 'Calm';
642var langWindFrom = 'Wind from '; /* used on alt/title tags on wind direction arrow*/
643
644var langThermoCurrently = 'Currently: '; /* used on alt/title tags for thermometer */
645var langThermoMax = 'Max: ';
646var langThermoMin = 'Min: ';
647
648var langTempRising    = 'Warmer %s'; /* used for trend arrow alt/title tags .. %s marks where value will be placed */
649var langTempFalling   = 'Colder %s';
650var langTempLastHour  = ' than last hour.';
651var langTempYesterday = ' than same time yesterday.';
652
653var langBaroRising  = 'Rising %s '; /* used for trend arrow alt/title tags .. %s marks where value will be placed */
654var langBaroFalling = 'Falling %s ';
655var langBaroPerHour = '/hour.'; /* will be assembled as rising/falling + value + uom + perhour text */
656
657var langHeatWords = new Array (
658    'Unknown', 'Extreme Heat Danger', 'Heat Danger', 'Extreme Heat Caution', 'Extremely Hot', 'Uncomfortably Hot',
659    'Hot', 'Warm', 'Comfortable', 'Chilly', 'Cool', 'Cold', 'Very Cold', 'Extremely Cold', 'Dangerously Cold', 'Extreme Cold Danger' );
660
661var langMoonPhases = new Array (
662    'NEW MOON' , 'Evening Crescent', 'FIRST QUARTER', 'Waxing Gibbous',
663    'FULL MOON', 'Waning Gibbous'  , 'LAST QUARTER' , 'Morning Crescent' );
664    
665var langMinutes = 'Minutes';
666//==============================================================================
667//                      E N D   of   S E T T I N G S                           .
668//==============================================================================
669
670
671
672
673
674//==============================================================================
675//                            I M P O R T A N T                                .
676//           DO NOT customize any of the stuff below this point.               .
677//            Everything is controlled by your settings above.                 .
678//==============================================================================
679
680;;;var doTooltip = 0; // set to 1 to have ajaxed variable names appear as tooltips (except for graphics)
681
682// -----------------------------------------------------------------------------
683var ie4     = document.all;
684var browser = navigator.appName;
685var ie8 = false;
686if (ie4 && /MSIE (\d+\.\d+);/.test(navigator.userAgent)) { //test for MSIE x.x;
687var ieversion = new Number(RegExp.$1); // capture x.x portion and store as a number
688   if (ieversion>=8) {
689      ie4=false;
690      ie8=true;
691    }
692}
693
694var langTransLookup = new Object;  // storage area for key/value for current conditions translation
695var timerAjaxLoader = null; // for resetting loading timeouts
696var notifyR = 0;    // for error 404 alerts: clientraw
697var notifyE = 0;    // for error 404 alerts: clientextra
698var extraRetry = 6; // retry time in seconds to fetch clientrawextra.txt
699var extraRetryInterval = 10000; // fetch retry in milliseconds for clientrawextra.txt
700var clientrawextra = null;
701
702var ajaxUpdates = 0; // update counter for limit by update.maxupdates
703var counterSecs = 0; // for MCHALLIS counter script from weather-watch.com (adapted by K. True)
704var lastajaxtimeformat = null; // used for reseting the counter when a real update is done
705
706var ajaxElements = new Array(); // used for reseting green flashing elements
707var uomElements  = new Array(); // used for storing page values for switching units-of-measure
708
709var PauseMsg  = ""; // leave blank
710var Indicator = ""; // leave blank
711var gotSettings=false, uom, dp, clientrawextraFile, saveUOM, savedateFmt, savetimeFmt, savetimeHM;
712
713//-------------------------------------------------------------- functions start
714function initialize() {
715   // FOR DEBUGING -- always override the settings above if testing on a local host
716   if (document.location.protocol==="file:"
717   ||  document.location.href.search("localhost")!==-1) {
718      //update.maxupdates = 0;
719      update.reloadtime = 5000;
720   }
721   // END DEBUGING --
722
723   if (typeof jserrNr!=="undefined" && jserrNr!==null) {
724      str = jserrors.replace(" in "," in:<br />");
725      jsmsg = '<div style="border-bottom: 1px solid gray;">'+str+'</div>';
726      set_ajax_obs(wxStation.useTag,jsmsg);
727      jsErrNr = null;
728   } else
729   if (wxStation.problemNr>0) {
730      pMsg= wxStation.problemMsg[wxStation.problemNr];
731      if (wxStation.showAlert) alert(pMsg);
732      else set_ajax_obs(wxStation.useTag,pMsg);
733      if (wxStation.stopUpdates) update.maxupdates = 2;
734   }
735
736   clientrawextraFile = clientrawFile.replace("clientraw","clientrawextra");
737   uom = (useUOM==='M')? metricUOM : imperialUOM;
738   dp  = (useUOM==='M')? metricDP  : imperialDP;
739   saveUOM = useUOM;
740   savedateFmt = uom.dateFmt;
741   savetimeFmt = uom.timeFmt;
742   savetimeHM  = uom.timeHM;
743
744   if (!showUOM) { // Strip UOMs if not required i.e. if the UOM is outside the ajaxtag spans
745      imperialUOM.Temp=''; metricUOM.Temp='';
746      imperialUOM.Wind=''; metricUOM.Wind='';
747      imperialUOM.Baro=''; metricUOM.Baro='';
748      imperialUOM.Rain=''; metricUOM.Rain='';
749      imperialUOM.Snow=''; metricUOM.Snow='';
750      imperialUOM.Alti=''; metricUOM.Alti='';
751      imperialUOM.Dist=''; metricUOM.Dist='';
752      imperialUOM.Deg =''; metricUOM.Deg ='';
753   }
754};
755
756function ajaxLoader_restart() {
757   ajaxUpdates = 0;
758   counterSecs = 0;
759   lastajaxtimeformat = null;
760   set_ajax_obs("ajaxindicator",Indicator);
761   set_ajax_obs("ajaxindicator2",Indicator);
762   ajaxLoader_clientextra(clientrawextraFile + '?' + new Date().getTime());
763   if (timerAjaxLoader!=="null") clearTimeout(timerAjaxLoader);
764   timerAjaxLoader = setTimeout("ajaxLoader(clientrawFile + '?' + new Date().getTime())", 20);
765};
766
767
768// toggle the units-of-measure between METRIC and ENGLISH
769function ajax_changeUnits () {
770   useUOM  = (useUOM==="E") ? "M" : "E" ;
771   uom     = (useUOM==="M") ? metricUOM : imperialUOM;
772   dp      = (useUOM==="M") ? metricDP  : imperialDP ;
773   colorM  = (useUOM==="E") ? "gray"    : "blue";
774   colorE  = (useUOM==="M") ? "gray"    : "blue";
775   var uomM = document.getElementById("uomM"); if (uomM) uomM.style.color = colorM;
776   var uomE = document.getElementById("uomE"); if (uomE) uomE.style.color = colorE;
777   var uomM2 = document.getElementById("uomM2"); if (uomM2) uomM2.style.color = colorM;
778   var uomE2 = document.getElementById("uomE2"); if (uomE2) uomE2.style.color = colorE;
779
780   switch (uom.Wind) {
781   case "mph": uom.langWind = langWindUOM[1]; break;
782   case "kph": uom.langWind = langWindUOM[2]; break;
783   case "m/s": uom.langWind = langWindUOM[3]; break;
784   default   : uom.langWind = langWindUOM[0];
785   }
786   ajax_page_convertTags(); // also convert tags convTemp, convWind ... etc.
787   ajaxUpdates = 0;
788   set_ajax_obs("ajaxindicator",new Date().getTime(),Indicator,flash.red);
789   set_ajax_obs("ajaxindicator2",new Date().getTime(),Indicator,flash.red);
790   ajaxLoader_restart();
791};
792
793
794// return all the elements for a given tag name on a page e.g. <span ..>
795function ajax_getElements ( name ) { // name = [span, div, ...]
796   if (ie4 && browser !== "Opera" && ! ie8)
797        return (document.body.getElementsByTagName(name));
798   else return (document     .getElementsByTagName(name));
799};
800
801// return the "class name" for a given element (as in: class="ajax convTemp noprint")
802function ajax_getClassName( element ) {
803   if (ie4 && browser !== "Opera" && ! ie8)
804        return (element.getAttribute("className"));
805   else return (element.getAttribute("class"));
806};
807
808String.prototype.getUnits = function() {
809// match and return any [ °C |°F | &deg;C | &deg;F | mm | in | in. | cb | kp | cm | ft | mb | hPa | inHg | mmHg | kts | m/s | mph | kph ]
810   return (this.match(/°C|°F|&deg;F|&deg;C|in\.|[a-z]+\/?[a-z]?/i));
811};
812
813// return the value
814function ajax_page_getTagValue ( element, type ) {
815   var html = element.innerHTML;
816   var val  = parseFloat(html);
817   var uom  = html.getUnits();
818   return ( val.convertToMetric(uom, type) );
819};
820
821// utility functions to navigate the <span class="..."> tags on the page and save their values
822function ajax_page_saveTags () {
823   uom     = (useUOM==="M") ? metricUOM : imperialUOM;
824   dp      = (useUOM==="M") ? metricDP  : imperialDP ;
825   colorM  = (useUOM==="E") ? "gray"    : "blue";
826   colorE  = (useUOM==="M") ? "gray"    : "blue";
827   var uomM = document.getElementById("uomM"); if (uomM) uomM.style.color = colorM;
828   var uomE = document.getElementById("uomE"); if (uomE) uomE.style.color = colorE;
829   var uomM2 = document.getElementById("uomM2"); if (uomM2) uomM2.style.color = colorM;
830   var uomE2 = document.getElementById("uomE2"); if (uomE2) uomE2.style.color = colorE;
831   switch (uom.Wind) {
832   case "mph": uom.langWind = langWindUOM[1]; break;
833   case "kph": uom.langWind = langWindUOM[2]; break;
834   case "m/s": uom.langWind = langWindUOM[3]; break;
835   default   : uom.langWind = langWindUOM[0];
836   }
837   var i, clas, name, iC = iF =0;
838   var pgElements = ajax_getElements('span');
839
840   for(i=0; i<pgElements.length; i++) {
841      clas = ajax_getClassName(pgElements[i]); // could be: class="ajax convTemp noprint"
842      if (clas!==null) {
843         // conversion elements
844         if ( clas.search    (/convTemp|convDdif|convWind|convBaro|convRain|convSoil|convMoist|convSnow|convDist|convAlti|convDate|convTime/i) > -1) {
845            name = clas.match(/convTemp|convDdif|convWind|convBaro|convRain|convSoil|convMoist|convSnow|convDist|convAlti|convDate|convTime/i);
846            name = name[0];
847            switch (name) {
848            case "convDate":
849            case "convTime": uomElements[iC++]  = [ pgElements[i], name, pgElements[i].innerHTML ]; break;
850            default        : uomElements[iC++]  = [ pgElements[i], name, aja
850x_page_getTagValue(pgElements[i],name) ];
851            }
852            ajaxElements[iF++] = pgElements[i]; // also add to flashing elements
853         }
854         // flashing elements
855         if (clas.search(/ajax/i) > -1)
856            ajaxElements[iF++] = pgElements[i];
857      }
858   }
859   var element = document.getElementById("ajaxindicator");
860   if (element) Indicator = element.innerHTML;
861   var element = document.getElementById("ajaxindicator2");
862   if (element) Indicator = element.innerHTML;
863   ajax_page_convertTags();
864};
865
866// convert "conv..." tags to required UOM
867function ajax_page_convertTags () {
868var i, name, val, ret;
869   for(i=0; i<uomElements.length; i++) {
870      name = uomElements[i][1];
871      val  = uomElements[i][2];
872      ret = null;
873      switch (name) {
874      case "convTemp": ret = val.convertTemp().toFixed(dp.Temp)    +uom.Temp; break;
875      case "convDdif": ret = val.convertDdif().toFixed(dp.Temp)    +uom.Temp; break;
876      case "convWind": ret = val.convertWind().toFixed(dp.Wind)+' '+uom.langWind; break;
877      case "convBaro": ret = val.convertBaro().toFixed(dp.Baro)+' '+uom.Baro; break;
878      case "convRain": ret = val.convertRain().toFixed(dp.Rain)+' '+uom.Rain; break;
879      case "convSoil": ret = val.convertSoil().toFixed(dp.Soil)+' '+uom.Soil; break;
880      case "convMoist": ret = val.convertMoist().toFixed(dp.Moist)+' '+uom.Moist; break;
881      case "convSnow": ret = val.convertSnow().toFixed(dp.Snow)+' '+uom.Snow; break;
882      case "convDist": ret = val.convertDist().toFixed(dp.Dist)+' '+uom.Dist; break;
883      case "convAlti": ret = val.convertAlti().toFixed(dp.Alti)+' '+uom.Alti; break;
884      case "convDate": ret = val.convertDate(); break;
885      case "convTime": ret = val.convertTime(); break;
886      }
887      if (ret!==null) {
888         uomElements[i][0].innerHTML = ret;
889         uomElements[i][0].style.color = flash.color;
890      }
891   }
892};
893
894
895// function for setting green flashing object
896function ajax_flash_green ( name ) {
897   var element = document.getElementById(name);
898   if (element)  element.style.color = flash.color;
899};
900
901// function for resetting green flashing object
902function ajax_flash_reset( usecolor ) {
903// reset all the <span class="ajax"...> styles to have no color override
904   for(var i=0; i<ajaxElements.length; i++) {
905      element = ajaxElements[i];
906      element.style.color = usecolor;
907   }
908};
909
910
911function set_ajax_obs( name, value , html , red) {
912// store away the current value in both the doc and the span as lastobs="value"
913// change color if value != lastobs
914   var element = document.getElementById(name);
915   if (! element ) { return; } // V1.04 -- don't set if missing the <span id=name> tag
916   var lastobs = element.getAttribute("lastobs");
917   element.setAttribute("lastobs",value);
918   if (value !== unescape(lastobs)) {
919      element.style.color = (red)? flash.red : flash.color;
920      ;;;if ( doTooltip ) element.setAttribute("title",'AJAX tag '+name);
921      element.innerHTML = ((typeof html==='undefined')?value:html); // moved inside to fix flashing issue (Jim at jcweather.us)
922   }
923};
924
925function set_ajax_uom( name, show ) {
926// this function will set an ID= to visible or hidden by setting the style="display: " from 'inline' or 'none'
927   var element = document.getElementById(name);
928   if (! element ) { return; }
929   if (show) element.style.display='inline';
930   else      element.style.display='none';
931};
932// --- end of flash-green functions
933
934
935function ajax_getWindDir (winddir) {
936// Take wind direction value, return the
937// text label based upon 16 point compass -- function by beeker425
938//  see http://www.weather-watch.com/smf/index.php/topic,20097.0.html
939   windlabel = new Array("N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW");
940   return windlabel[Math.floor(((parseInt(winddir) + 11) / 22.5) % 16 )];
941};
942
943function ajax_getWindDirLang (winddir) {
944// Take wind direction value, return the
945// text label based upon 16 point compass -- function by beeker425
946// ... see http://www.weather-watch.com/smf/index.php/topic,20097.0.html
947   return langWindDir[Math.floor(((parseInt(winddir) + 11) / 22.5) % 16 )];
948};
949
950function ajax_getIconName0 ( iconNr ,iconSet ) {
951// perform a lookup and return the graphic name for the condition icon
952// (using anole's wxsticker icon nameing convention)
953iconList = new Array(
954   "day_clear",           //  0 sunny
955   "night_clear",         //  1 clearnight
956   "day_partly_cloudy",   //  2 cloudy
957   "day_partly_cloudy",   //  3 cloudy2
958   "night_partly_cloudy", //  4 cloudynight
959   "day_clear",           //  5 dry
960   "fog",                 //  6 fog
961   "haze-sm",             //  7 haze
962   "day_heavy_rain",      //  8 heavyrain
963   "day_mostly_sunny",    //  9 mainlyfine
964   "mist-sm",             // 10 mist
965   "fog",                 // 11 nightfog
966   "night_heavy_rain",    // 12 nightheavyrain
967   "night_cloudy",        // 13 nightovercast
968   "night_rain",          // 14 nightrain
969   "night_light_rain",    // 15 nightshowers
970   "night_snow",          // 16 nightsnow
971   "night_tstorm",        // 17 nightthunder
972   "day_cloudy",          // 18 overcast
973   "day_partly_cloudy",   // 19 partlycloudy
974   "day_rain",            // 20 rain
975   "day_rain",            // 21 rain2
976   "day_light_rain",      // 22 showers2
977   "day_sleet",           // 23 sleet
978   "day_sleet",           // 24 sleetshowers
979   "day_snow",            // 25 snow
980   "day_snow",            // 26 snowmelt
981   "day_snow",            // 27 snowshowers2
982   "day_clear",           // 28 sunny
983   "day_tstorm",          // 29 thundershowers
984   "day_tstorm",          // 30 thundershowers2
985   "day_tstorm",          // 31 thunderstorms
986   "tornado",             // 32 tornado
987   "windy-sm",            // 33 windy
988   "day_partly_cloudy",   // 34 stopped rainning
989   "windyrain-sm"         // 35 windy/rain (new with V2.11)
990   );
991
992   if (iconNr >= 0 && iconNr <= 35) {
993      return ('<img src="'+ iconSet.src.replace(/(#PIC#|\{PIC\})/i, iconList[iconNr])
994             +'" width="' + iconSet.width
995             +'" height="'+ iconSet.height
996             +'" border="'+ iconSet.border
997             +'" vspace="'+ iconSet.vspace
998             +'" hspace="'+ iconSet.hspace
999             +'" style="' + iconSet.style
1000             +'" align="' + iconSet.align
1001             +'" alt="Current conditions" />');
1002   }  else return '';
1003};
1004
1005
1006function ajax_getIconName1 ( iconNr ,iconSet ) {
1007// perform a lookup and return the graphic for the condition icon
1008// (using NWS icon nameing convention)
1009var i0nr, iSrc;
1010iconList = new Array(
1011   "skc",          //  0 sunny
1012   "nskc",         //  1 clearnight
1013   "bkn",          //  2 cloudy
1014   "sct",          //  3 cloudy2
1015   "nbkn",         //  4 cloudynight
1016   "sct",          //  5 dry
1017   "fg",           //  6 fog
1018   "hazy",         //  7 haze
1019   "ra",           //  8 heavyrain
1020   "few",          //  9 mainlyfine
1021   "mist",         // 10 mist
1022   "nfg",          // 11 nightfog
1023   "nra",          // 12 nightheavyrain
1024   "novc",         // 13 nightovercast
1025   "nra",          // 14 nightrain
1026   "nshra",        // 15 nightshowers
1027   "nsn",          // 16 nightsnow
1028   "ntsra",        // 17 nightthunder
1029   "ovc",          // 18 overcast
1030   "bkn",          // 19 partlycloudy
1031   "ra",           // 20 rain
1032   "ra",           // 21 rain2
1033   "shra",         // 22 showers2
1034   "ip",           // 23 sleet
1035   "ip",           // 24 sleetshowers
1036   "sn",           // 25 snow
1037   "sn",           // 26 snowmelt
1038   "sn",           // 27 snowshowers2
1039   "skc",          // 28 sunny
1040   "scttsra",      // 29 thundershowers
1041   "hi_tsra",      // 30 thundershowers2
1042   "tsra",         // 31 thunderstorms
1043   "nsvrtsra",     // 32 tornado
1044   "wind",         // 33 windy
1045   "ra1",          // 34 stopped rainning
1046   "windyrain",    // 35 windy/rain (new with V2.11)
1047   "sunrise",      // 36 sunrise
1048   "sunset"        // 37 sunset
1049   );
1050
1051   if (iconNr >= 0 && iconNr <= 37) {
1052      i0nr = (iconNr).toString().str_pad(2);//,"0","L");
1053      iSrc = iconSet.src.replace(/(#PIC#|\{PIC\})/i, iconList[iconNr]);
1054      iSrc =        iSrc.replace(/(#0NR#|\{0NR\})/i, i0nr);
1055      iSrc =        iSrc.replace(/(#NR#|\{NR\})/i  , iconNr);
1056      return ('<img src="'+ iSrc
1057             +'" width="' + iconSet.width
1058             +'" height="'+ iconSet.height
1059             +'" border="'+ iconSet.border
1060             +'" vspace="'+ iconSet.vspace
1061             +'" hspace="'+ iconSet.hspace
1062             +'" style="' + iconSet.style
1063             +'" align="' + iconSet.align
1064             +'" alt="Current conditions" />');
1065   }  else return '';
1066};
1067
1068
1069//------------------------------------------------------------------------------
1070// CONVERSIONS: prototypes to handle conversions from clientraw data to desired units-of-measure
1071//------------------------------------------------------------------------------
1072Number.prototype.convertToMetric = function ( units, type ) { // convert to C, kts, hPa, mm, cm or meters
1073type = (typeof type === 'undefined')? "" : type;
1074   if (type==="convDate" || type==="convTime") return this;
1075   ;;;if (!units) alert("Error in convertToMetric: type="+type+" units="+units+" val="+this);
1076   switch (units.toString().toLowerCase()) { // lowercase in case we get FT or KMH etc
1077// temp to °C
1078   case "°f"    : 
1079   case "&deg;f": return((this - 32) / 1.8); // Celsius = (this - 32) * 0.556
1080// wind mph, km/h and m/s to kts
1081   case "kmh"   :
1082   case "kph"   :
1083   case "km/h"  : return (this * 0.539956803);
1084   case "mph"   : return (this / 1.150779450);
1085   case "m/s"   : return (this / 0.514444444);
1086// baro inHg, mmHg and kPa to hPa
1087   case "inhg"  : return (this * 33.86388667);
1088   case "mmhg"  : return (this * 1.3332239);
1089   case "kpa"   : return (this * 10.0);
1090// rain to mm and snow to cm
1091   case "in."   :
1092   case "in"    : if (type==="convSnow") return (this * 2.54);
1093                  else                  return (this * 25.4);
1094// distance miles and meters to km
1095   case "m"     : return (this / 1000);
1096   case "Km"	: return (this * 1);
1097   case "miles" : return (this / 1.6);
1098// altitude to meters
1099   case "ft"    : return (this / 3.2808399);
1100   default      : return (this * 1.0);
1101   }
1102};
1103
1104Number.prototype.convertDdif = function() { // °C
1105	switch (uom.Temp) {
1106	case "°F"    :
1107	case "&deg;F": return((this * 1.8) + 32.0);
1108	default      : return((this * 1.0) + 17.8);
1109	}
1110};
1111
1112Number.prototype.convertTemp = function() { // °C
1113   switch (uom.Temp) {
1114   case "&deg;F": return((this * 1.8) + 32.0);
1115   default      : return (this * 1.0);
1116   }
1117};
1118
1119Number.prototype.convertWind = function() { // kts
1120   switch (uom.Wind) {
1121   case "mph" : return (this * 1.15077945);
1122   case "kph" : return (this * 1.852);
1123   case "m/s" : return (this * 0.514444444);
1124   default    : return (this * 1.0);
1125   }
1126};
1127
1128Number.prototype.convertBaro = function() { // hPa
1129   switch (uom.Baro) {
1130   case "inHg": return (this / 33.863886666667);
1131   case "mmHg": return (this / 1.3332239);
1132   case "kPa" : return (this * 0.1);
1133   default    : return (this * 1.0);
1134   }
1135};
1136
1137Number.prototype.convertRain = function() { // mm
1138   switch (uom.Rain) {
1139   case "in.": return (this * 0.0393700787402);
1140   case "in" : return (this * 0.0393700787402);
1141   case "cm" : return (this * 0.1);
1142   default   : return (this * 1.0);
1143   }
1144};
1145
1146Number.prototype.convertSoil = function() { // cm
1147   switch (uom.Soil) {
1148   case "in.": return (this * 0.393700787402);
1149   case "in" : return (this * 0.393700787402);
1150   case "cm" : return (this * 1.0);
1151   default   : return (this * 1.0);
1152   }
1153};
1154
1155Number.prototype.convertMoist = function() { // cm
1156   switch (uom.Moist) {
1157   case "cb": return (this * 1.0);
1158   case "kp": return (this * 1.0);
1159   default  : return (this * 1.0);
1160   }
1161};
1162
1163Number.prototype.convertAlti = function() { // meters
1164   switch (uom.Alti) {
1165   case "ft" : return (this * 3.2808399); break;
1166   case "m"  : return (this * 0.3048); break;
1167   default   : return (this * 1.0);
1168   }
1169};
1170
1171Number.prototype.convertSnow = function() { // cm
1172   switch (uom.Snow) {
1173   case "in.": return (this * 0.3937007874020);
1174   case "in" : return (this * 0.3937007874020);
1175   case "ft" : return (this * 0.0328083989501);
1176   case "mm" : return (this * 10.0);
1177   case "m"  : return (this * 0.1);
1178   default   : return (this * 1.0);
1179   }
1180};
1181
1182Number.prototype.convertDist = function() { // km
1183   switch (uom.Dist) {
1184   case "Km"	: return (this * 1);
1185   case "m"     : return (this / 1000);
1186   case "miles" : return (this / 1.6);
1187   default   : return (this * 1);
1188   }
1189};
1190
1191// Switch date between Euro and US format i.e. 21-03-2010 to 3/21/2010 or 27-Sep-2012 to 09/27/2012
1192String.prototype.convertDate = function () {
1193var day,mth,yer,M;
1194var langM = new Array();
1195   fmtD = uom.dateFmt;
1196   sep  = savedateFmt.substr(1,1);
1197   vals = this.split(sep);
1198   keys = savedateFmt.split(sep);
1199   var today= new Date();
1200   day = today.getDate();
1201   mth = today.getMonth()+1;
1202   yer = today.getYear();
1203   for(var i=0; i<keys.length; i++) {
1204      switch (keys[i]) {
1205        case "j":
1206        case "d": day = vals[i];
1207                  break
1208        case "n":
1209        case "m": mth = vals[i];
1210                  break;
1211        case "M": M = vals[i];
1212                  for (var j=0; j<12; j++) { langM[j] = langMonths[j].substr(0,3); }
1213                  mth = langM.indexOf(M)+1;
1214                  break;
1215        case "F": M = vals[i];
1216                  mth = langMonths.indexOf(M)+1;
1217                  break;
1218        case "y": 
1219        case "Y": yer = vals[i];
1220                  break;
1221      }
1222   }
1223   timeD = new Date(yer,mth-1,day);
1224   return timeD.date(fmtD);
1225};
1226
1227// Switch time between 12h and 24h format i.e. 19:00 to 07:00pm
1228String.prototype.convertTime = function () {
1229  var hrs,min,sec = 0;
1230   fmtT = savetimeFmt;
1231   fmtU = uom.timeFmt;
1232   sec  = parseInt(this.substr(6,2));
1233   if (isNaN(sec)) {
1234      fmtT = savetimeHM;
1235      fmtU = uom.timeHM;
1236      sec  = 0;
1237   }
1238   sep  = fmtT.substr(1,1);
1239   vals = this.split(sep);
1240   keys = fmtT.split(sep);
1241   for(var i=0; i<keys.length; i++) {
1242      switch (keys[i]) {
1243        case "g":
1244        case "G":
1245        case "h": 
1246        case "H": hrs = vals[i];
1247                  break;
1248        case "i": min = vals[i];
1249                  break
1250        case "s": sec = vals[i];
1251                  break
1252        case "A":
1253        case "a": (vals[i]==='pm' || vals[i]==='PM')? hrs = hrs+12 : hrs = hrs;
1254                  break;
1255      }
1256   }   
1257   timeT = new Date();
1258   timeT.setHours(hrs,min,sec);
1259   return timeT.date(fmtU);
1260};
1261
1262
1263//----------------------------------------------------------- end of conversions
1264
1265
1266function ajax_getBeaufortNumber ( wind ) {
1267// return a number for the beaufort scale based on wind knots (native WD format)
1268  if (wind <  1 ) {return("0"); }
1269  if (wind <  4 ) {return("1"); }
1270  if (wind <  7 ) {return("2"); }
1271  if (wind < 11 ) {return("3"); }
1272  if (wind < 17 ) {return("4"); }
1273  if (wind < 22 ) {return("5"); }
1274  if (wind < 28 ) {return("6"); }
1275  if (wind < 34 ) {return("7"); }
1276  if (wind < 41 ) {return("8"); }
1277  if (wind < 48 ) {return("9"); }
1278  if (wind < 56 ) {return("10"); }
1279  if (wind < 64 ) {return("11"); }
1280  if (wind >=64 ) {return("12"); }
1281  return("0");
1282};
1283
1284
1285function ajax_getBaroTrend(btrnd) {
1286// routine from Anole's wxsticker PHP (adapted to JS by Ken True)
1287// input: trend in hPa or millibars
1288//   Barometric Trend(3 hour)
1289
1290// Change Rates
1291// Rapidly: =.06 inHg; 1.5 mmHg; 2.0 hPa; 2.0 mb
1292// Slowly : =.02 inHg; 0.5 mmHg; 0.7 hPa; 0.7 mb
1293
1294// 5 conditions
1295// Rising Rapidly
1296// Rising Slowly
1297// Steady
1298// Falling Slowly
1299// Falling Rapidly
1300
1301// Page 52 of the PDF Manual
1302// http://www.davisnet.com/product_documents/weather/manuals/07395.234-VP2_Manual.pdf
1303// figure out a text value for barometric pressure trend
1304   if ((btrnd >= -0.7) && (btrnd <= 0.7)) { return(langBaroTrend[0]); }
1305   if ((btrnd >   0.7) && (btrnd <  2.0)) { return(langBaroTrend[1]); }
1306   if (btrnd >=   2.0)                    { return(langBaroTrend[2]); }
1307   if ((btrnd <  -0.7) && (btrnd > -2.0)) { return(langBaroTrend[3]); }
1308   if (btrnd <=  -2.0)                    { return(langBaroTrend[4]); }
1309  return(btrnd);
1310};
1311
1312// Official colours for UV as specified by WHO, WMO & UNEP
1313var UVColor = new Array
1314   ( "none"    //  0
1315   , "#4EB400" //  1 Low
1316   , "#A0CE00" //  2
1317   , "#F7E400" //  3 Medium
1318   , "#F8B600" //  4
1319   , "#F88700" //  5
1320   , "#F85900" //  6 High
1321   , "#E82C0E" //  7
1322   , "#D8001D" //  8 Very High
1323   , "#FF0099" //  9
1324   , "#B54CFF" // 10
1325   , "#998CFF" // 11+Extreme
1326   );
1327
1328function ajax_getUVrange ( uv ) { // code simplified by FourOhFour on wxforum.net
1329   var uvword = "Unspec.";
1330   if (uv <= 0) {
1331       uvword = langUVWords[0];
1332   } else if (uv < 3) {
1333       uvword = "<span style=\"border: solid 1px; color: black; background-color: #4EB400;\">&nbsp;"+langUVWords[1]+"&nbsp;</span>";
1334   } else if (uv < 6) {
1335       uvword = "<span style=\"border: solid 1px; color: black; background-color: #F7E400;\">&nbsp;"+langUVWords[2]+"&nbsp;</span>";
1336   } else if (uv < 8) {
1337       uvword =  "<span style=\"border: solid 1px; color: black; background-color: #F85900;\">&nbsp;"+langUVWords[3]+"&nbsp;</span>";
1338   } else if (uv < 11) {
1339       uvword =  "<span style=\"border: solid 1px; color: #FFFFFF; background-color: #D8001D;\">&nbsp;"+langUVWords[4]+"&nbsp;</span>";
1340   } else {
1341       uvword =  "<span style=\"border: solid 1px; color: #FFFF00; background-color: #998CFF;\">&nbsp;"+langUVWords[5]+"&nbsp;</span>";
1342   }
1343   return uvword;
1344} // end ajax_getUVrange function
1345
1346
1347function ajax_getUVburnRate ( uv ) {
1348   var uvIdx  = Math.min(18,Math.round(uv));
1349   switch (uvIdx) {
1350   case  0: uvrate = 'NONE';  break;
1351   case  1: uvrate = 112;  break;
1352   case  2: uvrate =  56;  break;
1353   case  3: uvrate =  37;  break;
1354   case  4: uvrate =  28;  break;
1355   case  5: uvrate =  22;  break;
1356   case  6: uvrate =  19;  break;
1357   case  7: uvrate =  16;  break;
1358   case  8: uvrate =  14;  break;
1359   case  9: uvrate =  12;  break;
1360   case 10: uvrate =  11;  break;
1361   case 11: uvrate =  10;  break;
1362   case 12: uvrate =   9;  break;
1363   case 13: uvrate =   9;  break;
1364   case 14: uvrate =   8;  break;
1365   case 15: uvrate =   7;  break;
1366   case 16: uvrate =   6;  break;
1367   case 17: uvrate =   5;  break;
1368   case 18: uvrate =   4;  break;
1369   default: uvrate =   "N/A";
1370   }
1371   return (uvIdx<1)? uvrate : uvrate;
1372}; // end ajax_getUVburnRate function
1373
1374
1375function ajax_getTrendArrow( nowTemp, yesterTemp, Legend, textUP, textDN, numDp) {
1376// generate an <img> tag with alt= and title= for rising/falling values
1377var diff = nowTemp.toFixed(3) - yesterTemp.toFixed(3);
1378var absDiff = Math.abs(diff);
1379var diffStr = '' + diff.toFixed(numDp);
1380var absDiffStr = '' + absDiff.toFixed(numDp);
1381var image = '';
1382var msg = '';
1383
1384   if (diff === 0) { // no change
1385      msg = '';
1386      image = '<img src="' + imgDir + 'steady.gif'
1387            + '" alt="'    + msg
1388            + '" title="'  + msg
1389            + '" width="7" height="8" style="border: 0; margin: 1px 3px;" />';
1390   } else if (diff > 0) { // today is greater
1391      msg = textUP.replace(/\%s/,absDiffStr);
1392      image = '<img src="' + imgDir + 'rising.gif'
1393            + '" alt="'    + msg
1394            + '" title="'  + msg
1395            + '" width="7" height="8" style="border: 0; margin: 1px 3px;" />';
1396   } else { // today is lesser
1397      msg = textDN.replace(/\%s/,absDiffStr);
1398      image = '<img src="' + imgDir + 'falling.gif'
1399            + '" alt="'    + msg
1400            + '" title="'  + msg
1401            + '" width="7" height="8" style="border: 0; margin: 1px 3px;" />';
1402   }
1403   return ((Legend) ? (diff + Legend + image) : image);
1404}; // end ajax_getTrendArrow function
1405
1406
1407// function to add colored heatColorWord by Mike Challis
1408function ajax_getHeatColor(temp ,WindChill, Humidex) {
1409var fg = bg = hw = "";
1410var hcWord = langHeatWords[0];
1411var val = { fg:'', bg:'', hw:'' };
1412   if (temp > 32 && Humidex > 29) {
1413      switch (true) {
1414      case (Humidex   > 54): fg = "white"; bg = "#BA1928";
1414 hw = langHeatWords[ 1]; break;
1415      case (Humidex   > 45): fg = "white"; bg = "#E02538"; hw = langHeatWords[ 2]; break;
1416      case (Humidex   > 39): fg = "black"; bg = "#E178A1"; hw = langHeatWords[ 4]; break;
1417      case (Humidex   > 29): fg = "white"; bg = "#CC6633"; hw = langHeatWords[ 6]; break;
1418      }
1419   } else if (WindChill < 16 ) {
1420      switch (true) {
1421      case (WindChill <-28): fg = "black"; bg = "#91ACFF"; hw = langHeatWords[14]; break;
1422      case (WindChill <-18): fg = "black"; bg = "#91ACFF"; hw = langHeatWords[13]; break;
1423      case (WindChill < -9): fg = "white"; bg = "#806AF9"; hw = langHeatWords[12]; break;
1424      case (WindChill < -1): fg = "white"; bg = "#3366FF"; hw = langHeatWords[11]; break;
1425      case (WindChill <  8): fg = "white"; bg = "#6699FF"; hw = langHeatWords[10]; break;
1426      case (WindChill < 16): fg = "black"; bg = "#89B2EA"; hw = langHeatWords[ 9]; break;
1427      }
1428   }  else if (WindChill >= 16 && temp <= 32) {
1429      switch (true) {
1430      case (temp      < 26): fg = "black"; bg = "#C6EF8C"; hw = langHeatWords[ 8]; break;
1431      case (temp      <=32): fg = "black"; bg = "#CC9933"; hw = langHeatWords[ 7]; break;
1432      }
1433   }
1434   val = { fg:fg ,bg:bg ,hw:hw };
1435   return val;
1436}; // end ajax_getHeatColor function
1437
1438function ajax_getHeatColorWord(temp ,WindChill, Humidex) {
1439var val = ajax_getHeatColor(temp ,WindChill, Humidex);
1440return ((val.fg==="")? val.hw
1441                    : '<span style="border: solid 1px; color: '+val.fg+'; background-color: '+val.bg+';">&nbsp;'+val.hw+'&nbsp;</span>'
1442                    );
1443};
1444
1445function ajax_getHeatColorTemp(temp ,WindChill, Humidex, actTemp) {
1446var val = ajax_getHeatColor(temp ,WindChill, Humidex);
1447return ((val.fg==="")? actTemp.toFixed(dp.Temp)+uom.Temp
1448                    : '<span style="border: solid 1px; color: '+val.fg+'; background-color: '+val.bg+';">&nbsp;'+actTemp.toFixed(dp.Temp)+uom.Temp+'&nbsp;</span>'
1449                    );
1450};
1451
1452
1453// slice and dice the clientraw[49] for possible translation of current weather
1454//
1455function ajax_fixupCondition( rawcond ) {
1456var cond = rawcond;
1457  cond = cond.replace(/_/gm,' ');  // replace any _ with blank.
1458  cond = cond.replace(/ -/gm,'');  // replace any  - with null.
1459  cond = cond.replace(/[\r\n]/gm,'');  // remove embedded CR and/or LF
1460  var conds = cond.split('/');  // split up the arguments.
1461  var tstr = '';
1462  for (var i = 0;i<conds.length;i++) {
1463    var t = conds[i];
1464    //t = t.toLowerCase();
1465    t = t.ucfirst();
1466    t = t.replace(/\s+$/,'');  // trim trailing blanks
1467    if(langTransLookup[t]) {
1468                conds[i] = langTransLookup[t];
1469    } else { conds[i] = t;
1470   }
1471}
1472  if (conds[0].length === 0) { conds.splice(0,1);  } // remove blank entry
1473  if (conds[0] === conds[2]) { conds.splice(2,1); } // remove duplicate last entry
1474  return(conds.join(', '));
1475}; // end ajax_fixupCondition function
1476
1477
1478
1479// Mike Challis' counter function (adapted by Ken True)
1480function ajax_countup() {
1481var element = document.getElementById("ajaxcounter");
1482   if (element) {
1483      element.innerHTML = counterSecs;
1484      counterSecs++;
1485   }
1486};
1487// Counter duplicated for a second display on long dashboard page
1488function ajax_countup2() {
1489var element = document.getElementById("ajaxcounter2");
1490   if (element) {
1491      element.innerHTML = counterSecs;
1492   }
1493};
1494
1495
1496function ajax_getFireIndex ( fwi , fireImg ) {
1497   switch (true) {
1498     case (fwi< 14): idx = fireImg.imgNrs[0]; break;
1499     case (fwi< 35): idx = fireImg.imgNrs[1]; break;
1500     case (fwi< 64): idx = fireImg.imgNrs[2]; break;
1501     case (fwi< 122): idx = fireImg.imgNrs[3]; break;
1502     case (fwi< 232): idx = fireImg.imgNrs[4]; break;
1503     default      : idx = fireImg.imgNrs[5];
1504   }
1505return idx;
1506};
1507
1508function ajax_getCBIIndex ( CBI , fireImg2 ) {
1509   switch (true) {
1510     case (CBI< 1): idx = fireImg2.imgNrs[0]; break;
1511     case (CBI<50): idx = fireImg2.imgNrs[1]; break;
1512     case (CBI<75): idx = fireImg2.imgNrs[2]; break;
1513     case (CBI<90): idx = fireImg2.imgNrs[3]; break;
1514     case (CBI<97.5): idx = fireImg2.imgNrs[4]; break;
1515     default      : idx = fireImg2.imgNrs[5];
1516   }
1517return idx;
1518};
1519// -----------------------------------------------------------------------------
1520// MOON FUNTIONS                                                               .
1521// -----------------------------------------------------------------------------
1522function getMoonInfo () { // very crude way of determining moon ph
1522ase (but very accurate)
1523// ------------- start of USNO moon data -----------------------------
1524// JavaScript tables generated from USNO moon ephemeris data http://aa.usno.navy.mil/data/docs/MoonPhase.php
1525// using the one-year at a time query option
1526// Ken True - Saratoga-weather.org generated by USNO-moonphases.php - Version 1.00 - 15-Jan-2011 on 15 January 2011 23:05 EST
1527
1528var newMoons = new Array( // unixtime values in UTC/GMT
1529/* 2009 */ /* 26-Jan-2009 07:55 */ 1232956500, 1235525700, 1238083560, 1240629780, 1243167060, 1245699300, 1248230100, 1250762520, 1253299440, 1255843980, 1258398840, 1260964920,
1530/* 2010 */ /* 15-Jan-2010 07:11 */ 1263539460, 1266115860, 1268686860, 1271248140, 1273799040, 1276341300, 1278877200, 1281409680, 1283941800, 1286477040, 1289019120, 1291570560,
1531/* 2011 */ /* 04-Jan-2011 09:03 */ 1294131780, 1296700260, 1299271560, 1301841120, 1304405460, 1306962180, 1309510440, 1312051200, 1314587040, 1317121740, 1319658960, 1322201400, 1324749960,
1532/* 2012 */ /* 23-Jan-2012 07:39 */ 1327304340, 1329863700, 1332427020, 1334992680, 1337557620, 1340118120, 1342671840, 1345218840, 1347761460, 1350302520, 1352844480, 1355388120,
1533/* 2013 */ /* 11-Jan-2013 19:44 */ 1357933440, 1360480800, 1363031460, 1365586500, 1368145680, 1370706960, 1373267640, 1375825860, 1378380960, 1380933240, 1383483000, 1386030120,
1534/* 2014 */ /* 01-Jan-2014 11:14 */ 1388574840, 1391117880, 1393660800, 1396205100, 1398752040, 1401302400, 1403856480, 1406414520, 1408975980, 1411539240, 1414101420, 1416659520, 1419212160,
1535/* 2015 */ /* 20-Jan-2015 13:14 */ 1421759640, 1424303220, 1426844160, 1429383420, 1431922380, 1434463500, 1437009840, 1439563980, 1442126460, 1444694760, 1447264020, 1449829740,
1536/* 2016 */ /* 10-Jan-2016 01:30 */ 1452389400, 1454942340, 1457488440, 1460028240, 1462562940, 1465095540, 1467630060, 1470170640, 1472720580, 1475280660, 1477849080, 1480421880, 1482994380,
1537/* 2017 */ /* 28-Jan-2017 00:07 */ 1485562020, 1488121080, 1490669820, 1493208960, 1495741440, 1498271460, 1500803100, 1503340200, 1505885400, 1508440320, 1511005320, 1513578600,
1538/* 2018 */ /* 17-Jan-2018 02:17 */ 1516155420, 1518728700, 1521292260, 1523843820, 1526384880, 1528918980, 1531450080, 1533981480, 1536516060, 1539056820, 1541606520, 1544167200,
1539/* 2019 */ /* 06-Jan-2019 01:28 */ 1546738080, 1549314180, 1551888240, 1554454200, 1557009900, 1559556120, 1562094960, 1564629120, 1567161420, 1569695160, 1572233880, 1574780700, 1577337180,
1540/* 2020 */ /* 24-Jan-2020 21:42 */ 1579902120, 1582471920, 1585042080, 1587608760, 1590169140, 1592721660, 1595266380, 1597804920, 1600340400, 1602876660, 1605416820, 1607962560,
1541/* 2021 */ /* 13-Jan-2021 05:00 */ 1610514000, 1613070360, 1615630860, 1618194660, 1620759600, 1623322380, 1625879760, 1628430600, 1630975920, 1633518300, 1636060440, 1638603780,
1542/* 2022 */ /* 02-Jan-2022 18:33 */ 1641148380, 1643694360, 1646242500, 1648794240, 1651350480, 1653910200, 1656471120, 1659030900, 1661588220, 1664142840, 1666694940, 1669244220, 1671790620,
1543/* 2023 */ /* 21-Jan-2023 20:53 */ 1674334380, 1676876760, 1679419380, 1681963920, 1684511580, 1687063020, 1689618720, 1692178680, 1694742000, 1697306100, 1699867620
1544 ); /* end of newMoons array */
1545
1546var Q1Moons = new Array( // unixtime values in UTC/GMT
1547/* 2009 */ /* 02-Feb-2009 23:13 */ 1233616380, 1236152760, 1238682840, 1241210640, 1243740120, 1246274880, 1248818400, 1251373320, 1253940600, 1256517720, 1259098740, 1261676160,
1548/* 2010 */ /* 23-Jan-2010 10:53 */ 1264243980, 1266799320, 1269342000, 1271874000, 1274398980, 1276921740, 1279447800, 1281982440, 1284529800, 1287091620, 1289666340, 1292248740,
1549/* 2011 */ /* 12-Jan-2011 11:31 */ 1294831860, 1297408680, 1299973500, 1302523500, 1305059580, 1307585460, 1310106540, 1312628880, 1315157940, 1317698100, 1320251880, 1322819520,
1550/* 2012 */ /* 01-Jan-2012 06:15 */ 1325398500, 1327983000, 1330564860, 1333136460, 1335693420, 1338236160, 1340767800, 1343292960, 1345816440, 1348342860, 1350876720, 1353421860, 1355980740,
1551/* 2013 */ /* 18-Jan-2013 23:45 */ 1358552700, 1361133060, 1363714020, 1366288260, 1368851640, 1371403440, 1373944680, 1376477760, 1379005680, 1381532520, 1384063020, 1386601920,
1552/* 2014 */ /* 08-Jan-2014 03:39 */ 1389152340, 1391714520, 1394285220, 1396859460, 1399432500, 1402000740, 1404561540, 1407113400, 1409656260, 1412191920, 1414723680, 1417255560, 1419791460,
1553/* 2015 */ /* 27-Jan-2015 04:48 */ 1422334080, 1424884440, 1427442180, 1430006100, 1432574340, 1435143720, 1437710640, 1440271860, 1442825940, 1445373060, 1447914420, 1450451640,
1554/* 2016 */ /* 16-Jan-2016 23:26 */ 1452986760, 1455522360, 1458061380, 1460606340, 1463158920, 1465719000, 1468284720, 1470853260, 1473421740, 1475987580, 1478548260, 1481101380,
1555/* 2017 */ /* 05-Jan-2017 19:47 */ 1483645620, 1486181940, 1488713520, 1491244740, 1493779620, 1496320920, 1498870260, 1501428180, 1503994380, 1506567180, 1509142920, 1511715780, 1514280000,
1556/* 2018 */ /* 24-Jan-2018 22:20 */ 1516832400, 1519373340, 1521905700, 1524433500, 1526960940, 1529491860, 1532029920, 1534578480, 1537139700, 1539712920, 1542293640, 1544874540,
1557/* 2019 */ /* 14-Jan-2019 06:45 */ 1547448300, 1550010360, 1552559220, 1555095960, 1557623520, 1560146340, 1562669700, 1565199060, 1567739400, 1570294020, 1572862980, 1575442680,
1558/* 2020 */ /* 03-Jan-2020 04:45 */ 1578026700, 1580607720, 1583179020, 1585736460, 1588279080, 1590809400, 1593332160, 1595853120, 1598378280, 1600912500, 1603459380, 1606020300, 1608594060,
1559/* 2021 */ /* 20-Jan-2021 21:01 */ 1611176460, 1613760420, 1616337600, 1618901940, 1621451580, 1623988440, 1626516660, 1629040740, 1631565540, 1634095500, 1636634760, 1639186500,
1560/* 2022 */ /* 09-Jan-2022 18:11 */ 1641751860, 1644328200, 1646909100, 1649486880, 1652055660, 1654613280, 1657160040, 1659697560, 1662228480, 1664756040, 1667284620, 1669818960, 1672363200,
1561/* 2023 */ /* 28-Jan-2023 15:19 */ 1674919140, 1677485100, 1680057120, 1682630400, 1685200920, 1687765800, 1690322820, 1692871020, 1695411120, 1697945340, 1700477400
1562 ); /* end of Q1Moons array */
1563
1564var fullMoons = new Array( // unixtime values in UTC/GMT
1565/* 2009 */ /* 09-Feb-2009 14:49 */ 1234190940, 1236739080, 1239288960, 1241841660, 1244398320, 1246958460, 1249520100, 1252080180, 1254636600, 1257189240, 1259739000, 1262286780,
1566/* 2010 */ /* 30-Jan-2010 06:18 */ 1264832280, 1267375080, 1269915900, 1272457080, 1275001620, 1277551800, 1280108160, 1282669500, 1285233420, 1287797760, 1290360420, 1292919180,
1567/* 2011 */ /* 19-Jan-2011 21:21 */ 1295472060, 1298018160, 1300558200, 1303094640, 1305630540, 1308168840, 1310712000, 1313261820, 1315819620, 1318385160, 1320956160, 1323527760,
1568/* 2012 */ /* 09-Jan-2012 07:30 */ 1326094200, 1328651640, 1331199540, 1333739940, 1336275300, 1338808320, 1341341520, 1343878020, 1346421480, 1348975140, 1351540140, 1354113960, 1356690060,
1569/* 2013 */ /* 27-Jan-2013 04:38 */ 1359261480, 1361823960, 1364376420, 1366919820, 1369455900, 1371987120, 1374516900, 1377049500, 1379589180, 1382139480, 1384701360, 1387272480,
1570/* 2014 */ /* 16-Jan-2014 04:52 */ 1389847920, 1392421980, 1394989680, 1397547720, 1400094960, 1402632660, 1405164300, 1407694140, 1410226680, 1412765460, 1415312580, 1417868820,
1571/* 2015 */ /* 05-Jan-2015 04:53 */ 1420433580, 1423004940, 1425578700, 1428149100, 1430710920, 1433261940, 1435803600, 1438339380, 1440873300, 1443408600, 1445947500, 1448491440, 1451041860,
1572/* 2016 */ /* 24-Jan-2016 01:46 */ 1453599960, 1456165200, 1458734460, 1461302640, 1463865240, 1466420520, 1468968960, 1471512360, 1474052700, 1476591780, 1479131520, 1481673900,
1573/* 2017 */ /* 12-Jan-2017 11:34 */ 1484220840, 1486773180, 1489330440, 1491890880, 1494452520, 1497013800, 1499573160, 1502129460, 1504681380, 1507228800, 1509772980, 1512316020,
1574/* 2018 */ /* 02-Jan-2018 02:24 */ 1514859840, 1517405220, 1519951860, 1522499820, 1525049880, 1527603540, 1530161580, 1532722800, 1535284560, 1537843920, 1540399500, 1542951540, 1545500880,
1575/* 2019 */ /* 21-Jan-2019 05:16 */ 1548047760, 1550591580, 1553132580, 1555672320, 1558213860, 1560760260, 1563313080, 1565872140, 1568435580, 1571000880, 1573565640, 1576127520,
1576/* 2020 */ /* 10-Jan-2020 19:21 */ 1578684060, 1581233580, 1583776080, 1586313300, 1588848300, 1591384320, 1593924240, 1596470340, 1599024120, 1601586300, 1604155740, 1606728600, 1609298880,
1577/* 2021 */ /* 28-Jan-2021 19:16 */ 1611861360, 1614413820, 1616957280, 1619494260, 1622027640, 1624560000, 1627094220, 1629633720, 1632182100, 1634741820, 1637312220, 1639888500,
1578/* 2022 */ /* 17-Jan-2022 23:48 */ 1642463280, 1645030560, 1647587820, 1650135300, 1652674440, 1655207520, 1657737480, 1660268160, 1662803940, 1665348900, 1667905320, 1670472480,
1579/* 2023 */ /* 06-Jan-2023 23:08 */ 1673046480, 1675621680, 1678192800, 1680755640, 1683308040, 1685850120, 1688384340, 1690914720, 1693445700, 1695981420, 1698524640, 1701076560
1580 ); /* end of fullMoons array */
1581
1582var Q3Moons = new Array( // unixtime values in UTC/GMT
1583/* 2009 */ /* 16-Feb-2009 21:37 */ 1234820220, 1237398420, 1239975360, 1242545160, 1245104100, 1247651580, 1250189700, 1252721760, 1255251360, 1257782160, 1260317580,
1584/* 2010 */ /* 07-Jan-2010 10:39 */ 1262860740, 1265413680, 1267976520, 1270546620, 1273119300, 1275689580, 1278254100, 1280811540, 1283361720, 1285905120, 1288442760, 1290976560, 1293509880,
1585/* 2011 */ /* 26-Jan-2011 12:57 */ 1296046620, 1298589960, 1301141220, 1303699620, 1306263120, 1308829680, 1311397320, 1313963640, 1316525940, 1319081400, 1321628940, 1324169280,
1586/* 2012 */ /* 16-Jan-2012 09:08 */ 1326704880, 1329239040, 1331774700, 1334314200, 1336859220, 1339411260, 1341971280, 1344538500, 1347110100, 1349681580, 1352248560, 1354807860,
1587/* 2013 */ /* 05-Jan-2013 03:58 */ 1357358280, 1359899760, 1362433980, 1364963760, 1367493240, 1370026680, 1372567980, 1375119780, 1377682500, 1380254100, 1382830800, 1385407680, 1387979280,
1588/* 2014 */ /* 24-Jan-2014 05:20 */ 1390540800, 1393089300, 1395625560, 1398153120, 1400677140, 1403203140, 1405735680, 1408278360, 1410833100, 1413400320, 1415978100, 1418561460,
1589/* 2015 */ /* 13-Jan-2015 09:46 */ 1421142360, 1423713000, 1426268880, 1428810240, 1431340560, 1433864520, 1436387040, 1438912980, 1441446840, 1443992760, 1446553440, 1449128400,
1590/* 2016 */ /* 02-Jan-2016 05:30 */ 1451712600, 1454297280, 1456873860, 1459437420, 1461986940, 1464523920, 1467051540, 1469574000, 1472096460, 1474624560, 1477163640, 1479717180, 1482285360,
1591/* 2017 */ /* 19-Jan-2017 22:13 */ 1484863980, 1487446380, 1490025480, 1492595820, 1495153980, 1497699180, 1500233160, 1502759700, 1505283900, 1507811100, 1510346160, 1512892260,
1592/* 2018 */ /* 08-Jan-2018 22:25 */ 1515450300, 1518018840, 1520594400, 1523171820, 1525745340, 1528309920, 1530863460, 1533406680, 1535942220, 1538473500, 1541004000, 1543537140, 1546076040,
1593/* 2019 */ /* 27-Jan-2019 21:10 */ 1548623400, 1551180480, 1553746200, 1556317080, 1558888380, 1561455960, 1564017480, 1566572160, 1569120060, 1571661540, 1574197860, 1576731420,
1594/* 2020 */ /* 17-Jan-2020 12:58 */ 1579265880, 1581805020, 1584351240, 1586904960, 1589464980, 1592029440, 1594596540, 1597164300, 1599729960, 1602290340, 1604843160, 1607387760,
1595/* 2021 */ /* 06-Jan-2021 09:37 */ 1609925820, 1612460220, 1614994200, 1617530520, 1620071400, 1622618640, 1625173860, 1627737360, 1630307580, 1632880620, 1635451500, 1638016080, 1640571840,
1596/* 2022 */ /* 25-Jan-2022 13:41 */ 1643118060, 1645655520, 1648186620, 1650714960, 1653244980, 1655781060, 1658326680, 1660883760, 1663451520, 1666026900, 1668605220, 1671180960,
1597/* 2023 */ /* 15-Jan-2023 02:10 */ 1673748600, 1676304060, 1678846080, 1681377060, 1683901680, 1686425460, 1688953680, 1691490480, 1694038860, 1696600080, 1699173420, 1701755340
1598 ); /* end of Q3Moons array */
1599// ------------- end of USNO moon data -----------------------------
1600
1601   dt = new Date().getTime()/1000;  // Unix timestamp
1602   if (dt < newMoons[1])                 alert("Moon date must be after " +newMoons[1].date());
1603   if (dt > newMoons[newMoons.length-1]) alert("Moon date must be before "+newMoons[newMoons.length-1].date());
1604
1605   for (mi in newMoons) // find next New Moon from given date
1606      if (newMoons[mi]>dt) break;
1607
1608   // Get Moon dates
1609   NM = newMoons [mi-1]; // previous new moon
1610   Q1 = Q1Moons  [mi-1]; // 1st Q end
1611   Q2 = fullMoons[mi-1]; // 2nd Q end - Full moon
1612   Q3 = Q3Moons  [mi-1]; // 3rd Q end
1613   Q4 = newMoons [mi  ]; // 4th Q end - next new moon
1614
1615   // Divide each phase into 7 periods (4 phases x 7 = 28 periods)
1616   Q1p = Math.round((Q1-NM)/7);
1617   Q2p = Math.round((Q2-Q1)/7);
1618   Q3p = Math.round((Q3-Q2)/7);
1619   Q4p = Math.round((Q4-Q3)/7);
1620
1621   // Determine start and end times for major phases (lasting 1 period of 28)
1622   NMe = NM+(Q1p/2);                      //  0% .... - New moon
1623   Q1s = Q1-(Q1p/2);  Q1e = Q1+(Q2p/2);   // 50% 1stQ - First Quarter
1624   Q2s = Q2-(Q2p/2);  Q2e = Q2+(Q3p/2);   //100% 2ndQ - Full moon
1625   Q3s = Q3-(Q3p/2);  Q3e = Q3+(Q4p/2);   // 50% 3rdQ - Last Quarter
1626   NMs = Q4-(Q4p/2);                      //  0% 4thQ - New Moon
1627
1628// Determine age of moon in days since last new moon
1629   age = (dt - newMoons[mi-1])/86400; // age in days since last new moon
1630   dd  = Math.floor(age);
1631   hh  = Math.floor((age-dd)*24);
1632   mm  = Math.floor((((age-dd)*24)-hh)*60);
1633   age = dd+' days, '+hh+' hours, '+mm+' minutes';
1634
1635// Illumination
1636   switch (true) { // Determine moon age in degrees (0 to 360)
1637   case (dt<=Q1): ma = (dt - NM) * (90 / (Q1 - NM))+  0; break; // NM to Q1
1638   case (dt<=Q2): ma = (dt - Q1) * (90 / (Q2 - Q1))+ 90; break; // Q1 to FM
1639   case (dt<=Q3): ma = (dt - Q2) * (90 / (Q3 - Q2))+180; break; // FM to Q3
1640   case (dt<=Q4): ma = (dt - Q3) * (90 / (Q4 - Q3))+270; break; // Q3 to NM
1641   }
1642   ill = Math.abs(Math.round(100*(1+Math.cos(ma*(Math.PI/180)))/2)-100);
1643
1644// Deterime picture number (0-27) and moon phase
1645   switch (true) {
1646   case (dt<=NMe): pic =  0;                  ph = langMoonPhases[0]; break;
1647   case (dt< Q1s): pic =  1  +((dt-NMe)/Q1p); ph = langMoonPhases[1]; break; // or Waxing Crescent
1648   case (dt<=Q1e): pic =  7;                  ph = langMoonPhases[2]; break;
1649   case (dt< Q2s): pic =  7.5+((dt-Q1e)/Q2p); ph = langMoonPhases[3]; break;
1650   case (dt<=Q2e): pic = 14;                  ph = langMoonPhases[4]; break;
1651   case (dt< Q3s): pic = 14.5+((dt-Q2e)/Q3p); ph = langMoonPhases[5]; break;
1652   case (dt<=Q3e): pic = 21;                  ph = langMoonPhases[6]; break;
1653   case (dt< NMs): pic = 21.5+((dt-Q3e)/Q4p); ph = langMoonPhases[7]; break; // or Waning Crecent
1654   default       : pic =  0;                  ph = langMoonPhases[0];
1655   }
1656   info =
1657      {pic  : Math.round(pic)
1658      ,phase: ph
1659      ,age  : age
1660      ,ill  : ill
1661      };
1662return info;
1663}; // end getMoonInfo function
1664
1665
1666// ----------
1667// PROTOTYPES (PHP equivalents)
1668// ----------
1669
1670// Padding: left and right .. similar to "str_pad" function in php
1671String.prototype.str_pad = function ( cnt, chr, typ ) {
1672var sPad = "";
1673var char = (typeof chr === 'undefined')? "0" : chr;
1674var type = (typeof typ === 'undefined')? "R" : typ;
1675var iPad = cnt - Math.floor(this).toString().length;
1676   for (var i=0;i<iPad;i++) sPad+=char;
1677   return ((type==="R")? (sPad+this) : (this+sPad));
1678};
1679
1680// Make a string's first character uppercase ... similar to "ucfirst" function in php
1681String.prototype.ucfirst = function () {
1682   return this.substr(0,1).toUpperCase() + this.substr(1,this.length);
1683};
1684
1685//Determine the hour, Local Time Zone in JavaScript, not PHP!!!
1686//Must set in reference to UTC, NOT server time, which could be anywhere.
1687function get_hr() {
1688	var now = new Date();
1689	// Difference between Server's time and UTC, in hours.
1690	utc_hrs_diff = now.getTimezoneOffset()/60;
1691	// Local TZ hour adjusted for difference between local and server hours, if any,
1692	// by adjusting the hour to UTC and then adjusting the hour to the preferred TZ
1693	local_tz_hr = (now.getHours()+(utc_hrs_diff + utc_offset))%24;
1694	return local_tz_hr;	
1695}
1696var hr = get_hr();
1697//alert(hr);
1698
1699// Date formating ... similar to "date" function in php
1700Date.prototype.date = function ( fmt ) { // for fmt see "date" function in php eg. str = dt.date("d/m/Y H:i:s") = "28/04/2009 17:37:09"
1701// formats not supported: N, z, W, t, L, o, B, u, e, I, O, P, T, c, r, U
1702   if (typeof fmt === 'undefined')
1703      return (this.toLocaleString()); // ... 26 April 2009 02:12:58 PM
1704
1705   day = this.getDay();      // 0-6  (0=Sunday)
1706   dat = this.getDate();     // 1-31
1707   mth = this.getMonth()+1;  // 1-12 (1=January)
1708   yer = this.getFullYear(); // eg. 2009
1709   hrs = this.getHours();    // 0-23
1710   min = this.getMinutes();  // 0-59
1711   sec = this.getSeconds();  // 0-59
1712   tzo = get_hr()*3600;		// Use get_hr() function to set local tzo, not server tzo -43200 through 50400 seconds
1713//   tzo = this.getTimezoneOffset()*60; // -43200 through 50400 seconds
1714   switch (dat%10) { // day suffix eg. 23rd
1715   case  1: suf = dat===11? langDaySuf[3] : langDaySuf[0];
1716   case  2: suf = dat===12? langDaySuf[3] : langDaySuf[1];
1717   case  3: suf = dat===13? langDaySuf[3] : langDaySuf[2];
1718   default: suf =          langDaySuf[3];
1719   }
1720
1721// date (d, j)
1722   fmt = fmt.replace("d" ,dat.toString().str_pad(2)); // 01 to 31
1723   fmt = fmt.replace("j" ,dat); //  1 to 31
1724// week (w)
1725   fmt = fmt.replace("w" ,day); //  0 to 6
1726// month (m, n)
1727   fmt = fmt.replace("m" ,mth.toString().str_pad(2)); //  01 to 12
1728   fmt = fmt.replace("n" ,mth); // 1 to 12
1729// year (Y, y)
1730   fmt = fmt.replace("Y" ,yer);
1731   fmt = fmt.replace("y" ,yer%100);
1732// am/pm (A, a)
1733   ampm = (hrs<12)? langAM_PM[0] : langAM_PM[1];
1734   AMPM = (hrs<12)? langAM_PM[2] : langAM_PM[3];
1735   fmt = fmt.replace("a" ,ampm);
1736   fmt = fmt.replace("A" ,AMPM);
1737// hours (g, G, h, H)
1738   hrs12 = (hrs%12===0)? 12 : hrs%12;
1739   fmt = fmt.replace("g" ,hrs12); // 1 to 12
1740   fmt = fmt.replace("G" ,hrs);   // 0 to 23
1741   fmt = fmt.replace("h" ,hrs12.toString().str_pad(2)); // 01 to 12
1742   fmt = fmt.replace("H" ,hrs  .toString().str_pad(2)); // 00 to 23
1743// minutes (i)
1744   fmt = fmt.replace("i" ,min.toString().str_pad(2)); // 00 to 59
1745// seconds (s)
1746   fmt = fmt.replace("s" ,sec.toString().str_pad(2)); // 00 to 59
1747// timezone (Z)
1748   fmt = fmt.replace("Z" ,tzo); // -43200 through 50400 seconds
1749// other (S ,l ,D ,F, M)
1750   fmt = fmt.replace(/(\d+)S/g ,"$1"+suf); // eg. rd
1751   fmt = fmt.replace(/l(\s|,|-|\.)/ ,langDays[day]+"$1");                    // eg. Sunday
1752   fmt = fmt.replace(/D(\s|,|-|\.)/ ,langDays[day].substr(0,3)+"$1");     // eg. Sun
1753   fmt = fmt.replace(/F(\s|,|-|\.)/ ,langMonths[mth-1]+"$1");                // eg. January
1754   fmt = fmt.replace(/M(\s|,|-|\.)/ ,langMonths[mth-1].substr(0,3)+"$1"); // eg. Jan
1755   return (fmt);
1756};
1757
1758// returns "-" if number is less than 0
1759Number.prototype.sign = function () {
1760   return (this<0)? "-" : "";
1761};
1762// return rounded integer value of a number
1763Number.prototype.intval = function( dp ) {
1764   return (Math.floor(Math.abs(this.toFixed(dp))));
1765};
1766// return fraction as a rounded integer number
1767Number.prototype.fraction = function( dp ) {
1768   frac = Math.abs(this) - Math.floor(Math.abs(this));
1769   return frac.toFixed(dp);
1770};
1771
1772// Number formating ... thousands seperator and decimal point ... similar to "number_format" function in php
1773// Format a number with grouped thousands eg. str = num.number_format("23823.87273") = "23,823.87"
1774Number.prototype.number_format = function ( dp ,dpSep ,thouSep ) {
1775if (typeof dp === 'undefined') dp = 0;
1776if (typeof dpSep === 'undefined') dpSep = ".";
1777if (typeof thouSep === 'undefined') thouSep = ",";
1778var inum = this.intval(dp).toString();
1779var frac = this.fraction(dp).toString().substr(2);
1780var ret  = this.sign();
1781var f = (inum.length%3===0) ? 3 : inum.length%3;
1782   ret+= inum.substr(0, f);
1783   for (i=f; i<inum.length; i+=3)
1784      ret+= thouSep+inum.substr(i,3);
1785   if (dp>0) ret+=dpSep+frac;
1786return (ret);
1787};
1788
1789//==============================================================================
1790// Get clientrawextra.txt data  (only needs to be loaded once)                 .
1791// -----------------------------------------------------------------------------
1792function ajaxLoader_clientextra(urlExtra) {
1793var rawextra;
1794if (document.getElementById)
1795var x = (window.ActiveXObject) ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(urlExtra);
1796
1797if (x) { // got something back
1798   x.onreadystatechange = function() {
1799      try {
1800         if (x.readyState===4 && x.status===404) { // not found
1801            if (notifyE===1) alert("DASHBOARD ERROR:\nYour \""+clientrawextraFile+"\" file could not be found.");
1802            notifyE++;
1803         } else
1804         if (x.readyState===4 && x.status===200) { // Mike Challis added fix to fix random error: NS_ERROR_NOT_AVAILABLE
1805            rawextra = x.responseText.split(' ');
1806            var wdpattern=/\d+\.\d+.*!!/; // looks for '!!nn.nn!!' version string
1807            if (rawextra[0]==='12345' && (wdpattern.test(x.responseText)) )
1808               clientrawextra = rawextra;
1809            else // only save if fully downloaded
1810               setTimeout("ajaxLoader_clientextra(clientrawextraFile + '?' + new Date().getTime())", extraRetryInterval);
1811            notifyE=0;
1812         } // END if (x.readyState == 4 && x.status == 200)
1813      } // END try
1814      catch(e){}  // Mike Challis added fix to fix random error: NS_ERROR_NOT_AVAILABLE
1815   }; // END x.onreadystatechange = function()
1816
1817   x.open("GET", urlExtra, true);
1818   x.send(null);
1819} // END if(x)
1820};
1821
1822//==============================================================================
1823//  Get clientraw.txt data and format <span class="ajax" id="ajax..."></span> areas
1824// --------------------------------------------------------------------------------
1825function ajaxLoader(url) {
1826;;;var rand = new Date().getTime();
1827
1828if (document.getElementById) {
1829   var x = (window.ActiveXObject) ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(url);
1830} else {
1831   ;;;set_ajax_obs('ajaxProgress',rand+'elem','ERROR: No elements');
1832}
1833if (x) { // got something back
1834x.onreadystatechange = function() {
1835try {
1836   ;;;set_ajax_obs('ajaxProgress',rand+'ready','-- READY --');
1837   if (x.readyState===4 && x.status===200) { // Mike Challis added fix to fix random error: NS_ERROR_NOT_AVAILABLE
1838   var clientraw = x.responseText.split(' ');
1839   // now make sure we got the entire clientraw.txt  -- thanks to Johnnywx
1840   // valid clientraw.txt has '12345' at start and '!!' at end of record
1841   var wdpattern=/\d+\.\d+.*!!/; // looks for '!!nn.nn!!' version string
1842   // If we have a valid clientraw file AND ajaxUpdates is < update.maxupdates
1843
1844   if (clientraw[0] === '12345'
1845   &&  wdpattern.test(x.responseText)
1846   && (ajaxUpdates <= update.maxupdates || update.maxupdates > 0) ) {
1847   ;;;set_ajax_obs('ajaxProgress',rand+'start','-- START --');
1848
1849   if (update.maxupdates > 0) ajaxUpdates++; // increment counter if needed
1850
1851// -----------------------------------------------------------------------------
1852// Date / Time (WD)
1853      ;;;set_ajax_obs('ajaxProgress',rand+'date','in Dates');
1854      WDdt = new Date( clientraw[141], clientraw[36]-1, clientraw[35], clientraw[29], clientraw[30], clientraw[31]);
1855
1856      set_ajax_obs("ajaxndate"   , WDdt.date("F d, Y")); // Apr 16, 2009
1857      set_ajax_obs("ajaxndate2"  , WDdt.date("F d, Y"));  // April 16, 2009
1858      set_ajax_obs("ajaxntime"   , WDdt.date("H:i"));    // 2:37 pm
1859      set_ajax_obs("ajaxntimess" , WDdt.date("H:i:s"));  // 2:37:07 pm
1860      set_ajax_obs("ajaxntimess2" , WDdt.date("H:i:s"));  // 2:37:07 pm
1861      set_ajax_obs("ajaxdname"   , WDdt.date("D"));      // Mon
1862
1863      // current date and time of observation in clientraw.txt
1864      set_ajax_obs("ajaxdatetime", WDdt.date(uom.dateFmt+' '+uom.timeFmt)); // 16/4/2009 02:37:07pm
1865      set_ajax_obs("ajaxdate@"   , WDdt.date(uom.dateFmt) + ' @ '); // 6/4/2009 @
1866      set_ajax_obs("ajaxdate2"   , WDdt.date(uom.dateFmt) + ' @ '); // 6/4/2009 @
1867      set_ajax_obs("ajaxdate3"   , WDdt.date(uom.dateFmt) + ' @ '); // 6/4/2009 @
1868      set_ajax_obs("ajaxdate"    , WDdt.date(uom.dateFmt)); // 16/4/2009
1869      set_ajax_obs("ajaxtime"    , WDdt.date(uom.timeFmt)); // 02:37:07pm
1870      set_ajax_obs("gizmodate"   , WDdt.date(uom.dateFmt)); // 16/4/2009
1871      set_ajax_obs("gizmotime"   , WDdt.date(uom.timeFmt)); // 02:37:07pm
1872      set_ajax_obs("ajaxvers"    , "| Ajax 3.07");  //Set for Alt-Dashboard Ver 6.90+ by Burnsville Weather Live
1873
1874
1875// Outdoor temperature ... (°C)
1876//clientraw[4] = 40.7; // uncomment this for debugging
1877      ;;;set_ajax_obs('ajaxProgress',rand+'temp','in Temp'); // "ajaxProgress" tag for debugging ... gets removed by packer
1878      temp     = parseFloat(clientraw[ 4]).convertTemp();
1879      templast = parseFloat(clientraw[90]).convertTemp(); // last hours temp
1880      tempmax  = parseFloat(clientraw[46]).convertTemp();
1881      tempmin  = parseFloat(clientraw[47]).convertTemp();
1882      if (clientrawextra!==null)
1883           temp24hAgo = parseFloat(clientrawextra[21]).convertTemp();
1884      else temp24hAgo = temp;
1885      temp24hDiff = temp - temp24hAgo;
1886
1887      set_ajax_obs("ajaxtemp"   , temp.toFixed(dp.Temp) + uom.Temp);
1888      set_ajax_obs("ajaxtempNoU", temp.toFixed(dp.Temp));
1889      set_ajax_obs("gizmotemp"  , temp.toFixed(dp.Temp) + uom.Temp);
1890      set_ajax_obs("ajaxbigtemp", temp.toFixed(0) + uom.Temp);
1891
1892      temparrow = ajax_getTrendArrow( temp
1893                                    , templast
1894                                    , ''
1895                                    , langTempRising+uom.Temp+langTempLastHour
1896                                    , langTempFalling+uom.Temp+langTempLastHour
1897                                    , 1
1898                                    );
1899      set_ajax_obs("ajaxtemparrow" , (temp-templast).toFixed(dp.Temp), temparrow);
1900      set_ajax_obs("gizmotemparrow", temparrow);
1901
1902      temprate = temp - templast;
1903      temprate = temprate.toFixed(1);
1904      if (temprate > 0.0) { temprate = '+' + temprate; } // add a '+' for positive rates
1905      set_ajax_obs("ajaxtemprate" , temprate + uom.Temp);
1906      set_ajax_obs("gizmotemprate", temprate + uom.Temp);
1907
1908      set_ajax_obs("ajaxtempmax"   , tempmax    .toFixed(dp.Temp) + uom.Temp);
1909      set_ajax_obs("ajaxtempmin"   , tempmin    .toFixed(dp.Temp) + uom.Temp);
1910
1911      set_ajax_obs("ajax24hDiff"   , temp24hDiff.toFixed(dp.Temp) + uom.Temp);
1912      diffarrow = ajax_getTrendArrow( temp
1913                                    , temp24hAgo
1914                                    , ''
1915                                    , langTempRising+uom.Temp+langTempYesterday
1916                                    , langTempFalling+uom.Temp+langTempYesterday
1917                                    , 1
1918                                    );
1919      set_ajax_obs("ajax24hDiffarrow", (temp-temp24hDiff).toFixed(dp.Temp), diffarrow);
1920
1921
1922// Thermometer ...
1923      ;;;set_ajax_obs('ajaxProgress',rand+'term','in Thermometer');
1924      thermometerText = langThermoCurrently + temp.toFixed(dp.Temp) + uom.Temp
1925                  + ", " + langThermoMax + tempmax.toFixed(dp.Temp) + uom.Temp
1926                  + ", " + langThermoMin + tempmin.toFixed(dp.Temp) + uom.Temp;
1927
1928      param = '?uom=' + useUOM
1929            + '&t='   + temp.toFixed(dp.Temp)
1930            + '&iW='  + thermometerImg.width
1931            + '&iH='  + thermometerImg.height;
1932      set_ajax_obs("ajaxthermometer", param
1933         , '<img src="' + thermometerImg.src + param
1934         + '" alt="'    + thermometerText
1935         + '" title="'  + thermometerText
1936         + '" width="'  + thermometerImg.width
1937         + '" height="' + thermometerImg.height
1938         + '" hspace="' + thermometerImg.hspace
1939         + '" vspace="' + thermometerImg.vspace
1940         + '" border="' + thermometerImg.border
1941         + '" align="'  + thermometerImg.align
1942         + '" style="'  + thermometerImg.style
1943         + '" />');
1944      set_ajax_obs("ajaxcellthermometer", param
1945         , '<img src="' + cellthermometerImg.src + param
1946         + '" alt="'    + thermometerText
1947         + '" title="'  + thermometerText
1948         + '" width="'  + thermometerImg.width
1949         + '" height="' + thermometerImg.height
1950         + '" hspace="' + thermometerImg.hspace
1951         + '" vspace="' + thermometerImg.vspace
1952         + '" border="' + thermometerImg.border
1953         + '" align="'  + thermometerImg.align
1954         + '" style="'  + thermometerImg.style
1955         + '" />');
1956
1957
1958// Dewpoint ... (°C)
1959//clientraw[72] = -2.4
1960      ;;;set_ajax_obs('ajaxProgress',rand+'dewp','in Dewpoint');
1961      dew    = parseFloat(clientraw[ 72]).convertTemp();
1962      dewmin = parseFloat(clientraw[139]).convertTemp();
1963      dewmax = parseFloat(clientraw[138]).convertTemp();
1964
1965      set_ajax_obs("ajaxdew"   , dew   .toFixed(dp.Temp) + uom.Temp);
1966      set_ajax_obs("gizmodew"  , dew   .toFixed(dp.Temp) + uom.Temp);
1967      set_ajax_obs("ajaxdewmin", dewmin.toFixed(dp.Temp) + uom.Temp);
1968      set_ajax_obs("ajaxdewmax", dewmax.toFixed(dp.Temp) + uom.Temp);
1969
1970
1971// WetBulb ... (°C)
1972      ;;;set_ajax_obs('ajaxProgress',rand+'wetb','in Wetbulb');
1973      wetbulb = parseFloat(clientraw[159]).convertTemp();
1974      set_ajax_obs("ajaxwetbulb",wetbulb.toFixed(dp.Temp) + uom.Temp);
1975
1976// Humidex ... (°C)
1977      humidex    = parseFloat(clientraw[45]).convertTemp();
1978      humidexmin = parseFloat(clientraw[76]).convertTemp();
1979      humidexmax = parseFloat(clientraw[75]).convertTemp();
1980
1981      set_ajax_obs("ajaxhumidex"   , humidex   .toFixed(dp.Temp) + uom.Temp);
1982      set_ajax_obs("ajaxhumidexmin", humidexmin.toFixed(dp.Temp) + uom.Temp);
1983      set_ajax_obs("ajaxhumidexmax", humidexmax.toFixed(dp.Temp) + uom.Temp);
1984
1985
1986// Heat Index ... (°C)
1987      heatidx    = parseFloat(clientraw[112]).convertTemp();
1988      heatidxmin = parseFloat(clientraw[111]).convertTemp();
1989      heatidxmax = parseFloat(clientraw[110]).convertTemp();
1990
1991      set_ajax_obs("ajaxheatidx"   , heatidx   .toFixed(dp.Temp) + uom.Temp);
1992      set_ajax_obs("ajaxheatidx2"   , heatidx   .toFixed(dp.Temp) + uom.Temp);
1993      set_ajax_obs("ajaxheatidxmin", heatidxmin.toFixed(dp.Temp) + uom.Temp);
1994      set_ajax_obs("ajaxheatidxmax", heatidxmax.toFixed(dp.Temp) + uom.Temp);
1995
1996
1997// WindChill ... (°C)
1998      windchill    = parseFloat(clientraw[44]).convertTemp();
1999      windchillmin = parseFloat(clientraw[78]).convertTemp();
2000      windchillmax = parseFloat(clientraw[77]).convertTemp();
2001
2002      set_ajax_obs("ajaxwindchill"   , windchill   .toFixed(dp.Temp) + uom.Temp);
2003      set_ajax_obs("ajaxwindchill2"   , windchill   .toFixed(dp.Temp) + uom.Temp);
2004      set_ajax_obs("ajaxwindchillmin", windchillmin.toFixed(dp.Temp) + uom.Temp);
2005      set_ajax_obs("ajaxwindchillmax", windchillmax.toFixed(dp.Temp) + uom.Temp);
2006
2007
2008// FeelsLike ... (°C)
2009      ;;;set_ajax_obs('ajaxProgress',rand+'feel','in Feelslike');
2010      temp = clientraw[4]; // note.. temp in C
2011//      switch (true) {
2012//      case (temp<=16.0): feelslike = clientraw[44]; break; // use WindChill
2013//      case (temp>=27.0): feelslike = clientraw[45]; break; // use Humidex
2014//      default          : feelslike = temp;                 // use temperature
2015//      }
2016        if (temp <= 16.0 ) {
2017		  feelslike = clientraw[44]; //use WindChill
2018		  feelslike1 = clientraw[44]; //use WindChill
2019		} else if (temp >=27.0) {
2020		  feelslike = clientraw[45]; //use Humidex
2021		  feelslike1 = clientraw[45]; //use Humidex
2022		} else {
2023		  feelslike = temp;   // use temperature
2024		  feelslike1 = temp;   // use temperature
2025      }
2026      feelslike  = Math.round(parseFloat(feelslike).convertTemp());
2027        feelslike1  = Math.round(parseFloat(feelslike1).convertTemp());
2028      set_ajax_obs("ajaxfeelslike" , feelslike + uom.Temp);
2029        set_ajax_obs("ajaxfeelslike1",feelslike1 + uom.Temp);
2030
2031	  //Indoor
2032	  indoortemp = (parseFloat(clientraw[12]).convertTemp()).toFixed(1);
2033	  set_ajax_obs("ajaxindoortemp",indoortemp + uom.Temp);
2034
2035	  indoorhumid = clientraw[13];
2036	  set_ajax_obs("ajaxindoorhumid",indoorhumid);
2037
2038      // mike challis added heatColorWord feature
2039      heatColorWord = ajax_getHeatColorWord(clientraw[4],clientraw[44],clientraw[45]);
2040      set_ajax_obs("ajaxheatcolorword", heatColorWord);
2041
2042      temp = parseFloat(clientraw[ 4]).convertTemp();
2043      tempColorBg = ajax_getHeatColorTemp(clientraw[4],clientraw[44],clientraw[45], temp);
2044      set_ajax_obs("ajaxtempcolor", temp.toFixed(dp.Temp), tempColorBg);
2045
2046
2047// Apparent temperature ... (°C)
2048      apparenttemp    = parseFloat(clientraw[130]).convertTemp();
2049      apparenttempmin = parseFloat(clientraw[136]).convertTemp();
2050      apparenttempmax = parseFloat(clientraw[137]).convertTemp();
2051
2052      set_ajax_obs("ajaxapparenttemp"   , apparenttemp   .toFixed(dp.Temp) + uom.Temp);
2053      set_ajax_obs("ajaxapparenttempmin", apparenttempmin.toFixed(dp.Temp) + uom.Temp);
2054      set_ajax_obs("ajaxapparenttempmax", apparenttempmax.toFixed(dp.Temp) + uom.Temp);
2055
2056
2057// Humidity ... %
2058//clientraw[5] = 100;
2059      ;;;set_ajax_obs('ajaxProgress',rand+'humi','in Humidity');
2060      humidity = clientraw[5];
2061      set_ajax_obs("ajaxhumidity" , humidity);
2062      set_ajax_obs("gizmohumidity", humidity);
2063      // sorry.. no min/max data for humidity available in clientraw.txt
2064
2065
2066// Pressure ... (hPa)
2067      ;;;set_ajax_obs('ajaxProgress',rand+'baro','in Baro');
2068      pressure      = parseFloat(clientraw[  6]).convertBaro();
2069      pressuremin   = parseFloat(clientraw[132]).convertBaro();;
2070      pressuremax   = parseFloat(clientraw[131]).convertBaro();;
2071      pressuretrend = parseFloat(clientraw[ 50]).convertBaro();
2072      barotrendtext = ajax_getBaroTrend(clientraw[50]);
2073
2074      set_ajax_obs("ajaxbaro"      , pressure.toFixed(dp.Baro) +' '+ uom.Baro);
2075      set_ajax_obs("ajaxbaroNoU"   , pressure.toFixed(dp.Baro));
2076      set_ajax_obs("gizmobaro"     , pressure.toFixed(dp.Baro) +' '+ uom.Baro);
2077
2078      pressuretrend = pressuretrend.toFixed(dp.Baro+1);
2079      if (pressuretrend > 0.0) {pressuretrend = '+' + pressuretrend; } // add '+' to rate
2080      set_ajax_obs("ajaxbarotrend" , pressuretrend + uom.Baro);
2081      set_ajax_obs("gizmobarotrend", pressuretrend + uom.Baro);
2082      baroarrow = ajax_getTrendArrow( pressure
2083                                    , pressure-pressuretrend
2084                                    , ''
2085                                    , langBaroRising +uom.Baro+langBaroPerHour
2086                                    , langBaroFalling+uom.Baro+langBaroPerHour
2087                                    , 2
2088                                    );
2089      set_ajax_obs("ajaxbaroarrow"     , pressuretrend, baroarrow);
2090      set_ajax_obs("ajaxbarotrendtext" , barotrendtext);
2091      set_ajax_obs("gizmobarotrendtext", barotrendtext);
2092      set_ajax_obs("ajaxbaromin"       , pressuremin.toFixed(dp.Baro) +' '+ uom.Baro);
2093      set_ajax_obs("ajaxbaromax"       , pressuremax.toFixed(dp.Baro) +' '+ uom.Baro);
2094
2095
2096// Wind ... (kts)
2097//clientraw[  2] = 10.2;
2098//clientraw[140] = 20.2;
2099      ;;;set_ajax_obs('ajaxProgress',rand+'wspd','in WindSpeed');
2100      wind        = parseFloat(clientraw[  2]).convertWind(); // Wind gust
2101      gust        = parseFloat(clientraw[140]).convertWind(); // Max wind gust in last minute
2102      windmaxavg  = parseFloat(clientraw[113]).convertWind(); // Max avg speed
2103      maxgust     = parseFloat(clientraw[ 71]).convertWind(); // Max wind gust
2104      maxgusttime  = clientraw[135].replace("_", " ");         // Max wind gust time
2105      beaufortnum = ajax_getBeaufortNumber(clientraw[2]);
2106
2107   // Wind Run
2108   //clientraw[173] = 25.5
2109   	  windrun	  = parseFloat(clientraw[173]).convertDist(); // Wind Run Today
2110      ;;;set_ajax_obs('ajaxwindrun', windrun.toFixed(dp.Dist) +' '+ uom.Dist);
2111
2112   // Wind gust
2113      if (maxgust > 0.0 )
2114           set_ajax_obs("ajaxmaxgust"   , maxgust.toFixed(dp.Wind) +' '+ uom.langWind);
2115      else set_ajax_obs("ajaxmaxgust"   , 'Calm');
2116
2117   // Max wind gust
2118      set_ajax_obs("ajaxwindmaxgust"    , maxgust.toFixed(dp.Wind) +' '+ uom.langWind);
2119      set_ajax_obs("ajaxwindmaxgusttime", maxgusttime);
2120
2121   // Max wind gust No UofM
2122      set_ajax_obs("ajaxwindmaxgust2"    , maxgust.toFixed(dp.Wind));
2123
2124// Windspeed ... beaufort
2125      set_ajax_obs("ajaxbeaufortnum"    , beaufortnum);
2126      set_ajax_obs("ajaxbeaufort"       , langBeaufort[beaufortnum]);
2127
2128   // Max avg speed
2129      set_ajax_obs("ajaxwindmaxavg"     , windmaxavg.toFixed(dp.Wind) +' '+ uom.langWind);
2130
2131   // Current wind speed
2132      if (wind > 0.0) {
2133      set_ajax_obs("ajaxwind"      , wind.toFixed(dp.Wind) +' '+ uom.langWind);
2134      set_ajax_obs("ajaxwind2"      , wind.toFixed(dp.Wind) +' '+ uom.langWind);
2135      set_ajax_obs("ajaxwindNoU"   , wind.toFixed(dp.Wind));
2136      set_ajax_obs("gizmowind"     , wind.toFixed(dp.Wind) +' '+ uom.langWind);
2137      set_ajax_uom("ajaxwinduom"   , true);
2138      } else {
2139      set_ajax_obs("ajaxwind"      , langWindCalm);
2140      set_ajax_obs("ajaxwind2"      , langWindCalm);
2141      set_ajax_obs("ajaxwindNoU"   , langWindCalm);
2142      set_ajax_obs("gizmowind"     , langWindCalm);
2143      set_ajax_uom("ajaxwinduom"   , false);
2144      }
2145
2146   // Current gust speed
2147      if (gust > 0.0) {
2148      set_ajax_obs("ajaxgust"      , gust.toFixed(dp.Wind) +' '+ uom.langWind);
2149      set_ajax_obs("ajaxgust2"      , gust.toFixed(dp.Wind) +' '+ uom.langWind);
2150      set_ajax_obs("ajaxgustNoU"   , gust.toFixed(dp.Wind));
2151      set_ajax_obs("gizmogust"     , gust.toFixed(dp.Wind) +' '+ uom.langWind);
2152      set_ajax_uom("ajaxgustuom"   , true);
2153      } else {
2154      set_ajax_obs("ajaxgust"      , langGustNone);
2155      set_ajax_obs("ajaxgust2"      , langGustNone);
2156      set_ajax_obs("ajaxgustNoU"   , langGustNone);
2157      set_ajax_obs("gizmogust"     , langGustNone);
2158      set_ajax_uom("ajaxgustuom"   , false);
2159      }
2160
2161
2162// Wind direction & wind rose grapic ...
2163      ;;;set_ajax_obs('ajaxProgress',rand+'wdir','in WindDir');
2164      windDeg   = parseFloat(clientraw[3]);
2165      windDir   = ajax_getWindDir(clientraw[3]);
2166      valLang   = ajax_getWindDirLang(clientraw[3]); /* to enable translations */
2167
2168      ;;;set_ajax_obs('ajaxProgress',rand+'rose','in WindRose');
2169      if (gust > 0.0 || wind > 0.0 || wrImg.calm==="") {
2170         windicon = '<img src="' + imgDir + windDir + '.gif' // small arrow direction
2171            + '" alt="'   + langWindFrom + valLang
2172            + '" title="' + langWindFrom + valLang
2173            + '" width="14" height="14" />';
2174         set_ajax_obs("ajaxwindicon"  , valLang, windicon);
2175         set_ajax_obs("gizmowindicon" , valLang, windicon);
2176         set_ajax_obs("ajaxwinddir"   , valLang);
2177         set_ajax_obs("ajaxwinddir2"   , valLang);
2178         set_ajax_obs("gizmowinddir"  , valLang);
2179         set_ajax_obs("ajaxwinddeg"   , windDeg + uom.Deg);
2180         set_ajax_obs("gizmowinddeg"  , windDeg + uom.Deg);
2181
2182         src = wrImg.src.replace(/(#LANG#|\{LANG\})/i, wrImg.lang);
2183         src = src.replace      (/(#DIR#|\{DIR\})/i  , wrImg.xlate? valLang : windDir);
2184         set_ajax_obs(wrImg.useTag, src
2185            , '<img src="' + src
2186            + '" alt="'    + langWindFrom + valLang
2187            + '" title="'  + langWindFrom + valLang
2188            + '" width="'  + wrImg.width
2189            + '" height="' + wrImg.height
2190            + '" hspace="' + wrImg.hspace
2191            + '" vspace="' + wrImg.vspace
2192            + '" border="' + wrImg.border
2193            + '" align="'  + wrImg.align
2194            + '" style="'  + wrImg.style
2195            + '" />');
2196      } else { // Wind calm
2197         set_ajax_obs("ajaxwindicon"  , "");
2198         set_ajax_obs("gizmowindicon" , "");
2199         set_ajax_obs("ajaxwinddir"   , "");
2200         set_ajax_obs("gizmowinddir"  , "");
2201         set_ajax_obs("ajaxwinddeg"   , "");
2202         set_ajax_obs("gizmowinddeg"  , "");
2203
2204         src = wrImg.src.replace(/(#LANG#|\{LANG\})/i, wrImg.lang);
2205         src = src.replace      (/(#DIR#|\{DIR\})/i  , wrImg.calm);
2206         set_ajax_obs(wrImg.useTag , src
2207            , '<img src="' + src
2208            + '" alt="'    + langBeaufort[0]
2209            + '" title="'  + langBeaufort[0]
2210            + '" width="'  + wrImg.width
2211            + '" height="' + wrImg.height
2212            + '" hspace="' + wrImg.hspace
2213            + '" vspace="' + wrImg.vspace
2214            + '" border="' + wrImg.border
2215            + '" align="'  + wrImg.align
2216            + '" style="'  + wrImg.style
2217            + '" />');
2218      }
2219
2220
2221// Solar Radiation
2222      ;;;set_ajax_obs('ajaxProgress',rand+'sol','in Solar');
2223      solar    = clientraw[127] * 1.0;
2224      solarpct = clientraw[34];
2225      if (clientrawextra!==null) {maxsolar = clientrawextra[684];}
2226	  	else {maxsolar = 1500;}
2227      set_ajax_obs("ajaxsolar"   ,solar.toFixed(0));
2228      set_ajax_obs("ajaxsolarpct",solarpct);
2229
2230      SII = Math.min(10,Math.round(solar*10/maxsolar));
2231      src = siImg.src.replace(/(#INDEX#|\{INDEX\})/i, SII);
2232      set_ajax_obs(siImg.useTag, SII
2233         ,'<img src="'  + src
2234         + '" alt="'    + SII
2235         + '" title="Current Solar Index Using WM2'
2236         + '" width="'  + siImg.width
2237         + '" height="' + siImg.height
2238         + '" hspace="' + siImg.hspace
2239         + '" vspace="' + siImg.vspace
2240         + '" border="' + siImg.border
2241         + '" align="'  + siImg.align
2242         + '" style="'  + siImg.style
2243         + '" />');
2244
2245      SII2 = Math.min(10,Math.floor(solarpct*0.1));
2246      src = siImg2.src.replace(/(#INDEX#|\{INDEX\})/i, SII2);
2247      set_ajax_obs(siImg2.useTag, SII2
2248         ,'<img src="'  + src
2249         + '" alt="'    + SII2
2250         + '" title="Current Solar Index Using Solar%'
2251         + '" width="'  + siImg2.width
2252         + '" height="' + siImg.height
2253         + '" hspace="' + siImg2.hspace
2254         + '" vspace="' + siImg2.vspace
2255         + '" border="' + siImg2.border
2256         + '" align="'  + siImg2.align
2257         + '" style="'  + siImg2.style
2258         + '" />');
2259
2260
2261// UV Index
2262      ;;;set_ajax_obs('ajaxProgress',rand+'uv','in UV');
2263      uv = parseFloat(clientraw[79]);
2264      set_ajax_obs("ajaxuv"   ,uv.toFixed(dp.UV));
2265      set_ajax_obs("ajaxuvNoD",uv.toFixed(0));
2266      set_ajax_obs("gizmouv"  ,uv.toFixed(dp.UV)) ;
2267
2268      uvword = ajax_getUVrange(uv);
2269      set_ajax_obs("ajaxuvword" ,uv, uvword);
2270      set_ajax_obs("gizmouvword",uv, uvword);
2271
2272      uvburnrate = ajax_getUVburnRate(uv);
2273      set_ajax_obs("ajaxuvburnrate",uvburnrate);
2274
2275      UVI = Math.min(11,Math.round(uv));
2276      src = uvImg.src.replace(/(#INDEX#|\{INDEX\})/i, UVI);
2277      set_ajax_obs(uvImg.useTag, UVI
2278         ,'<img src="'  + src
2279         + '" alt="'    + UVI
2280         + '" title="Current UV Index'
2281         + '" width="'  + uvImg.width
2282         + '" height="' + uvImg.height
2283         + '" hspace="' + uvImg.hspace
2284         + '" vspace="' + uvImg.vspace
2285         + '" border="' + uvImg.border
2286         + '" align="'  + uvImg.align
2287         + '" style="'  + uvImg.style
2288         + '" />');
2289
2290// Rain ... (mm)
2291      ;;;set_ajax_obs('ajaxProgress',rand+'rain','in Rain');
2292      rain        = parseFloat( clientraw[ 7]).convertRain();
2293      rainYes     = parseFloat( clientraw[19]).convertRain();
2294      rainMonth   = parseFloat( clientraw[ 8]).convertRain();
2295      rainYear    = parseFloat( clientraw[ 9]).convertRain();
2296      rainratehr  = parseFloat((clientraw[10])*60).convertRain(); // make per hour rate.
2297      rainratemax = parseFloat((clientraw[11])*60).convertRain(); // make per hour rate
2298
2299      set_ajax_obs("ajaxrainratehr" ,rainratehr .toFixed(dp.Rain+1) +' '+ uom.Rain);
2300      set_ajax_obs("ajaxrainratemax",rainratemax.toFixed(dp.Rain+1) +' '+ uom.Rain);
2301
2302      set_ajax_obs("ajaxrain"       ,rain   .toFixed(dp.Rain)   +' '+ uom.Rain);
2303      set_ajax_obs("ajaxrain2"      ,rain   .toFixed(dp.Rain)   +' '+ uom.Rain);
2304      set_ajax_obs("ajaxrainYes"    ,rainYes.toFixed(dp.Rain)   +' '+ uom.Rain);
2305      set_ajax_obs("ajaxrainydy"    ,rainYes.toFixed(dp.Rain)   +' '+ uom.Rain); // old yesterdays rain tag for compatibility
2306
2307      set_ajax_obs("ajaxrainmo"     ,rainMonth.toFixed(dp.Rain) +' '+ uom.Rain);
2308      set_ajax_obs("ajaxrainyr"     ,rainYear .toFixed(dp.Rain) +' '+ uom.Rain);
2309
2310      set_ajax_obs("ajaxrainNoU"    ,rain     .toFixed(dp.Rain));
2311      set_ajax_obs("gizmorain"      ,rain     .toFixed(dp.Rain) +' '+ uom.Rain);
2312
2313      if (clientrawextra!==null) {
2314         ;;;set_ajax_obs('ajaxProgress',rand+'rainex','in Rain Extra');
2315         // Rain in last week
2316         rainMon = parseFloat((clientrawextra[484])/10).convertRain();
2317         rainTue = parseFloat((clientrawextra[485])/10).convertRain();
2318         rainWed = parseFloat((clientrawextra[486])/10).convertRain();
2319         rainThu = parseFloat((clientrawextra[487])/10).convertRain();
2320         rainFri = parseFloat((clientrawextra[488])/10).convertRain();
2321         rainSat = parseFloat((clientrawextra[489])/10).convertRain();
2322         rainSun = parseFloat((clientrawextra[490])/10).convertRain();
2323         set_ajax_obs("ajaxrainSun" ,rainSun.toFixed(dp.Rain) +' '+ uom.Rain);
2324         set_ajax_obs("ajaxrainMon" ,rainMon.toFixed(dp.Rain) +' '+ uom.Rain);
2325         set_ajax_obs("ajaxrainTue" ,rainTue.toFixed(dp.Rain) +' '+ uom.Rain);
2326         set_ajax_obs("ajaxrainWed" ,rainWed.toFixed(dp.Rain) +' '+ uom.Rain);
2327         set_ajax_obs("ajaxrainThu" ,rainThu.toFixed(dp.Rain) +' '+ uom.Rain);
2328         set_ajax_obs("ajaxrainFri" ,rainFri.toFixed(dp.Rain) +' '+ uom.Rain);
2329         set_ajax_obs("ajaxrainSat" ,rainSat.toFixed(dp.Rain) +' '+ uom.Rain);
2330
2331         // Record alltime daily rain
2332         rcdRain   = parseFloat(clientrawextra[349]).convertRain();
2333         rcdRainDt = new Date ( clientrawextra[354], clientrawextra[353]-1, clientrawextra[352] // YMD
2334                              , clientrawextra[350], clientrawextra[351]  , 0); //HMS
2335         set_ajax_obs("ajaxRcdRain"    , rcdRain.toFixed(dp.Rain) +' '+ uom.Rain);
2336         set_ajax_obs("ajaxRcdRainTime", rcdRainDt.date(uom.timeHM));
2337         set_ajax_obs("ajaxRcdRainDate", rcdRainDt.date(uom.dateFmt));
2338
2339         // Record alltime daily rain in 1 hour
2340         rcdRainHr   = parseFloat(clientrawextra[355]).convertRain();
2341         rcdRainHrDt = new Date ( clientrawextra[360], clientrawextra[359]-1, clientrawextra[358] // YMD
2342                                , clientrawextra[356], clientrawextra[357]  , 0); //HMS
2343         set_ajax_obs("ajaxRcdRainHr"    , rcdRainHr.toFixed(dp.Rain) +' '+ uom.Rain);
2344         set_ajax_obs("ajaxRcdRainHrTime", rcdRainHrDt.date(uom.timeHM));
2345         set_ajax_obs("ajaxRcdRainHrDate", rcdRainHrDt.date(uom.dateFmt));
2346
2347         // Days with/without rain
2348         daysRain   = parseInt( clientrawextra[483]); // nr of days with rain (MTD)
2349         daysNoRain = parseInt( clientrawextra[482]); // nr of days since last rain
2350         set_ajax_obs("ajaxDaysRain"  , daysRain   );
2351         set_ajax_obs("ajaxDaysNoRain", daysNoRain );
2352      }
2353
2354
2355// Snow ... (cm)
2356      ;;;set_ajax_obs('ajaxProgress',rand+'snow','in Snow');
2357      if (clientrawextra!==null) {
2358         snowToday  = parseFloat(clientrawextra[479]).convertSnow();
2359         snowMonth  = parseFloat(clientrawextra[480]).convertSnow();
2360         snowSeason = parseFloat(clientrawextra[481]).convertSnow();
2361         snowDepth  = parseFloat(clientrawextra[697]).convertSnow();
2362         set_ajax_obs("ajaxsnowToday" ,snowToday .toFixed(dp.Snow) +' '+ uom.Snow);
2363         set_ajax_obs("ajaxsnowToday2" ,snowToday .toFixed(dp.Snow) +' '+ uom.Snow);
2364         set_ajax_obs("ajaxsnowMonth" ,snowMonth .toFixed(dp.Snow) +' '+ uom.Snow);
2365         set_ajax_obs("ajaxsnowSeason",snowSeason.toFixed(dp.Snow) +' '+ uom.Snow);
2366         set_ajax_obs("ajaxsnowDepth" ,snowDepth .toFixed(dp.Snow) +' '+ uom.Snow);
2367      }
2368
2369
2370// Lightning ...
2371      ;;;set_ajax_obs('ajaxProgress',rand+'ligh','in Lightning');
2372
2373      lighteningcountlastminute = clientraw[114];
2374      set_ajax_obs("ajaxlightning",lighteningcountlastminute);
2375
2376      lastlightningstriketime = clientraw[115];
2377      set_ajax_obs("ajaxlightningtime",lastlightningstriketime);
2378
2379      lastlightningstrikedate = clientraw[116];
2380      set_ajax_obs("ajaxlightningdate",lastlightningstrikedate);
2381
2382      lighteningdistance = parseFloat(clientraw[118]).convertDist();
2383      set_ajax_obs("ajaxlightningdist",lighteningdistance .toFixed(dp.Dist) +' '+ uom.Dist);
2384
2385      lighteningbearing = clientraw[119];
2386      set_ajax_obs("ajaxlightningbearing",lighteningbearing + uom.Deg);
2387
2388
2389// Cloud Height ... (meters)
2390      ;;;set_ajax_obs('ajaxProgress',rand+'cloud','in Clouds');
2391      temp = clientraw[ 4];
2392      dewp = clientraw[72];
2393      pres = parseFloat(clientraw[6]).convertBaro();
2394      rain = parseFloat(clientraw[7]).convertRain();
2395      wind = parseFloat(clientraw[1]).convertWind(); // gust = clientraw[2]
2396      wdir = ajax_getWindDirLang(clientraw[3]);
2397      cloudheight = Math.max(0,(temp-dewp)/0.00802)*1.0 + cloudImg.stationAlt; // in meters
2398      altitude = Math.round(cloudheight.convertAlti());
2399      above = (cloudImg.stationAlt>0)? ' ASL' : ' AGL';
2400      cloudText = altitude.toString() + uom.Alti + above;
2401      param = '?uom=' + useUOM + '&buster=' + altitude + pres + beaufortnum + rain;
2402      set_ajax_obs("ajaxcloudheightimg", param
2403         ,'<img src="'  + cloudImg.src + param
2404         + '" alt="'    + cloudText
2405         + '" title="'  + cloudText
2406         + '" width="'  + cloudImg.width
2407         + '" height="' + cloudImg.height
2408         + '" hspace="' + cloudImg.hspace
2409         + '" vspace="' + cloudImg.vspace
2410         + '" align="'  + cloudImg.align
2411         + '" border="' + cloudImg.border
2412         + '" style="'  + cloudImg.style
2413         + '" />');
2414      set_ajax_obs("ajaxcloudheight",cloudText);
2415
2416
2417// Fire Risk ... (FWI)
2418      ;;;set_ajax_obs('ajaxProgress',rand+'fire','in Fire Risk');
2419      if (clientrawextra!==null) {
2420         FWI = parseFloat(clientrawextra[635]).toFixed(1);
2421         set_ajax_obs("ajaxfireindex",FWI);
2422         idx = ajax_getFireIndex(FWI ,fireImg);
2423         src = fireImg.src.replace(/(#IMGNR#|\{IMGNR\})/i ,idx);
2424         set_ajax_obs(fireImg.useTag, idx
2425            ,'<img src="'  + src
2426            + '" alt="'    + FWI
2427            + '" title="'  + FWI
2428            + '" width="'  + fireImg.width
2429            + '" height="' + fireImg.height
2430            + '" hspace="' + fireImg.hspace
2431            + '" vspace="' + fireImg.vspace
2432            + '" border="' + fireImg.border
2433            + '" align="'  + fireImg.align
2434            + '" style="'  + fireImg.style
2435            + '" />');
2436      }
2437
2438      liveFWI   = 2*Math.exp(-0.45+0.987*Math.log(10, 2.71828183)-0.0345*humidity+0.0338*temp+0.0234*wind);
2439      set_ajax_obs("ajaxLiveFWI","Live FWI: "+liveFWI.toFixed(1));
2440      liveFWI10 = 2*Math.exp(-0.45+0.987*Math.log(10, 2.71828183)-0.0345*humidity+0.0338*temp+0.0234*windmaxavg);
2441      set_ajax_obs("ajaxLiveFWI10","Live FWI: "+liveFWI10.toFixed(1));
2442
2443
2444// Fire Risk ... (CBI)
2445      ;;;set_ajax_obs('ajaxProgress',rand+'fire','in CBI');
2446      if (clientrawextra!==null) {
2447         CBI = parseFloat(clientrawextra[765]);
2448         set_ajax_obs("ajaxcbiindex",CBI);
2449         idx = ajax_getCBIIndex(CBI ,fireImg2);
2450         src = fireImg2.src.replace(/(#IMGNR#|\{IMGNR\})/i ,idx);
2451         set_ajax_obs(fireImg2.useTag, idx
2452            ,'<img src="'  + src
2453            + '" alt="'    + CBI
2454            + '" title="'  + CBI
2455            + '" width="'  + fireImg2.width
2456            + '" height="' + fireImg2.height
2457            + '" hspace="' + fireImg2.hspace
2458            + '" vspace="' + fireImg2.vspace
2459            + '" border="' + fireImg2.border
2460            + '" align="'  + fireImg2.align
2461            + '" style="'  + fireImg2.style
2462            + '" />');
2463      }
2464
2465
2466// Leaf wetness ...
2467      ;;;set_ajax_obs('ajaxProgress',rand+'leaf','in Leaf wetness');
2468      VPleaf = clientraw[156] * 1.0;
2469      set_ajax_obs("ajaxVPleaf" ,VPleaf);
2470
2471
2472// Sun/Moon rise/set (needed by all functions below) ...
2473      if (clientrawextra!==null) {
2474         ;;;set_ajax_obs('ajaxProgress',rand+'getMS','stuck in sun/moon info');
2475         YY = clientraw[141];
2476         MM = clientraw[36];
2477         DD = clientraw[35];
2478         SR = clientrawextra[556]; // sunrise
2479         SS = clientrawextra[557]; // sunset
2480         MR = clientrawextra[558]; // moonrise
2481         MS = clientrawextra[559]; // moonset
2482         // Sun rise/set
2483         sunriseWD   = MM+'/'+DD+'/'+YY+' '+SR.replace(/AM/i," AM").replace(/PM/i," PM");
2484         sunsetWD    = MM+'/'+DD+'/'+YY+' '+SS.replace(/AM/i," AM").replace(/PM/i," PM");
2485         sunrise     = new Date(sunriseWD);
2486         sunset      = new Date(sunsetWD);
2487         sunriseWC   = sunrise.getTime() - (webcamImg.delayDayNight*60*1000);
2488         sunsetWC    = sunset.getTime()  + (webcamImg.delayDayNight*60*1000);
2489         // Moon rise/set
2490         moonriseWD = MM+'/'+DD+'/'+YY+' '+MR.replace(/AM/i," AM").replace(/PM/i," PM");
2491         moonsetWD  = MM+'/'+DD+'/'+YY+' '+MS.replace(/AM/i," AM").replace(/PM/i," PM");
2492         moonrise   = new Date(moonriseWD);
2493         moonset    = new Date(moonsetWD);
2494         // Time now
2495      }
2496      WDnow = WDdt.getTime();
2497
2498// Moon & Sun ... rise & set, pic, phase, illumination
2499      ;;;set_ajax_obs('ajaxProgress',rand+'moon','in Moon');
2500      mooninfo = getMoonInfo();
2501      moonNS   = parseFloat(clientraw[160])>0 ? "NH" : "SH"; // latitude
2502      set_ajax_obs("ajaxmoonphase",mooninfo.phase);
2503      set_ajax_obs("ajaxmoonpct"  ,mooninfo.ill+'%');
2504      moonText = mooninfo.phase + ', Moon at ' + mooninfo.age + ' in cycle (' + mooninfo.ill + '%)';
2505      src = moonImg.src.replace(/(#BG#|\{BG\})/i  , moonImg.bg);
2506      src = src.replace        (/(#NS#|\{NS\})/i  , moonNS);
2507      src = src.replace        (/(#AGE#|\{AGE\})/i, mooninfo.pic.toString().str_pad(2));
2508      set_ajax_obs(moonImg.useTag, mooninfo.age+mooninfo.ill+mooninfo.pic
2509         ,'<img src="'  + src
2510         + '" alt="'    + moonText
2511         + '" title="'  + moonText
2512         + '" width="'  + moonImg.width
2513         + '" height="' + moonImg.height
2514         + '" hspace="' + moonImg.hspace
2515         + '" vspace="' + moonImg.vspace
2516         + '" border="' + moonImg.border
2517         + '" align="'  + moonImg.align
2518         + '" style="'  + moonImg.style
2519         + '" />');
2520
2521      // 100x00 black background img for Astronomy page
2522      src = moonImg.src.replace(/(#BG#|\{BG\})/i  , 'b');
2523      src = src.replace        (/(#NS#|\{NS\})/i  , moonNS);
2524      src = src.replace        (/(#AGE#|\{AGE\})/i, mooninfo.pic.toString().str_pad(2));
2525      set_ajax_obs("ajaxmoonimg100", mooninfo.age+mooninfo.ill+mooninfo.pic
2526         ,'<img src="'  + src
2527         + '" alt="'    + moonText
2528         + '" title="'  + moonText
2529         + '" width="100" height="100" />');
2530
2531      if (clientrawextra!==null) {
2532         set_ajax_obs("ajaxsunrise" ,sunrise .date(uom.timeHM));
2533         set_ajax_obs("ajaxsunset"  ,sunset  .date(uom.timeHM));
2534         set_ajax_obs("ajaxmoonrise",moonrise.date(uom.timeHM));
2535         set_ajax_obs("ajaxmoonset" ,moonset .date(uom.timeHM));
2536      }
2537
2538
2539// Current conditions description and icon ...
2540      ;;;set_ajax_obs('ajaxProgress',rand+'cond','in Conditions');
2541      // check if we need the icon instead of the webcam image at night
2542      if (!webcamImg.useCamAtNight && clientrawextra!==null) {
2543         if (WDnow < sunriseWC || WDnow > sunsetWC)
2544            webcamImg.swapIconWithWebcam = false;
2545      }
2546      currentcond = clientraw[49];
2547      currentcond = currentcond.replace(/_/g,' ');
2548      // currentcond = currentcond.replace(/Dry/g,'');
2549      currentcond = currentcond.replace(/\\/g,', ');
2550      currentcond = currentcond.replace(/\//g,', ');
2551      currentcond = ajax_fixupCondition(currentcond);
2552      currIconNr  = parseInt(clientraw[48]);
2553      set_ajax_obs("ajaxcurrentcond" ,currentcond);
2554      set_ajax_obs("gizmocurrentcond",currentcond);
2555
2556      VPforcast = clientrawextra[531];
2557      VPforcast = VPforcast.replace(/\\/g,', ');
2558      VPforcast = ajax_fixupCondition(VPforcast.replace("temp.","temperature"));
2559      set_ajax_obs("ajaxVPforcast",VPforcast);
2560
2561      if (!webcamImg.swapIconWithWebcam) {
2562         switch (wxIcon.useName) { // dashboard icons
2563          case 0: set_ajax_obs(wxIcon.useTag ,clientraw[48] ,ajax_getIconName0(currIconNr,wxIcon)); break; // Anole's icon names
2564          case 1: set_ajax_obs(wxIcon.useTag ,clientraw[48] ,ajax_getIconName1(currIconNr,wxIcon)); break; // NWS icon names
2565          case 2: set_ajax_obs(wxIcon.useTag ,1 ,wxIcon.yoHTML); break; // YoWindow icon
2566          case 9: //Dynamic icon creation similar to cloud height (not yet implemented)
2567                  param = '?uom=' + useUOM
2568                        + '&con=' + currentcond
2569                        + '&iW='  + wxIcon.width
2570                        + '&iH='  + wxIcon.height;
2571                  set_ajax_obs(wxIcon.useTag, param
2572                     ,'<img src="'  + wxIcon.src + param
2573                     + '" alt="'    + currentcond
2574                     + '" title="'  + currentcond
2575                     + '" width="'  + wxIcon.width
2576                     + '" height="' + wxIcon.height
2577                     + '" hspace="' + wxIcon.hspace
2578                     + '" vspace="' + wxIcon.vspace
2579                     + '" border="' + wxIcon.border
2580                     + '" align="'  + wxIcon.align
2581                     + '" style="'  + wxIcon.style
2582                     + '" />');
2583                  break;
2584         default: set_ajax_obs(wxIcon.useTag ,'<div style="border: 2px solid red">INVALID ICON FUNCTION #'+wxIcon.useName+'"</div>');
2585                  set_ajax_obs(wxIcon.useTag ,'<div style="border: 2px solid red">INVALID ICON FUNCTION #'+wxIcon.useName+'"</div>');
2586         }
2587      }
2588
2589
2590// Current webcam snap ...
2591      ;;;set_ajax_obs('ajaxProgress',rand+'webcam','in Webcam');
2592      if (webcamImg.swapIconWithWebcam)
2593           ajaxTag = wxIcon.useTag;
2594      else ajaxTag = webcamImg.useTag;
2595
2596      if (webcamImg.webcamUpdate!==0) { // if 0 then no ajax updates requested
2597         now = new Date();
2598         minutes  = (now.getHours()*60) + now.getMinutes();
2599         interval = Math.floor(minutes / webcamImg.webcamUpdate);
2600         param = '?buster=' + interval;
2601         if (clientrawextra!==null && (WDnow<sunriseWC || WDnow>sunsetWC))
2602              src = webcamImg.srcNgt;
2603         else src = webcamImg.src;
2604         set_ajax_obs(ajaxTag, interval
2605            ,'<img src="'  + src + param
2606            + '" alt="'    + currentcond
2607            + '" title="'  + currentcond
2608            + '" width="'  + webcamImg.width
2609            + '" height="' + webcamImg.height
2610            + '" hspace="' + webcamImg.hspace
2611            + '" vspace="' + webcamImg.vspace
2612            + '" border="' + webcamImg.border
2613            + '" align="'  + webcamImg.align
2614            + '" style="'  + webcamImg.style
2615            + '" />');
2616      }
2617// ----------------------------------------------------------------- end of tags
2618
2619      if (lastajaxtimeformat !== WDdt.date("d-m-Y H:i:s")) {
2620         counterSecs = 0; // reset timer
2621         lastajaxtimeformat = WDdt.date("d-m-Y H:i:s"); // remember this time
2622      }
2623
2624     } // END if(clientraw[0] = '12345' and '!!' at end)
2625     notifyR=0;
2626    } // END if (x.readyState == 4 && x.status == 200)
2627
2628    set_ajax_obs('ajaxupdatecount'   ,ajaxUpdates);        /* for test pages */
2629    set_ajax_obs('ajaxmaxupdatecount',update.maxupdates); /* for test pages */
2630    set_ajax_obs('ajaxState' , x.readyState);             /* for test pages */
2631    set_ajax_obs('ajaxStatus', x.statusText);             /* for test pages */
2632    if (x.readyState===4 && x.status===404) { // not found
2633       if (notifyR===1) {
2634          htp = 'http://'+window.location.host;
2635			 crf = clientrawFile.substr(0,1)==='.'? htp+clientrawFile.substr(1,clientrawFile.length) : clientrawFile+' (2)';
2636		    alert("AJAX DASHBOARD ERROR:\nYour \""+crf+"\" file could not be found.");
2637		 }
2638       notifyR++;
2639    }
2640    ;;;set_ajax_obs('ajaxProgress',rand+'done','-- DONE --');
2641    } // END try
2642
2643    catch(e){}  // Mike Challis added fix to fix random error: NS_ERROR_NOT_AVAILABLE
2644
2645    }; // END x.onreadystatechange = function()
2646
2647    x.open("GET", url, true);
2648    x.send(null);
2649
2650    // now ensure that the indicator flashes on every AJAX fetch
2651    ajax_flash_green("ajaxindicator");
2652    ajax_flash_green("ajaxindicator2");
2653    ajax_flash_green("gizmoindicator");
2654
2655    //  reset the flash colors, and restart the update unless maxupdate limit is reached
2656    setTimeout("ajax_flash_reset('')",flash.time); // change text back to default color
2657
2658    if (update.maxupdates === 0 || ajaxUpdates < update.maxupdates-1) {
2659       timerAjaxLoader = setTimeout("ajaxLoader(clientrawFile + '?' + new Date().getTime())", update.reloadtime); // get new data
2660    } else {
2661       counterSecs = 0; // reset timer
2662       stopTime = new Date().getTime();
2663       PauseMsg = '';
2664       if (update.showRefresh)
2665          PauseMsg = '<span onclick="javascript:ajaxLoader_restart();" style="color:blue; cursor:pointer;" title="'+langRestart+'"><b>'+langRefresh+'</b></span>&nbsp;&nbsp;&nbsp;';
2666       PauseMsg+= '<b style="color:red">'+langPauseMsg+'</b>';
2667       set_ajax_obs("ajaxindicator",stopTime,PauseMsg);
2668       set_ajax_obs("ajaxindicator2",stopTime,PauseMsg);
2669    }
2670  } else {// if (x)
2671    set_ajax_obs('ajaxProgress',rand+'http',"AJAX DASHBOARD ERROR:\nNo HTTP Request");
2672  }
2673}; // end ajaxLoader function
2674
2675
2676
2677// invoke when first loaded on page
2678window.onload=function() {
2679   if (gotSettings) loadSettings(); // we've got a seperate settings file
2680   initialize();
2681   ajax_page_saveTags();
2682   ajaxLoader_clientextra(clientrawextraFile + '?' + new Date().getTime());
2683   window.setInterval("ajax_countup()", 1000); // run the counter for seconds since update
2684   window.setInterval("ajax_countup2()", 1000); // run the counter for seconds since update
2685   ajaxLoader(clientrawFile        + '?' + new Date().getTime());
2686};
2687
2688
2689
2690

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.