add new files default tip
authorpabs@pablotron.org
Thu Mar 05 15:40:14 2009 -0500 (3 years ago)
changeset 103eadb8c9323fc
parent 102 2901a52e3b23
add new files
TODO
extras/json2-min.js
extras/json2.js
extras/swfobject-min.js
extras/swfobject.js
persist-all-min.js
persist-min.js
     1.1 --- a/TODO	Thu Mar 05 15:39:50 2009 -0500
     1.2 +++ b/TODO	Thu Mar 05 15:40:14 2009 -0500
     1.3 @@ -17,3 +17,4 @@
     1.4  [ ] documentation on same origin policy
     1.5  [ ] full usage examples
     1.6  [ ] add data_path url and move persist.swf and iframe shim to same directory
     1.7 +[ ] add note about serializing stuff with http://www.json.org/json2.js
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/extras/json2-min.js	Thu Mar 05 15:40:14 2009 -0500
     2.3 @@ -0,0 +1,29 @@
     2.4 +
     2.5 +if(!this.JSON){JSON={};}
     2.6 +(function(){function f(n){return n<10?'0'+n:n;}
     2.7 +if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return this.getUTCFullYear()+'-'+
     2.8 +f(this.getUTCMonth()+1)+'-'+
     2.9 +f(this.getUTCDate())+'T'+
    2.10 +f(this.getUTCHours())+':'+
    2.11 +f(this.getUTCMinutes())+':'+
    2.12 +f(this.getUTCSeconds())+'Z';};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
    2.13 +var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
    2.14 +function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
    2.15 +if(typeof rep==='function'){value=rep.call(holder,key,value);}
    2.16 +switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
    2.17 +gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
    2.18 +v=partial.length===0?'[]':gap?'[\n'+gap+
    2.19 +partial.join(',\n'+gap)+'\n'+
    2.20 +mind+']':'['+partial.join(',')+']';gap=mind;return v;}
    2.21 +if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
    2.22 +v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+
    2.23 +mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
    2.24 +if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
    2.25 +rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
    2.26 +return str('',{'':value});};}
    2.27 +if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
    2.28 +return reviver.call(holder,key,value);}
    2.29 +cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
    2.30 +('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
    2.31 +if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
    2.32 +throw new SyntaxError('JSON.parse');};}})();
    2.33 \ No newline at end of file
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/extras/json2.js	Thu Mar 05 15:40:14 2009 -0500
     3.3 @@ -0,0 +1,478 @@
     3.4 +/*
     3.5 +    http://www.JSON.org/json2.js
     3.6 +    2008-11-19
     3.7 +
     3.8 +    Public Domain.
     3.9 +
    3.10 +    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
    3.11 +
    3.12 +    See http://www.JSON.org/js.html
    3.13 +
    3.14 +    This file creates a global JSON object containing two methods: stringify
    3.15 +    and parse.
    3.16 +
    3.17 +        JSON.stringify(value, replacer, space)
    3.18 +            value       any JavaScript value, usually an object or array.
    3.19 +
    3.20 +            replacer    an optional parameter that determines how object
    3.21 +                        values are stringified for objects. It can be a
    3.22 +                        function or an array of strings.
    3.23 +
    3.24 +            space       an optional parameter that specifies the indentation
    3.25 +                        of nested structures. If it is omitted, the text will
    3.26 +                        be packed without extra whitespace. If it is a number,
    3.27 +                        it will specify the number of spaces to indent at each
    3.28 +                        level. If it is a string (such as '\t' or '&nbsp;'),
    3.29 +                        it contains the characters used to indent at each level.
    3.30 +
    3.31 +            This method produces a JSON text from a JavaScript value.
    3.32 +
    3.33 +            When an object value is found, if the object contains a toJSON
    3.34 +            method, its toJSON method will be called and the result will be
    3.35 +            stringified. A toJSON method does not serialize: it returns the
    3.36 +            value represented by the name/value pair that should be serialized,
    3.37 +            or undefined if nothing should be serialized. The toJSON method
    3.38 +            will be passed the key associated with the value, and this will be
    3.39 +            bound to the object holding the key.
    3.40 +
    3.41 +            For example, this would serialize Dates as ISO strings.
    3.42 +
    3.43 +                Date.prototype.toJSON = function (key) {
    3.44 +                    function f(n) {
    3.45 +                        // Format integers to have at least two digits.
    3.46 +                        return n < 10 ? '0' + n : n;
    3.47 +                    }
    3.48 +
    3.49 +                    return this.getUTCFullYear()   + '-' +
    3.50 +                         f(this.getUTCMonth() + 1) + '-' +
    3.51 +                         f(this.getUTCDate())      + 'T' +
    3.52 +                         f(this.getUTCHours())     + ':' +
    3.53 +                         f(this.getUTCMinutes())   + ':' +
    3.54 +                         f(this.getUTCSeconds())   + 'Z';
    3.55 +                };
    3.56 +
    3.57 +            You can provide an optional replacer method. It will be passed the
    3.58 +            key and value of each member, with this bound to the containing
    3.59 +            object. The value that is returned from your method will be
    3.60 +            serialized. If your method returns undefined, then the member will
    3.61 +            be excluded from the serialization.
    3.62 +
    3.63 +            If the replacer parameter is an array of strings, then it will be
    3.64 +            used to select the members to be serialized. It filters the results
    3.65 +            such that only members with keys listed in the replacer array are
    3.66 +            stringified.
    3.67 +
    3.68 +            Values that do not have JSON representations, such as undefined or
    3.69 +            functions, will not be serialized. Such values in objects will be
    3.70 +            dropped; in arrays they will be replaced with null. You can use
    3.71 +            a replacer function to replace those with JSON values.
    3.72 +            JSON.stringify(undefined) returns undefined.
    3.73 +
    3.74 +            The optional space parameter produces a stringification of the
    3.75 +            value that is filled with line breaks and indentation to make it
    3.76 +            easier to read.
    3.77 +
    3.78 +            If the space parameter is a non-empty string, then that string will
    3.79 +            be used for indentation. If the space parameter is a number, then
    3.80 +            the indentation will be that many spaces.
    3.81 +
    3.82 +            Example:
    3.83 +
    3.84 +            text = JSON.stringify(['e', {pluribus: 'unum'}]);
    3.85 +            // text is '["e",{"pluribus":"unum"}]'
    3.86 +
    3.87 +
    3.88 +            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
    3.89 +            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
    3.90 +
    3.91 +            text = JSON.stringify([new Date()], function (key, value) {
    3.92 +                return this[key] instanceof Date ?
    3.93 +                    'Date(' + this[key] + ')' : value;
    3.94 +            });
    3.95 +            // text is '["Date(---current time---)"]'
    3.96 +
    3.97 +
    3.98 +        JSON.parse(text, reviver)
    3.99 +            This method parses a JSON text to produce an object or array.
   3.100 +            It can throw a SyntaxError exception.
   3.101 +
   3.102 +            The optional reviver parameter is a function that can filter and
   3.103 +            transform the results. It receives each of the keys and values,
   3.104 +            and its return value is used instead of the original value.
   3.105 +            If it returns what it received, then the structure is not modified.
   3.106 +            If it returns undefined then the member is deleted.
   3.107 +
   3.108 +            Example:
   3.109 +
   3.110 +            // Parse the text. Values that look like ISO date strings will
   3.111 +            // be converted to Date objects.
   3.112 +
   3.113 +            myData = JSON.parse(text, function (key, value) {
   3.114 +                var a;
   3.115 +                if (typeof value === 'string') {
   3.116 +                    a =
   3.117 +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
   3.118 +                    if (a) {
   3.119 +                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
   3.120 +                            +a[5], +a[6]));
   3.121 +                    }
   3.122 +                }
   3.123 +                return value;
   3.124 +            });
   3.125 +
   3.126 +            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
   3.127 +                var d;
   3.128 +                if (typeof value === 'string' &&
   3.129 +                        value.slice(0, 5) === 'Date(' &&
   3.130 +                        value.slice(-1) === ')') {
   3.131 +                    d = new Date(value.slice(5, -1));
   3.132 +                    if (d) {
   3.133 +                        return d;
   3.134 +                    }
   3.135 +                }
   3.136 +                return value;
   3.137 +            });
   3.138 +
   3.139 +
   3.140 +    This is a reference implementation. You are free to copy, modify, or
   3.141 +    redistribute.
   3.142 +
   3.143 +    This code should be minified before deployment.
   3.144 +    See http://javascript.crockford.com/jsmin.html
   3.145 +
   3.146 +    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
   3.147 +    NOT CONTROL.
   3.148 +*/
   3.149 +
   3.150 +/*jslint evil: true */
   3.151 +
   3.152 +/*global JSON */
   3.153 +
   3.154 +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
   3.155 +    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
   3.156 +    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
   3.157 +    lastIndex, length, parse, prototype, push, replace, slice, stringify,
   3.158 +    test, toJSON, toString, valueOf
   3.159 +*/
   3.160 +
   3.161 +// Create a JSON object only if one does not already exist. We create the
   3.162 +// methods in a closure to avoid creating global variables.
   3.163 +
   3.164 +if (!this.JSON) {
   3.165 +    JSON = {};
   3.166 +}
   3.167 +(function () {
   3.168 +
   3.169 +    function f(n) {
   3.170 +        // Format integers to have at least two digits.
   3.171 +        return n < 10 ? '0' + n : n;
   3.172 +    }
   3.173 +
   3.174 +    if (typeof Date.prototype.toJSON !== 'function') {
   3.175 +
   3.176 +        Date.prototype.toJSON = function (key) {
   3.177 +
   3.178 +            return this.getUTCFullYear()   + '-' +
   3.179 +                 f(this.getUTCMonth() + 1) + '-' +
   3.180 +                 f(this.getUTCDate())      + 'T' +
   3.181 +                 f(this.getUTCHours())     + ':' +
   3.182 +                 f(this.getUTCMinutes())   + ':' +
   3.183 +                 f(this.getUTCSeconds())   + 'Z';
   3.184 +        };
   3.185 +
   3.186 +        String.prototype.toJSON =
   3.187 +        Number.prototype.toJSON =
   3.188 +        Boolean.prototype.toJSON = function (key) {
   3.189 +            return this.valueOf();
   3.190 +        };
   3.191 +    }
   3.192 +
   3.193 +    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
   3.194 +        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
   3.195 +        gap,
   3.196 +        indent,
   3.197 +        meta = {    // table of character substitutions
   3.198 +            '\b': '\\b',
   3.199 +            '\t': '\\t',
   3.200 +            '\n': '\\n',
   3.201 +            '\f': '\\f',
   3.202 +            '\r': '\\r',
   3.203 +            '"' : '\\"',
   3.204 +            '\\': '\\\\'
   3.205 +        },
   3.206 +        rep;
   3.207 +
   3.208 +
   3.209 +    function quote(string) {
   3.210 +
   3.211 +// If the string contains no control characters, no quote characters, and no
   3.212 +// backslash characters, then we can safely slap some quotes around it.
   3.213 +// Otherwise we must also replace the offending characters with safe escape
   3.214 +// sequences.
   3.215 +
   3.216 +        escapable.lastIndex = 0;
   3.217 +        return escapable.test(string) ?
   3.218 +            '"' + string.replace(escapable, function (a) {
   3.219 +                var c = meta[a];
   3.220 +                return typeof c === 'string' ? c :
   3.221 +                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
   3.222 +            }) + '"' :
   3.223 +            '"' + string + '"';
   3.224 +    }
   3.225 +
   3.226 +
   3.227 +    function str(key, holder) {
   3.228 +
   3.229 +// Produce a string from holder[key].
   3.230 +
   3.231 +        var i,          // The loop counter.
   3.232 +            k,          // The member key.
   3.233 +            v,          // The member value.
   3.234 +            length,
   3.235 +            mind = gap,
   3.236 +            partial,
   3.237 +            value = holder[key];
   3.238 +
   3.239 +// If the value has a toJSON method, call it to obtain a replacement value.
   3.240 +
   3.241 +        if (value && typeof value === 'object' &&
   3.242 +                typeof value.toJSON === 'function') {
   3.243 +            value = value.toJSON(key);
   3.244 +        }
   3.245 +
   3.246 +// If we were called with a replacer function, then call the replacer to
   3.247 +// obtain a replacement value.
   3.248 +
   3.249 +        if (typeof rep === 'function') {
   3.250 +            value = rep.call(holder, key, value);
   3.251 +        }
   3.252 +
   3.253 +// What happens next depends on the value's type.
   3.254 +
   3.255 +        switch (typeof value) {
   3.256 +        case 'string':
   3.257 +            return quote(value);
   3.258 +
   3.259 +        case 'number':
   3.260 +
   3.261 +// JSON numbers must be finite. Encode non-finite numbers as null.
   3.262 +
   3.263 +            return isFinite(value) ? String(value) : 'null';
   3.264 +
   3.265 +        case 'boolean':
   3.266 +        case 'null':
   3.267 +
   3.268 +// If the value is a boolean or null, convert it to a string. Note:
   3.269 +// typeof null does not produce 'null'. The case is included here in
   3.270 +// the remote chance that this gets fixed someday.
   3.271 +
   3.272 +            return String(value);
   3.273 +
   3.274 +// If the type is 'object', we might be dealing with an object or an array or
   3.275 +// null.
   3.276 +
   3.277 +        case 'object':
   3.278 +
   3.279 +// Due to a specification blunder in ECMAScript, typeof null is 'object',
   3.280 +// so watch out for that case.
   3.281 +
   3.282 +            if (!value) {
   3.283 +                return 'null';
   3.284 +            }
   3.285 +
   3.286 +// Make an array to hold the partial results of stringifying this object value.
   3.287 +
   3.288 +            gap += indent;
   3.289 +            partial = [];
   3.290 +
   3.291 +// Is the value an array?
   3.292 +
   3.293 +            if (Object.prototype.toString.apply(value) === '[object Array]') {
   3.294 +
   3.295 +// The value is an array. Stringify every element. Use null as a placeholder
   3.296 +// for non-JSON values.
   3.297 +
   3.298 +                length = value.length;
   3.299 +                for (i = 0; i < length; i += 1) {
   3.300 +                    partial[i] = str(i, value) || 'null';
   3.301 +                }
   3.302 +
   3.303 +// Join all of the elements together, separated with commas, and wrap them in
   3.304 +// brackets.
   3.305 +
   3.306 +                v = partial.length === 0 ? '[]' :
   3.307 +                    gap ? '[\n' + gap +
   3.308 +                            partial.join(',\n' + gap) + '\n' +
   3.309 +                                mind + ']' :
   3.310 +                          '[' + partial.join(',') + ']';
   3.311 +                gap = mind;
   3.312 +                return v;
   3.313 +            }
   3.314 +
   3.315 +// If the replacer is an array, use it to select the members to be stringified.
   3.316 +
   3.317 +            if (rep && typeof rep === 'object') {
   3.318 +                length = rep.length;
   3.319 +                for (i = 0; i < length; i += 1) {
   3.320 +                    k = rep[i];
   3.321 +                    if (typeof k === 'string') {
   3.322 +                        v = str(k, value);
   3.323 +                        if (v) {
   3.324 +                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
   3.325 +                        }
   3.326 +                    }
   3.327 +                }
   3.328 +            } else {
   3.329 +
   3.330 +// Otherwise, iterate through all of the keys in the object.
   3.331 +
   3.332 +                for (k in value) {
   3.333 +                    if (Object.hasOwnProperty.call(value, k)) {
   3.334 +                        v = str(k, value);
   3.335 +                        if (v) {
   3.336 +                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
   3.337 +                        }
   3.338 +                    }
   3.339 +                }
   3.340 +            }
   3.341 +
   3.342 +// Join all of the member texts together, separated with commas,
   3.343 +// and wrap them in braces.
   3.344 +
   3.345 +            v = partial.length === 0 ? '{}' :
   3.346 +                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
   3.347 +                        mind + '}' : '{' + partial.join(',') + '}';
   3.348 +            gap = mind;
   3.349 +            return v;
   3.350 +        }
   3.351 +    }
   3.352 +
   3.353 +// If the JSON object does not yet have a stringify method, give it one.
   3.354 +
   3.355 +    if (typeof JSON.stringify !== 'function') {
   3.356 +        JSON.stringify = function (value, replacer, space) {
   3.357 +
   3.358 +// The stringify method takes a value and an optional replacer, and an optional
   3.359 +// space parameter, and returns a JSON text. The replacer can be a function
   3.360 +// that can replace values, or an array of strings that will select the keys.
   3.361 +// A default replacer method can be provided. Use of the space parameter can
   3.362 +// produce text that is more easily readable.
   3.363 +
   3.364 +            var i;
   3.365 +            gap = '';
   3.366 +            indent = '';
   3.367 +
   3.368 +// If the space parameter is a number, make an indent string containing that
   3.369 +// many spaces.
   3.370 +
   3.371 +            if (typeof space === 'number') {
   3.372 +                for (i = 0; i < space; i += 1) {
   3.373 +                    indent += ' ';
   3.374 +                }
   3.375 +
   3.376 +// If the space parameter is a string, it will be used as the indent string.
   3.377 +
   3.378 +            } else if (typeof space === 'string') {
   3.379 +                indent = space;
   3.380 +            }
   3.381 +
   3.382 +// If there is a replacer, it must be a function or an array.
   3.383 +// Otherwise, throw an error.
   3.384 +
   3.385 +            rep = replacer;
   3.386 +            if (replacer && typeof replacer !== 'function' &&
   3.387 +                    (typeof replacer !== 'object' ||
   3.388 +                     typeof replacer.length !== 'number')) {
   3.389 +                throw new Error('JSON.stringify');
   3.390 +            }
   3.391 +
   3.392 +// Make a fake root object containing our value under the key of ''.
   3.393 +// Return the result of stringifying the value.
   3.394 +
   3.395 +            return str('', {'': value});
   3.396 +        };
   3.397 +    }
   3.398 +
   3.399 +
   3.400 +// If the JSON object does not yet have a parse method, give it one.
   3.401 +
   3.402 +    if (typeof JSON.parse !== 'function') {
   3.403 +        JSON.parse = function (text, reviver) {
   3.404 +
   3.405 +// The parse method takes a text and an optional reviver function, and returns
   3.406 +// a JavaScript value if the text is a valid JSON text.
   3.407 +
   3.408 +            var j;
   3.409 +
   3.410 +            function walk(holder, key) {
   3.411 +
   3.412 +// The walk method is used to recursively walk the resulting structure so
   3.413 +// that modifications can be made.
   3.414 +
   3.415 +                var k, v, value = holder[key];
   3.416 +                if (value && typeof value === 'object') {
   3.417 +                    for (k in value) {
   3.418 +                        if (Object.hasOwnProperty.call(value, k)) {
   3.419 +                            v = walk(value, k);
   3.420 +                            if (v !== undefined) {
   3.421 +                                value[k] = v;
   3.422 +                            } else {
   3.423 +                                delete value[k];
   3.424 +                            }
   3.425 +                        }
   3.426 +                    }
   3.427 +                }
   3.428 +                return reviver.call(holder, key, value);
   3.429 +            }
   3.430 +
   3.431 +
   3.432 +// Parsing happens in four stages. In the first stage, we replace certain
   3.433 +// Unicode characters with escape sequences. JavaScript handles many characters
   3.434 +// incorrectly, either silently deleting them, or treating them as line endings.
   3.435 +
   3.436 +            cx.lastIndex = 0;
   3.437 +            if (cx.test(text)) {
   3.438 +                text = text.replace(cx, function (a) {
   3.439 +                    return '\\u' +
   3.440 +                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
   3.441 +                });
   3.442 +            }
   3.443 +
   3.444 +// In the second stage, we run the text against regular expressions that look
   3.445 +// for non-JSON patterns. We are especially concerned with '()' and 'new'
   3.446 +// because they can cause invocation, and '=' because it can cause mutation.
   3.447 +// But just to be safe, we want to reject all unexpected forms.
   3.448 +
   3.449 +// We split the second stage into 4 regexp operations in order to work around
   3.450 +// crippling inefficiencies in IE's and Safari's regexp engines. First we
   3.451 +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
   3.452 +// replace all simple value tokens with ']' characters. Third, we delete all
   3.453 +// open brackets that follow a colon or comma or that begin the text. Finally,
   3.454 +// we look to see that the remaining characters are only whitespace or ']' or
   3.455 +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
   3.456 +
   3.457 +            if (/^[\],:{}\s]*$/.
   3.458 +test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
   3.459 +replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
   3.460 +replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
   3.461 +
   3.462 +// In the third stage we use the eval function to compile the text into a
   3.463 +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
   3.464 +// in JavaScript: it can begin a block or an object literal. We wrap the text
   3.465 +// in parens to eliminate the ambiguity.
   3.466 +
   3.467 +                j = eval('(' + text + ')');
   3.468 +
   3.469 +// In the optional fourth stage, we recursively walk the new structure, passing
   3.470 +// each name/value pair to a reviver function for possible transformation.
   3.471 +
   3.472 +                return typeof reviver === 'function' ?
   3.473 +                    walk({'': j}, '') : j;
   3.474 +            }
   3.475 +
   3.476 +// If the text is not JSON parseable, then a SyntaxError is thrown.
   3.477 +
   3.478 +            throw new SyntaxError('JSON.parse');
   3.479 +        };
   3.480 +    }
   3.481 +})();
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/extras/swfobject-min.js	Thu Mar 05 15:40:14 2009 -0500
     4.3 @@ -0,0 +1,34 @@
     4.4 +
     4.5 +if(typeof deconcept=="undefined")var deconcept=new Object();if(typeof deconcept.util=="undefined")deconcept.util=new Object();if(typeof deconcept.SWFObjectUtil=="undefined")deconcept.SWFObjectUtil=new Object();deconcept.SWFObject=function(swf,id,w,h,ver,c,quality,xiRedirectUrl,redirectUrl,detectKey){if(!document.getElementById){return;}
     4.6 +this.DETECT_KEY=detectKey?detectKey:'detectflash';this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(swf){this.setAttribute('swf',swf);}
     4.7 +if(id){this.setAttribute('id',id);}
     4.8 +if(w){this.setAttribute('width',w);}
     4.9 +if(h){this.setAttribute('height',h);}
    4.10 +if(ver){this.setAttribute('version',new deconcept.PlayerVersion(ver.toString().split(".")));}
    4.11 +this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}
    4.12 +if(c){this.addParam('bgcolor',c);}
    4.13 +var q=quality?quality:'high';this.addParam('quality',q);this.setAttribute('useExpressInstall',false);this.setAttribute('doExpressInstall',false);var xir=(xiRedirectUrl)?xiRedirectUrl:window.location;this.setAttribute('xiRedirectUrl',xir);this.setAttribute('redirectUrl','');if(redirectUrl){this.setAttribute('redirectUrl',redirectUrl);}}
    4.14 +deconcept.SWFObject.prototype={useExpressInstall:function(path){this.xiSWFPath=!path?"expressinstall.swf":path;this.setAttribute('useExpressInstall',true);},setAttribute:function(name,value){this.attributes[name]=value;},getAttribute:function(name){return this.attributes[name];},addParam:function(name,value){this.params[name]=value;},getParams:function(){return this.params;},addVariable:function(name,value){this.variables[name]=value;},getVariable:function(name){return this.variables[name];},getVariables:function(){return this.variables;},getVariablePairs:function(){var variablePairs=new Array();var key;var variables=this.getVariables();for(key in variables){variablePairs.push(key+"="+variables[key]);}
    4.15 +return variablePairs;},getSWFHTML:function(){var swfNode="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute('swf',this.xiSWFPath);}
    4.16 +swfNode='<embed type="application/x-shockwave-flash" src="'+this.getAttribute('swf')+'" width="'+this.getAttribute('width')+'" height="'+this.getAttribute('height')+'"';swfNode+=' id="'+this.getAttribute('id')+'" name="'+this.getAttribute('id')+'" ';var params=this.getParams();for(var key in params){swfNode+=[key]+'="'+params[key]+'" ';}
    4.17 +var pairs=this.getVariablePairs().join("&");if(pairs.length>0){swfNode+='flashvars="'+pairs+'"';}
    4.18 +swfNode+='/>';}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute('swf',this.xiSWFPath);}
    4.19 +swfNode='<object id="'+this.getAttribute('id')+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+this.getAttribute('width')+'" height="'+this.getAttribute('height')+'">';swfNode+='<param name="movie" value="'+this.getAttribute('swf')+'" />';var params=this.getParams();for(var key in params){swfNode+='<param name="'+key+'" value="'+params[key]+'" />';}
    4.20 +var pairs=this.getVariablePairs().join("&");if(pairs.length>0){swfNode+='<param name="flashvars" value="'+pairs+'" />';}
    4.21 +swfNode+="</object>";}
    4.22 +return swfNode;},write:function(elementId){if(this.getAttribute('useExpressInstall')){var expressInstallReqVer=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(expressInstallReqVer)&&!this.installedVer.versionIsValid(this.getAttribute('version'))){this.setAttribute('doExpressInstall',true);this.addVariable("MMredirectURL",escape(this.getAttribute('xiRedirectUrl')));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}
    4.23 +if(this.skipDetect||this.getAttribute('doExpressInstall')||this.installedVer.versionIsValid(this.getAttribute('version'))){var n=(typeof elementId=='string')?document.getElementById(elementId):elementId;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute('redirectUrl')!=""){document.location.replace(this.getAttribute('redirectUrl'));}}
    4.24 +return false;}}
    4.25 +deconcept.SWFObjectUtil.getPlayerVersion=function(){var PlayerVersion=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){PlayerVersion=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");PlayerVersion=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(PlayerVersion.major==6){return PlayerVersion;}}
    4.26 +try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){}}
    4.27 +if(axo!=null){PlayerVersion=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}
    4.28 +return PlayerVersion;}
    4.29 +deconcept.PlayerVersion=function(arrVersion){this.major=arrVersion[0]!=null?parseInt(arrVersion[0]):0;this.minor=arrVersion[1]!=null?parseInt(arrVersion[1]):0;this.rev=arrVersion[2]!=null?parseInt(arrVersion[2]):0;}
    4.30 +deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.major<fv.major)return false;if(this.major>fv.major)return true;if(this.minor<fv.minor)return false;if(this.minor>fv.minor)return true;if(this.rev<fv.rev)return false;return true;}
    4.31 +deconcept.util={getRequestParameter:function(param){var q=document.location.search||document.location.hash;if(q){var pairs=q.substring(1).split("&");for(var i=0;i<pairs.length;i++){if(pairs[i].substring(0,pairs[i].indexOf("="))==param){return pairs[i].substring((pairs[i].indexOf("=")+1));}}}
    4.32 +return"";}}
    4.33 +deconcept.SWFObjectUtil.cleanupSWFs=function(){var objects=document.getElementsByTagName("OBJECT");for(var i=0;i<objects.length;i++){objects[i].style.display='none';for(var x in objects[i]){if(typeof objects[i][x]=='function'){objects[i][x]=function(){};}}}}
    4.34 +if(deconcept.SWFObject.doPrepUnload){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);}
    4.35 +window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);}
    4.36 +if(Array.prototype.push==null){Array.prototype.push=function(item){this[this.length]=item;return this.length;}}
    4.37 +var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;
    4.38 \ No newline at end of file
     5.1 --- a/extras/swfobject.js	Thu Mar 05 15:39:50 2009 -0500
     5.2 +++ b/extras/swfobject.js	Thu Mar 05 15:40:14 2009 -0500
     5.3 @@ -209,8 +209,3 @@
     5.4  }
     5.5  /* add Array.push if needed (ie5) */
     5.6  if (Array.prototype.push == null) { Array.prototype.push = function(item) { this[this.length] = item; return this.length; }}
     5.7 -
     5.8 -/* add some aliases for ease of use/backwards compatibility */
     5.9 -var getQueryParamValue = deconcept.util.getRequestParameter;
    5.10 -var FlashObject = deconcept.SWFObject; // for legacy support
    5.11 -var SWFObject = deconcept.SWFObject;
     6.1 --- a/persist-all-min.js	Thu Mar 05 15:39:50 2009 -0500
     6.2 +++ b/persist-all-min.js	Thu Mar 05 15:40:14 2009 -0500
     6.3 @@ -31,7 +31,7 @@
     6.4  if(deconcept.SWFObject.doPrepUnload){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);}
     6.5  window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);}
     6.6  if(Array.prototype.push==null){Array.prototype.push=function(item){this[this.length]=item;return this.length;}}
     6.7 -var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;(function(){if(window.google&&google.gears)
     6.8 +(function(){if(window.google&&google.gears)
     6.9  return;var F=null;if(typeof GearsFactory!='undefined'){F=new GearsFactory();}else{try{F=new ActiveXObject('Gears.Factory');if(F.getBuildInfo().indexOf('ie_mobile')!=-1)
    6.10  F.privateSetGlobalObject(this);}catch(e){if((typeof navigator.mimeTypes!='undefined')&&navigator.mimeTypes["application/x-googlegears"]){F=document.createElement("object");F.style.display="none";F.width=0;F.height=0;F.type="application/x-googlegears";document.documentElement.appendChild(F);}}}
    6.11  if(!F)
    6.12 @@ -50,7 +50,11 @@
    6.13  return null;end=c.indexOf(';',len);if(end<0)
    6.14  end=c.length;return un(c.substring(len,end));},remove:function(k){var r=me.get(k),opt={expires:EPOCH};doc.cookie=cookify(k,'',opt);return r;},keys:function(){var c=doc.cookie,ps=c.split('; '),i,p,r=[];for(i=0;i<ps.length;i++){p=ps[i].split('=');r.push(un(p[0]));}
    6.15  return r;},all:function(){var c=doc.cookie,ps=c.split('; '),i,p,r=[];for(i=0;i<ps.length;i++){p=ps[i].split('=');r.push([un(p[0]),un(p[1])]);}
    6.16 -return r;},version:'0.2.1',enabled:false};me.enabled=alive.call(me);return me;}());empty=function(){};esc=function(str){return'PS'+str.replace(/_/g,'__').replace(/ /g,'_s');};C={search_order:['localstorage','whatwg_db','globalstorage','gears','ie','flash','cookie'],name_re:/^[a-z][a-z0-9_ -]+$/i,methods:['init','get','set','remove','load','save'],sql:{version:'1',create:"CREATE TABLE IF NOT EXISTS persist_data (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)",get:"SELECT v FROM persist_data WHERE k = ?",set:"INSERT INTO persist_data(k, v) VALUES (?, ?)",remove:"DELETE FROM persist_data WHERE k = ?"},flash:{div_id:'_persist_flash_wrap',id:'_persist_flash',path:'persist.swf',size:{w:1,h:1},args:{autostart:true}}};B={gears:{size:-1,test:function(){return(window.google&&window.google.gears)?true:false;},methods:{transaction:function(fn){var db=this.db;db.execute('BEGIN').close();fn.call(this,db);db.execute('COMMIT').close();},init:function(){var db;db=this.db=google.gears.factory.create('beta.database');db.open(esc(this.name));db.execute(C.sql.create).close();},get:function(key,fn,scope){var r,sql=C.sql.get;if(!fn)
    6.17 +return r;},version:'0.2.1',enabled:false};me.enabled=alive.call(me);return me;}());var index_of=(function(){if(Array.prototype.indexOf)
    6.18 +return function(ary,val){return Array.prototype.indexOf.call(ary,val);};else
    6.19 +return function(ary,val){var i,l;for(i=0,l=ary.length;i<l;i++)
    6.20 +if(ary[i]==val)
    6.21 +return i;return-1;};})();empty=function(){};esc=function(str){return'PS'+str.replace(/_/g,'__').replace(/ /g,'_s');};C={search_order:['localstorage','whatwg_db','globalstorage','gears','ie','flash','cookie'],name_re:/^[a-z][a-z0-9_ -]+$/i,methods:['init','get','set','remove','load','save'],sql:{version:'1',create:"CREATE TABLE IF NOT EXISTS persist_data (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)",get:"SELECT v FROM persist_data WHERE k = ?",set:"INSERT INTO persist_data(k, v) VALUES (?, ?)",remove:"DELETE FROM persist_data WHERE k = ?"},flash:{div_id:'_persist_flash_wrap',id:'_persist_flash',path:'persist.swf',size:{w:1,h:1},args:{autostart:true}}};B={gears:{size:-1,test:function(){return(window.google&&window.google.gears)?true:false;},methods:{transaction:function(fn){var db=this.db;db.execute('BEGIN').close();fn.call(this,db);db.execute('COMMIT').close();},init:function(){var db;db=this.db=google.gears.factory.create('beta.database');db.open(esc(this.name));db.execute(C.sql.create).close();},get:function(key,fn,scope){var r,sql=C.sql.get;if(!fn)
    6.22  return;this.transaction(function(t){var is_valid,val;r=t.execute(sql,[key]);is_valid=r.isValidRow();val=is_valid?r.field(0):null;r.close();fn.call(scope||this,is_valid,val);});},set:function(key,val,fn,scope){var rm_sql=C.sql.remove,sql=C.sql.set,r;this.transaction(function(t){t.execute(rm_sql,[key]).close();t.execute(sql,[key,val]).close();if(fn)
    6.23  fn.call(scope||this,true,val);});},remove:function(key,fn,scope){var get_sql=C.sql.get;sql=C.sql.remove,r,val=null,is_valid=false;this.transaction(function(t){if(fn){r=t.execute(get_sql,[key]);is_valid=r.isValidRow();val=is_valid?r.field(0):null;r.close();}
    6.24  if(!fn||is_valid){t.execute(sql,[key]).close();}
    6.25 @@ -80,8 +84,8 @@
    6.26  fn.call(scope||this,val!=null,val);},set:function(key,val,fn,scope){key=this.key(key);ec.set(key,val,this.o);if(fn)
    6.27  fn.call(scope||this,true,val);},remove:function(key,val,fn,scope){var val;key=this.key(key);val=ec.remove(key)
    6.28  if(fn)
    6.29 -fn.call(scope||this,val!=null,val);}}},flash:{test:function(){if(!window.SWFObject||!deconcept||!deconcept.SWFObjectUtil)
    6.30 -return false;var major=deconcept.SWFObjectUtil.getPlayerVersion().major;return(major>=8)?true:false;},methods:{init:function(){if(!B.flash.el){var o,key,el,cfg=C.flash;el=document.createElement('div');el.id=cfg.div_id;document.body.appendChild(el);o=new SWFObject(this.o.swf_path||cfg.path,cfg.id,cfg.size.w,cfg.size.h,'8');for(key in cfg.args)
    6.31 +fn.call(scope||this,val!=null,val);}}},flash:{test:function(){if(!deconcept||!deconcept.SWFObjectUtil)
    6.32 +return false;var major=deconcept.SWFObjectUtil.getPlayerVersion().major;return(major>=8)?true:false;},methods:{init:function(){if(!B.flash.el){var o,key,el,cfg=C.flash;el=document.createElement('div');el.id=cfg.div_id;document.body.appendChild(el);o=new deconcept.SWFObject(this.o.swf_path||cfg.path,cfg.id,cfg.size.w,cfg.size.h,'8');for(key in cfg.args)
    6.33  o.addVariable(key,cfg.args[key]);o.write(el);B.flash.el=document.getElementById(cfg.id);}
    6.34  this.el=B.flash.el;},get:function(key,fn,scope){var val;key=esc(key);val=this.el.get(this.name,key);if(fn)
    6.35  fn.call(scope||this,val!==null,val);},set:function(key,val,fn,scope){var old_val;key=esc(key);old_val=this.el.set(this.name,key,val);if(fn)
    6.36 @@ -89,7 +93,7 @@
    6.37  fn.call(scope||this,true,val);}}}};var init=function(){var i,l,b,key,fns=C.methods,keys=C.search_order;for(i=0,l=fns.length;i<l;i++)
    6.38  P.Store.prototype[fns[i]]=empty;P.type=null;P.size=-1;for(i=0,l=keys.length;!P.type&&i<l;i++){b=B[keys[i]];if(b.test()){P.type=keys[i];P.size=b.size;for(key in b.methods)
    6.39  P.Store.prototype[key]=b.methods[key];}}
    6.40 -P._init=true;};P={VERSION:VERSION,type:null,size:0,add:function(o){B[o.id]=o;C.search_order=[o.id].concat(C.search_order);init();},remove:function(id){var ofs=C.search_order.indexOf(id);if(ofs<0)
    6.41 +P._init=true;};P={VERSION:VERSION,type:null,size:0,add:function(o){B[o.id]=o;C.search_order=[o.id].concat(C.search_order);init();},remove:function(id){var ofs=index_of(C.search_order,id);if(ofs<0)
    6.42  return;C.search_order.splice(ofs,1);delete B[id];init();},Cookie:ec,Store:function(name,o){if(!C.name_re.exec(name))
    6.43  throw new Error("Invalid name");if(!P.type)
    6.44  throw new Error("No suitable storage found");o=o||{};this.name=name;o.domain=o.domain||location.host||'localhost';o.domain=o.domain.replace(/:\d+$/,'')
     7.1 --- a/persist-min.js	Thu Mar 05 15:39:50 2009 -0500
     7.2 +++ b/persist-min.js	Thu Mar 05 15:40:14 2009 -0500
     7.3 @@ -18,7 +18,11 @@
     7.4  return null;end=c.indexOf(';',len);if(end<0)
     7.5  end=c.length;return un(c.substring(len,end));},remove:function(k){var r=me.get(k),opt={expires:EPOCH};doc.cookie=cookify(k,'',opt);return r;},keys:function(){var c=doc.cookie,ps=c.split('; '),i,p,r=[];for(i=0;i<ps.length;i++){p=ps[i].split('=');r.push(un(p[0]));}
     7.6  return r;},all:function(){var c=doc.cookie,ps=c.split('; '),i,p,r=[];for(i=0;i<ps.length;i++){p=ps[i].split('=');r.push([un(p[0]),un(p[1])]);}
     7.7 -return r;},version:'0.2.1',enabled:false};me.enabled=alive.call(me);return me;}());empty=function(){};esc=function(str){return'PS'+str.replace(/_/g,'__').replace(/ /g,'_s');};C={search_order:['localstorage','whatwg_db','globalstorage','gears','ie','flash','cookie'],name_re:/^[a-z][a-z0-9_ -]+$/i,methods:['init','get','set','remove','load','save'],sql:{version:'1',create:"CREATE TABLE IF NOT EXISTS persist_data (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)",get:"SELECT v FROM persist_data WHERE k = ?",set:"INSERT INTO persist_data(k, v) VALUES (?, ?)",remove:"DELETE FROM persist_data WHERE k = ?"},flash:{div_id:'_persist_flash_wrap',id:'_persist_flash',path:'persist.swf',size:{w:1,h:1},args:{autostart:true}}};B={gears:{size:-1,test:function(){return(window.google&&window.google.gears)?true:false;},methods:{transaction:function(fn){var db=this.db;db.execute('BEGIN').close();fn.call(this,db);db.execute('COMMIT').close();},init:function(){var db;db=this.db=google.gears.factory.create('beta.database');db.open(esc(this.name));db.execute(C.sql.create).close();},get:function(key,fn,scope){var r,sql=C.sql.get;if(!fn)
     7.8 +return r;},version:'0.2.1',enabled:false};me.enabled=alive.call(me);return me;}());var index_of=(function(){if(Array.prototype.indexOf)
     7.9 +return function(ary,val){return Array.prototype.indexOf.call(ary,val);};else
    7.10 +return function(ary,val){var i,l;for(i=0,l=ary.length;i<l;i++)
    7.11 +if(ary[i]==val)
    7.12 +return i;return-1;};})();empty=function(){};esc=function(str){return'PS'+str.replace(/_/g,'__').replace(/ /g,'_s');};C={search_order:['localstorage','whatwg_db','globalstorage','gears','ie','flash','cookie'],name_re:/^[a-z][a-z0-9_ -]+$/i,methods:['init','get','set','remove','load','save'],sql:{version:'1',create:"CREATE TABLE IF NOT EXISTS persist_data (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)",get:"SELECT v FROM persist_data WHERE k = ?",set:"INSERT INTO persist_data(k, v) VALUES (?, ?)",remove:"DELETE FROM persist_data WHERE k = ?"},flash:{div_id:'_persist_flash_wrap',id:'_persist_flash',path:'persist.swf',size:{w:1,h:1},args:{autostart:true}}};B={gears:{size:-1,test:function(){return(window.google&&window.google.gears)?true:false;},methods:{transaction:function(fn){var db=this.db;db.execute('BEGIN').close();fn.call(this,db);db.execute('COMMIT').close();},init:function(){var db;db=this.db=google.gears.factory.create('beta.database');db.open(esc(this.name));db.execute(C.sql.create).close();},get:function(key,fn,scope){var r,sql=C.sql.get;if(!fn)
    7.13  return;this.transaction(function(t){var is_valid,val;r=t.execute(sql,[key]);is_valid=r.isValidRow();val=is_valid?r.field(0):null;r.close();fn.call(scope||this,is_valid,val);});},set:function(key,val,fn,scope){var rm_sql=C.sql.remove,sql=C.sql.set,r;this.transaction(function(t){t.execute(rm_sql,[key]).close();t.execute(sql,[key,val]).close();if(fn)
    7.14  fn.call(scope||this,true,val);});},remove:function(key,fn,scope){var get_sql=C.sql.get;sql=C.sql.remove,r,val=null,is_valid=false;this.transaction(function(t){if(fn){r=t.execute(get_sql,[key]);is_valid=r.isValidRow();val=is_valid?r.field(0):null;r.close();}
    7.15  if(!fn||is_valid){t.execute(sql,[key]).close();}
    7.16 @@ -48,8 +52,8 @@
    7.17  fn.call(scope||this,val!=null,val);},set:function(key,val,fn,scope){key=this.key(key);ec.set(key,val,this.o);if(fn)
    7.18  fn.call(scope||this,true,val);},remove:function(key,val,fn,scope){var val;key=this.key(key);val=ec.remove(key)
    7.19  if(fn)
    7.20 -fn.call(scope||this,val!=null,val);}}},flash:{test:function(){if(!window.SWFObject||!deconcept||!deconcept.SWFObjectUtil)
    7.21 -return false;var major=deconcept.SWFObjectUtil.getPlayerVersion().major;return(major>=8)?true:false;},methods:{init:function(){if(!B.flash.el){var o,key,el,cfg=C.flash;el=document.createElement('div');el.id=cfg.div_id;document.body.appendChild(el);o=new SWFObject(this.o.swf_path||cfg.path,cfg.id,cfg.size.w,cfg.size.h,'8');for(key in cfg.args)
    7.22 +fn.call(scope||this,val!=null,val);}}},flash:{test:function(){if(!deconcept||!deconcept.SWFObjectUtil)
    7.23 +return false;var major=deconcept.SWFObjectUtil.getPlayerVersion().major;return(major>=8)?true:false;},methods:{init:function(){if(!B.flash.el){var o,key,el,cfg=C.flash;el=document.createElement('div');el.id=cfg.div_id;document.body.appendChild(el);o=new deconcept.SWFObject(this.o.swf_path||cfg.path,cfg.id,cfg.size.w,cfg.size.h,'8');for(key in cfg.args)
    7.24  o.addVariable(key,cfg.args[key]);o.write(el);B.flash.el=document.getElementById(cfg.id);}
    7.25  this.el=B.flash.el;},get:function(key,fn,scope){var val;key=esc(key);val=this.el.get(this.name,key);if(fn)
    7.26  fn.call(scope||this,val!==null,val);},set:function(key,val,fn,scope){var old_val;key=esc(key);old_val=this.el.set(this.name,key,val);if(fn)
    7.27 @@ -57,7 +61,7 @@
    7.28  fn.call(scope||this,true,val);}}}};var init=function(){var i,l,b,key,fns=C.methods,keys=C.search_order;for(i=0,l=fns.length;i<l;i++)
    7.29  P.Store.prototype[fns[i]]=empty;P.type=null;P.size=-1;for(i=0,l=keys.length;!P.type&&i<l;i++){b=B[keys[i]];if(b.test()){P.type=keys[i];P.size=b.size;for(key in b.methods)
    7.30  P.Store.prototype[key]=b.methods[key];}}
    7.31 -P._init=true;};P={VERSION:VERSION,type:null,size:0,add:function(o){B[o.id]=o;C.search_order=[o.id].concat(C.search_order);init();},remove:function(id){var ofs=C.search_order.indexOf(id);if(ofs<0)
    7.32 +P._init=true;};P={VERSION:VERSION,type:null,size:0,add:function(o){B[o.id]=o;C.search_order=[o.id].concat(C.search_order);init();},remove:function(id){var ofs=index_of(C.search_order,id);if(ofs<0)
    7.33  return;C.search_order.splice(ofs,1);delete B[id];init();},Cookie:ec,Store:function(name,o){if(!C.name_re.exec(name))
    7.34  throw new Error("Invalid name");if(!P.type)
    7.35  throw new Error("No suitable storage found");o=o||{};this.name=name;o.domain=o.domain||location.host||'localhost';o.domain=o.domain.replace(/:\d+$/,'')