var ajaxVersion  = "7.00";
var ajaxVersDate = "12-Jan-2012"; /* Release date
+------------------------------------------------------------------------------+
|    Project: Cartelake/TNET/Saratoga PWS Website templates (WD)               |
|     Module: ajaxWDws.js   (packed version is: ajaxWDwx-packed.js)            |
|    Purpose: Ajax update from WD clientraw.txt for weather station websites.  |
|Description: This alternative ajaxWDwx.js script has been heavily modified    |
|             and has many new ajax tags. Setup has been simplified and many   |
|             new features have been added (see Version History below).        |
|Discussions: For a discussion and new releases go to the Weather-Watch forum: |
|             http://www.weather-watch.com/smf/index.php/topic,43859.0.html    |
|    Authors: Matthew Romer .. v7.00 http://wawaweather.net                    |
|             Kevin Reed .....       http://www.tnetweather.com                |
|             Pinto ..........       http://www.joske-online.be                |
|             Tom ............       http://CarterLake.org                     |
|             Ken True ....... v2.00 http://Saratoga-weather.org               |
|             Mike Challis ...       http://www.carmosaic.com/weather/         |
|             FourOhFour .....       http://skigod.us (at wxforum.net)         |
|             Jim ............       http://jcweather.us                       |
|             Scott .......... v3.00 http://www.WebsterWeatherLIVE.com         |
|             Rainer ......... v9.00 http://www.bashewa.com                    |
| Modifid by: Rainer Finkeldeh, rainer@bashewa.com, www.bashewa.com            |
|  Copyright: (c) 2006-2010 Copyright Bashewa Weather Station and those above. |
|Source code: http://www.bashewa.com/downloads/bws-script-ajaxWDwx.zip         |
| ---------------------------------------------------------------------------- |
| NOTES: This version of "ajaxWDwx.js" has been modified by www.bashewa.com    |
|        To see how changes to this script have been implemented go to:        |
|           http://www.bashewa.com/ajax-dashboard.php?sce=view                 |
|        For available "ajax tags" and descriptions go to:                     |
|           http://www.bashewa.com/wxclientrawparser.php                       |
| ---------------------------------------------------------------------------- |
| JS SIZE REDUCTION:                                                           |
| If you want to pack this script after you have made changes, go here:        |
|     http://dean.edwards.name/packer/                                         |
| ... make a "ajaxWDwx-packed.js" file and change this line in "top.php" to:   |
|     <script type="text/javascript" src="ajaxWDwx-packed.js"></script>        |
| ... This will reduce the size to ±34% of it's original size (±38kb).         |
| ---------------------------------------------------------------------------- |
| SCRIPT DOWNLOADS:                                                            |
|       Cloud base graphic:  http://www.bashewa.com/download-cloud-base.php    |
|     Gradient thermometer:  http://www.bashewa.com/download-thermometer.php   |
|   Dynamic condition icon:  (not yet implemented)                             |
+------------------------------------------------------------------------------+
| USAGE and WARRANTY:                                                          |
| ---------------------------------------------------------------------------- |
| You may copy/modify/use this script as you see fit.                          |
| No warranty is expressed or implied.                                         |
|                                                                              |
| This program is free software; you can redistribute it and/or modify it      |
| under the terms of the GNU General Public License as published by the Free   |
| Software Foundation; either version 2 of the License, or (at your option)    |
| any later version.                                                           |
|                                                                              |
| This program is distributed in the hope that it will be useful, but          |
| WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY   |
| or FITNESS FOR A PARTICULAR PURPOSE.                                         |
| See the GNU General Public License for more details.                         |
|                                                                              |
| You should have received a copy of the GNU General Public License along      |
| with this program; if not, write to the:                                     |
|    Free Software Foundation, Inc.,                                           |
|    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA                  |
+------------------------------------------------------------------------------+


================================================================================
                       HOW TO IMPLEMENT UOM SWITCHING                          .
================================================================================
for implementation see:  http://www.bashewa.com/ajax-dashboard.php?sce=view
Add the following code somewhere into your "ajax-dashboard.php":
    ----------------------------------------------------------------------------
    <div onClick="javascript:ajax_changeUnits();" style="cursor: pointer"><b>
         <span id="uomM" style="color: gray;">METRIC</span> |
         <span id="uomE" style="color: blue;">IMPERIAL</span></b>
    </div>
    ----------------------------------------------------------------------------
For static field that don't have an "ajaxtag" you need to add one of the
following classes to your fields:
    ----------------------------------------------------------------------------
    <span class="convTemp">82.7&deg;F</span>   ...for temp
    <span class="convWind">   2.7 mph</span>   ...for wind
    <span class="convBaro">30.30 inHg</span>   ...for temp
    <span class="convRain">   1.04 in</span>   ...for rain
    <span class="convSnow">   12.4 in</span>   ...for snow
    <span class="convAlti">   2793 ft</span>   ...for altitude
    <span class="convDist">  15 miles</span>   ...for distance
    <span class="convDate">20-10-2009</span>   ...for dates
    <span class="convTime">  15:32:27</span>   ...for times
    ----------------------------------------------------------------------------
NOTE: the value in the span must include the units-of-measure for them be converted.
You'll also need the modified "thermometer.php" script that supports UOM switching.
Get it here:  http://www.weather-watch.com/smf/index.php/topic,43750.0.html
================================================================================
*/

//============================================================================\\
//                            S E T T I N G S                                 \\
//             P L E A S E   R E A D    T H I S   F I R S T                   \\
// You can have seperate settings in "ajaxWDwx-settings.js" so that you don't \\
// have to redo them each time a new version of this script is released.      \\
// I suggest strongly that you do so and also to use the packed version of    \\
// this script i.e. ajaxWDwx-packed.js.                                       \\
// -------------------------------------------------------------------------- \\
// If you have seperate settings in a file "ajaxWDwx-settings.js" then you    \\
// need to add the following line to your "top.php" file:                     \\
//     <script type="text/javascript" src="ajaxWDwx-settings.js"></script>    \\
// below this line in "top.php":                                              \\
//     <script type="text/javascript" src="ajaxWDwx.js"></script>             \\
//============================================================================\\

//============================================================================\\
//                 A D D I T I O N A L  S E T T I N G S                       \\
//             P L E A S E   R E A D    T H I S   F I R S T                   \\
// The following entries need to be added to the "ajaxWDwx.js" script so that \\
// the extra functions and features in this script may work.                  \\
// In the following function "function ajaxLoader(url)", the following line:  \\
// 					 clientrawloaded = 1;                                             \\
// needs to be added just below the entry                                     \\
//    ;;;set_ajax_obs('ajaxProgress',rand+'start','-- START --');             \\
//                                                                            \\
// Change the following line:                                                 \\
//    set_ajax_obs("ajaxbigtemp", temp.toFixed(0) + uom.Temp);                \\
// to the following                                                           \\
//    /*      set_ajax_obs("ajaxbigtemp", temp.toFixed(0) + uom.Temp); */     \\
//      			if (temp < 0){                                                  \\
//       				document.getElementById("ajaxbigtemp").src = "./images/bignumb"+useUOM+"/n"+(temp.toFixed(0)*-1)+".png"; \\
//       			} else {                                                        \\
//       				document.getElementById("ajaxbigtemp").src = "./images/bignumb"+useUOM+"/"+temp.toFixed(0)+".png"; \\
//            }                                                               \\
//                                                                            \\
// In the section "switch (wxIcon.useName) {                                  \\
// between the "case 1: and case 9:"	section add the following               \\
//       case wxIcon.useName:                                                 \\
//				tempvar = 'ajax_getIconName'+wxIcon.useName;                        \\
//				if(typeof window[tempvar] == 'function') {                          \\
//					current_conditions_custom(clientraw[48]);                         \\
//					break;                                                            \\ 
//				} else {                                                            \\  
//					set_ajax_obs(wxIcon.useTag ,'<div style="border: 2px solid red">INVALID ICON FUNCTION #'+wxIcon.useName+'"</div>'); \\
//					break;                                                            \\ 
//				}                                                                   \\
//                                                                            \\
// just before the following entry:                                           \\
//     "// now ensure that the indicator flashes on every AJAX fetch"         \\
// add the following entries                                                  \\
// 	// load special scheduled tasks                                           \\
//	if (typeof extra_tasks() == 'function') {                                 \\
//		extra_tasks();                                                          \\
//  }                                                                         \\
// -------------------------------------------------------------------------- \\



//==============================================================================
// Settings (required ... should be done in ajaxWDwx-settings.js)              .
//==============================================================================
var clientrawFile = './clientraw.txt'; // location of clientraw.txt relative to this page on website

var useUOM = 'M';   // [ E | M ] ... Units Of Measure:
                    //               E = English/Imperial
                    //               M = Metric
                    // NOTE: You can change individual units below in UNITS-OF-MEASURE.

var showUOM = true; // set to FALSE if no units should be displayed inside "ajaxtags".
                    // i.e. if your UOM's are outside the of the "ajaxtag" spans.
                    // Note: If you have implemented UOM switching this needs to
                    //       be TRUE and all your UOM's need to be on the inside
                    //       of your "ajaxtags".

//==============================================================================
// Settings (optional ... should be done in ajaxWDwx-settings.js)              .
//==============================================================================

var wxStation =   // Your Weather Station status
   {problemNr : 0 // Pick a problemMsg number from below
   ,problemMsg:   // Problem reports ... the selected message below by "problemNr" will be reported in the wxStation.useTag box
      {0:'No problems'
      ,1:'<b style="color:red">...your msg here...</b><br />...your msg here...<br />'
      } // you can add as many problem messages as you like to the above ... just number them properly
   ,stopUpdates: false // Stop the ajax updates for the problem reported ... you should do so if your station is out-of-order
   ,showAlert  : false // Show an alert box instead of a msg in wxStation.useTag box. Use "\n" for line breaks.
   ,useTag     : "ajaxindicator" // you can specify a different "ajaxtag" here to suit your requirements
   };

var update = // for ajax update interval
   {reloadtime: 5000   // fetch clientraw.txt file every 5 seconds (1000 ms = 1 second )
   ,maxupdates: 0     // Maximum number of updates/fetches allowed (set to zero for unlimited)
                       // maxupdates * reloadtime / 1000 = (number of seconds to update)
                       // i.e. 36 x 5000 / 1000 = 180 seconds (3 minutes)
                       // Note: if you upload your clientraw.txt file every 30 seconds
                       //       then the visitor will see (180/30) = (6 updates in total).
   ,showRefresh: true  // show REFRESH hyperlink after "maxupdates" have been exceeded.
   };

var flash = // for update indicator
   {color: '#00CC00'   // color to flash for changed observations (RGB) (def #00CC00 = green)
   ,red  : '#FF0000'   // color to flash red for warnings/alarms  (RGB) (def #FF0000 = red)
   ,time : 2000        // milliseconds to keep flash color on (2000 = 2 seconds);
   };


//==============================================================================
// STATIC IMAGES                                                               .
//==============================================================================
// IMAGE LOCATION: default root folder for graphic images & icons
// ... (for root folder specify "./")

var imgDir = './ajax-images/'; // with trailing slash

// NOTE: do not delete any of the words enclosed in {} in the src parts eg. {PIC}
//       They'll get replaced by their corresponding values later in the script.

//------------------------------------------------------------------------------
// DASHBOARD ICONS: optional settings for current conditions graphic for dashboard
// tag: "ajaxconditionicon" or "ajaxconditionicon2" ... specify it below in wxIcon.useTag
// e.g. graphic name: "./ajax-images/bkn.gif"
// .... grab the animated icons for set 2 here: http://www.bashewa.com/downloads/bws-icons-current.zip
// used to set the extension of the wxIcon graphics from various icon groups
var wxIcon =
   {src    : imgDir+"{PIC}.jpg" // where {PIC} will = picname from function specified in wxIcon.useName below
   ,width  : 74 ,height: 74 ,hspace: 0 ,vspace: 0 ,border: 0
   ,style  : ""  // eg. "border: 2px solid silver"
   ,align  : ""  // [ left | right | top | bottom | middle | texttop | absbottom | absmiddle ]
   ,useTag : "ajaxconditionicon2" // [ ajaxconditionicon | ajaxconditionicon2 ] ... ajax tagname to use
   ,useName: 1   // [ 0| 1 | 2 | 3 | 9 ] function for getting icon names ...
   };            //                  0 = Anole's icon names ............ see ajax_getIconName0()
                 //                  1 = NWS icon names ................ see ajax_getIconName1()
                 //                  3 = Environment Canada icon names . see ajax_getIconName3()
                 //                  9 = Dynamic current icons ......... NOT IMPLEMENTED
// used to set the extension of the wxIcon graphics from various icon groups
//var wxIconExtension = new Array("gif", "jpg", "gif", "gif", "", "", "", "", "", "");
//wxIcon.src = imgDir+"{PIC}."+wxIconExtension[wxIcon.useName];  // must be last for extension to be set properly


//------------------------------------------------------------------------------
// WIND ROSE: optional settings for the Wind Rose graphic
// tag: "ajaxwindiconwr"
// e.g. graphic name: "./ajax-images/wr-SSE.gif"  or  "./ajax-images/wr-nl-SSE.gif"
// .... grab the wind rose icons here: http://www.bashewa.com/downloads/bws-icons-wind.zip

var wrImg =
   {src   : imgDir+"wind/wr-{LANG}{DIR}.png"  // where {DIR} will = wind dir (e.g. NNW), {LANG} = wrImg.lang
   ,width : 58 ,height: 58 ,hspace: 0 ,vspace: 0 ,border: 0
   ,style : ""
   ,align : "" // [ left | right | top | bottom | middle | texttop | absbottom | absmiddle ]
   ,lang  : "" // with trailing dash (e.g. "nl-" will result in graphic name: "./ajax-images/wr-nl-SSE.gif")
   ,calm  : "calm" // substitution for {DIR} (e.g "wr-calm.gif") ... specify "" if not to be shown or not available
   ,xlate : true   // translate wind direction for icon names (multilingual system)
   ,useTag: "ajaxwindiconwr" // ajax tagname to use where the windrose icon should be placed
   };


//------------------------------------------------------------------------------
// UV: optional settings for the UV graphic
// tag: "ajaxuvimg"
// e.g. graphic name: "./ajax-images/uv/1/uv12.gif"
// .... grab UV pics here: http://www.bashewa.com/download/bws-icons-uv.zip
var uvImg =
   {src   : imgDir+"uv/uv{INDEX}.gif" // where {INDEX} will = UV index (0 to 11)
   ,width : 34 ,height: 65 ,hspace: 0 ,vspace: 0 ,border: 0
   ,style : ""
   ,align : ""
   ,useTag: "ajaxuvimg"
   };


//------------------------------------------------------------------------------
// MOON: optional settings for the moon phase graphic
// tag: "ajaxmoonimg"
// e.g. graphic name: "./ajax-images/moon/w/NH-moon07.gif"
// .... grab the Moon images here: http://www.bashewa.com/downloads/bws-icons-moon.zip
var moonImg =
   {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
   ,bg    : "w" // [ w | b ] moon background (w=white, b=black)
   ,width : 50 ,height: 50 ,hspace: 0 ,vspace: 0 ,border: 0
   ,style : ""
   ,align : ""
   ,useTag: "ajaxmoonimg"
   };


//------------------------------------------------------------------------------
// FIRE INDEX: optional setting for the fire risk graphic
// tag: "ajaxfireimg"
// e.g. graphic name: "./ajax-images/fire/fire3.gif"
// .... grab the FWI icons here: http://www.bashewa.com/downloads/bws-icons-fire.zip
var fireImg =
   {src   : imgDir+"Fire{IMGNR}.png" // where {IMGNR} will = fire index (0=very low, 1=low, 2=moderate, 3=high, 4=extreme) from fireImg.imgNrs below
   ,width : 60 ,height: 65 ,hspace: 0 ,vspace: 0 ,border: 0
   ,style : ""
   ,align : ""
   ,imgNrs: // we all have different numbering systems for our FWI icons it seems ... specify the 5 icon numbers below
      {0:"0"  ,1:"16"  ,2:"25"  ,3:"31" ,4:"32"}
   ,useTag: "ajaxfireimg"
   };


//------------------------------------------------------------------------------
// WEBCAM IMAGE: optional setting for the webcam graphic
// tag: "ajaxwebcamimg"
// e.g. picture name: "./ajax-images/webcam/snap00.jpg"
var webcamImg =
   {src   : imgDir+"webcam/snap00.jpg" // full path and image name of your current webcam picture
   ,srcNgt: imgDir+"webcam/snap00.jpg" // full path and image name of your current nightcam picture (after/before "delayDayNight")
   ,width : 170 ,height: 127 ,hspace: 0 ,vspace: 0 ,border: 0
   ,style : ""
   ,align : ""
   ,webcamUpdate      : 5     // Webcam update interval in minutes (set to 0 for no updates i.e. visitor must reload page for updates)
   ,swapIconWithWebcam: false // swap current conditions icon (tag "ajaxconditionicon2") with webcam image during day and night unless useCamAtNight=false;
   ,useCamAtNight     : false // use current conditions icon at night time instead of webcam image
   ,delayDayNight     : 15    // day starts given minutes before sunrise and night starts given min after sunset - for night icon switch
   ,useTag: "ajaxwebcamimg"
   };


//==============================================================================
// DYNAMIC SCRIPT IMAGES                                                       .
//==============================================================================

// THERMOMETER: optional setting for the dynamic thermometer graphic
// tag: "ajaxthermometer"
// ... you'll need the new thermometer.php script from www.bashewa.com for UOM switching.
// ... read here  : http://www.weather-watch.com/smf/index.php/topic,39180.0.html
// ... get it here: http://www.bashewa.com/download-thermometer.php
var thermometerImg =
   {src   : "./thermometer.php" // path and script for dynamic thermometer PNG image (optional)
   ,width : 54 ,height: 170 ,hspace: 0 ,vspace: 0 ,border: 0
   ,style : ""
   ,align : ""
   ,useTag: "ajaxthermometer"
   };


//------------------------------------------------------------------------------
// CLOUD BASE: optional setting for the dynamic cloud height graphic
// tag: "ajaxcloudheightimg"
// ... you'll need the cloud-base.php script from www.bashewa.com
// ... get it here: http://www.bashewa.com/download-cloud-base.php
var cloudImg =
   {src   : "./cloud-base.php" // path and script for dynamic cloud height image (optional)
   ,width : 100 ,height: 200 ,hspace: 0 ,vspace: 0 ,border: 0
   ,style : ""
   ,align : ""
   ,stationAlt: 0 // your station altitude in meters for cloud height graphic if you want ASL (meters = ft / 3.2808399)
   ,useTag: "ajaxcloudheightimg"
   };


//------------------------------------------------------------------------------
// DYNAMIC CURRENT ICON: settings for the dynamic current conditions graphic
// tag: "ajaxconditionicon2"
// ... you'll need the dynamic-icon.php script from www.bashewa.com
// ... get it here: (NOT YET IMPLEMENTED)
// Set this up in wxIcon in DASHBOARD ICONS above:  { src: "./dynamic-icon.php" ,width: 170 ,height: 127, useName: 9 }



//==============================================================================
// UNITS-OF-MEASURE / UOM (optional)
// ... change to your desired UOM's and decimal places
//==============================================================================
// ENGLISH (Imperial)
var imperialUOM =
   {Temp: '&deg;F' // [ &dec;C | &dec;F ] ......................... Temp
   ,Wind: 'mph'    // [ kts | mph | kph  | m/s  ] ................. Wind
   ,Baro: 'inHg'   // [ hPa | mb  | inHg | mmHg ] ................. Baro
   ,Rain: 'in'     // [ mm  | in  ] ............................... Rain
   ,Snow: 'in'     // [ cm  | in  ] ............................... Snow
   ,Alti: 'ft'     // [ m   | ft  ] ........................... Altitude
   ,Dist: 'miles'  // [ m   | km  | miles] .................... Distance
   ,Deg : '&deg;'  // [ deg | &deg; ] ..................... Direction/UV
   ,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" )
   ,timeFmt: "g:i:sa" // 3:27:01 pm ... same format as "date" function in php ( for 24h clock use "H:i:s" )
   ,timeHM : "g:ia"   // 3:27 pm ...... same format as "date" function in php ( for 24h clock use "H:i" )
   };
var imperialDP = // decimal places
   { Temp:1 ,Wind:1 ,Baro:2 ,Rain:2 ,Snow:2 ,Alti:0 ,Dist:2 ,UV:0 };
//----------------------------------------------------------------------
// METRIC
var metricUOM =
   {Temp: '&deg;C' // [ &dec;C | &dec;F ] ..........................Temp
   ,Wind: 'kph'    // [ kts | mph | kph  | m/s  ] ................. Wind
   ,Baro: 'hPa'    // [ hPa | mb  | inHg | mmHg ] ................. Baro
   ,Rain: 'mm'     // [ mm  | in  ] ............................... Rain
   ,Snow: 'cm'     // [ cm  | in  ] ............................... Snow
   ,Alti: 'm'      // [ m   | ft  ] ........................... Altitude
   ,Dist: 'km'     // [ m   | km  | miles] .................... Distance
   ,Deg : '&deg;'  // [ deg | &deg; ] ........................ Direction
   ,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)
   ,timeFmt: "H:i:sa" // 15:27:01 ..... same format as "date" function in php  ( for 12h clock use "g:i:s a" )
   ,timeHM : "H:ia"   // 15:27 ........ same format as "date" function in php  ( for 12h clock use "g:i a" )
   };
var metricDP = // decimal places
   { Temp:1 ,Wind:1 ,Baro:0 ,Rain:1 ,Snow:0 ,Alti:0 ,Dist:2 ,UV:0 };


//==============================================================================
//                            I M P O R T A N T                                .
//                          LANGUAGE TRANSLATION                               .
//           No need to change if you're using the Multilingual Templates:     .
//           (af, de, dk, el, en, es, fi, fr, it, nl, no, pl, pt, se, us)      .
// =========================================================================== .
// You don't need to customize this area if you're using English or if you're  .
// using the Canada/World Mutilingual templates. Instead change your language  .
// in "Settings.php" i.e. $SITE['lang']='nl';                                  .
// If translations are incorrect then edit the "language-??.js" files.         .
//==============================================================================
var langRestart  = 'Restart live updates';
var langRefresh  = 'REFRESH'; // RESTART
var langPauseMsg = 'Updates paused';

var langMonths   = new Array ("January","February","March","April","May","June","July","August","September","October","November","December");
var langDays     = new Array ("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
var langDaySuf   = new Array ("st","nd","rd","th"); // day suffix as in 1st, 2nd, 3rd, 4th
var langAM_PM    = new Array ("am","pm","AM","PM");
var langWindUOM  = new Array ("kts", "mph", "km/h", "m/s");

var langBaroTrend = new Array (
    "Steady", "Rising Slowly", "Rising Rapidly", "Falling Slowly", "Falling Rapidly");

var langUVWords = new Array (
    "None", "Low", "Medium", "High", "Very&nbsp;High", "Extreme", "Unknown" );

var langBeaufort = new Array ( /* Beaufort 0 to 12 in array */
    "Calm", "Light air", "Light breeze", "Gentle breeze", "Moderate breeze", "Fresh breeze",
    "Strong breeze", "Near gale", "Gale", "Strong gale", "Storm", "Violent storm", "Hurricane");

var langWindDir = new Array( /* used for alt and title tags on wind dir arrow and wind direction display */
    "N", "NNE", "NE", "ENE",
    "E", "ESE", "SE", "SSE",
    "S", "SSW", "SW", "WSW",
    "W", "WNW", "NW", "NNW");

var langWindCalm = 'Calm';
var langGustNone = 'None';
var langWindFrom = 'Wind from '; /* used on alt/title tags on wind direction arrow*/

var langThermoCurrently = 'Currently: '; /* used on alt/title tags for thermometer */
var langThermoMax = 'Max: ';
var langThermoMin = 'Min: ';

var langTempRising    = 'Warmer %s'; /* used for trend arrow alt/title tags .. %s marks where value will be placed */
var langTempFalling   = 'Colder %s';
var langTempLastHour  = ' than last hour.';
var langTempYesterday = ' than same time yesterday.';

var langBaroRising  = 'Rising %s '; /* used for trend arrow alt/title tags .. %s marks where value will be placed */
var langBaroFalling = 'Falling %s ';
var langBaroPerHour = '/hour.'; /* will be assembled as rising/falling + value + uom + perhour text */

var langHeatWords = new Array (
    'Unknown', 'Extreme Heat Danger', 'Heat Danger', 'Extreme Heat Caution', 'Extremely Hot', 'Uncomfortably Hot',
    'Hot', 'Warm', 'Comfortable', 'Chilly', 'Cool', 'Cold', 'Very Cold', 'Extremely Cold', 'Dangerously Cold', 'Extreme Cold Danger' );

//==============================================================================
//                      E N D   of   S E T T I N G S                           .
//==============================================================================

//==============================================================================
//                           Set Units Of Measure                              .
//==============================================================================

function get_cookie(a) {
	var b = a + "=";
	var c = document.cookie;
	if (c.length > 0) {
		begin = c.indexOf(b);
		if (begin != -1) {
			begin += b.length;
			end = c.indexOf(";", begin);
			if (end == -1) end = c.length;
			return unescape(c.substring(begin, end))
		}
	}
	return null
}

function set_cookie(c_name,value,exdays) {
	var exdate=new Date();
	exdate.setDate(exdate.getDate() + exdays);
	var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString());
	document.cookie=c_name + "=" + c_value;
}

if (get_cookie("UOM")) {
	var a = get_cookie("UOM");
	if (a == '1') {
		useUOM = 'M';
	} else {
		useUOM = 'E';
	}
}

//==============================================================================
//                            I M P O R T A N T                                .
//           DO NOT customize any of the stuff below this point.               .
//            Everything is controlled by your settings above.                 .
//==============================================================================

;;;var doTooltip = 0; // set to 1 to have ajaxed variable names appear as tooltips (except for graphics)

// -----------------------------------------------------------------------------
var ie4     = document.all;
var browser = navigator.appName;
var ie8 = false;
if (ie4 && /MSIE (\d+\.\d+);/.test(navigator.userAgent)) { //test for MSIE x.x;
var ieversion = new Number(RegExp.$1); // capture x.x portion and store as a number
   if (ieversion>=8) {
      ie4=false;
      ie8=true;
    }
}

var langTransLookup = new Object;  // storage area for key/value for current conditions translation
var timerAjaxLoader = null; // for resetting loading timeouts
var notifyR = 0;    // for error 404 alerts: clientraw
var notifyE = 0;    // for error 404 alerts: clientextra
var extraRetry = 6; // retry time in seconds to fetch clientrawextra.txt
var extraRetryInterval = 10000; // fetch retry in milliseconds for clientrawextra.txt
var clientrawextra = null;

var ajaxUpdates = 0; // update counter for limit by update.maxupdates
var counterSecs = 0; // for MCHALLIS counter script from weather-watch.com (adapted by K. True)
var lastajaxtimeformat = null; // used for reseting the counter when a real update is done

var ajaxElements = new Array(); // used for reseting green flashing elements
var uomElements  = new Array(); // used for storing page values for switching units-of-measure

var PauseMsg  = ""; // leave blank
var Indicator = ""; // leave blank
var gotSettings=false, uom, dp, clientrawextraFile;

//-------------------------------------------------------------- functions start
function initialize() {
   // FOR DEBUGING -- always override the settings above if testing on a local host
   if (document.location.protocol=="file:"
   ||  document.location.href.search("localhost")!=-1) {
      //update.maxupdates = 0;
      update.reloadtime = 5000;
   }
   // END DEBUGING --

   if (typeof jserrNr!="undefined" && jserrNr!=null) {
      str = jserrors.replace(" in "," in:<br />");
      jsmsg = '<div style="border-bottom: 1px solid gray;">'+str+'</div>';
      set_ajax_obs(wxStation.useTag,jsmsg);
      jsErrNr = null;
   } else
   if (wxStation.problemNr>0) {
      pMsg= wxStation.problemMsg[wxStation.problemNr];
      if (wxStation.showAlert) alert(pMsg);
      else set_ajax_obs(wxStation.useTag,pMsg);
      if (wxStation.stopUpdates) update.maxupdates = 2;
   }

   clientrawextraFile = clientrawFile.replace("clientraw","clientrawextra");
   uom = (useUOM=='M')? metricUOM : imperialUOM;
   dp  = (useUOM=='M')? metricDP  : imperialDP;

   if (!showUOM) { // Strip UOMs if not required i.e. if the UOM is outside the ajaxtag spans
      imperialUOM.Temp=''; metricUOM.Temp='';
      imperialUOM.Wind=''; metricUOM.Wind='';
      imperialUOM.Baro=''; metricUOM.Baro='';
      imperialUOM.Rain=''; metricUOM.Rain='';
      imperialUOM.Snow=''; metricUOM.Snow='';
      imperialUOM.Alti=''; metricUOM.Alti='';
      imperialUOM.Dist=''; metricUOM.Dist='';
      imperialUOM.Deg =''; metricUOM.Deg ='';
   }
};

function ajaxLoader_restart() {
   ajaxUpdates = 0;
   counterSecs = 0;
   lastajaxtimeformat = null;
   set_ajax_obs("ajaxindicator",Indicator);
   ajaxLoader_clientextra(clientrawextraFile + '?' + new Date().getTime());
   if (timerAjaxLoader!="null") clearTimeout(timerAjaxLoader);
   timerAjaxLoader = setTimeout("ajaxLoader(clientrawFile + '?' + new Date().getTime())", 20);
};


// toggle the units-of-measure between METRIC and ENGLISH
function ajax_changeUnits () {

	if (useUOM == 'M') {
		set_cookie("UOM",0,6) //switch to imperial
	} else {
		set_cookie("UOM",1,6) //switch to metric
	}

  useUOM  = (useUOM=="E") ? "M" : "E" ;
  uom     = (useUOM=="M") ? metricUOM : imperialUOM;
  dp      = (useUOM=="M") ? metricDP  : imperialDP ;
  colorM  = (useUOM=="E") ? "gray"    : "blue";
  colorE  = (useUOM=="M") ? "gray"    : "blue";
  var uomM = document.getElementById("uomM"); if (uomM) uomM.style.color = colorM;
  var uomE = document.getElementById("uomE"); if (uomE) uomE.style.color = colorE;

  switch (uom.Wind) {
		case "mph": uom.langWind = langWindUOM[1]; break;
		case "kph": uom.langWind = langWindUOM[2]; break;
		case "m/s": uom.langWind = langWindUOM[3]; break;
		default   : uom.langWind = langWindUOM[0];
  }
  ajax_page_convertTags(); // also convert tags convTemp, convWind ... etc.
  ajaxUpdates = 0;
  set_ajax_obs("ajaxindicator",new Date().getTime(),Indicator,flash.red);
  window.location.reload();
	//ajaxLoader_restart();
};


// return all the elements for a given tag name on a page e.g. <span ..>
function ajax_getElements ( name ) { // name = [span, div, ...]
   if (ie4 && browser != "Opera" && ! ie8)
        return (document.body.getElementsByTagName(name));
   else return (document     .getElementsByTagName(name));
};

// return the "class name" for a given element (as in: class="ajax convTemp noprint")
function ajax_getClassName( element ) {
   if (ie4 && browser != "Opera" && ! ie8)
        return (element.getAttribute("className"));
   else return (element.getAttribute("class"));
};

String.prototype.getUnits = function() {
// match and return any [ °C |°F | &dec;C | &dec;F | mm | in | in. | cm | ft | mb | hPa | inHg | mmHg | kts | m/s | mph | kph ]
   return (this.match(/°C|°F|&dec;F|&dec;C|in\.|[a-z]+\/?[a-z]?/i));
};

// return the value
function ajax_page_getTagValue ( element, type ) {
   var html = element.innerHTML;
   var val  = parseFloat(html);
   var uom  = html.getUnits();
   return ( val.convertToMetric(uom, type) );
};

// utility functions to navigate the <span class="..."> tags on the page and save their values
function ajax_page_saveTags () {
   uom     = (useUOM=="M") ? metricUOM : imperialUOM;
   dp      = (useUOM=="M") ? metricDP  : imperialDP ;
   colorM  = (useUOM=="E") ? "gray"    : "blue";
   colorE  = (useUOM=="M") ? "gray"    : "blue";
   var uomM = document.getElementById("uomM"); if (uomM) uomM.style.color = colorM;
   var uomE = document.getElementById("uomE"); if (uomE) uomE.style.color = colorE;
   switch (uom.Wind) {
   case "mph": uom.langWind = langWindUOM[1]; break;
   case "kph": uom.langWind = langWindUOM[2]; break;
   case "m/s": uom.langWind = langWindUOM[3]; break;
   default   : uom.langWind = langWindUOM[0];
   }
   var i, name , iC = iF =0;
   var pgElements = ajax_getElements('span');

   for(i=0; i<pgElements.length; i++) {
      name = ajax_getClassName(pgElements[i]); // could be: class="ajax convTemp noprint"
      if (name!=null) {
         // conversion elements
         if ( name.search    (/convTemp|convWind|convBaro|convRain|convSnow|convDist|convAlti|convDate|convTime/i) > -1) {
            conv = name.match(/convTemp|convWind|convBaro|convRain|convSnow|convDist|convAlti|convDate|convTime/i);
            switch (conv) {
            case "convDate":
            case "convTime": uomElements[iC++]  = [ pgElements[i], conv, pgElements[i].innerHTML ];
            default        : uomElements[iC++]  = [ pgElements[i], conv, ajax_page_getTagValue(pgElements[i],name) ];
            }
            ajaxElements[iF++] = pgElements[i]; // also add to flashing elements
         }
         // flashing elements
         if (name.search(/ajax/i) > -1)
            ajaxElements[iF++] = pgElements[i];
      }
   }
   var element = document.getElementById("ajaxindicator");
   if (element) Indicator = element.innerHTML;
   ajax_page_convertTags();
};

// convert "conv..." tags to required UOM
function ajax_page_convertTags () {
var i, name, val, ret;

   for(i=0; i<uomElements.length; i++) {
      name = String(uomElements[i][1]);
      val  = uomElements[i][2];
			val = String(val);
			val = val.replace(/[^.0-9]/g, '');
			val = parseFloat(val)
      ret = null;
			
switch (name) {
//case "convTemp": ret = val.convertTemp().toFixed(dp.Temp)    +uom.Temp; break;
//case "convWind": ret = val.convertWind().toFixed(dp.Wind)+' '+uom.langWind; break;
//case "convBaro": ret = val.convertBaro().toFixed(dp.Baro)+' '+uom.Baro; break;
//case "convRain": ret = val.convertRain().toFixed(dp.Rain)+' '+uom.Rain; break;
//case "convSnow": ret = val.convertSnow().toFixed(dp.Snow)+' '+uom.Snow; break;
//case "convDist": ret = val.convertDist().toFixed(dp.Dist)+' '+uom.Dist; break;
//case "convAlti": ret = val.convertAlti().toFixed(dp.Alti)+' '+uom.Alti; break;
//case "convDate": ret = val.convertTime(); alert('date works'); break;
//case "convTime": ret = val.convertTime(); alert('time works'); break;
//default    : ret = val.convertWind().toFixed(dp.Wind)+' '+uom.langWind; break;
}

      if (ret!=null) {
        uomElements[i][0].innerHTML = ret;
         uomElements[i][0].style.color = flash.color;
      }
   }
};


// function for setting green flashing object
function ajax_flash_green ( name ) {
   var element = document.getElementById(name);
   if (element)  element.style.color = flash.color;
};

// function for resetting green flashing object
function ajax_flash_reset( usecolor ) {
// reset all the <span class="ajax"...> styles to have no color override
   for(var i=0; i<ajaxElements.length; i++) {
      element = ajaxElements[i];
      element.style.color = usecolor;
   }
};


function set_ajax_obs( name, value , html , red) {
// store away the current value in both the doc and the span as lastobs="value"
// change color if value != lastobs
   var element = document.getElementById(name);
   if (! element ) { return; } // V1.04 -- don't set if missing the <span id=name> tag
   var lastobs = element.getAttribute("lastobs");
   element.setAttribute("lastobs",value);
   if (value != unescape(lastobs)) {
      element.style.color = (red)? flash.red : flash.color;
      ;;;if ( doTooltip ) element.setAttribute("title",'AJAX tag '+name);
      element.innerHTML = ((typeof html=='undefined')?value:html); // moved inside to fix flashing issue (Jim at jcweather.us)
   }
};

function set_ajax_uom( name, show ) {
// this function will set an ID= to visible or hidden by setting the style="display: " from 'inline' or 'none'
   var element = document.getElementById(name);
   if (! element ) { return; }
   if (show) element.style.display='inline';
   else      element.style.display='none';
};
// --- end of flash-green functions


function ajax_getWindDir (winddir) {
// Take wind direction value, return the
// text label based upon 16 point compass -- function by beeker425
//  see http://www.weather-watch.com/smf/index.php/topic,20097.0.html
   windlabel = new Array("N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW");
   return windlabel[Math.floor(((parseInt(winddir) + 11) / 22.5) % 16 )];
};

function ajax_getWindDirLang (winddir) {
// Take wind direction value, return the
// text label based upon 16 point compass -- function by beeker425
// ... see http://www.weather-watch.com/smf/index.php/topic,20097.0.html
   return langWindDir[Math.floor(((parseInt(winddir) + 11) / 22.5) % 16 )];
};

function ajax_getIconName0 ( iconNr ,iconSet ) {
// perform a lookup and return the graphic name for the condition icon
// (using anole's wxsticker icon nameing convention)
iconList = new Array(
   "day_clear",           //  0 sunny
   "night_clear",         //  1 clearnight
   "day_partly_cloudy",   //  2 cloudy
   "day_partly_cloudy",   //  3 cloudy2
   "night_partly_cloudy", //  4 cloudynight
   "day_clear",           //  5 dry
   "fog",                 //  6 fog
   "haze",                //  7 haze
   "day_heavy_rain",      //  8 heavyrain
   "day_mostly_sunny",    //  9 mainlyfine
   "mist",                // 10 mist
   "fog",                 // 11 nightfog
   "night_heavy_rain",    // 12 nightheavyrain
   "night_cloudy",        // 13 nightovercast
   "night_rain",          // 14 nightrain
   "night_light_rain",    // 15 nightshowers
   "night_snow",          // 16 nightsnow
   "night_tstorm",        // 17 nightthunder
   "day_cloudy",          // 18 overcast
   "day_partly_cloudy",   // 19 partlycloudy
   "day_rain",            // 20 rain
   "day_rain",            // 21 rain2
   "day_light_rain",      // 22 showers2
   "day_sleet",           // 23 sleet
   "day_sleet",           // 24 sleetshowers
   "day_snow",            // 25 snow
   "day_snow",            // 26 snowmelt
   "day_snow",            // 27 snowshowers2
   "day_clear",           // 28 sunny
   "day_tstorm",          // 29 thundershowers
   "day_tstorm",          // 30 thundershowers2
   "day_tstorm",          // 31 thunderstorms
   "tornado",             // 32 tornado
   "windy",               // 33 windy
   "day_partly_cloudy",   // 34 stopped rainning
   "windyrain"            // 35 windy/rain (new with V2.11)
   );

   if (iconNr >= 0 && iconNr <= 35) {
      return ('<img src="'+ iconSet.src.replace(/(#PIC#|\{PIC\})/i, iconList[iconNr])
             +'" width="' + iconSet.width
             +'" height="'+ iconSet.height
             +'" border="'+ iconSet.border
             +'" vspace="'+ iconSet.vspace
             +'" hspace="'+ iconSet.hspace
             +'" style="' + iconSet.style
             +'" align="' + iconSet.align
             +'" alt="Current conditions" />');
   }  else return '';
};


function ajax_getIconName1 ( iconNr ,iconSet ) {
// perform a lookup and return the graphic for the condition icon
// (using NWS icon nameing convention)
var i0nr, iSrc;
iconList = new Array(
   "skc",          //  0 sunny
   "nskc",         //  1 clearnight
   "bkn",          //  2 cloudy
   "sct",          //  3 cloudy2
   "nbkn",         //  4 cloudynight
   "sct",          //  5 dry
   "fg",           //  6 fog
   "hazy",         //  7 haze
   "ra",           //  8 heavyrain
   "few",          //  9 mainlyfine
   "mist",         // 10 mist
   "nfg",          // 11 nightfog
   "nra",          // 12 nightheavyrain
   "novc",         // 13 nightovercast
   "nra",          // 14 nightrain
   "nshra",        // 15 nightshowers
   "nsn",          // 16 nightsnow
   "ntsra",        // 17 nightthunder
   "ovc",          // 18 overcast
   "bkn",          // 19 partlycloudy
   "ra",           // 20 rain
   "ra",           // 21 rain2
   "shra",         // 22 showers2
   "ip",           // 23 sleet
   "ip",           // 24 sleetshowers
   "sn",           // 25 snow
   "sn",           // 26 snowmelt
   "sn",           // 27 snowshowers2
   "skc",          // 28 sunny
   "scttsra",      // 29 thundershowers
   "hi_tsra",      // 30 thundershowers2
   "tsra",         // 31 thunderstorms
   "nsvrtsra",     // 32 tornado
   "wind",         // 33 windy
   "ra1",          // 34 stopped rainning
   "windyrain",    // 35 windy/rain (new with V2.11)
   "sunrise",      // 36 sunrise
   "sunset"        // 37 sunset
   );

   if (iconNr >= 0 && iconNr <= 37) {
      i0nr = (iconNr).toString().str_pad(2);//,"0","L");
      iSrc = iconSet.src.replace(/(#PIC#|\{PIC\})/i, iconList[iconNr]);
      iSrc =        iSrc.replace(/(#0NR#|\{0NR\})/i, i0nr);
      iSrc =        iSrc.replace(/(#NR#|\{NR\})/i  , iconNr);
      return ('<img src="'+ iSrc
             +'" width="' + iconSet.width
             +'" height="'+ iconSet.height
             +'" border="'+ iconSet.border
             +'" vspace="'+ iconSet.vspace
             +'" hspace="'+ iconSet.hspace
             +'" style="' + iconSet.style
             +'" align="' + iconSet.align
             +'" alt="Current conditions" />');
   }  else return '';
};


//------------------------------------------------------------------------------
// CONVERSIONS: prototypes to handle conversions from clientraw data to desired units-of-measure
//------------------------------------------------------------------------------
Number.prototype.convertToMetric = function ( units, type ) { // convert to C, kts, hPa, mm, cm or meters
type = (typeof type == 'undefined')? "" : type;
   if (type=="convDate" || type=="convTime") return this;
   ;;;if (!units) alert("Error in convertToMetric: "+type);
   switch (units.toString().toLowerCase()) { // lowercase in case we get FT or KMH etc
// temp to °C
   case "°f"    : 
   case "&deg;f": return((this - 32) / 1.8); // Celsius = (this - 32) * 0.556
// wind mph, km/h and m/s to kts
   case "kmh"   :
   case "kph"   :
   case "km/h"  : return (this * 0.539956803);
   case "mph"   : return (this / 1.150779450);
   case "m/s"   : return (this / 0.514444444);
// baro inHg, mmHg and kPa to hPa
   case "inhg"  : return (this * 33.86388667);
   case "mmhg"  : return (this * 1.3332239);
   case "kpa"   : return (this * 10.0);
// rain to mm and snow to cm
   case "in."   :
   case "in"    : if (type=="convSnow") return (this * 2.54);
                  else                  return (this * 25.4);
// distance miles and meters to km
   case "m"     : return (this / 1000);
   case "miles" : return (this / 1.150779450);
// altitude to meters
   case "ft"    : return (this / 3.2808399);
   default      : return (this * 1.0);
   }
};


Number.prototype.convertTemp = function() { // °C
   switch (uom.Temp) {
   case "&deg;F": return((this * 1.8) + 32.0);
   default      : return (this * 1.0);
   }
};

Number.prototype.convertWind = function() { // kts
   switch (uom.Wind) {
   case "mph" : return (this * 1.15077945);
   case "kph" : return (this * 1.852);
   case "m/s" : return (this * 0.514444444);
   default    : return (this * 1.0);
   }
};

Number.prototype.convertBaro = function() { // hPa
   switch (uom.Baro) {
   case "inHg": return (this / 33.863886666667);
   case "mmHg": return (this / 1.3332239);
   case "kPa" : return (this * 0.1);
   default    : return (this * 1.0);
   }
};

Number.prototype.convertRain = function() { // mm
   switch (uom.Rain) {
   case "in.": return (this * 0.0393700787402);
   case "in" : return (this * 0.0393700787402);
   case "cm" : return (this * 0.1);
   default   : return (this * 1.0);
   }
};

Number.prototype.convertAlti = function() { // meters
   switch (uom.Alti) {
   case "ft" : return (this * 3.2808399); break;
   default   : return (this * 1.0);
   }
};

Number.prototype.convertSnow = function() { // cm
   switch (uom.Snow) {
   case "in.": return (this * 0.3937007874020);
   case "in" : return (this * 0.3937007874020);
   case "ft" : return (this * 0.0328083989501);
   case "mm" : return (this * 10.0);
   case "m"  : return (this * 0.1);
   default   : return (this * 1.0);
   }
};

Number.prototype.convertDist = function() { // km
   switch (uom.Dist) {
   case "m"     : return (this / 1000);
   case "miles" : return (this / 1.150779450);
   default   : return (this * 1.0);
   }
};

// Switch date between Euro and US format i.e. 21-03-2010 to 3/21/2010
String.prototype.convDate = function () {
   return "worksD";//this;
};

// Switch time between 12h and 24h format i.e. 19:00 to 07:00pm
String.prototype.convTime = function () {
   return "worksT";//this;
};


//----------------------------------------------------------- end of conversions


function ajax_getBeaufortNumber ( wind ) {
// return a number for the beaufort scale based on wind knots (native WD format)
  if (wind <  1 ) {return("0"); }
  if (wind <  4 ) {return("1"); }
  if (wind <  7 ) {return("2"); }
  if (wind < 11 ) {return("3"); }
  if (wind < 17 ) {return("4"); }
  if (wind < 22 ) {return("5"); }
  if (wind < 28 ) {return("6"); }
  if (wind < 34 ) {return("7"); }
  if (wind < 41 ) {return("8"); }
  if (wind < 48 ) {return("9"); }
  if (wind < 56 ) {return("10"); }
  if (wind < 64 ) {return("11"); }
  if (wind >=64 ) {return("12"); }
  return("0");
};


function ajax_getBaroTrend(btrnd) {
// routine from Anole's wxsticker PHP (adapted to JS by Ken True)
// input: trend in hPa or millibars
//   Barometric Trend(3 hour)

// Change Rates
// Rapidly: =.06 inHg; 1.5 mmHg; 2.0 hPa; 2.0 mb
// Slowly : =.02 inHg; 0.5 mmHg; 0.7 hPa; 0.7 mb

// 5 conditions
// Rising Rapidly
// Rising Slowly
// Steady
// Falling Slowly
// Falling Rapidly

// Page 52 of the PDF Manual
// http://www.davisnet.com/product_documents/weather/manuals/07395.234-VP2_Manual.pdf
// figure out a text value for barometric pressure trend
   if ((btrnd >= -0.7) && (btrnd <= 0.7)) { return(langBaroTrend[0]); }
   if ((btrnd >   0.7) && (btrnd <  2.0)) { return(langBaroTrend[1]); }
   if (btrnd >=   2.0)                    { return(langBaroTrend[2]); }
   if ((btrnd <  -0.7) && (btrnd > -2.0)) { return(langBaroTrend[3]); }
   if (btrnd <=  -2.0)                    { return(langBaroTrend[4]); }
  return(btrnd);
};

// Official colours for UV as specified by WHO, WMO & UNEP
var UVColor = new Array
   ( "none"    //  0
   , "#4EB400" //  1 Low
   , "#A0CE00" //  2
   , "#F7E400" //  3 Medium
   , "#F8B600" //  4
   , "#F88700" //  5
   , "#F85900" //  6 High
   , "#E82C0E" //  7
   , "#D8001D" //  8 Very High
   , "#FF0099" //  9
   , "#B54CFF" // 10
   , "#998CFF" // 11+Extreme
   );

function ajax_getUVrange ( uv ) { // code simplified by FourOhFour on wxforum.net
   var uvword = "None";
   var uvclr1  = UVColor[Math.min(11,Math.round(uv))];
   switch (true) {
   case (uv < 0): uvword = langUVWords[6]; uvclr2 = 'none';    break; // UV sensor is not sending
   case (uv == 0): uvword = langUVWords[0]; uvclr2 = 'none';    break; // None
   case (uv < 3): uvword = langUVWords[1]; uvclr2 = '#4EB400'; break; // Low
   case (uv < 6): uvword = langUVWords[2]; uvclr2 = '#F7E400'; break; // Medium
   case (uv < 8): uvword = langUVWords[3]; uvclr2 = '#F85900'; break; // High
   case (uv <11): uvword = langUVWords[4]; uvclr2 = '#D8001D'; break; // Very High
   case (uv >18): uvword = langUVWords[6]; uvclr2 = 'none';    break; // UV sensor is not sending
   default      : uvword = langUVWords[5]; uvclr2 = '#998CFF';        // Extreme
   }
   // return ('<span style="border: 1px solid gray; text-transform: uppercase; font-weight: bold; padding-bottom: 1px; background-color: '+ uvclr1 +';">&nbsp;'+Math.round(uv) +'&nbsp;'+ uvword +'&nbsp;</span>');
   return ('<span style="border: 1px solid gray; text-transform: uppercase; font-weight: bold; padding-bottom: 1px; background-color: '+ uvclr1 +';">&nbsp;'+ uvword +'&nbsp;</span>');
}; // end ajax_getUVrange function


function ajax_getUVburnRate ( uv ) {
   var uvIdx  = Math.min(18,Math.round(uv));
   switch (uvIdx) {
   case  1: uvrate = 112;  break;
   case  2: uvrate =  56;  break;
   case  3: uvrate =  37;  break;
   case  4: uvrate =  28;  break;
   case  5: uvrate =  22;  break;
   case  6: uvrate =  19;  break;
   case  7: uvrate =  16;  break;
   case  8: uvrate =  14;  break;
   case  9: uvrate =  12;  break;
   case 10: uvrate =  11;  break;
   case 11: uvrate =  10;  break;
   case 12: uvrate =   9;  break;
   case 13: uvrate =   9;  break;
   case 14: uvrate =   8;  break;
   case 15: uvrate =   7;  break;
   case 16: uvrate =   6;  break;
   case 17: uvrate =   5;  break;
   case 18: uvrate =   4;  break;
   default: uvrate =   "N/A";
   }
   return uvrate;
}; // end ajax_getUVburnRate function


function ajax_getTrendArrow( nowTemp, yesterTemp, Legend, textUP, textDN, numDp) {
// generate an <img> tag with alt= and title= for rising/falling values
var diff = nowTemp.toFixed(3) - yesterTemp.toFixed(3);
var absDiff = Math.abs(diff);
var diffStr = '' + diff.toFixed(numDp);
var absDiffStr = '' + absDiff.toFixed(numDp);
var image = '';
var msg = '';

   if (diff == 0) { // no change
      msg = '';
      image = '<img src="' + imgDir + 'steady.gif'
            + '" alt="'    + msg
            + '" title="'  + msg
            + '" width="7" height="8" style="border: 0; margin: 1px 3px;" />';
   } else if (diff > 0) { // today is greater
      msg = textUP.replace(/\%s/,absDiffStr);
      image = '<img src="' + imgDir + 'rising.gif'
            + '" alt="'    + msg
            + '" title="'  + msg
            + '" width="7" height="8" style="border: 0; margin: 1px 3px;" />';
   } else { // today is lesser
      msg = textDN.replace(/\%s/,absDiffStr);
      image = '<img src="' + imgDir + 'falling.gif'
            + '" alt="'    + msg
            + '" title="'  + msg
            + '" width="7" height="8" style="border: 0; margin: 1px 3px;" />';
   }
   return ((Legend) ? (diff + Legend + image) : image);
}; // end ajax_getTrendArrow function


// function to add colored heatColorWord by Mike Challis
function ajax_getHeatColor(temp ,WindChill, Humidex) {
var fg = bg = hw = "";
var hcWord = langHeatWords[0];
var val = { fg:'', bg:'', hw:'' };
   if (temp > 32 && Humidex > 29) {
      switch (true) {
      case (Humidex   > 54): fg = "white"; bg = "#BA1928"; hw = langHeatWords[ 1]; break;
      case (Humidex   > 45): fg = "white"; bg = "#E02538"; hw = langHeatWords[ 2]; break;
      case (Humidex   > 39): fg = "black"; bg = "#E178A1"; hw = langHeatWords[ 4]; break;
      case (Humidex   > 29): fg = "white"; bg = "#CC6633"; hw = langHeatWords[ 6]; break;
      }
   } else if (WindChill < 16 ) {
      switch (true) {
      case (WindChill <-28): fg = "black"; bg = "#91ACFF"; hw = langHeatWords[14]; break;
      case (WindChill <-18): fg = "black"; bg = "#91ACFF"; hw = langHeatWords[13]; break;
      case (WindChill < -9): fg = "white"; bg = "#806AF9"; hw = langHeatWords[12]; break;
      case (WindChill < -1): fg = "white"; bg = "#3366FF"; hw = langHeatWords[11]; break;
      case (WindChill <  8): fg = "white"; bg = "#6699FF"; hw = langHeatWords[10]; break;
      case (WindChill < 16): fg = "black"; bg = "#89B2EA"; hw = langHeatWords[ 9]; break;
      }
   }  else if (WindChill >= 16 && temp <= 32) {
      switch (true) {
      case (temp      < 26): fg = "black"; bg = "#C6EF8C"; hw = langHeatWords[ 8]; break;
      case (temp      <=32): fg = "black"; bg = "#CC9933"; hw = langHeatWords[ 7]; break;
      }
   }
   val = { fg:fg ,bg:bg ,hw:hw };
   return val;
}; // end ajax_getHeatColor function

function ajax_getHeatColorWord(temp ,WindChill, Humidex) {
var val = ajax_getHeatColor(temp ,WindChill, Humidex);
return ((val.fg=="")? val.hw
                    : '<span style="border: solid 1px; color: '+val.fg+'; background-color: '+val.bg+';">&nbsp;'+val.hw+'&nbsp;</span>'
                    );
};

function ajax_getHeatColorTemp(temp ,WindChill, Humidex, actTemp) {
var val = ajax_getHeatColor(temp ,WindChill, Humidex);
return ((val.fg=="")? actTemp.toFixed(dp.Temp)+uom.Temp
                    : '<span style="border: solid 1px; color: '+val.fg+'; background-color: '+val.bg+';">&nbsp;'+actTemp.toFixed(dp.Temp)+uom.Temp+'&nbsp;</span>'
                    );
};


// slice and dice the clientraw[49] for possible translation of current weather
//
function ajax_fixupCondition( rawcond ) {
var cond  = rawcond;
    cond  = cond.replace(/_/gm,' ');     // replace any _ with blank.
    cond  = cond.replace(/[\r\n]/gm,''); // remove embedded CR and/or LF
var conds = cond.split('/');             // split up the arguments.
var tstr = '';
   for (var i = 0;i<conds.length;i++) {
      var t = conds[i];
      t = t.toLowerCase();
      t = t.ucfirst();
      t = t.replace(/\s+$/,'');  // trim trailing blanks
      if(langTransLookup[t]) conds[i] = langTransLookup[t];
      else                   conds[i] = t;
   }
   if (conds[0].length == 0) { conds.splice(0,1);  } // remove blank entry
   if (conds[0] == conds[2]) { conds.splice(2,1); } // remove duplicate last entry
   return(conds.join(', '));
}; // end ajax_fixupCondition function


// Mike Challis' counter function (adapted by Ken True)
function ajax_countup() {
var element = document.getElementById("ajaxcounter");
   if (element) {
      element.innerHTML = counterSecs;
      counterSecs++;
   }
};


function ajax_getFireIndex ( fwi , fireImg ) {
   switch (true) {
     case (fwi==0): idx = fireImg.imgNrs[0]; break;
     case (fwi< 7): idx = fireImg.imgNrs[1]; break;
     case (fwi<16): idx = fireImg.imgNrs[2]; break;
     case (fwi<25): idx = fireImg.imgNrs[3]; break;
     case (fwi<31): idx = fireImg.imgNrs[4]; break;
     default      : idx = fireImg.imgNrs[5];
   }
return idx;
};

// ----------
// PROTOTYPES (PHP equivalents)
// ----------

// Padding: left and right .. similar to "str_pad" function in php
String.prototype.str_pad = function ( cnt, chr, typ ) {
var sPad = "";
var char = (typeof chr == 'undefined')? "0" : chr;
var type = (typeof typ == 'undefined')? "R" : typ;
var iPad = cnt - Math.floor(this).toString().length;
   for (var i=0;i<iPad;i++) sPad+=char;
   return ((type=="R")? (sPad+this) : (this+sPad));
};

// Make a string's first character uppercase ... similar to "ucfirst" function in php
String.prototype.ucfirst = function () {
   return this.substr(0,1).toUpperCase() + this.substr(1,this.length);
};

// Date formating ... similar to "date" function in php
Date.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"
// formats not supported: N, z, W, t, L, o, B, u, e, I, O, P, T, c, r, U
   if (typeof fmt == 'undefined')
      return (this.toLocaleString()); // ... 26 April 2009 02:12:58 PM

   day = this.getDay();      // 0-6  (0=Sunday)
   dat = this.getDate();     // 1-31
   mth = this.getMonth()+1;  // 1-12 (1=January)
   yer = this.getFullYear(); // eg. 2009
   hrs = this.getHours();    // 0-23
   min = this.getMinutes();  // 0-59
   sec = this.getSeconds();  // 0-59
   tzo = this.getTimezoneOffset()*60; // -43200 through 50400 seconds
   switch (dat%10) { // day suffix eg. 23rd
   case  1: suf = dat==11? langDaySuf[3] : langDaySuf[0];
   case  2: suf = dat==12? langDaySuf[3] : langDaySuf[1];
   case  3: suf = dat==13? langDaySuf[3] : langDaySuf[2];
   default: suf =          langDaySuf[3];
   }

// date (d, j)
   fmt = fmt.replace("d" ,dat.toString().str_pad(2)); // 01 to 31
   fmt = fmt.replace("j" ,dat); //  1 to 31
// week (w)
   fmt = fmt.replace("w" ,day); //  0 to 6
// month (m, n)
   fmt = fmt.replace("m" ,mth.toString().str_pad(2)); //  01 to 12
   fmt = fmt.replace("n" ,mth); // 1 to 12
// year (Y, y)
   fmt = fmt.replace("Y" ,yer);
   fmt = fmt.replace("y" ,yer%100);
// am/pm (A, a)
   ampm = (hrs<12)? langAM_PM[0] : langAM_PM[1];
   AMPM = (hrs<12)? langAM_PM[2] : langAM_PM[3];
   fmt = fmt.replace("a" ,ampm);
   fmt = fmt.replace("A" ,AMPM);
// hours (g, G, h, H)
   hrs12 = (hrs%12==0)? 12 : hrs%12;
   fmt = fmt.replace("g" ,hrs12); // 1 to 12
   fmt = fmt.replace("G" ,hrs);   // 0 to 23
   fmt = fmt.replace("h" ,hrs12.toString().str_pad(2)); // 01 to 12
   fmt = fmt.replace("H" ,hrs  .toString().str_pad(2)); // 00 to 23
// minutes (i)
   fmt = fmt.replace("i" ,min.toString().str_pad(2)); // 00 to 59
// seconds (s)
   fmt = fmt.replace("s" ,sec.toString().str_pad(2)); // 00 to 59
// timezone (Z)
   fmt = fmt.replace("Z" ,tzo); // -43200 through 50400 seconds
// other (S ,l ,D ,F, M)
   fmt = fmt.replace(/(\d+)S/g ,"$1"+suf); // eg. rd
   fmt = fmt.replace(/l(\s|,|-|\.)/ ,langDays[day]+"$1");                    // eg. Sunday
   fmt = fmt.replace(/D(\s|,|-|\.)/ ,langDays[day].substring(0,3)+"$1");     // eg. Sun
   fmt = fmt.replace(/F(\s|,|-|\.)/ ,langMonths[mth-1]+"$1");                // eg. January
   fmt = fmt.replace(/M(\s|,|-|\.)/ ,langMonths[mth-1].substring(0,3)+"$1"); // eg. Jan
   return (fmt);
};

// returns "-" if number is less than 0
Number.prototype.sign = function () {
   return (this<0)? "-" : "";
};
// return rounded integer value of a number
Number.prototype.intval = function( dp ) {
   return (Math.floor(Math.abs(this.toFixed(dp))));
};
// return fraction as a rounded integer number
Number.prototype.fraction = function( dp ) {
   frac = Math.abs(this) - Math.floor(Math.abs(this));
   return frac.toFixed(dp);
};

// Number formating ... thousands seperator and decimal point ... similar to "number_format" function in php
// Format a number with grouped thousands eg. str = num.number_format("23823.87273") = "23,823.87"
Number.prototype.number_format = function ( dp ,dpSep ,thouSep ) {
if (typeof dp == 'undefined') dp = 0;
if (typeof dpSep == 'undefined') dpSep = ".";
if (typeof thouSep == 'undefined') thouSep = ",";
var inum = this.intval(dp).toString();
var frac = this.fraction(dp).toString().substr(2);
var ret  = this.sign();
var f = (inum.length%3==0) ? 3 : inum.length%3;
   ret+= inum.substr(0, f);
   for (i=f; i<inum.length; i+=3)
      ret+= thouSep+inum.substr(i,3);
   if (dp>0) ret+=dpSep+frac;
return (ret);
};

//==============================================================================
// Get clientrawextra.txt data  (only needs to be loaded once)                 .
// -----------------------------------------------------------------------------
function ajaxLoader_clientextra(urlExtra) {
var rawextra;
if (document.getElementById)
var x = (window.ActiveXObject) ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(urlExtra);

if (x) { // got something back
   x.onreadystatechange = function() {
      try {
         if (x.readyState==4 && x.status==404) { // not found
            if (notifyE==1) alert("DASHBOARD ERROR:\nYour \""+clientrawextraFile+"\" file could not be found.");
            notifyE++;
         } else
         if (x.readyState==4 && x.status==200) { // Mike Challis added fix to fix random error: NS_ERROR_NOT_AVAILABLE
            rawextra = x.responseText.split(' ');
            var wdpattern=/\d+\.\d+.*!!/; // looks for '!!nn.nn!!' version string
            if (rawextra[0]=='12345' && (wdpattern.test(x.responseText)) )
               clientrawextra = rawextra;
            else // only save if fully downloaded
               setTimeout("ajaxLoader_clientextra(clientrawextraFile + '?' + new Date().getTime())", extraRetryInterval);
            notifyE=0;
         } // END if (x.readyState == 4 && x.status == 200)
      } // END try
      catch(e){}  // Mike Challis added fix to fix random error: NS_ERROR_NOT_AVAILABLE
   }; // END x.onreadystatechange = function()

   x.open("GET", urlExtra, true);
   x.send(null);
} // END if(x)
};

//==============================================================================
//  Get clientraw.txt data and format <span class="ajax" id="ajax..."></span> areas
// --------------------------------------------------------------------------------
function ajaxLoader(url) {
;;;var rand = new Date().getTime();

if (document.getElementById) {
   var x = (window.ActiveXObject) ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(url);
} else {
   ;;;set_ajax_obs('ajaxProgress',rand+'elem','ERROR: No elements');
}
if (x) { // got something back
x.onreadystatechange = function() {
try {
   ;;;set_ajax_obs('ajaxProgress',rand+'ready','-- READY --');
   if (x.readyState==4 && x.status==200) { // Mike Challis added fix to fix random error: NS_ERROR_NOT_AVAILABLE
   var clientraw = x.responseText.split(' ');
   // now make sure we got the entire clientraw.txt  -- thanks to Johnnywx
   // valid clientraw.txt has '12345' at start and '!!' at end of record
   var wdpattern=/\d+\.\d+.*!!/; // looks for '!!nn.nn!!' version string
   // If we have a valid clientraw file AND ajaxUpdates is < update.maxupdates

   if (clientraw[0] == '12345'
   &&  wdpattern.test(x.responseText)
   && (ajaxUpdates <= update.maxupdates || update.maxupdates > 0) ) {
   ;;;set_ajax_obs('ajaxProgress',rand+'start','-- START --');
	 clientrawloaded = 1;

   if (update.maxupdates > 0) ajaxUpdates++; // increment counter if needed

// -----------------------------------------------------------------------------
// Date / Time (WD)
      ;;;set_ajax_obs('ajaxProgress',rand+'date','in Dates');
      WDdt = new Date( clientraw[141], clientraw[36]-1, clientraw[35], clientraw[29], clientraw[30], clientraw[31]);

      set_ajax_obs("ajaxndate"   , WDdt.date("F d, Y")); // Apr 16, 2009
      set_ajax_obs("ajaxndate2"  , WDdt.date("F d, Y"));  // April 16, 2009
      set_ajax_obs("ajaxntime"   , WDdt.date("g:i a"));    // 2:37 pm
      set_ajax_obs("ajaxntimess" , WDdt.date("g:i:s a"));  // 2:37:07 pm
      set_ajax_obs("ajaxdname"   , WDdt.date("D"));      // Mon

      // current date and time of observation in clientraw.txt
      set_ajax_obs("ajaxdatetime", WDdt.date(uom.dateFmt+' '+uom.timeFmt)); // 16/4/2009 02:37:07pm
      set_ajax_obs("ajaxdate@"   , WDdt.date(uom.dateFmt) + ' @ '); // 6/4/2009 @
      set_ajax_obs("ajaxdate2"   , WDdt.date(uom.dateFmt) + ' @ '); // 6/4/2009 @
      set_ajax_obs("ajaxdate"    , WDdt.date(uom.dateFmt)); // 16/4/2009
      set_ajax_obs("ajaxtime"    , WDdt.date(uom.timeFmt)); // 02:37:07pm
      set_ajax_obs("gizmodate"   , WDdt.date(uom.dateFmt)); // 16/4/2009
      set_ajax_obs("gizmotime"   , WDdt.date(uom.timeFmt)); // 02:37:07pm


// Outdoor temperature ... (°C)
//clientraw[4] = 40.7; // uncomment this for debugging
      ;;;set_ajax_obs('ajaxProgress',rand+'temp','in Temp'); // "ajaxProgress" tag for debugging ... gets removed by packer
      temp     = parseFloat(clientraw[ 4]).convertTemp();
      templast = parseFloat(clientraw[90]).convertTemp(); // last hours temp
      tempmax  = parseFloat(clientraw[46]).convertTemp();
      tempmin  = parseFloat(clientraw[47]).convertTemp();
      if (clientrawextra!=null)
           temp24hAgo = parseFloat(clientrawextra[21]).convertTemp();
      else temp24hAgo = temp;
      temp24hDiff = temp - temp24hAgo;

      set_ajax_obs("ajaxtemp"   , temp.toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxtempNoU", temp.toFixed(dp.Temp));
      set_ajax_obs("gizmotemp"  , temp.toFixed(dp.Temp) + uom.Temp);
/*      set_ajax_obs("ajaxbigtemp", temp.toFixed(0) + uom.Temp); */
			if (temp < 0){
				document.getElementById("ajaxbigtemp").src = "./images/bignumb"+useUOM+"/n"+(temp.toFixed(0)*-1)+".png";
			} else {
				document.getElementById("ajaxbigtemp").src = "./images/bignumb"+useUOM+"/"+temp.toFixed(0)+".png";
			}

      temparrow = ajax_getTrendArrow( temp
                                    , templast
                                    , ''
                                    , langTempRising+uom.Temp+langTempLastHour
                                    , langTempFalling+uom.Temp+langTempLastHour
                                    , 1
                                    );
      set_ajax_obs("ajaxtemparrow" , (temp-templast).toFixed(dp.Temp), temparrow);
      set_ajax_obs("gizmotemparrow", temparrow);

      temprate = temp - templast;
      temprate = temprate.toFixed(1);
      if (temprate > 0.0) { temprate = '+' + temprate; } // add a '+' for positive rates
      set_ajax_obs("ajaxtemprate" , temprate + uom.Temp);
      set_ajax_obs("gizmotemprate", temprate + uom.Temp);

      set_ajax_obs("ajaxtempmax"   , tempmax    .toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxtempmin"   , tempmin    .toFixed(dp.Temp) + uom.Temp);

      set_ajax_obs("ajax24hDiff"   , temp24hDiff.toFixed(dp.Temp) + uom.Temp);
      diffarrow = ajax_getTrendArrow( temp
                                    , temp24hAgo
                                    , ''
                                    , langTempRising+uom.Temp+langTempYesterday
                                    , langTempFalling+uom.Temp+langTempYesterday
                                    , 1
                                    );
      set_ajax_obs("ajax24hDiffarrow", (temp-temp24hDiff).toFixed(dp.Temp), diffarrow);


// Thermometer ...
      ;;;set_ajax_obs('ajaxProgress',rand+'term','in Thermometer');
      thermometerText = langThermoCurrently + temp.toFixed(dp.Temp) + uom.Temp
                  + ", " + langThermoMax + tempmax.toFixed(dp.Temp) + uom.Temp
                  + ", " + langThermoMin + tempmin.toFixed(dp.Temp) + uom.Temp;

      param = '?uom=' + useUOM
            + '&t='   + temp.toFixed(dp.Temp)
            + '&iW='  + thermometerImg.width
            + '&iH='  + thermometerImg.height;
      set_ajax_obs("ajaxthermometer", param
         , '<img src="' + thermometerImg.src + param
         + '" alt="'    + thermometerText
         + '" title="'  + thermometerText
         + '" width="'  + thermometerImg.width
         + '" height="' + thermometerImg.height
         + '" hspace="' + thermometerImg.hspace
         + '" vspace="' + thermometerImg.vspace
         + '" border="' + thermometerImg.border
         + '" align="'  + thermometerImg.align
         + '" style="'  + thermometerImg.style
         + '" />');


// Dewpoint ... (°C)
//clientraw[72] = -2.4
      ;;;set_ajax_obs('ajaxProgress',rand+'dewp','in Dewpoint');
      dew    = parseFloat(clientraw[ 72]).convertTemp();
      dewmin = parseFloat(clientraw[139]).convertTemp();
      dewmax = parseFloat(clientraw[138]).convertTemp();

      set_ajax_obs("ajaxdew"   , dew   .toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("gizmodew"  , dew   .toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxdewmin", dewmin.toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxdewmax", dewmax.toFixed(dp.Temp) + uom.Temp);


// WetBulb ... (°C)
      ;;;set_ajax_obs('ajaxProgress',rand+'wetb','in Wetbulb');
      wetbulb = parseFloat(clientraw[159]).convertTemp();
      set_ajax_obs("ajaxwetbulb",wetbulb.toFixed(dp.Temp) + uom.Temp);

// Humidex ... (°C)
      humidex    = parseFloat(clientraw[45]).convertTemp();
      humidexmin = parseFloat(clientraw[76]).convertTemp();
      humidexmax = parseFloat(clientraw[75]).convertTemp();

      set_ajax_obs("ajaxhumidex"   , humidex   .toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxhumidexmin", humidexmin.toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxhumidexmax", humidexmax.toFixed(dp.Temp) + uom.Temp);


// Heat Index ... (°C)
      heatidx    = parseFloat(clientraw[112]).convertTemp();
      heatidxmin = parseFloat(clientraw[111]).convertTemp();
      heatidxmax = parseFloat(clientraw[110]).convertTemp();

      set_ajax_obs("ajaxheatidx"   , heatidx   .toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxheatidxmin", heatidxmin.toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxheatidxmax", heatidxmax.toFixed(dp.Temp) + uom.Temp);


// WindChill ... (°C)
      windchill    = parseFloat(clientraw[44]).convertTemp();
      windchillmin = parseFloat(clientraw[78]).convertTemp();
      windchillmax = parseFloat(clientraw[77]).convertTemp();

      set_ajax_obs("ajaxwindchill"   , windchill   .toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxwindchillmin", windchillmin.toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxwindchillmax", windchillmax.toFixed(dp.Temp) + uom.Temp);


// FeelsLike ... (°C)
      ;;;set_ajax_obs('ajaxProgress',rand+'feel','in Feelslike');
      temp = clientraw[4]; // note.. temp in C
      switch (true) {
      case (temp<=16.0): feelslike = clientraw[44]; break; // use WindChill
      case (temp>=27.0): feelslike = clientraw[45]; break; // use Humidex
      default          : feelslike = temp;                 // use temperature
      }
      feelslike  = Math.round(parseFloat(feelslike).convertTemp());
      set_ajax_obs("ajaxfeelslike" , feelslike + uom.Temp);

      // mike challis added heatColorWord feature
      heatColorWord = ajax_getHeatColorWord(clientraw[4],clientraw[44],clientraw[45]);
      set_ajax_obs("ajaxheatcolorword", heatColorWord);

      temp = parseFloat(clientraw[ 4]).convertTemp();
      tempColorBg = ajax_getHeatColorTemp(clientraw[4],clientraw[44],clientraw[45], temp);
      set_ajax_obs("ajaxtempcolor", temp.toFixed(dp.Temp), tempColorBg);


// Apparent temperature ... (°C)
      apparenttemp    = parseFloat(clientraw[130]).convertTemp();
      apparenttempmin = parseFloat(clientraw[136]).convertTemp();
      apparenttempmax = parseFloat(clientraw[137]).convertTemp();

      set_ajax_obs("ajaxapparenttemp"   , apparenttemp   .toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxapparenttempmin", apparenttempmin.toFixed(dp.Temp) + uom.Temp);
      set_ajax_obs("ajaxapparenttempmax", apparenttempmax.toFixed(dp.Temp) + uom.Temp);


// Humidity ... %
//clientraw[5] = 100;
      ;;;set_ajax_obs('ajaxProgress',rand+'humi','in Humidity');
      humidity = clientraw[5];
      set_ajax_obs("ajaxhumidity" , humidity);
      set_ajax_obs("gizmohumidity", humidity);
      // sorry.. no min/max data for humidity available in clientraw.txt


// Pressure ... (hPa)
      ;;;set_ajax_obs('ajaxProgress',rand+'baro','in Baro');
      pressure      = parseFloat(clientraw[  6]).convertBaro();
      pressuremin   = parseFloat(clientraw[132]).convertBaro();;
      pressuremax   = parseFloat(clientraw[131]).convertBaro();;
      pressuretrend = parseFloat(clientraw[ 50]).convertBaro();
      barotrendtext = ajax_getBaroTrend(clientraw[50]);

      set_ajax_obs("ajaxbaro"      , pressure.toFixed(dp.Baro) +' '+ uom.Baro);
      set_ajax_obs("ajaxbaroNoU"   , pressure.toFixed(dp.Baro));
      set_ajax_obs("gizmobaro"     , pressure.toFixed(dp.Baro) +' '+ uom.Baro);

      pressuretrend = pressuretrend.toFixed(dp.Baro+1);
      if (pressuretrend > 0.0) {pressuretrend = '+' + pressuretrend; } // add '+' to rate
      set_ajax_obs("ajaxbarotrend" , pressuretrend + uom.Baro);
      set_ajax_obs("gizmobarotrend", pressuretrend + uom.Baro);
      baroarrow = ajax_getTrendArrow( pressure
                                    , pressure-pressuretrend
                                    , ''
                                    , langBaroRising +uom.Baro+langBaroPerHour
                                    , langBaroFalling+uom.Baro+langBaroPerHour
                                    , 2
                                    );
      set_ajax_obs("ajaxbaroarrow"     , pressuretrend, baroarrow);
      set_ajax_obs("ajaxbarotrendtext" , barotrendtext);
      set_ajax_obs("gizmobarotrendtext", barotrendtext);
      set_ajax_obs("ajaxbaromin"       , pressuremin.toFixed(dp.Baro) +' '+ uom.Baro);
      set_ajax_obs("ajaxbaromax"       , pressuremax.toFixed(dp.Baro) +' '+ uom.Baro);


// Wind ... (kts)
//clientraw[  2] = 10.2;
//clientraw[140] = 20.2;
      ;;;set_ajax_obs('ajaxProgress',rand+'wspd','in WindSpeed');
      wind        = parseFloat(clientraw[  2]).convertWind(); // Wind gust
      gust        = parseFloat(clientraw[140]).convertWind(); // Max wind gust in last minute
      windmaxavg  = parseFloat(clientraw[113]).convertWind(); // Max avg speed
      maxgust     = parseFloat(clientraw[ 71]).convertWind(); // Max wind gust
      maxgusttime  = clientraw[135];                           // Max wind gust time
      beaufortnum = ajax_getBeaufortNumber(clientraw[2]);

   // Wind gust
      if (maxgust > 0.0 )
           set_ajax_obs("ajaxmaxgust"   , maxgust.toFixed(dp.Wind) +' '+ uom.langWind);
      else set_ajax_obs("ajaxmaxgust"   , 'None');

   // Max wind gust
      set_ajax_obs("ajaxwindmaxgust"    , maxgust.toFixed(dp.Wind) +' '+ uom.langWind);
      set_ajax_obs("ajaxwindmaxgusttime", maxgusttime);

   // Max wind gust No UofM
      set_ajax_obs("ajaxwindmaxgust2"    , maxgust.toFixed(dp.Wind));

// Windspeed ... beaufort
      set_ajax_obs("ajaxbeaufortnum"    , beaufortnum);
      set_ajax_obs("ajaxbeaufort"       , langBeaufort[beaufortnum]);

   // Max avg speed
      set_ajax_obs("ajaxwindmaxavg"     , windmaxavg.toFixed(dp.Wind) +' '+ uom.langWind);

   // Current wind speed
      if (wind > 0.0) {
      set_ajax_obs("ajaxwind"      , wind.toFixed(dp.Wind) +' '+ uom.langWind);
      set_ajax_obs("ajaxwind2"      , wind.toFixed(dp.Wind) +' '+ uom.langWind);
      set_ajax_obs("ajaxwindNoU"   , wind.toFixed(dp.Wind));
      set_ajax_obs("gizmowind"     , wind.toFixed(dp.Wind) +' '+ uom.langWind);
      set_ajax_uom("ajaxwinduom"   , true);
      } else {
      set_ajax_obs("ajaxwind"      , langWindCalm);
      set_ajax_obs("ajaxwind2"      , langWindCalm);
      set_ajax_obs("ajaxwindNoU"   , langWindCalm);
      set_ajax_obs("gizmowind"     , langWindCalm);
      set_ajax_uom("ajaxwinduom"   , false);
      }

   // Current gust speed
      if (gust > 0.0) {
      set_ajax_obs("ajaxgust"      , gust.toFixed(dp.Wind) +' '+ uom.langWind);
      set_ajax_obs("ajaxgust2"      , gust.toFixed(dp.Wind) +' '+ uom.langWind);
      set_ajax_obs("ajaxgustNoU"   , gust.toFixed(dp.Wind));
      set_ajax_obs("gizmogust"     , gust.toFixed(dp.Wind) +' '+ uom.langWind);
      set_ajax_uom("ajaxgustuom"   , true);
      } else {
      set_ajax_obs("ajaxgust"      , langGustNone);
      set_ajax_obs("ajaxgust2"      , langGustNone);
      set_ajax_obs("ajaxgustNoU"   , langGustNone);
      set_ajax_obs("gizmogust"     , langGustNone);
      set_ajax_uom("ajaxgustuom"   , false);
      }


// Wind direction & wind rose grapic ...
      ;;;set_ajax_obs('ajaxProgress',rand+'wdir','in WindDir');
      windDeg   = parseFloat(clientraw[3]);
      windDir   = ajax_getWindDir(clientraw[3]);
      valLang   = ajax_getWindDirLang(clientraw[3]); /* to enable translations */

      ;;;set_ajax_obs('ajaxProgress',rand+'rose','in WindRose');
      if (gust > 0.0 || wind > 0.0 || wrImg.calm=="") {
         windicon = '<img src="' + imgDir + windDir + '.gif' // small arrow direction
            + '" alt="'   + langWindFrom + valLang
            + '" title="' + langWindFrom + valLang
            + '" width="14" height="14" />';
         set_ajax_obs("ajaxwindicon"  , valLang, windicon);
         set_ajax_obs("gizmowindicon" , valLang, windicon);
         set_ajax_obs("ajaxwinddir"   , valLang);
         set_ajax_obs("ajaxwinddir2"   , valLang);
         set_ajax_obs("gizmowinddir"  , valLang);
         set_ajax_obs("ajaxwinddeg"   , windDeg + uom.Deg);
         set_ajax_obs("gizmowinddeg"  , windDeg + uom.Deg);

         src = wrImg.src.replace(/(#LANG#|\{LANG\})/i, wrImg.lang);
         src = src.replace      (/(#DIR#|\{DIR\})/i  , wrImg.xlate? valLang : windDir);
         set_ajax_obs(wrImg.useTag, src
            , '<img src="' + src
            + '" alt="'    + langWindFrom + valLang
            + '" title="'  + langWindFrom + valLang
            + '" width="'  + wrImg.width
            + '" height="' + wrImg.height
            + '" hspace="' + wrImg.hspace
            + '" vspace="' + wrImg.vspace
            + '" border="' + wrImg.border
            + '" align="'  + wrImg.align
            + '" style="'  + wrImg.style
            + '" />');
      } else { // Wind calm
         set_ajax_obs("ajaxwindicon"  , "");
         set_ajax_obs("gizmowindicon" , "");
         set_ajax_obs("ajaxwinddir"   , "");
         set_ajax_obs("gizmowinddir"  , "");
         set_ajax_obs("ajaxwinddeg"   , "");
         set_ajax_obs("gizmowinddeg"  , "");

         src = wrImg.src.replace(/(#LANG#|\{LANG\})/i, wrImg.lang);
         src = src.replace      (/(#DIR#|\{DIR\})/i  , wrImg.calm);
         set_ajax_obs(wrImg.useTag , src
            , '<img src="' + src
            + '" alt="'    + langBeaufort[0]
            + '" title="'  + langBeaufort[0]
            + '" width="'  + wrImg.width
            + '" height="' + wrImg.height
            + '" hspace="' + wrImg.hspace
            + '" vspace="' + wrImg.vspace
            + '" border="' + wrImg.border
            + '" align="'  + wrImg.align
            + '" style="'  + wrImg.style
            + '" />');
      }


// Solar Radiation
      ;;;set_ajax_obs('ajaxProgress',rand+'sol','in Solar');
      solar    = clientraw[127] * 1.0;
      solarpct = clientraw[34];
      set_ajax_obs("ajaxsolar"   ,solar.toFixed(0));
      set_ajax_obs("ajaxsolarpct",solarpct);


// UV Index
      ;;;set_ajax_obs('ajaxProgress',rand+'uv','in UV');
      uv = parseFloat(clientraw[79]);
      set_ajax_obs("ajaxuv"   ,uv.toFixed(dp.UV));
      set_ajax_obs("ajaxuvNoD",uv.toFixed(0));
      set_ajax_obs("gizmouv"  ,uv.toFixed(dp.UV)) ;

      uvword = ajax_getUVrange(uv);
      set_ajax_obs("ajaxuvword" ,uv, uvword);
      set_ajax_obs("gizmouvword",uv, uvword);

      uvburnrate = ajax_getUVburnRate(uv);
      set_ajax_obs("ajaxuvburnrate",uvburnrate);

      UVI = Math.min(11,Math.round(uv));
      src = uvImg.src.replace(/(#INDEX#|\{INDEX\})/i, UVI);
      set_ajax_obs(uvImg.useTag, UVI
         ,'<img src="'  + src
         + '" alt="'    + UVI
         + '" title="'  + UVI
         + '" width="'  + uvImg.width
         + '" height="' + uvImg.height
         + '" hspace="' + uvImg.hspace
         + '" vspace="' + uvImg.vspace
         + '" border="' + uvImg.border
         + '" align="'  + uvImg.align
         + '" style="'  + uvImg.style
         + '" />');

// Rain ... (mm)
      ;;;set_ajax_obs('ajaxProgress',rand+'rain','in Rain');
      rain        = parseFloat( clientraw[ 7]).convertRain();
      rainYes     = parseFloat( clientraw[19]).convertRain();
      rainMonth   = parseFloat( clientraw[ 8]).convertRain();
      rainYear    = parseFloat( clientraw[ 9]).convertRain();
      rainratehr  = parseFloat((clientraw[10])*60).convertRain(); // make per hour rate.
      rainratemax = parseFloat((clientraw[11])*60).convertRain(); // make per hour rate

      set_ajax_obs("ajaxrainratehr" ,rainratehr .toFixed(dp.Rain+1) +' '+ uom.Rain);
      set_ajax_obs("ajaxrainratemax",rainratemax.toFixed(dp.Rain+1) +' '+ uom.Rain);

      set_ajax_obs("ajaxrain"       ,rain   .toFixed(dp.Rain)   +' '+ uom.Rain);
      set_ajax_obs("ajaxrain2"      ,rain   .toFixed(dp.Rain)   +' '+ uom.Rain);
      set_ajax_obs("ajaxrainYes"    ,rainYes.toFixed(dp.Rain)   +' '+ uom.Rain);
      set_ajax_obs("ajaxrainydy"    ,rainYes.toFixed(dp.Rain)   +' '+ uom.Rain); // old yesterdays rain tag for compatibility

      set_ajax_obs("ajaxrainmo"     ,rainMonth.toFixed(dp.Rain) +' '+ uom.Rain);
      set_ajax_obs("ajaxrainyr"     ,rainYear .toFixed(dp.Rain) +' '+ uom.Rain);

      set_ajax_obs("ajaxrainNoU"    ,rain     .toFixed(dp.Rain));
      set_ajax_obs("gizmorain"      ,rain     .toFixed(dp.Rain) +' '+ uom.Rain);

      if (clientrawextra!=null) {
         ;;;set_ajax_obs('ajaxProgress',rand+'rainex','in Rain Extra');
         // Rain in last week
         rainMon = parseFloat((clientrawextra[484])/10).convertRain();
         rainTue = parseFloat((clientrawextra[485])/10).convertRain();
         rainWed = parseFloat((clientrawextra[486])/10).convertRain();
         rainThu = parseFloat((clientrawextra[487])/10).convertRain();
         rainFri = parseFloat((clientrawextra[488])/10).convertRain();
         rainSat = parseFloat((clientrawextra[489])/10).convertRain();
         rainSun = parseFloat((clientrawextra[490])/10).convertRain();
         set_ajax_obs("ajaxrainSun" ,rainSun.toFixed(dp.Rain) +' '+ uom.Rain);
         set_ajax_obs("ajaxrainMon" ,rainMon.toFixed(dp.Rain) +' '+ uom.Rain);
         set_ajax_obs("ajaxrainTue" ,rainTue.toFixed(dp.Rain) +' '+ uom.Rain);
         set_ajax_obs("ajaxrainWed" ,rainWed.toFixed(dp.Rain) +' '+ uom.Rain);
         set_ajax_obs("ajaxrainThu" ,rainThu.toFixed(dp.Rain) +' '+ uom.Rain);
         set_ajax_obs("ajaxrainFri" ,rainFri.toFixed(dp.Rain) +' '+ uom.Rain);
         set_ajax_obs("ajaxrainSat" ,rainSat.toFixed(dp.Rain) +' '+ uom.Rain);

         // Record alltime daily rain
         rcdRain   = parseFloat(clientrawextra[349]).convertRain();
         rcdRainDt = new Date ( clientrawextra[354], clientrawextra[353]-1, clientrawextra[352] // YMD
                              , clientrawextra[350], clientrawextra[351]  , 0); //HMS
         set_ajax_obs("ajaxRcdRain"    , rcdRain.toFixed(dp.Rain) +' '+ uom.Rain);
         set_ajax_obs("ajaxRcdRainTime", rcdRainDt.date(uom.timeHM));
         set_ajax_obs("ajaxRcdRainDate", rcdRainDt.date(uom.dateFmt));

         // Record alltime daily rain in 1 hour
         rcdRainHr   = parseFloat(clientrawextra[355]).convertRain();
         rcdRainHrDt = new Date ( clientrawextra[360], clientrawextra[359]-1, clientrawextra[358] // YMD
                                , clientrawextra[356], clientrawextra[357]  , 0); //HMS
         set_ajax_obs("ajaxRcdRainHr"    , rcdRainHr.toFixed(dp.Rain) +' '+ uom.Rain);
         set_ajax_obs("ajaxRcdRainHrTime", rcdRainHrDt.date(uom.timeHM));
         set_ajax_obs("ajaxRcdRainHrDate", rcdRainHrDt.date(uom.dateFmt));

         // Days with/without rain
         daysRain   = parseInt( clientrawextra[483]); // nr of days with rain (MTD)
         daysNoRain = parseInt( clientrawextra[482]); // nr of days since last rain
         set_ajax_obs("ajaxDaysRain"  , daysRain   );
         set_ajax_obs("ajaxDaysNoRain", daysNoRain );
      }


// Snow ... (cm)
      ;;;set_ajax_obs('ajaxProgress',rand+'snow','in Snow');
      if (clientrawextra!=null) {
         snowToday  = parseFloat(clientrawextra[479]).convertSnow();
         snowMonth  = parseFloat(clientrawextra[480]).convertSnow();
         snowSeason = parseFloat(clientrawextra[481]).convertSnow();
         snowDepth  = parseFloat(clientrawextra[697]).convertSnow();
         set_ajax_obs("ajaxsnowToday" ,snowToday .toFixed(dp.Snow) +' '+ uom.Snow);
         set_ajax_obs("ajaxsnowToday2" ,snowToday .toFixed(dp.Snow) +' '+ uom.Snow);
         set_ajax_obs("ajaxsnowMonth" ,snowMonth .toFixed(dp.Snow) +' '+ uom.Snow);
         set_ajax_obs("ajaxsnowSeason",snowSeason.toFixed(dp.Snow) +' '+ uom.Snow);
         set_ajax_obs("ajaxsnowDepth" ,snowDepth .toFixed(dp.Snow) +' '+ uom.Snow);
      }


// Lightning ...
      ;;;set_ajax_obs('ajaxProgress',rand+'ligh','in Lightning');

      lighteningcountlastminute = clientraw[114];
      set_ajax_obs("ajaxlightning",lighteningcountlastminute);

      lighteningcountlasttime = clientraw[115] + " " + clientraw[116];
      set_ajax_obs("ajaxlightningtime",lighteningcountlasttime);

      lighteningdistance = parseFloat(clientraw[118]).convertDist();
      set_ajax_obs("ajaxlightningdist",lighteningdistance .toFixed(dp.Dist) +' '+ uom.Dist);

      lighteningbearing = clientraw[119];
      set_ajax_obs("ajaxlightningbearing",lighteningbearing + uom.Deg);


// Cloud Height ... (meters)
      ;;;set_ajax_obs('ajaxProgress',rand+'cloud','in Clouds');
      temp = clientraw[ 4];
      dewp = clientraw[72];
      pres = parseFloat(clientraw[6]).convertBaro();
      rain = parseFloat(clientraw[7]).convertRain();
      wind = parseFloat(clientraw[1]).convertWind(); // gust = clientraw[2]
      wdir = ajax_getWindDirLang(clientraw[3]);
      cloudheight = Math.max(0,(temp-dewp)/0.00802)*1.0 + cloudImg.stationAlt; // in meters
      altitude = Math.round(cloudheight.convertAlti());
      above = (cloudImg.stationAlt>0)? ' ASL' : ' AGL';
      cloudText = altitude.toString() + uom.Alti + above;
      param = '?uom=' + useUOM + '&buster=' + altitude + pres + beaufortnum + rain;
      set_ajax_obs("ajaxcloudheightimg", param
         ,'<img src="'  + cloudImg.src + param
         + '" alt="'    + cloudText
         + '" title="'  + cloudText
         + '" width="'  + cloudImg.width
         + '" height="' + cloudImg.height
         + '" hspace="' + cloudImg.hspace
         + '" vspace="' + cloudImg.vspace
         + '" align="'  + cloudImg.align
         + '" border="' + cloudImg.border
         + '" style="'  + cloudImg.style
         + '" />');
      set_ajax_obs("ajaxcloudheight",cloudText);


// Fire Risk ... (FWI)
      ;;;set_ajax_obs('ajaxProgress',rand+'fire','in Fire Risk');
      if (clientrawextra!=null) {
         FWI = parseFloat(clientrawextra[635]);
         set_ajax_obs("ajaxfireindex",FWI);
         idx = ajax_getFireIndex(FWI ,fireImg);
         src = fireImg.src.replace(/(#IMGNR#|\{IMGNR\})/i ,idx);
         set_ajax_obs(fireImg.useTag, idx
            ,'<img src="'  + src
            + '" alt="'    + FWI
            + '" title="'  + FWI
            + '" width="'  + fireImg.width
            + '" height="' + fireImg.height
            + '" hspace="' + fireImg.hspace
            + '" vspace="' + fireImg.vspace
            + '" border="' + fireImg.border
            + '" align="'  + fireImg.align
            + '" style="'  + fireImg.style
            + '" />');
      }


// Leaf wetness ...
      ;;;set_ajax_obs('ajaxProgress',rand+'leaf','in Leaf wetness');
      VPleaf = clientraw[156];
      set_ajax_obs("ajaxVPleaf" ,VPleaf);


// Sun/Moon rise/set (needed by all functions below) ...
      if (clientrawextra!=null) {
         ;;;set_ajax_obs('ajaxProgress',rand+'getMS','stuck in sun/moon info');
         YY = clientraw[141];
         MM = clientraw[36];
         DD = clientraw[35];
         SR = clientrawextra[556]; // sunrise
         SS = clientrawextra[557]; // sunset
         MR = clientrawextra[558]; // moonrise
         MS = clientrawextra[559]; // moonset
         // Sun rise/set
         sunriseWD   = MM+'/'+DD+'/'+YY+' '+SR.replace(/AM/i," AM").replace(/PM/i," PM");
         sunsetWD    = MM+'/'+DD+'/'+YY+' '+SS.replace(/AM/i," AM").replace(/PM/i," PM");
         sunrise     = new Date(sunriseWD);
         sunset      = new Date(sunsetWD);
         sunriseWC   = sunrise.getTime() - (webcamImg.delayDayNight*60*1000);
         sunsetWC    = sunset.getTime()  + (webcamImg.delayDayNight*60*1000);
         // Moon rise/set
         moonriseWD = MM+'/'+DD+'/'+YY+' '+MR.replace(/AM/i," AM").replace(/PM/i," PM");
         moonsetWD  = MM+'/'+DD+'/'+YY+' '+MS.replace(/AM/i," AM").replace(/PM/i," PM");
         moonrise   = new Date(moonriseWD);
         moonset    = new Date(moonsetWD);
         // Time now
      }
      WDnow = WDdt.getTime();

// Moon & Sun ... rise & set
      if (clientrawextra!=null) {
         set_ajax_obs("ajaxsunrise" ,sunrise .date(uom.timeHM));
         set_ajax_obs("ajaxsunset"  ,sunset  .date(uom.timeHM));
         set_ajax_obs("ajaxmoonrise",moonrise.date(uom.timeHM));
         set_ajax_obs("ajaxmoonset" ,moonset .date(uom.timeHM));
      }


// Current conditions description and icon ...
      ;;;set_ajax_obs('ajaxProgress',rand+'cond','in Conditions');
      // check if we need the icon instead of the webcam image at night
      if (!webcamImg.useCamAtNight && clientrawextra!=null) {
         if (WDnow < sunriseWC || WDnow > sunsetWC)
            webcamImg.swapIconWithWebcam = false;
      }
      currentcond = clientraw[49];
      // currentcond = currentcond.replace(/_/g,' ');
      // currentcond = currentcond.replace(/^\/Dry\//g,'');
      currentcond = currentcond.replace(/\\/g,', ');
      // currentcond = currentcond.replace(/\//g,', ');
      currentcond = "It is " + ajax_fixupCondition(currentcond);
      currIconNr  = parseInt(clientraw[48]);
      set_ajax_obs("ajaxcurrentcond" ,currentcond);
      set_ajax_obs("gizmocurrentcond",currentcond);

      if (!webcamImg.swapIconWithWebcam) {

	  switch (wxIcon.useName) { // dashboard icons

	      case 0: set_ajax_obs(wxIcon.useTag ,clientraw[48] ,ajax_getIconName0(currIconNr,wxIcon)); break; // Anole's icon names
          case 1: set_ajax_obs(wxIcon.useTag ,clientraw[48] ,ajax_getIconName1(currIconNr,wxIcon)); break; // NWS icon names
//        case 0: set_ajax_obs(wxIcon.useTag ,1 ,wxIcon.yoHTML); break; // YoWindow icon
          case wxIcon.useName: 
				tempvar = 'ajax_getIconName'+wxIcon.useName;
				if(typeof window[tempvar] == 'function') {
					current_conditions_custom(clientraw[48]);
					break;
				} else {
					set_ajax_obs(wxIcon.useTag ,'<div style="border: 2px solid red">INVALID ICON FUNCTION #'+wxIcon.useName+'"</div>');
					break;
				}
          case 9: //Dynamic icon creation similar to cloud height (not yet implemented)
                  param = '?uom=' + useUOM
                        + '&con=' + currentcond
                        + '&iW='  + wxIcon.width
                        + '&iH='  + wxIcon.height;
                  set_ajax_obs(wxIcon.useTag, param
                     ,'<img src="'  + wxIcon.src + param
                     + '" alt="'    + currentcond
                     + '" title="'  + currentcond
                     + '" width="'  + wxIcon.width
                     + '" height="' + wxIcon.height
                     + '" hspace="' + wxIcon.hspace
                     + '" vspace="' + wxIcon.vspace
                     + '" border="' + wxIcon.border
                     + '" align="'  + wxIcon.align
                     + '" style="'  + wxIcon.style
                     + '" />');
                  break;
         default:set_ajax_obs(wxIcon.useTag ,'<div style="border: 2px solid red">INVALID ICON FUNCTION #'+wxIcon.useName+'"</div>');
				 set_ajax_obs(wxIcon.useTag ,'<div style="border: 2px solid red">INVALID ICON FUNCTION #'+wxIcon.useName+'"</div>');
		 }			
	 }


// Current webcam snap ...
      ;;;set_ajax_obs('ajaxProgress',rand+'webcam','in Webcam');
      if (webcamImg.swapIconWithWebcam)
           ajaxTag = wxIcon.useTag;
      else ajaxTag = webcamImg.useTag;

      if (webcamImg.webcamUpdate!=0) { // if 0 then no ajax updates requested
         now = new Date();
         minutes  = (now.getHours()*60) + now.getMinutes();
         interval = Math.floor(minutes / webcamImg.webcamUpdate);
         param = '?buster=' + interval;
         if (clientrawextra!=null && (WDnow<sunriseWC || WDnow>sunsetWC))
              src = webcamImg.srcNgt;
         else src = webcamImg.src;
         set_ajax_obs(ajaxTag, interval
            ,'<img src="'  + src + param
            + '" alt="'    + currentcond
            + '" title="'  + currentcond
            + '" width="'  + webcamImg.width
            + '" height="' + webcamImg.height
            + '" hspace="' + webcamImg.hspace
            + '" vspace="' + webcamImg.vspace
            + '" border="' + webcamImg.border
            + '" align="'  + webcamImg.align
            + '" style="'  + webcamImg.style
            + '" />');
      }
// ----------------------------------------------------------------- end of tags

      if (lastajaxtimeformat != WDdt.date("d-m-Y H:i:s")) {
         counterSecs = 0; // reset timer
         lastajaxtimeformat = WDdt.date("d-m-Y H:i:s"); // remember this time
      }

     } // END if(clientraw[0] = '12345' and '!!' at end)
     notifyR=0;
    } // END if (x.readyState == 4 && x.status == 200)

    set_ajax_obs('ajaxupdatecount'   ,ajaxUpdates);        /* for test pages */
    set_ajax_obs('ajaxmaxupdatecount',update.maxupdates); /* for test pages */
    set_ajax_obs('ajaxState' , x.readyState);             /* for test pages */
    set_ajax_obs('ajaxStatus', x.statusText);             /* for test pages */
    if (x.readyState==4 && x.status==404) { // not found
       if (notifyR==1) {
          htp = 'http://'+window.location.host;
			 crf = clientrawFile.substr(0,1)=='.'? htp+clientrawFile.substr(1,clientrawFile.length) : clientrawFile+' (2)';
		    alert("AJAX DASHBOARD ERROR:\nYour \""+crf+"\" file could not be found.");
		 }
       notifyR++;
    }
    ;;;set_ajax_obs('ajaxProgress',rand+'done','-- DONE --');
    } // END try

    catch(e){}  // Mike Challis added fix to fix random error: NS_ERROR_NOT_AVAILABLE

    }; // END x.onreadystatechange = function()

    x.open("GET", url, true);
    x.send(null);
	
//		if (useUOM == "M") {
//			set_ajax_obs('ajaxcloudheightvalue',clientraw[73]);
//		} else {
//document.write(currentcond);
//			set_ajax_obs('ajaxcloudheightvalue',clientraw[73]);
//		}

	
	// load special scheduled tasks
	if (typeof extra_tasks() == 'function') {
		extra_tasks();  
	}

    // now ensure that the indicator flashes on every AJAX fetch
    ajax_flash_green("ajaxindicator");
    ajax_flash_green("gizmoindicator");

    //  reset the flash colors, and restart the update unless maxupdate limit is reached
    setTimeout("ajax_flash_reset('')",flash.time); // change text back to default color

    if (update.maxupdates == 0 || ajaxUpdates < (update.maxupdates-1)) {
       timerAjaxLoader = setTimeout("ajaxLoader(clientrawFile + '?' + new Date().getTime())", update.reloadtime); // get new data
    } else {
       counterSecs = 0; // reset timer
       stopTime = new Date().getTime();
       PauseMsg = '';
       if (update.showRefresh)
          PauseMsg = '<span onclick="javascript:ajaxLoader_restart();" style="color:blue; cursor:pointer;" title="'+langRestart+'"><b>'+langRefresh+'</b></span>&nbsp;&nbsp;&nbsp;';
       PauseMsg+= '<b style="color:red">'+langPauseMsg+'</b>';
       set_ajax_obs("ajaxindicator",stopTime,PauseMsg);
    }
  } else {// if (x)
    set_ajax_obs('ajaxProgress',rand+'http',"AJAX DASHBOARD ERROR:\nNo HTTP Request");
  }
}; // end ajaxLoader function



// invoke when first loaded on page
window.onload=function() {
   if (gotSettings) loadSettings(); // we've got a seperate settings file
   initialize();
   ajax_page_saveTags();
   ajaxLoader_clientextra(clientrawextraFile + '?' + new Date().getTime());
   window.setInterval("ajax_countup()", 1000); // run the counter for seconds since update
   ajaxLoader(clientrawFile        + '?' + new Date().getTime());
};





