UNPKG

sm2

Version:

sm2,sm3,cryptojs,crypto,base64,rsa,aes crypt

1,624 lines (1,466 loc) 952 kB
/* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ /** * CryptoJS core components. */ var CryptoJS = CryptoJS || (function (Math, undefined) { /** * CryptoJS namespace. */ var C = {}; /** * Library namespace. */ var C_lib = C.lib = {}; /** * Base object for prototypal inheritance. */ var Base = C_lib.Base = (function () { function F() {} return { /** * Creates a new object that inherits from this object. * * @param {Object} overrides Properties to copy into the new object. * * @return {Object} The new object. * * @static * * @example * * var MyType = CryptoJS.lib.Base.extend({ * field: 'value', * * method: function () { * } * }); */ extend: function (overrides) { // Spawn F.prototype = this; var subtype = new F(); // Augment if (overrides) { subtype.mixIn(overrides); } // Create default initializer if (!subtype.hasOwnProperty('init')) { subtype.init = function () { subtype.$super.init.apply(this, arguments); }; } // Initializer's prototype is the subtype object subtype.init.prototype = subtype; // Reference supertype subtype.$super = this; return subtype; }, /** * Extends this object and runs the init method. * Arguments to create() will be passed to init(). * * @return {Object} The new object. * * @static * * @example * * var instance = MyType.create(); */ create: function () { var instance = this.extend(); instance.init.apply(instance, arguments); return instance; }, /** * Initializes a newly created object. * Override this method to add some logic when your objects are created. * * @example * * var MyType = CryptoJS.lib.Base.extend({ * init: function () { * // ... * } * }); */ init: function () { }, /** * Copies properties into this object. * * @param {Object} properties The properties to mix in. * * @example * * MyType.mixIn({ * field: 'value' * }); */ mixIn: function (properties) { for (var propertyName in properties) { if (properties.hasOwnProperty(propertyName)) { this[propertyName] = properties[propertyName]; } } // IE won't copy toString using the loop above if (properties.hasOwnProperty('toString')) { this.toString = properties.toString; } }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = instance.clone(); */ clone: function () { return this.init.prototype.extend(this); } }; }()); /** * An array of 32-bit words. * * @property {Array} words The array of 32-bit words. * @property {number} sigBytes The number of significant bytes in this word array. */ var WordArray = C_lib.WordArray = Base.extend({ /** * Initializes a newly created word array. * * @param {Array} words (Optional) An array of 32-bit words. * @param {number} sigBytes (Optional) The number of significant bytes in the words. * * @example * * var wordArray = CryptoJS.lib.WordArray.create(); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); */ init: function (words, sigBytes) { words = this.words = words || []; if (sigBytes != undefined) { this.sigBytes = sigBytes; } else { this.sigBytes = words.length * 4; } }, /** * Converts this word array to a string. * * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex * * @return {string} The stringified word array. * * @example * * var string = wordArray + ''; * var string = wordArray.toString(); * var string = wordArray.toString(CryptoJS.enc.Utf8); */ toString: function (encoder) { return (encoder || Hex).stringify(this); }, /** * Concatenates a word array to this word array. * * @param {WordArray} wordArray The word array to append. * * @return {WordArray} This word array. * * @example * * wordArray1.concat(wordArray2); */ concat: function (wordArray) { // Shortcuts var thisWords = this.words; var thatWords = wordArray.words; var thisSigBytes = this.sigBytes; var thatSigBytes = wordArray.sigBytes; // Clamp excess bits this.clamp(); // Concat if (thisSigBytes % 4) { // Copy one byte at a time for (var i = 0; i < thatSigBytes; i++) { var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); } } else if (thatWords.length > 0xffff) { // Copy one word at a time for (var i = 0; i < thatSigBytes; i += 4) { thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; } } else { // Copy all words at once thisWords.push.apply(thisWords, thatWords); } this.sigBytes += thatSigBytes; // Chainable return this; }, /** * Removes insignificant bits. * * @example * * wordArray.clamp(); */ clamp: function () { // Shortcuts var words = this.words; var sigBytes = this.sigBytes; // Clamp words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); words.length = Math.ceil(sigBytes / 4); }, /** * Creates a copy of this word array. * * @return {WordArray} The clone. * * @example * * var clone = wordArray.clone(); */ clone: function () { var clone = Base.clone.call(this); clone.words = this.words.slice(0); return clone; }, /** * Creates a word array filled with random bytes. * * @param {number} nBytes The number of random bytes to generate. * * @return {WordArray} The random word array. * * @static * * @example * * var wordArray = CryptoJS.lib.WordArray.random(16); */ random: function (nBytes) { var words = []; for (var i = 0; i < nBytes; i += 4) { words.push((Math.random() * 0x100000000) | 0); } return new WordArray.init(words, nBytes); } }); /** * Encoder namespace. */ var C_enc = C.enc = {}; /** * Hex encoding strategy. */ var Hex = C_enc.Hex = { /** * Converts a word array to a hex string. * * @param {WordArray} wordArray The word array. * * @return {string} The hex string. * * @static * * @example * * var hexString = CryptoJS.enc.Hex.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var hexChars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; hexChars.push((bite >>> 4).toString(16)); hexChars.push((bite & 0x0f).toString(16)); } return hexChars.join(''); }, /** * Converts a hex string to a word array. * * @param {string} hexStr The hex string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Hex.parse(hexString); */ parse: function (hexStr) { // Shortcut var hexStrLength = hexStr.length; // Convert var words = []; for (var i = 0; i < hexStrLength; i += 2) { words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); } return new WordArray.init(words, hexStrLength / 2); } }; /** * Latin1 encoding strategy. */ var Latin1 = C_enc.Latin1 = { /** * Converts a word array to a Latin1 string. * * @param {WordArray} wordArray The word array. * * @return {string} The Latin1 string. * * @static * * @example * * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var latin1Chars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; latin1Chars.push(String.fromCharCode(bite)); } return latin1Chars.join(''); }, /** * Converts a Latin1 string to a word array. * * @param {string} latin1Str The Latin1 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); */ parse: function (latin1Str) { // Shortcut var latin1StrLength = latin1Str.length; // Convert var words = []; for (var i = 0; i < latin1StrLength; i++) { words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); } return new WordArray.init(words, latin1StrLength); } }; /** * UTF-8 encoding strategy. */ var Utf8 = C_enc.Utf8 = { /** * Converts a word array to a UTF-8 string. * * @param {WordArray} wordArray The word array. * * @return {string} The UTF-8 string. * * @static * * @example * * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); */ stringify: function (wordArray) { try { return decodeURIComponent(escape(Latin1.stringify(wordArray))); } catch (e) { throw new Error('Malformed UTF-8 data'); } }, /** * Converts a UTF-8 string to a word array. * * @param {string} utf8Str The UTF-8 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); */ parse: function (utf8Str) { return Latin1.parse(unescape(encodeURIComponent(utf8Str))); } }; /** * Abstract buffered block algorithm template. * * The property blockSize must be implemented in a concrete subtype. * * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 */ var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ /** * Resets this block algorithm's data buffer to its initial state. * * @example * * bufferedBlockAlgorithm.reset(); */ reset: function () { // Initial values this._data = new WordArray.init(); this._nDataBytes = 0; }, /** * Adds new data to this block algorithm's buffer. * * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. * * @example * * bufferedBlockAlgorithm._append('data'); * bufferedBlockAlgorithm._append(wordArray); */ _append: function (data) { // Convert string to WordArray, else assume WordArray already if (typeof data == 'string') { data = Utf8.parse(data); } // Append this._data.concat(data); this._nDataBytes += data.sigBytes; }, /** * Processes available data blocks. * * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. * * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. * * @return {WordArray} The processed data. * * @example * * var processedData = bufferedBlockAlgorithm._process(); * var processedData = bufferedBlockAlgorithm._process(!!'flush'); */ _process: function (doFlush) { // Shortcuts var data = this._data; var dataWords = data.words; var dataSigBytes = data.sigBytes; var blockSize = this.blockSize; var blockSizeBytes = blockSize * 4; // Count blocks ready var nBlocksReady = dataSigBytes / blockSizeBytes; if (doFlush) { // Round up to include partial blocks nBlocksReady = Math.ceil(nBlocksReady); } else { // Round down to include only full blocks, // less the number of blocks that must remain in the buffer nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); } // Count words ready var nWordsReady = nBlocksReady * blockSize; // Count bytes ready var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); // Process blocks if (nWordsReady) { for (var offset = 0; offset < nWordsReady; offset += blockSize) { // Perform concrete-algorithm logic this._doProcessBlock(dataWords, offset); } // Remove processed words var processedWords = dataWords.splice(0, nWordsReady); data.sigBytes -= nBytesReady; } // Return processed words return new WordArray.init(processedWords, nBytesReady); }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = bufferedBlockAlgorithm.clone(); */ clone: function () { var clone = Base.clone.call(this); clone._data = this._data.clone(); return clone; }, _minBufferSize: 0 }); /** * Abstract hasher template. * * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) */ var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ /** * Configuration options. */ cfg: Base.extend(), /** * Initializes a newly created hasher. * * @param {Object} cfg (Optional) The configuration options to use for this hash computation. * * @example * * var hasher = CryptoJS.algo.SHA256.create(); */ init: function (cfg) { // Apply config defaults this.cfg = this.cfg.extend(cfg); // Set initial values this.reset(); }, /** * Resets this hasher to its initial state. * * @example * * hasher.reset(); */ reset: function () { // Reset data buffer BufferedBlockAlgorithm.reset.call(this); // Perform concrete-hasher logic this._doReset(); }, /** * Updates this hasher with a message. * * @param {WordArray|string} messageUpdate The message to append. * * @return {Hasher} This hasher. * * @example * * hasher.update('message'); * hasher.update(wordArray); */ update: function (messageUpdate) { // Append this._append(messageUpdate); // Update the hash this._process(); // Chainable return this; }, /** * Finalizes the hash computation. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} messageUpdate (Optional) A final message update. * * @return {WordArray} The hash. * * @example * * var hash = hasher.finalize(); * var hash = hasher.finalize('message'); * var hash = hasher.finalize(wordArray); */ finalize: function (messageUpdate) { // Final message update if (messageUpdate) { this._append(messageUpdate); } // Perform concrete-hasher logic var hash = this._doFinalize(); return hash; }, blockSize: 512/32, /** * Creates a shortcut function to a hasher's object interface. * * @param {Hasher} hasher The hasher to create a helper for. * * @return {Function} The shortcut function. * * @static * * @example * * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); */ _createHelper: function (hasher) { return function (message, cfg) { return new hasher.init(cfg).finalize(message); }; }, /** * Creates a shortcut function to the HMAC's object interface. * * @param {Hasher} hasher The hasher to use in this HMAC helper. * * @return {Function} The shortcut function. * * @static * * @example * * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); */ _createHmacHelper: function (hasher) { return function (message, key) { return new C_algo.HMAC.init(hasher, key).finalize(message); }; } }); /** * Algorithm namespace. */ var C_algo = C.algo = {}; return C; }(Math)); /* Copyright (c) 2011, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html version: 2.9.0 */ /** * The YAHOO object is the single global object used by YUI Library. It * contains utility function for setting up namespaces, inheritance, and * logging. YAHOO.util, YAHOO.widget, and YAHOO.example are namespaces * created automatically for and used by the library. * @module yahoo * @title YAHOO Global */ /** * YAHOO_config is not included as part of the library. Instead it is an * object that can be defined by the implementer immediately before * including the YUI library. The properties included in this object * will be used to configure global properties needed as soon as the * library begins to load. * @class YAHOO_config * @static */ /** * A reference to a function that will be executed every time a YAHOO module * is loaded. As parameter, this function will receive the version * information for the module. See <a href="YAHOO.env.html#getVersion"> * YAHOO.env.getVersion</a> for the description of the version data structure. * @property listener * @type Function * @static * @default undefined */ /** * Set to true if the library will be dynamically loaded after window.onload. * Defaults to false * @property injecting * @type boolean * @static * @default undefined */ /** * Instructs the yuiloader component to dynamically load yui components and * their dependencies. See the yuiloader documentation for more information * about dynamic loading * @property load * @static * @default undefined * @see yuiloader */ /** * Forces the use of the supplied locale where applicable in the library * @property locale * @type string * @static * @default undefined */ if (typeof YAHOO == "undefined" || !YAHOO) { /** * The YAHOO global namespace object. If YAHOO is already defined, the * existing YAHOO object will not be overwritten so that defined * namespaces are preserved. * @class YAHOO * @static */ var YAHOO = {}; } /** * Returns the namespace specified and creates it if it doesn't exist * <pre> * YAHOO.namespace("property.package"); * YAHOO.namespace("YAHOO.property.package"); * </pre> * Either of the above would create YAHOO.property, then * YAHOO.property.package * * Be careful when naming packages. Reserved words may work in some browsers * and not others. For instance, the following will fail in Safari: * <pre> * YAHOO.namespace("really.long.nested.namespace"); * </pre> * This fails because "long" is a future reserved word in ECMAScript * * For implementation code that uses YUI, do not create your components * in the namespaces defined by YUI ( * <code>YAHOO.util</code>, * <code>YAHOO.widget</code>, * <code>YAHOO.lang</code>, * <code>YAHOO.tool</code>, * <code>YAHOO.example</code>, * <code>YAHOO.env</code>) -- create your own namespace (e.g., 'companyname'). * * @method namespace * @static * @param {String*} arguments 1-n namespaces to create * @return {Object} A reference to the last namespace object created */ YAHOO.namespace = function() { var a=arguments, o=null, i, j, d; for (i=0; i<a.length; i=i+1) { d=(""+a[i]).split("."); o=YAHOO; // YAHOO is implied, so it is ignored if it is included for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) { o[d[j]]=o[d[j]] || {}; o=o[d[j]]; } } return o; }; /** * Uses YAHOO.widget.Logger to output a log message, if the widget is * available. * Note: LogReader adds the message, category, and source to the DOM as HTML. * * @method log * @static * @param {HTML} msg The message to log. * @param {HTML} cat The log category for the message. Default * categories are "info", "warn", "error", time". * Custom categories can be used as well. (opt) * @param {HTML} src The source of the the message (opt) * @return {Boolean} True if the log operation was successful. */ YAHOO.log = function(msg, cat, src) { var l=YAHOO.widget.Logger; if(l && l.log) { return l.log(msg, cat, src); } else { return false; } }; /** * Registers a module with the YAHOO object * @method register * @static * @param {String} name the name of the module (event, slider, etc) * @param {Function} mainClass a reference to class in the module. This * class will be tagged with the version info * so that it will be possible to identify the * version that is in use when multiple versions * have loaded * @param {Object} data metadata object for the module. Currently it * is expected to contain a "version" property * and a "build" property at minimum. */ YAHOO.register = function(name, mainClass, data) { var mods = YAHOO.env.modules, m, v, b, ls, i; if (!mods[name]) { mods[name] = { versions:[], builds:[] }; } m = mods[name]; v = data.version; b = data.build; ls = YAHOO.env.listeners; m.name = name; m.version = v; m.build = b; m.versions.push(v); m.builds.push(b); m.mainClass = mainClass; // fire the module load listeners for (i=0;i<ls.length;i=i+1) { ls[i](m); } // label the main class if (mainClass) { mainClass.VERSION = v; mainClass.BUILD = b; } else { YAHOO.log("mainClass is undefined for module " + name, "warn"); } }; /** * YAHOO.env is used to keep track of what is known about the YUI library and * the browsing environment * @class YAHOO.env * @static */ YAHOO.env = YAHOO.env || { /** * Keeps the version info for all YUI modules that have reported themselves * @property modules * @type Object[] */ modules: [], /** * List of functions that should be executed every time a YUI module * reports itself. * @property listeners * @type Function[] */ listeners: [] }; /** * Returns the version data for the specified module: * <dl> * <dt>name:</dt> <dd>The name of the module</dd> * <dt>version:</dt> <dd>The version in use</dd> * <dt>build:</dt> <dd>The build number in use</dd> * <dt>versions:</dt> <dd>All versions that were registered</dd> * <dt>builds:</dt> <dd>All builds that were registered.</dd> * <dt>mainClass:</dt> <dd>An object that was was stamped with the * current version and build. If * mainClass.VERSION != version or mainClass.BUILD != build, * multiple versions of pieces of the library have been * loaded, potentially causing issues.</dd> * </dl> * * @method getVersion * @static * @param {String} name the name of the module (event, slider, etc) * @return {Object} The version info */ YAHOO.env.getVersion = function(name) { return YAHOO.env.modules[name] || null; }; /** * Do not fork for a browser if it can be avoided. Use feature detection when * you can. Use the user agent as a last resort. YAHOO.env.ua stores a version * number for the browser engine, 0 otherwise. This value may or may not map * to the version number of the browser using the engine. The value is * presented as a float so that it can easily be used for boolean evaluation * as well as for looking for a particular range of versions. Because of this, * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9 * reports 1.8). * @class YAHOO.env.ua * @static */ /** * parses a user agent string (or looks for one in navigator to parse if * not supplied). * @method parseUA * @since 2.9.0 * @static */ YAHOO.env.parseUA = function(agent) { var numberify = function(s) { var c = 0; return parseFloat(s.replace(/\./g, function() { return (c++ == 1) ? '' : '.'; })); }, nav = navigator, o = { /** * Internet Explorer version number or 0. Example: 6 * @property ie * @type float * @static */ ie: 0, /** * Opera version number or 0. Example: 9.2 * @property opera * @type float * @static */ opera: 0, /** * Gecko engine revision number. Will evaluate to 1 if Gecko * is detected but the revision could not be found. Other browsers * will be 0. Example: 1.8 * <pre> * Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7 * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8 * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81 * Firefox 3.0 <-- 1.9 * Firefox 3.5 <-- 1.91 * </pre> * @property gecko * @type float * @static */ gecko: 0, /** * AppleWebKit version. KHTML browsers that are not WebKit browsers * will evaluate to 1, other browsers 0. Example: 418.9 * <pre> * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the * latest available for Mac OSX 10.3. * Safari 2.0.2: 416 <-- hasOwnProperty introduced * Safari 2.0.4: 418 <-- preventDefault fixed * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run * different versions of webkit * Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been * updated, but not updated * to the latest patch. * Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native * SVG and many major issues fixed). * Safari 3.0.4 (523.12) 523.12 <-- First Tiger release - automatic * update from 2.x via the 10.4.11 OS patch. * Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event. * yahoo.com user agent hack removed. * </pre> * http://en.wikipedia.org/wiki/Safari_version_history * @property webkit * @type float * @static */ webkit: 0, /** * Chrome will be detected as webkit, but this property will also * be populated with the Chrome version number * @property chrome * @type float * @static */ chrome: 0, /** * The mobile property will be set to a string containing any relevant * user agent information when a modern mobile browser is detected. * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series * devices with the WebKit-based browser, and Opera Mini. * @property mobile * @type string * @static */ mobile: null, /** * Adobe AIR version number or 0. Only populated if webkit is detected. * Example: 1.0 * @property air * @type float */ air: 0, /** * Detects Apple iPad's OS version * @property ipad * @type float * @static */ ipad: 0, /** * Detects Apple iPhone's OS version * @property iphone * @type float * @static */ iphone: 0, /** * Detects Apples iPod's OS version * @property ipod * @type float * @static */ ipod: 0, /** * General truthy check for iPad, iPhone or iPod * @property ios * @type float * @static */ ios: null, /** * Detects Googles Android OS version * @property android * @type float * @static */ android: 0, /** * Detects Palms WebOS version * @property webos * @type float * @static */ webos: 0, /** * Google Caja version number or 0. * @property caja * @type float */ caja: nav && nav.cajaVersion, /** * Set to true if the page appears to be in SSL * @property secure * @type boolean * @static */ secure: false, /** * The operating system. Currently only detecting windows or macintosh * @property os * @type string * @static */ os: null }, ua = agent || (navigator && navigator.userAgent), loc = window && window.location, href = loc && loc.href, m; o.secure = href && (href.toLowerCase().indexOf("https") === 0); if (ua) { if ((/windows|win32/i).test(ua)) { o.os = 'windows'; } else if ((/macintosh/i).test(ua)) { o.os = 'macintosh'; } else if ((/rhino/i).test(ua)) { o.os = 'rhino'; } // Modern KHTML browsers should qualify as Safari X-Grade if ((/KHTML/).test(ua)) { o.webkit = 1; } // Modern WebKit browsers are at least X-Grade m = ua.match(/AppleWebKit\/([^\s]*)/); if (m && m[1]) { o.webkit = numberify(m[1]); // Mobile browser check if (/ Mobile\//.test(ua)) { o.mobile = 'Apple'; // iPhone or iPod Touch m = ua.match(/OS ([^\s]*)/); if (m && m[1]) { m = numberify(m[1].replace('_', '.')); } o.ios = m; o.ipad = o.ipod = o.iphone = 0; m = ua.match(/iPad|iPod|iPhone/); if (m && m[0]) { o[m[0].toLowerCase()] = o.ios; } } else { m = ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/); if (m) { // Nokia N-series, Android, webOS, ex: NokiaN95 o.mobile = m[0]; } if (/webOS/.test(ua)) { o.mobile = 'WebOS'; m = ua.match(/webOS\/([^\s]*);/); if (m && m[1]) { o.webos = numberify(m[1]); } } if (/ Android/.test(ua)) { o.mobile = 'Android'; m = ua.match(/Android ([^\s]*);/); if (m && m[1]) { o.android = numberify(m[1]); } } } m = ua.match(/Chrome\/([^\s]*)/); if (m && m[1]) { o.chrome = numberify(m[1]); // Chrome } else { m = ua.match(/AdobeAIR\/([^\s]*)/); if (m) { o.air = m[0]; // Adobe AIR 1.0 or better } } } if (!o.webkit) { // not webkit // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr) m = ua.match(/Opera[\s\/]([^\s]*)/); if (m && m[1]) { o.opera = numberify(m[1]); m = ua.match(/Version\/([^\s]*)/); if (m && m[1]) { o.opera = numberify(m[1]); // opera 10+ } m = ua.match(/Opera Mini[^;]*/); if (m) { o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316 } } else { // not opera or webkit m = ua.match(/MSIE\s([^;]*)/); if (m && m[1]) { o.ie = numberify(m[1]); } else { // not opera, webkit, or ie m = ua.match(/Gecko\/([^\s]*)/); if (m) { o.gecko = 1; // Gecko detected, look for revision m = ua.match(/rv:([^\s\)]*)/); if (m && m[1]) { o.gecko = numberify(m[1]); } } } } } } return o; }; YAHOO.env.ua = YAHOO.env.parseUA(); /* * Initializes the global by creating the default namespaces and applying * any new configuration information that is detected. This is the setup * for env. * @method init * @static * @private */ (function() { YAHOO.namespace("util", "widget", "example"); /*global YAHOO_config*/ if ("undefined" !== typeof YAHOO_config) { var l=YAHOO_config.listener, ls=YAHOO.env.listeners,unique=true, i; if (l) { // if YAHOO is loaded multiple times we need to check to see if // this is a new config object. If it is, add the new component // load listener to the stack for (i=0; i<ls.length; i++) { if (ls[i] == l) { unique = false; break; } } if (unique) { ls.push(l); } } } })(); /** * Provides the language utilites and extensions used by the library * @class YAHOO.lang */ YAHOO.lang = YAHOO.lang || {}; (function() { var L = YAHOO.lang, OP = Object.prototype, ARRAY_TOSTRING = '[object Array]', FUNCTION_TOSTRING = '[object Function]', OBJECT_TOSTRING = '[object Object]', NOTHING = [], HTML_CHARS = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#x27;', '/': '&#x2F;', '`': '&#x60;' }, // ADD = ["toString", "valueOf", "hasOwnProperty"], ADD = ["toString", "valueOf"], OB = { /** * Determines wheather or not the provided object is an array. * @method isArray * @param {any} o The object being testing * @return {boolean} the result */ isArray: function(o) { return OP.toString.apply(o) === ARRAY_TOSTRING; }, /** * Determines whether or not the provided object is a boolean * @method isBoolean * @param {any} o The object being testing * @return {boolean} the result */ isBoolean: function(o) { return typeof o === 'boolean'; }, /** * Determines whether or not the provided object is a function. * Note: Internet Explorer thinks certain functions are objects: * * var obj = document.createElement("object"); * YAHOO.lang.isFunction(obj.getAttribute) // reports false in IE * * var input = document.createElement("input"); // append to body * YAHOO.lang.isFunction(input.focus) // reports false in IE * * You will have to implement additional tests if these functions * matter to you. * * @method isFunction * @param {any} o The object being testing * @return {boolean} the result */ isFunction: function(o) { return (typeof o === 'function') || OP.toString.apply(o) === FUNCTION_TOSTRING; }, /** * Determines whether or not the provided object is null * @method isNull * @param {any} o The object being testing * @return {boolean} the result */ isNull: function(o) { return o === null; }, /** * Determines whether or not the provided object is a legal number * @method isNumber * @param {any} o The object being testing * @return {boolean} the result */ isNumber: function(o) { return typeof o === 'number' && isFinite(o); }, /** * Determines whether or not the provided object is of type object * or function * @method isObject * @param {any} o The object being testing * @return {boolean} the result */ isObject: function(o) { return (o && (typeof o === 'object' || L.isFunction(o))) || false; }, /** * Determines whether or not the provided object is a string * @method isString * @param {any} o The object being testing * @return {boolean} the result */ isString: function(o) { return typeof o === 'string'; }, /** * Determines whether or not the provided object is undefined * @method isUndefined * @param {any} o The object being testing * @return {boolean} the result */ isUndefined: function(o) { return typeof o === 'undefined'; }, /** * IE will not enumerate native functions in a derived object even if the * function was overridden. This is a workaround for specific functions * we care about on the Object prototype. * @property _IEEnumFix * @param {Function} r the object to receive the augmentation * @param {Function} s the object that supplies the properties to augment * @static * @private */ _IEEnumFix: (YAHOO.env.ua.ie) ? function(r, s) { var i, fname, f; for (i=0;i<ADD.length;i=i+1) { fname = ADD[i]; f = s[fname]; if (L.isFunction(f) && f!=OP[fname]) { r[fname]=f; } } } : function(){}, /** * <p> * Returns a copy of the specified string with special HTML characters * escaped. The following characters will be converted to their * corresponding character entities: * <code>&amp; &lt; &gt; &quot; &#x27; &#x2F; &#x60;</code> * </p> * * <p> * This implementation is based on the * <a href="http://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet">OWASP * HTML escaping recommendations</a>. In addition to the characters * in the OWASP recommendation, we also escape the <code>&#x60;</code> * character, since IE interprets it as an attribute delimiter when used in * innerHTML. * </p> * * @method escapeHTML * @param {String} html String to escape. * @return {String} Escaped string. * @static * @since 2.9.0 */ escapeHTML: function (html) { return html.replace(/[&<>"'\/`]/g, function (match) { return HTML_CHARS[match]; }); }, /** * Utility to set up the prototype, constructor and superclass properties to * support an inheritance strategy that can chain constructors and methods. * Static members will not be inherited. * * @method extend * @static * @param {Function} subc the object to modify * @param {Function} superc the object to inherit * @param {Object} overrides additional properties/methods to add to the * subclass prototype. These will override the * matching items obtained from the superclass * if present. */ extend: function(subc, superc, overrides) { if (!superc||!subc) { throw new Error("extend failed, please check that " + "all dependencies are included."); } var F = function() {}, i; F.prototype=superc.prototype; subc.prototype=new F(); subc.prototype.constructor=subc; subc.superclass=superc.prototype; if (superc.prototype.constructor == OP.constructor) { superc.prototype.constructor=superc; } if (overrides) { for (i in overrides) { if (L.hasOwnProperty(overrides, i)) { subc.prototype[i]=overrides[i]; } } L._IEEnumFix(subc.prototype, overrides); } }, /** * Applies all properties in the supplier to the receiver if the * receiver does not have these properties yet. Optionally, one or * more methods/properties can be specified (as additional * parameters). This option will overwrite the property if receiver * has it already. If true is passed as the third parameter, all * properties will be applied and _will_ overwrite properties in * the receiver. * * @method augmentObject * @static * @since 2.3.0 * @param {Function} r the object to receive the augmentation * @param {Function} s the object that supplies the properties to augment * @param {String*|boolean} arguments zero or more properties methods * to augment the receiver with. If none specified, everything * in the supplier will be used unless it would * overwrite an existing property in the receiver. If true * is specified as the third parameter, all properties will * be applied and will overwrite an existing property in * the receiver */ augmentObject: function(r, s) { if (!s||!r) { throw new Error("Absorb failed, verify dependencies."); } var a=arguments, i, p, overrideList=a[2]; if (overrideList && overrideList!==true) { // only absorb the specified properties for (i=2; i<a.length; i=i+1) { r[a[i]] = s[a[i]]; } } else { // take everything, overwriting only if the third parameter is true for (p in s) { if (overrideList || !(p in r)) { r[p] = s[p]; } } L._IEEnumFix(r, s); } return r; }, /** * Same as YAHOO.lang.augmentObject, except it only applies prototype properties * @see YAHOO.lang.augmentObject * @method augmentProto * @static * @param {Function} r the object to receive the augmentation * @param {Function} s the object that supplies the properties to augment * @param {String*|boolean} arguments zero or more properties methods * to augment the receiver with. If none specified, everything * in the supplier will be used unless it would overwrite an existing * property in the receiver. if true is specified as the third * parameter, all properties will be applied and will overwrite an * existing property in the receiver */ augmentProto: function(r, s) { if (!s||!r) { throw new Error("Augment failed, verify dependencies."); } //var a=[].concat(arguments); var a=[r.prototype,s.prototype], i; for (i=2;i<arguments.length;i=i+1) { a.push(arguments[i]); } L.augmentObject.apply(this, a); return r; }, /** * Returns a simple string representation of the object or array. * Other types of objects will be returned unprocessed. Arrays * are expected to be indexed. Use object notation for * associative arrays. * @method dump * @since 2.3.0 * @param o {Object} The object to dump * @param d {int} How deep to recurse child objects, default 3 * @return {String} the dump result */ dump: function(o, d) { var i,len,s=[],OBJ="{...}",FUN="f(){...}", COMMA=', ', ARROW=' => '; // Cast non-objects to string // Skip dates because the std toString is what we want // Skip HTMLElement-like objects because trying to dump // an element will cause an unhandled exception in FF 2.x if (!L.isObject(o)) { return o + ""; } else if (o instanceof Date || ("nodeType" in o && "tagName" in o)) { return o; } else if (L.isFunction(o)) { return FUN; } // dig into child objects the depth specifed. Default 3 d = (L.isNumber(d)) ? d : 3; // arrays [1, 2, 3] if (L.isArray(o)) { s.push("["); for (i=0,len=o.length;i<len;i=i+1) { if (L.isObject(o[i])) { s.push((d > 0) ? L.dump(o[i], d-1) : OBJ); } else { s.push(o[i]); } s.push(COMMA); } if (s.length > 1) { s.pop(); } s.push("]"); // objects {k1 => v1, k2 => v2} } else { s.push("{"); for (i in o) { if