function has(name) {
	    if (has[name] !== undef) {
	      // Return cached feature test result.
	      return has[name];
	    }
	
	    var isSupported;
	    if (name == "bug-string-char-index") {
	      // IE <= 7 doesn't support accessing string characters using square
	      // bracket notation. IE 8 only supports this for primitives.
	      isSupported = "a"[0] != "a";
	    } else if (name == "json") {
	      // Indicates whether both `JSON.stringify` and `JSON.parse` are
	      // supported.
	      isSupported = has("json-stringify") && has("json-parse");
	    } else {
	      var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';
	      // Test `JSON.stringify`.
	      if (name == "json-stringify") {
	        var stringify = JSON3.stringify, stringifySupported = typeof stringify == "function" && isExtended;
	        if (stringifySupported) {
	          // A test function object with a custom `toJSON` method.
	          (value = function () {
	            return 1;
	          }).toJSON = value;
	          try {
	            stringifySupported =
	              // Firefox 3.1b1 and b2 serialize string, number, and boolean
	              // primitives as object literals.
	              stringify(0) === "0" &&
	              // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object
	              // literals.
	              stringify(new Number()) === "0" &&
	              stringify(new String()) == '""' &&
	              // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or
	              // does not define a canonical JSON representation (this applies to
	              // objects with `toJSON` properties as well, *unless* they are nested
	              // within an object or array).
	              stringify(getClass) === undef &&
	              // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and
	              // FF 3.1b3 pass this test.
	              stringify(undef) === undef &&
	              // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,
	              // respectively, if the value is omitted entirely.
	              stringify() === undef &&
	              // FF 3.1b1, 2 throw an error if the given value is not a number,
	              // string, array, object, Boolean, or `null` literal. This applies to
	              // objects with custom `toJSON` methods as well, unless they are nested
	              // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`
	              // methods entirely.
	              stringify(value) === "1" &&
	              stringify([value]) == "[1]" &&
	              // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of
	              // `"[null]"`.
	              stringify([undef]) == "[null]" &&
	              // YUI 3.0.0b1 fails to serialize `null` literals.
	              stringify(null) == "null" &&
	              // FF 3.1b1, 2 halts serialization if an array contains a function:
	              // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3
	              // elides non-JSON values from objects and arrays, unless they
	              // define custom `toJSON` methods.
	              stringify([undef, getClass, null]) == "[null,null,null]" &&
	              // Simple serialization test. FF 3.1b1 uses Unicode escape sequences
	              // where character escape codes are expected (e.g., `\b` => `\u0008`).
	              stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized &&
	              // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.
	              stringify(null, value) === "1" &&
	              stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
	              // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly
	              // serialize extended years.
	              stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
	              // The milliseconds are optional in ES 5, but required in 5.1.
	              stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
	              // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative
	              // four-digit years instead of six-digit years. Credits: @Yaffle.
	              stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
	              // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond
	              // values less than 1000. Credits: @Yaffle.
	              stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
	          } catch (exception) {
	            stringifySupported = false;
	          }
	        }
	        isSupported = stringifySupported;
	      }
	      // Test `JSON.parse`.
	      if (name == "json-parse") {
	        var parse = JSON3.parse;
	        if (typeof parse == "function") {
	          try {
	            // FF 3.1b1, b2 will throw an exception if a bare literal is provided.
	            // Conforming implementations should also coerce the initial argument to
	            // a string prior to parsing.
	            if (parse("0") === 0 && !parse(false)) {
	              // Simple parsing test.
	              value = parse(serialized);
	              var parseSupported = value["a"].length == 5 && value["a"][0] === 1;
	              if (parseSupported) {
	                try {
	                  // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.
	                  parseSupported = !parse('"\t"');
	                } catch (exception) {}
	                if (parseSupported) {
	                  try {
	                    // FF 4.0 and 4.0.1 allow leading `+` signs and leading
	                    // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow
	                    // certain octal literals.
	                    parseSupported = parse("01") !== 1;
	                  } catch (exception) {}
	                }
	                if (parseSupported) {
	                  try {
	                    // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal
	                    // points. These environments, along with FF 3.1b1 and 2,
	                    // also allow trailing commas in JSON objects and arrays.
	                    parseSupported = parse("1.") !== 1;
	                  } catch (exception) {}
	                }
	              }
	            }
	          } catch (exception) {
	            parseSupported = false;
	          }
	        }
	        isSupported = parseSupported;
	      }
	    }
	    return has[name] = !!isSupported;
	  }
// implementations are spec-compliant. Based on work by Ken Snyder.
implementations are spec-compliant. Based on work by Ken Snyder.
implementations are spec - compliant . Based on work by Ken Snyder .
function has(name) {
	    if (has[name] !== undef) {
	      return has[name];
	    }
	    var isSupported;
	    if (name == "bug-string-char-index") {
	      isSupported = "a"[0] != "a";
	    } else if (name == "json") {
	      isSupported = has("json-stringify") && has("json-parse");
	    } else {
	      var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';
	      if (name == "json-stringify") {
	        var stringify = JSON3.stringify, stringifySupported = typeof stringify == "function" && isExtended;
	        if (stringifySupported) {
	          (value = function () {
	            return 1;
	          }).toJSON = value;
	          try {
	            stringifySupported =
	              stringify(0) === "0" &&
	              stringify(new Number()) === "0" &&
	              stringify(new String()) == '""' &&
	              stringify(getClass) === undef &&
	              stringify(undef) === undef &&
	              stringify() === undef &&
	              stringify(value) === "1" &&
	              stringify([value]) == "[1]" &&
	              stringify([undef]) == "[null]" &&
	              stringify(null) == "null" &&
	              stringify([undef, getClass, null]) == "[null,null,null]" &&
	              stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized &&
	              stringify(null, value) === "1" &&
	              stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
	              stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
	              stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
	              stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
	              stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
	          } catch (exception) {
	            stringifySupported = false;
	          }
	        }
	        isSupported = stringifySupported;
	      }
	      if (name == "json-parse") {
	        var parse = JSON3.parse;
	        if (typeof parse == "function") {
	          try {
	            if (parse("0") === 0 && !parse(false)) {
	              value = parse(serialized);
	              var parseSupported = value["a"].length == 5 && value["a"][0] === 1;
	              if (parseSupported) {
	                try {
	                  parseSupported = !parse('"\t"');
	                } catch (exception) {}
	                if (parseSupported) {
	                  try {
	                    parseSupported = parse("01") !== 1;
	                  } catch (exception) {}
	                }
	                if (parseSupported) {
	                  try {
	                    parseSupported = parse("1.") !== 1;
	                  } catch (exception) {}
	                }
	              }
	            }
	          } catch (exception) {
	            parseSupported = false;
	          }
	        }
	        isSupported = parseSupported;
	      }
	    }
	    return has[name] = !!isSupported;
	  }
function has ( name ) { if ( has [ name ] !== undef ) { return has [ name ] ; } var isSupported ; if ( name == "bug-string-char-index" ) { isSupported = "a" [ 0 ] != "a" ; } else if ( name == "json" ) { isSupported = has ( "json-stringify" ) && has ( "json-parse" ) ; } else { var value , serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}' ; if ( name == "json-stringify" ) { var stringify = JSON3 . stringify , stringifySupported = typeof stringify == "function" && isExtended ; if ( stringifySupported ) { ( value = function ( ) { return 1 ; } ) . toJSON = value ; try { stringifySupported = stringify ( 0 ) === "0" && stringify ( new Number ( ) ) === "0" && stringify ( new String ( ) ) == '""' && stringify ( getClass ) === undef && stringify ( undef ) === undef && stringify ( ) === undef && stringify ( value ) === "1" && stringify ( [ value ] ) == "[1]" && stringify ( [ undef ] ) == "[null]" && stringify ( null ) == "null" && stringify ( [ undef , getClass , null ] ) == "[null,null,null]" && stringify ( { "a" : [ value , true , false , null , "\x00\b\n\f\r\t" ] } ) == serialized && stringify ( null , value ) === "1" && stringify ( [ 1 , 2 ] , null , 1 ) == "[\n 1,\n 2\n]" && stringify ( new Date ( - 8.64e15 ) ) == '"-271821-04-20T00:00:00.000Z"' && stringify ( new Date ( 8.64e15 ) ) == '"+275760-09-13T00:00:00.000Z"' && stringify ( new Date ( - 621987552e5 ) ) == '"-000001-01-01T00:00:00.000Z"' && stringify ( new Date ( - 1 ) ) == '"1969-12-31T23:59:59.999Z"' ; } catch ( exception ) { stringifySupported = false ; } } isSupported = stringifySupported ; } if ( name == "json-parse" ) { var parse = JSON3 . parse ; if ( typeof parse == "function" ) { try { if ( parse ( "0" ) === 0 && ! parse ( false ) ) { value = parse ( serialized ) ; var parseSupported = value [ "a" ] . length == 5 && value [ "a" ] [ 0 ] === 1 ; if ( parseSupported ) { try { parseSupported = ! parse ( '"\t"' ) ; } catch ( exception ) { } if ( parseSupported ) { try { parseSupported = parse ( "01" ) !== 1 ; } catch ( exception ) { } } if ( parseSupported ) { try { parseSupported = parse ( "1." ) !== 1 ; } catch ( exception ) { } } } } } catch ( exception ) { parseSupported = false ; } } isSupported = parseSupported ; } } return has [ name ] = ! ! isSupported ; }
implementations are spec-compliant.
implementations are spec - compliant .
// Return cached feature test result. // IE <= 7 doesn't support accessing string characters using square // bracket notation. IE 8 only supports this for primitives. // Indicates whether both `JSON.stringify` and `JSON.parse` are // supported. // Test `JSON.stringify`. // A test function object with a custom `toJSON` method. // Firefox 3.1b1 and b2 serialize string, number, and boolean // primitives as object literals. // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object // literals. // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or // does not define a canonical JSON representation (this applies to // objects with `toJSON` properties as well, *unless* they are nested // within an object or array). // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and // FF 3.1b3 pass this test. // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s, // respectively, if the value is omitted entirely. // FF 3.1b1, 2 throw an error if the given value is not a number, // string, array, object, Boolean, or `null` literal. This applies to // objects with custom `toJSON` methods as well, unless they are nested // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON` // methods entirely. // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of // `"[null]"`. // YUI 3.0.0b1 fails to serialize `null` literals. // FF 3.1b1, 2 halts serialization if an array contains a function: // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3 // elides non-JSON values from objects and arrays, unless they // define custom `toJSON` methods. // Simple serialization test. FF 3.1b1 uses Unicode escape sequences // where character escape codes are expected (e.g., `\b` => `\u0008`). // FF 3.1b1 and b2 ignore the `filter` and `width` arguments. // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly // serialize extended years. // The milliseconds are optional in ES 5, but required in 5.1. // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative // four-digit years instead of six-digit years. Credits: @Yaffle. // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond // values less than 1000. Credits: @Yaffle. // Test `JSON.parse`. // FF 3.1b1, b2 will throw an exception if a bare literal is provided. // Conforming implementations should also coerce the initial argument to // a string prior to parsing. // Simple parsing test. // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings. // FF 4.0 and 4.0.1 allow leading `+` signs and leading // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow // certain octal literals. // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal // points. These environments, along with FF 3.1b1 and 2, // also allow trailing commas in JSON objects and arrays.