
(function(){if(window.google&&google.gears){return;}
var factory=null;if(typeof GearsFactory!='undefined'){factory=new GearsFactory();}else{try{factory=new ActiveXObject('Gears.Factory');if(factory.getBuildInfo().indexOf('ie_mobile')!=-1){factory.privateSetGlobalObject(this);}}catch(e){if((typeof navigator.mimeTypes!='undefined')&&navigator.mimeTypes["application/x-googlegears"]){factory=document.createElement("object");factory.style.display="none";factory.width=0;factory.height=0;factory.type="application/x-googlegears";document.documentElement.appendChild(factory);}}}
if(!factory){return;}
if(!window.google){google={};}
if(!google.gears){google.gears={factory:factory};}})();var GG={debug:false,available:false,enabled:false,init:function(){if(!window.console)this.debug=false;if(location.href.match('https')){if(this.debug)console.warn('NOTICE: Google Gears is specifically disabled on the secure site.');return;}
if((window.google)&&(google.gears)){this.available=true;if(this.debug)console.log('Google Gears is available');}else{if(this.debug)console.log('Google Gears is not installed');return;}
if(google.gears.factory.hasPermission){this.enabled=true;if(this.debug)console.log('Google Gears is enabled');}else{var siteName='iStockphoto.com';var icon='/static/images/icons/logo_istock_48x48.png';var mssg='This site would like to use Google Gears to speed-up your browsing experience by caching small, commonly-used files on your computer.';if(this.debug)console.warn('Google Gears not enabled for this site');this.enabled=google.gears.factory.getPermission(siteName,icon,mssg);}}}
GG.init();var managedFilestore={debug:false,enabled:false,localserver:false,managedStore:false,storeName:'istock-cdn',manifestFile:'/manifest.php',init:function(){if(!window.console)this.debug=false;if(!window.GG||!GG.enabled)return;this.startLocalServer();this.openManagedStore();this.updateManagedStore();},startLocalServer:function(){try{this.localserver=google.gears.factory.create('beta.localserver');if(this.debug)console.log('Localserver successfully started in managedFilestore class');}catch(e){if(this.debug)console.error('Unable to start the localserver: '+e.message);}},openManagedStore:function(){if(!this.localserver)return;try{this.managedStore=this.localserver.openManagedStore(this.storeName)||this.localserver.createManagedStore(this.storeName);this.enabled=true;if(this.debug)console.log('ManagedStore successfully opened in managedFilestore class');this.managedStore.manifestUrl=this.manifestFile;if(this.debug)console.log('ManagedStore manifest file URL set to '+this.managedStore.manifestUrl);}catch(e){if(this.debug)console.error('Unable to open/create the managedStore: '+e.message);}},updateManagedStore:function(){if(!this.managedStore)return;try{this.managedStore.checkForUpdate();if(this.debug)console.log('ManagedStore at version: '+this.managedStore.currentVersion);}catch(e){if(this.debug)console.error('Unable to update the managedStore: '+e.message);}},removeStore:function(){var self=managedFilestore;try{self.localserver.removeManagedStore(self.storeName);self.managedStore=false;if(self.debug)console.log('ManagedStore successfully removed');return true;}catch(e){if(self.debug)console.error('Unable to remove the ManagedStore: '+e.message);return false;}}}
managedFilestore.init();var db={debug:false,enabled:false,publicDbName:'istock-db-public',publicDb:false,init:function(){if(!window.console)this.debug=false;if(!window.GG||!GG.enabled)return;if(this.debug)console.log('Initializing the DB');this.publicDb=this.openDb(this.publicDbName);this.createTables();},openDb:function(dbName){var db=false;if(!dbName){if(this.debug)console.error('No database named passed to db.openDb function.');return false;}
if(this.debug)console.log('Opening the '+dbName+' database');try{db=google.gears.factory.create('beta.database');}catch(e){if(this.debug)console.error('Unable to create the DB: '+e.message);return false;}
try{db.open(dbName);}catch(e){if(this.debug)console.error('Unable to open the "'+dbName+'" DB: '+e.message);return false;}
this.enabled=(db)?true:false;return db;},removeDb:function(){var self=db;try{self.publicDb.remove();if(self.debug)console.log('Database successfully removed');return true;}catch(e){if(self.debug)console.error('Unable to remove the database: '+e.message);return false;}},q:function(sql,params){var self=db;if(!sql)return;if(!params){params=null;}else if('object'!=typeof(params)){if(self.debug)console.error('Query parameters are not an object');return;}
if(self.debug){console.log('Query: '+sql);console.log(params);}
try{var rs=self.publicDb.execute(sql,params);}catch(e){if(self.debug)console.error('Unable to complete query: '+e.message);return{'rowsAffected':0,'insertId':0,'result':{}};}
var rowsAffected=0
var insertId=0
var resultSet=[];switch(sql.substr(0,3).toUpperCase()){case'CRE':case'BEG':case'COM':break;case'INS':rowsAffected=self.publicDb.rowsAffected;insertId=self.publicDb.lastInsertRowId;break;case'UPD':rowsAffected=self.publicDb.rowsAffected;break;case'DEL':rowsAffected=self.publicDb.rowsAffected;break;case'SEL':default:while(rs.isValidRow()){var row={};var qtyFields=rs.fieldCount();var i=0;while(i<qtyFields){row[rs.fieldName(i)]=rs.field(i);++i;}
resultSet.push(row);rs.next();}
break;}
rs.close();var resultObj={'rowsAffected':rowsAffected,'insertId':insertId,'result':resultSet};if(self.debug)console.log(resultObj);return resultObj;},createTables:function(){var sql="CREATE TABLE IF NOT EXISTS tbl_settings ("+"setting VARCHAR, "+"value VARCHAR "+");";this.q(sql);var sql="CREATE TABLE IF NOT EXISTS tbl_filestore ("+"url VARCHAR, "+"timestamp INT, "+"count INT, "+"bytes INT "+");";this.q(sql);}}
db.init();var publicFilestore={debug:false,enabled:false,localserver:false,fileStore:false,storeName:'istock-cache',purgeFrequency:14,bandwidthReportFrequency:7,URLsToStore:[],dbQueries:[],init:function(){if(!window.console)this.debug=false;if(!window.GG||!GG.enabled)return;this.startLocalServer();this.openFileStore();},startLocalServer:function(){try{this.localserver=google.gears.factory.create('beta.localserver');if(this.debug)console.log('Localserver successfully started in publicFilestore class');}catch(e){if(this.debug)console.error('Unable to start the localserver: '+e.message);}},openFileStore:function(){if(!this.localserver)return;try{this.fileStore=this.localserver.openStore(this.storeName)||this.localserver.createStore(this.storeName);this.enabled=true;if(this.debug)console.log('Public filestore successfully created/opened in publicFilestore class');}catch(e){if(this.debug)console.error('Unable to open/create the publicFilestore: '+e.message);}},removeStore:function(){var self=publicFilestore;try{self.localserver.removeStore(self.storeName);self.fileStore=false;if(self.debug)console.log('FileStore successfully removed');return true;}catch(e){if(self.debug)console.error('Unable to remove the FileStore: '+e.message);return false;}},storeOnPageFiles:function(){var self=publicFilestore;try{self.getCSSandJS();self.getIMG();}catch(e){if(self.debug)console.error('Public filestore: getOnPageFileList unable to complete: '+e.message);return;}
self.saveFilesInList();},storeSingleFile:function(url){var self=publicFilestore;if(self.debug)console.log('storeSingleFile:'+url);if(!self.enabled)return;self.addURLtoList(url);self.saveFilesInList();},saveFilesInList:function(){var self=publicFilestore;if(self.URLsToStore.length>0){self.URLsToStore.uniq().each(function(url){self.storeFileInGears(url);});self.URLsToStore.clear();}
if(self.dbQueries.length>0){db.q('BEGIN');self.dbQueries.each(function(params){db.q(params.sql,params.data);});db.q('COMMIT');self.dbQueries.clear();}
return;},getCSSandJS:function(){var self=publicFilestore;if(location.href.match('dev-')){if(self.debug)console.warn('Reminder: no JS or CSS files are stored to Gears on a dev-xxxx domain');return true;}
var headElm=document.getElementsByTagName("head")[0];if(!headElm)throw({'message':'No "head" element found in document'});$$(headElm).each(function(elm){switch(elm.type){case'text/css':case'image/ico':if(elm.href)self.addURLtoList(elm.href);break;case'text/javascript':if(elm.src)self.addURLtoList(elm.src);break;default:break;}});return true;},getIMG:function(){var self=publicFilestore;$$('img').each(function(elm){if(elm.src)self.addURLtoList(elm.src);});return true;},addURLtoList:function(url){var self=publicFilestore;if(!url.match('.istockphoto.com')){if(self.debug)console.log('Not adding to list: '+url+' (not from correct domain)');}else{self.URLsToStore.push(url);if(self.debug)console.log('Adding to list: '+url);}},storeFileInGears:function(url){var self=publicFilestore;if(!url)return;try{var isUrlCaptured=self.fileStore.isCaptured(url);}catch(e){if(self.debug)console.error('Unable to determine if url is captured: '+e.message);return}
if(isUrlCaptured){try{var bytes=self.fileStore.getHeader(url,'Content-Length')||0;}catch(e){if(self.debug)console.error('Unable to get size of file: '+e.message);var bytes=0;}
if(self.debug)console.log('File already captured: '+url);self.dbQueries.push({'sql':"UPDATE tbl_filestore SET count = count + 1, bytes = ? WHERE url = ?",'data':[bytes,url]});}else{try{self.fileStore.capture(url);self.dbQueries.push({'sql':"INSERT INTO tbl_filestore (url, timestamp, count) VALUES (?, ?, ?)",'data':[url,parseInt(new Date().getTime()),0]});}catch(e){if(self.debug)console.error('Unable to capture file '+url+': '+e.message);}}},purgeOldFiles:function(){var self=publicFilestore;if(self.debug)console.log('Purging old files');var now=new Date().getTime();var obj=db.q("SELECT value FROM tbl_settings WHERE setting = ?",["lastPurgeDate"]);if(obj.result.length==0){db.q("INSERT INTO tbl_settings (setting, value) VALUES (?, ?)",["lastPurgeDate",0]);var lastPurgeDate=now;}else{var lastPurgeDate=parseInt(obj.result[0].value);}
if(lastPurgeDate<(now-(60*60*24*1000))){var purgeThresholdDate=now-(60*60*self.purgeFrequency*1000);var files=db.q("SELECT url FROM tbl_filestore WHERE timestamp <= ?",[purgeThresholdDate]);files.result.each(function(file){try{self.fileStore.remove(file.url);if(self.debug)console.log('Removing from public store: '+file.url);}catch(e){if(self.debug)console.log('Unable to remove file from public fileStore: '+e.message);}});db.q("DELETE FROM tbl_filestore WHERE timestamp <= ?",[purgeThresholdDate]);db.q("UPDATE tbl_settings SET value = ? WHERE setting = 'lastPurgeDate'",[now]);}else{if(self.debug)console.log('No purge needed.');}},purgeSpecificFiles:function(){var self=publicFilestore;if(self.debug)console.log('Purging specific files');if(!window.GGItemsToClear)return;GGItemsToClear.each(function(url){try{self.fileStore.remove(url);db.q("DELETE FROM tbl_filestore WHERE url = ?",[url]);if(self.debug)console.log('Removing specific file from  public store: '+url);}catch(e){if(self.debug)console.log('Unable to specifically remove file '+url+' from public fileStore: '+e.message);}});},reportBandwidthStats:function(){var self=publicFilestore;if(self.debug)console.log('Checking if we need to report bandwidth stats');var now=new Date().getTime();var obj=db.q("SELECT value FROM tbl_settings WHERE setting = ?",["lastBandwidthStatsDate"]);if(obj.result.length==0){db.q("INSERT INTO tbl_settings (setting, value) VALUES (?, ?)",["lastBandwidthStatsDate",0]);var lastBandwidthStatsDate=now;}else{var lastBandwidthStatsDate=parseInt(obj.result[0].value);}
var oneWeekAgo=now-(60*60*24*self.bandwidthReportFrequency*1000);if(lastBandwidthStatsDate<oneWeekAgo){if(self.debug)console.log('Reporting bandwidth stats');var obj=db.q("SELECT SUM(count) as requests, SUM(bytes * count) AS bandwidth FROM tbl_filestore WHERE timestamp >= ?",[oneWeekAgo]);var qtyRequests=obj.result[0].requests;var qtyBandwidth=obj.result[0].bandwidth;var xhr=google.gears.factory.create('beta.httprequest');xhr.open('GET','/ajax_class_creator.php?ajax_class=googlegears&ajax_action=ReportBandwidthStats&qtyRequests='+qtyRequests+'&qtyBandwidth='+qtyBandwidth);if(self.debug){xhr.onreadystatechange=function(){if(xhr.readyState==4){console.log(xhr.responseText);}}}
xhr.send();db.q("UPDATE tbl_settings SET value = ? WHERE setting = 'lastBandwidthStatsDate'",[now]);}else{if(self.debug)console.log('No need to report bandwidth stats, done less than 1 week ago');}}}
publicFilestore.init();Event.observe(window,'load',function(){if(!window.GG||!GG.enabled)return;if(!publicFilestore.enabled){if(publicFilestore.debug)console.error('Public filestore: cannot store page files - no access to local fileStore');return;};if(!window.db||!db.enabled){if(publicFilestore.debug)console.error('Public filestore: cannot store page files - no access to DB');return;};publicFilestore.storeOnPageFiles.defer();publicFilestore.purgeSpecificFiles.delay(10);publicFilestore.reportBandwidthStats.delay(15);publicFilestore.purgeOldFiles.delay(20);});