Modernizr, added title to single post, removed footer.
authorLaury GvR <laury@gaslightmedia.com>
Fri, 2 Oct 2015 20:25:40 +0000 (16:25 -0400)
committerLaury GvR <laury@gaslightmedia.com>
Fri, 2 Oct 2015 20:25:40 +0000 (16:25 -0400)
370 files changed:
css/app.css
css/app.css.map
js/modernizr/Gruntfile.js [new file with mode: 0644]
js/modernizr/feature-detects/a/download.js [new file with mode: 0644]
js/modernizr/feature-detects/ambientlight.js [new file with mode: 0644]
js/modernizr/feature-detects/applicationcache.js [new file with mode: 0644]
js/modernizr/feature-detects/audio.js [new file with mode: 0644]
js/modernizr/feature-detects/audio/loop.js [new file with mode: 0644]
js/modernizr/feature-detects/audio/preload.js [new file with mode: 0644]
js/modernizr/feature-detects/audio/webaudio.js [new file with mode: 0644]
js/modernizr/feature-detects/battery.js [new file with mode: 0644]
js/modernizr/feature-detects/battery/lowbattery.js [new file with mode: 0644]
js/modernizr/feature-detects/blob.js [new file with mode: 0644]
js/modernizr/feature-detects/canvas.js [new file with mode: 0644]
js/modernizr/feature-detects/canvas/blending.js [new file with mode: 0644]
js/modernizr/feature-detects/canvas/todataurl.js [new file with mode: 0644]
js/modernizr/feature-detects/canvas/winding.js [new file with mode: 0644]
js/modernizr/feature-detects/canvastext.js [new file with mode: 0644]
js/modernizr/feature-detects/contenteditable.js
js/modernizr/feature-detects/contextmenu.js
js/modernizr/feature-detects/cookies.js
js/modernizr/feature-detects/cors.js
js/modernizr/feature-detects/crypto/getrandomvalues.js [new file with mode: 0644]
js/modernizr/feature-detects/css/all.js [new file with mode: 0644]
js/modernizr/feature-detects/css/animations.js [new file with mode: 0644]
js/modernizr/feature-detects/css/appearance.js [new file with mode: 0644]
js/modernizr/feature-detects/css/backgroundblendmode.js [new file with mode: 0644]
js/modernizr/feature-detects/css/backgroundcliptext.js [new file with mode: 0644]
js/modernizr/feature-detects/css/backgroundposition-shorthand.js [new file with mode: 0644]
js/modernizr/feature-detects/css/backgroundposition-xy.js [new file with mode: 0644]
js/modernizr/feature-detects/css/backgroundrepeat.js [new file with mode: 0644]
js/modernizr/feature-detects/css/backgroundsize.js [new file with mode: 0644]
js/modernizr/feature-detects/css/backgroundsizecover.js [new file with mode: 0644]
js/modernizr/feature-detects/css/borderimage.js [new file with mode: 0644]
js/modernizr/feature-detects/css/borderradius.js [new file with mode: 0644]
js/modernizr/feature-detects/css/boxshadow.js [new file with mode: 0644]
js/modernizr/feature-detects/css/boxsizing.js [new file with mode: 0644]
js/modernizr/feature-detects/css/calc.js [new file with mode: 0644]
js/modernizr/feature-detects/css/checked.js [new file with mode: 0644]
js/modernizr/feature-detects/css/chunit.js [new file with mode: 0644]
js/modernizr/feature-detects/css/columns.js [new file with mode: 0644]
js/modernizr/feature-detects/css/cubicbezierrange.js [new file with mode: 0644]
js/modernizr/feature-detects/css/displayrunin.js [new file with mode: 0644]
js/modernizr/feature-detects/css/displaytable.js [new file with mode: 0644]
js/modernizr/feature-detects/css/ellipsis.js [new file with mode: 0644]
js/modernizr/feature-detects/css/escape.js [new file with mode: 0644]
js/modernizr/feature-detects/css/exunit.js [new file with mode: 0644]
js/modernizr/feature-detects/css/filters.js [new file with mode: 0644]
js/modernizr/feature-detects/css/flexbox.js [new file with mode: 0644]
js/modernizr/feature-detects/css/flexboxlegacy.js [new file with mode: 0644]
js/modernizr/feature-detects/css/flexboxtweener.js [new file with mode: 0644]
js/modernizr/feature-detects/css/flexwrap.js [new file with mode: 0644]
js/modernizr/feature-detects/css/fontface.js [new file with mode: 0644]
js/modernizr/feature-detects/css/generatedcontent.js [new file with mode: 0644]
js/modernizr/feature-detects/css/gradients.js [new file with mode: 0644]
js/modernizr/feature-detects/css/hsla.js [new file with mode: 0644]
js/modernizr/feature-detects/css/hyphens.js [new file with mode: 0644]
js/modernizr/feature-detects/css/invalid.js [new file with mode: 0644]
js/modernizr/feature-detects/css/lastchild.js [new file with mode: 0644]
js/modernizr/feature-detects/css/mask.js [new file with mode: 0644]
js/modernizr/feature-detects/css/mediaqueries.js [new file with mode: 0644]
js/modernizr/feature-detects/css/multiplebgs.js [new file with mode: 0644]
js/modernizr/feature-detects/css/nthchild.js [new file with mode: 0644]
js/modernizr/feature-detects/css/objectfit.js [new file with mode: 0644]
js/modernizr/feature-detects/css/opacity.js [new file with mode: 0644]
js/modernizr/feature-detects/css/overflow-scrolling.js [new file with mode: 0644]
js/modernizr/feature-detects/css/pointerevents.js [new file with mode: 0644]
js/modernizr/feature-detects/css/positionsticky.js [new file with mode: 0644]
js/modernizr/feature-detects/css/pseudoanimations.js [new file with mode: 0644]
js/modernizr/feature-detects/css/pseudotransitions.js [new file with mode: 0644]
js/modernizr/feature-detects/css/reflections.js [new file with mode: 0644]
js/modernizr/feature-detects/css/regions.js [new file with mode: 0644]
js/modernizr/feature-detects/css/remunit.js [new file with mode: 0644]
js/modernizr/feature-detects/css/resize.js [new file with mode: 0644]
js/modernizr/feature-detects/css/rgba.js [new file with mode: 0644]
js/modernizr/feature-detects/css/scrollbars.js [new file with mode: 0644]
js/modernizr/feature-detects/css/shapes.js [new file with mode: 0644]
js/modernizr/feature-detects/css/siblinggeneral.js [new file with mode: 0644]
js/modernizr/feature-detects/css/subpixelfont.js [new file with mode: 0644]
js/modernizr/feature-detects/css/supports.js [new file with mode: 0644]
js/modernizr/feature-detects/css/target.js [new file with mode: 0644]
js/modernizr/feature-detects/css/textalignlast.js [new file with mode: 0644]
js/modernizr/feature-detects/css/textshadow.js [new file with mode: 0644]
js/modernizr/feature-detects/css/transforms.js [new file with mode: 0644]
js/modernizr/feature-detects/css/transforms3d.js [new file with mode: 0644]
js/modernizr/feature-detects/css/transformstylepreserve3d.js [new file with mode: 0644]
js/modernizr/feature-detects/css/transitions.js [new file with mode: 0644]
js/modernizr/feature-detects/css/userselect.js [new file with mode: 0644]
js/modernizr/feature-detects/css/valid.js [new file with mode: 0644]
js/modernizr/feature-detects/css/vhunit.js [new file with mode: 0644]
js/modernizr/feature-detects/css/vmaxunit.js [new file with mode: 0644]
js/modernizr/feature-detects/css/vminunit.js [new file with mode: 0644]
js/modernizr/feature-detects/css/vwunit.js [new file with mode: 0644]
js/modernizr/feature-detects/css/will-change.js [new file with mode: 0644]
js/modernizr/feature-detects/css/wrapflow.js [new file with mode: 0644]
js/modernizr/feature-detects/custom-protocol-handler.js
js/modernizr/feature-detects/customevent.js [new file with mode: 0644]
js/modernizr/feature-detects/dart.js
js/modernizr/feature-detects/dataview-api.js
js/modernizr/feature-detects/dom/classlist.js [new file with mode: 0644]
js/modernizr/feature-detects/dom/createElement-attrs.js [new file with mode: 0644]
js/modernizr/feature-detects/dom/dataset.js [new file with mode: 0644]
js/modernizr/feature-detects/dom/documentfragment.js [new file with mode: 0644]
js/modernizr/feature-detects/dom/hidden.js [new file with mode: 0644]
js/modernizr/feature-detects/dom/microdata.js [new file with mode: 0644]
js/modernizr/feature-detects/dom/mutationObserver.js [new file with mode: 0644]
js/modernizr/feature-detects/elem/datalist.js [new file with mode: 0644]
js/modernizr/feature-detects/elem/details.js [new file with mode: 0644]
js/modernizr/feature-detects/elem/output.js [new file with mode: 0644]
js/modernizr/feature-detects/elem/picture.js [new file with mode: 0644]
js/modernizr/feature-detects/elem/progress-meter.js [new file with mode: 0644]
js/modernizr/feature-detects/elem/ruby.js [new file with mode: 0644]
js/modernizr/feature-detects/elem/template.js [new file with mode: 0644]
js/modernizr/feature-detects/elem/time.js [new file with mode: 0644]
js/modernizr/feature-detects/elem/track.js [new file with mode: 0644]
js/modernizr/feature-detects/elem/unknown.js [new file with mode: 0644]
js/modernizr/feature-detects/emoji.js
js/modernizr/feature-detects/es5/array.js [new file with mode: 0644]
js/modernizr/feature-detects/es5/date.js [new file with mode: 0644]
js/modernizr/feature-detects/es5/function.js [new file with mode: 0644]
js/modernizr/feature-detects/es5/object.js [new file with mode: 0644]
js/modernizr/feature-detects/es5/specification.js [new file with mode: 0644]
js/modernizr/feature-detects/es5/strictmode.js [new file with mode: 0644]
js/modernizr/feature-detects/es5/string.js [new file with mode: 0644]
js/modernizr/feature-detects/es5/syntax.js [new file with mode: 0644]
js/modernizr/feature-detects/es5/undefined.js [new file with mode: 0644]
js/modernizr/feature-detects/es6/array.js [new file with mode: 0644]
js/modernizr/feature-detects/es6/contains.js [new file with mode: 0644]
js/modernizr/feature-detects/es6/generators.js [new file with mode: 0644]
js/modernizr/feature-detects/es6/math.js [new file with mode: 0644]
js/modernizr/feature-detects/es6/number.js [new file with mode: 0644]
js/modernizr/feature-detects/es6/object.js [new file with mode: 0644]
js/modernizr/feature-detects/es6/promises.js [new file with mode: 0644]
js/modernizr/feature-detects/es6/string.js [new file with mode: 0644]
js/modernizr/feature-detects/event/deviceorientation-motion.js [new file with mode: 0644]
js/modernizr/feature-detects/event/oninput.js [new file with mode: 0644]
js/modernizr/feature-detects/eventlistener.js [new file with mode: 0644]
js/modernizr/feature-detects/exif-orientation.js
js/modernizr/feature-detects/file/api.js [new file with mode: 0644]
js/modernizr/feature-detects/file/filesystem.js [new file with mode: 0644]
js/modernizr/feature-detects/flash.js [new file with mode: 0644]
js/modernizr/feature-detects/forms/capture.js [new file with mode: 0644]
js/modernizr/feature-detects/forms/fileinput.js [new file with mode: 0644]
js/modernizr/feature-detects/forms/fileinputdirectory.js [new file with mode: 0644]
js/modernizr/feature-detects/forms/formattribute.js [new file with mode: 0644]
js/modernizr/feature-detects/forms/inputnumber-l10n.js [new file with mode: 0644]
js/modernizr/feature-detects/forms/placeholder.js [new file with mode: 0644]
js/modernizr/feature-detects/forms/requestautocomplete.js [new file with mode: 0644]
js/modernizr/feature-detects/forms/validation.js [new file with mode: 0644]
js/modernizr/feature-detects/fullscreen-api.js
js/modernizr/feature-detects/gamepad.js
js/modernizr/feature-detects/geolocation.js [new file with mode: 0644]
js/modernizr/feature-detects/hashchange.js [new file with mode: 0644]
js/modernizr/feature-detects/hiddenscroll.js [new file with mode: 0644]
js/modernizr/feature-detects/history.js [new file with mode: 0644]
js/modernizr/feature-detects/htmlimports.js [new file with mode: 0644]
js/modernizr/feature-detects/ie8compat.js
js/modernizr/feature-detects/iframe/sandbox.js [new file with mode: 0644]
js/modernizr/feature-detects/iframe/seamless.js [new file with mode: 0644]
js/modernizr/feature-detects/iframe/srcdoc.js [new file with mode: 0644]
js/modernizr/feature-detects/img/apng.js [new file with mode: 0644]
js/modernizr/feature-detects/img/jpegxr.js [new file with mode: 0644]
js/modernizr/feature-detects/img/sizes.js [new file with mode: 0644]
js/modernizr/feature-detects/img/srcset.js [new file with mode: 0644]
js/modernizr/feature-detects/img/webp-alpha.js [new file with mode: 0644]
js/modernizr/feature-detects/img/webp-animation.js [new file with mode: 0644]
js/modernizr/feature-detects/img/webp-lossless.js [new file with mode: 0644]
js/modernizr/feature-detects/img/webp.js [new file with mode: 0644]
js/modernizr/feature-detects/indexeddb.js [new file with mode: 0644]
js/modernizr/feature-detects/indexeddbblob.js [new file with mode: 0644]
js/modernizr/feature-detects/input.js [new file with mode: 0644]
js/modernizr/feature-detects/input/formaction.js [new file with mode: 0644]
js/modernizr/feature-detects/input/formenctype.js [new file with mode: 0644]
js/modernizr/feature-detects/input/formmethod.js [new file with mode: 0644]
js/modernizr/feature-detects/input/formtarget.js [new file with mode: 0644]
js/modernizr/feature-detects/inputsearchevent.js [new file with mode: 0644]
js/modernizr/feature-detects/inputtypes.js [new file with mode: 0644]
js/modernizr/feature-detects/intl.js [new file with mode: 0644]
js/modernizr/feature-detects/json.js
js/modernizr/feature-detects/lists-reversed.js
js/modernizr/feature-detects/mathml.js
js/modernizr/feature-detects/network/beacon.js [new file with mode: 0644]
js/modernizr/feature-detects/network/connection.js [new file with mode: 0644]
js/modernizr/feature-detects/network/eventsource.js [new file with mode: 0644]
js/modernizr/feature-detects/network/fetch.js [new file with mode: 0644]
js/modernizr/feature-detects/network/xhr-responsetype-arraybuffer.js [new file with mode: 0644]
js/modernizr/feature-detects/network/xhr-responsetype-blob.js [new file with mode: 0644]
js/modernizr/feature-detects/network/xhr-responsetype-document.js [new file with mode: 0644]
js/modernizr/feature-detects/network/xhr-responsetype-json.js [new file with mode: 0644]
js/modernizr/feature-detects/network/xhr-responsetype-text.js [new file with mode: 0644]
js/modernizr/feature-detects/network/xhr-responsetype.js [new file with mode: 0644]
js/modernizr/feature-detects/network/xhr2.js [new file with mode: 0644]
js/modernizr/feature-detects/notification.js
js/modernizr/feature-detects/pagevisibility-api.js [new file with mode: 0644]
js/modernizr/feature-detects/performance.js
js/modernizr/feature-detects/pointerevents.js [new file with mode: 0644]
js/modernizr/feature-detects/pointerlock-api.js
js/modernizr/feature-detects/postmessage.js [new file with mode: 0644]
js/modernizr/feature-detects/proximity.js [new file with mode: 0644]
js/modernizr/feature-detects/queryselector.js [new file with mode: 0644]
js/modernizr/feature-detects/quota-management-api.js
js/modernizr/feature-detects/requestanimationframe.js
js/modernizr/feature-detects/script/async.js [new file with mode: 0644]
js/modernizr/feature-detects/script/defer.js [new file with mode: 0644]
js/modernizr/feature-detects/serviceworker.js [new file with mode: 0644]
js/modernizr/feature-detects/speech/speech-recognition.js [new file with mode: 0644]
js/modernizr/feature-detects/speech/speech-synthesis.js [new file with mode: 0644]
js/modernizr/feature-detects/storage/localstorage.js [new file with mode: 0644]
js/modernizr/feature-detects/storage/sessionstorage.js [new file with mode: 0644]
js/modernizr/feature-detects/storage/websqldatabase.js [new file with mode: 0644]
js/modernizr/feature-detects/style/scoped.js [new file with mode: 0644]
js/modernizr/feature-detects/svg.js [new file with mode: 0644]
js/modernizr/feature-detects/svg/asimg.js [new file with mode: 0644]
js/modernizr/feature-detects/svg/clippaths.js [new file with mode: 0644]
js/modernizr/feature-detects/svg/filters.js [new file with mode: 0644]
js/modernizr/feature-detects/svg/foreignobject.js [new file with mode: 0644]
js/modernizr/feature-detects/svg/inline.js [new file with mode: 0644]
js/modernizr/feature-detects/svg/smil.js [new file with mode: 0644]
js/modernizr/feature-detects/templatestrings.js [new file with mode: 0644]
js/modernizr/feature-detects/textarea/maxlength.js [new file with mode: 0644]
js/modernizr/feature-detects/touchevents.js [new file with mode: 0644]
js/modernizr/feature-detects/typed-arrays.js [new file with mode: 0644]
js/modernizr/feature-detects/unicode-range.js [new file with mode: 0644]
js/modernizr/feature-detects/unicode.js
js/modernizr/feature-detects/url/bloburls.js [new file with mode: 0644]
js/modernizr/feature-detects/url/data-uri.js [new file with mode: 0644]
js/modernizr/feature-detects/url/parser.js [new file with mode: 0644]
js/modernizr/feature-detects/userdata.js
js/modernizr/feature-detects/vibration.js
js/modernizr/feature-detects/video.js [new file with mode: 0644]
js/modernizr/feature-detects/video/autoplay.js [new file with mode: 0644]
js/modernizr/feature-detects/video/loop.js [new file with mode: 0644]
js/modernizr/feature-detects/video/preload.js [new file with mode: 0644]
js/modernizr/feature-detects/vml.js [new file with mode: 0644]
js/modernizr/feature-detects/web-intents.js
js/modernizr/feature-detects/webanimations.js [new file with mode: 0644]
js/modernizr/feature-detects/webgl.js [new file with mode: 0644]
js/modernizr/feature-detects/webgl/extensions.js [new file with mode: 0644]
js/modernizr/feature-detects/webrtc/datachannel.js [new file with mode: 0644]
js/modernizr/feature-detects/webrtc/getusermedia.js [new file with mode: 0644]
js/modernizr/feature-detects/webrtc/peerconnection.js [new file with mode: 0644]
js/modernizr/feature-detects/websockets.js [new file with mode: 0644]
js/modernizr/feature-detects/websockets/binary.js [new file with mode: 0644]
js/modernizr/feature-detects/window/framed.js [new file with mode: 0644]
js/modernizr/feature-detects/window/matchmedia.js [new file with mode: 0644]
js/modernizr/feature-detects/workers/blobworkers.js [new file with mode: 0644]
js/modernizr/feature-detects/workers/dataworkers.js [new file with mode: 0644]
js/modernizr/feature-detects/workers/sharedworkers.js [new file with mode: 0644]
js/modernizr/feature-detects/workers/transferables.js [new file with mode: 0644]
js/modernizr/feature-detects/workers/webworkers.js [new file with mode: 0644]
js/modernizr/lib/build-query.js [new file with mode: 0644]
js/modernizr/lib/build.js [new file with mode: 0644]
js/modernizr/lib/cli.js [new file with mode: 0644]
js/modernizr/lib/generate-banner.js [new file with mode: 0644]
js/modernizr/lib/metadata.js [new file with mode: 0644]
js/modernizr/lib/options.js [new file with mode: 0644]
js/modernizr/src/Modernizr.js [new file with mode: 0644]
js/modernizr/src/ModernizrProto.js [new file with mode: 0644]
js/modernizr/src/addTest.js [new file with mode: 0644]
js/modernizr/src/atRule.js [new file with mode: 0644]
js/modernizr/src/classes.js [new file with mode: 0644]
js/modernizr/src/contains.js [new file with mode: 0644]
js/modernizr/src/createElement.js [new file with mode: 0644]
js/modernizr/src/cssToDOM.js [new file with mode: 0644]
js/modernizr/src/cssomPrefixes.js [new file with mode: 0644]
js/modernizr/src/docElement.js [new file with mode: 0644]
js/modernizr/src/domPrefixes.js [new file with mode: 0644]
js/modernizr/src/domToCSS.js [new file with mode: 0644]
js/modernizr/src/fnBind.js [new file with mode: 0644]
js/modernizr/src/generate.js [new file with mode: 0644]
js/modernizr/src/getBody.js [new file with mode: 0644]
js/modernizr/src/hasEvent.js [new file with mode: 0644]
js/modernizr/src/hasOwnProp.js [new file with mode: 0644]
js/modernizr/src/html5printshiv.js [new file with mode: 0644]
js/modernizr/src/html5shiv.js [new file with mode: 0644]
js/modernizr/src/injectElementWithStyles.js [new file with mode: 0644]
js/modernizr/src/inputElem.js [new file with mode: 0644]
js/modernizr/src/is.js [new file with mode: 0644]
js/modernizr/src/isSVG.js [new file with mode: 0644]
js/modernizr/src/load.js [new file with mode: 0644]
js/modernizr/src/mStyle.js [new file with mode: 0644]
js/modernizr/src/modElem.js [new file with mode: 0644]
js/modernizr/src/mq.js [new file with mode: 0644]
js/modernizr/src/nativeTestProps.js [new file with mode: 0644]
js/modernizr/src/omPrefixes.js [new file with mode: 0644]
js/modernizr/src/prefixed.js [new file with mode: 0644]
js/modernizr/src/prefixedCSS.js [new file with mode: 0644]
js/modernizr/src/prefixes.js [new file with mode: 0644]
js/modernizr/src/roundedEquals.js [new file with mode: 0644]
js/modernizr/src/setClasses.js [new file with mode: 0644]
js/modernizr/src/slice.js [new file with mode: 0644]
js/modernizr/src/testAllProps.js [new file with mode: 0644]
js/modernizr/src/testDOMProps.js [new file with mode: 0644]
js/modernizr/src/testProp.js [new file with mode: 0644]
js/modernizr/src/testProps.js [new file with mode: 0644]
js/modernizr/src/testPropsAll.js [new file with mode: 0644]
js/modernizr/src/testRunner.js [new file with mode: 0644]
js/modernizr/src/testStyles.js [new file with mode: 0644]
js/modernizr/src/testXhrType.js [new file with mode: 0644]
js/modernizr/src/tests.js [new file with mode: 0644]
js/modernizr/src/toStringFn.js [new file with mode: 0644]
js/modernizr/test/browser/integration/bools.js [new file with mode: 0644]
js/modernizr/test/browser/integration/caniuse.js [new file with mode: 0644]
js/modernizr/test/browser/integration/classes.js [new file with mode: 0644]
js/modernizr/test/browser/integration/global.js [new file with mode: 0644]
js/modernizr/test/browser/integration/iframe.js [new file with mode: 0644]
js/modernizr/test/browser/integration/prefixed-atRule.js [new file with mode: 0644]
js/modernizr/test/browser/integration/prefixed-autobind.js [new file with mode: 0644]
js/modernizr/test/browser/integration/prefixed.js [new file with mode: 0644]
js/modernizr/test/browser/integration/prefixedCSS.js [new file with mode: 0644]
js/modernizr/test/browser/integration/svg.js [new file with mode: 0644]
js/modernizr/test/browser/setup.js [new file with mode: 0644]
js/modernizr/test/browser/src/Modernizr.js [new file with mode: 0644]
js/modernizr/test/browser/src/ModernizrProto.js [new file with mode: 0644]
js/modernizr/test/browser/src/addTest.js [new file with mode: 0644]
js/modernizr/test/browser/src/atRule.js [new file with mode: 0644]
js/modernizr/test/browser/src/classes.js [new file with mode: 0644]
js/modernizr/test/browser/src/contains.js [new file with mode: 0644]
js/modernizr/test/browser/src/createElement.js [new file with mode: 0644]
js/modernizr/test/browser/src/cssToDOM.js [new file with mode: 0644]
js/modernizr/test/browser/src/cssomPrefixes.js [new file with mode: 0644]
js/modernizr/test/browser/src/docElement.js [new file with mode: 0644]
js/modernizr/test/browser/src/domPrefixes.js [new file with mode: 0644]
js/modernizr/test/browser/src/domToCSS.js [new file with mode: 0644]
js/modernizr/test/browser/src/fnBind.js [new file with mode: 0644]
js/modernizr/test/browser/src/generate.js [new file with mode: 0644]
js/modernizr/test/browser/src/getBody.js [new file with mode: 0644]
js/modernizr/test/browser/src/hasEvent.js [new file with mode: 0644]
js/modernizr/test/browser/src/hasOwnProp.js [new file with mode: 0644]
js/modernizr/test/browser/src/html5printshiv.js [new file with mode: 0644]
js/modernizr/test/browser/src/html5shiv.js [new file with mode: 0644]
js/modernizr/test/browser/src/injectElementWithStyles.js [new file with mode: 0644]
js/modernizr/test/browser/src/inputElem.js [new file with mode: 0644]
js/modernizr/test/browser/src/is.js [new file with mode: 0644]
js/modernizr/test/browser/src/load.js [new file with mode: 0644]
js/modernizr/test/browser/src/mStyle.js [new file with mode: 0644]
js/modernizr/test/browser/src/modElem.js [new file with mode: 0644]
js/modernizr/test/browser/src/mq.js [new file with mode: 0644]
js/modernizr/test/browser/src/nativeTestProps.js [new file with mode: 0644]
js/modernizr/test/browser/src/omPrefixes.js [new file with mode: 0644]
js/modernizr/test/browser/src/prefixed.js [new file with mode: 0644]
js/modernizr/test/browser/src/prefixedCSS.js [new file with mode: 0644]
js/modernizr/test/browser/src/prefixes.js [new file with mode: 0644]
js/modernizr/test/browser/src/roundedEquals.js [new file with mode: 0644]
js/modernizr/test/browser/src/setClasses.js [new file with mode: 0644]
js/modernizr/test/browser/src/slice.js [new file with mode: 0644]
js/modernizr/test/browser/src/testAllProps.js [new file with mode: 0644]
js/modernizr/test/browser/src/testDOMProps.js [new file with mode: 0644]
js/modernizr/test/browser/src/testProp.js [new file with mode: 0644]
js/modernizr/test/browser/src/testProps.js [new file with mode: 0644]
js/modernizr/test/browser/src/testPropsAll.js [new file with mode: 0644]
js/modernizr/test/browser/src/testRunner.js [new file with mode: 0644]
js/modernizr/test/browser/src/testStyles.js [new file with mode: 0644]
js/modernizr/test/browser/src/testXhrType.js [new file with mode: 0644]
js/modernizr/test/browser/src/tests.js [new file with mode: 0644]
js/modernizr/test/browser/src/toStringFn.js [new file with mode: 0644]
js/modernizr/test/browser/svgUnit.js [new file with mode: 0644]
js/modernizr/test/cleanup.js [new file with mode: 0644]
js/modernizr/test/js/lib/sinon.js [new file with mode: 0644]
js/modernizr/test/js/lib/uaparser.js
js/modernizr/test/mocks/lib/build-query.js [new file with mode: 0644]
js/modernizr/test/mocks/lib/metadata.js [new file with mode: 0644]
js/modernizr/test/node/lib/build.js [new file with mode: 0644]
js/modernizr/test/node/lib/cli.js [new file with mode: 0644]
js/modernizr/test/node/lib/metadata.js [new file with mode: 0644]
js/modernizr/test/node/lib/options.js [new file with mode: 0644]
js/modernizr/test/universal/lib/build-hash.js [new file with mode: 0644]
js/modernizr/test/universal/lib/generate-banner.js [new file with mode: 0644]
scss/_blog.scss
single.php

index 22dc2db..ec9e73d 100644 (file)
@@ -7112,7 +7112,8 @@ input[type="submit"].blogbutton {
     #blog-posts-over article .entry-header .entry-title {
       margin-bottom: 0; }
     #blog-posts-over article .entry-header .meta.date {
-      font-family: "Josefin Sans"; }
+      font-family: "Josefin Sans";
+      color: grey; }
 
 /*#searchform div input &[type="text"] {
     width: 95%;
index 3036231..7d9d0c4 100644 (file)
@@ -65,6 +65,6 @@
                "../bower_components/foundation/scss/foundation/components/_global.scss"
        ],
        "sourcesContent": [],
-       "mappings": "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",
+       "mappings": "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",
        "names": []
 }
\ No newline at end of file
diff --git a/js/modernizr/Gruntfile.js b/js/modernizr/Gruntfile.js
new file mode 100644 (file)
index 0000000..b426544
--- /dev/null
@@ -0,0 +1,247 @@
+/*global module */
+
+var browsers = require('./test/browser/sauce-browsers.json');
+
+module.exports = function(grunt) {
+  'use strict';
+
+  // Load grunt dependencies
+  require('load-grunt-tasks')(grunt);
+
+  var browserTests = grunt.file.expand([
+    'test/universal/**/*.js',
+    'test/browser/**/*.js',
+    '!test/browser/setup.js',
+    '!test/browser/integration/*.js'
+  ]);
+
+  grunt.initConfig({
+    env: {
+      nodeTests: [
+        'test/universal/**/*.js',
+        'test/node/**/*.js'
+      ],
+      browserTests: browserTests,
+      coverage: {
+        APP_DIR_FOR_CODE_COVERAGE: 'test/coverage/instrument',
+        urls: [
+          'http://localhost:9999/test/unit.html',
+          'http://localhost:9999/test/index.html'
+        ]
+      }
+    },
+    generate: {
+      dest: './dist/modernizr-build.js'
+    },
+    copy: {
+      'gh-pages': {
+        files: [
+          {
+            expand: true,
+            src: [
+              './**/*',
+              '!./test/coverage/**',
+              '!./node_modules/*grunt-*/**',
+              '!./node_modules/**/node_modules/**'
+            ],
+            dest: 'gh-pages'
+          }
+        ]
+      }
+    },
+    jscs: {
+      src: [
+        'Gruntfile.js',
+        'src/*.js',
+        'lib/*.js',
+        'test/**/*.js',
+        'feature-detects/**/*.js',
+        '!src/html5printshiv.js',
+        '!test/coverage/**/*.js',
+        '!test/js/lib/**/*.js',
+        '!src/html5shiv.js'
+      ]
+    },
+    jshint: {
+      options: {
+        jshintrc: true,
+        ignores: [
+          'src/html5printshiv.js',
+          'src/html5shiv.js'
+        ]
+      },
+      files: [
+        'Gruntfile.js',
+        'src/*.js',
+        'lib/*.js',
+        'feature-detects/**/*.js'
+      ],
+      tests: {
+        options: {
+          jshintrc: true
+        },
+        files: {
+          src: [
+            '<%= env.nodeTests%>',
+            '<%= env.browserTests %>',
+            'test/browser/setup.js',
+            'test/browser/integration/*.js'
+          ]
+        }
+      }
+    },
+    clean: {
+      dist: [
+        'dist',
+        'test/coverage',
+        'test/*.html',
+        'gh-pages'
+      ]
+    },
+    jade: {
+      compile: {
+        options: {
+          data: {
+            unitTests: browserTests,
+            integrationTests: grunt.file.expand(['test/browser/integration/*.js'])
+          }
+        },
+        files: {
+          'test/unit.html': 'test/browser/unit.jade',
+          'test/iframe.html': 'test/browser/iframe.jade',
+          'test/index.html': 'test/browser/integration.jade'
+        }
+      }
+    },
+    connect: {
+      server: {
+        options: {
+          middleware: function(connect, options) {
+            return [
+              function(req, res, next) {
+                // catchall middleware used in testing
+                var ua = req.headers['user-agent'];
+
+                // record code coverage results from browsers
+                if (req.url == '/coverage/client' && req.method == 'POST') {
+                  var name = encodeURI(ua.replace(/\//g, '-'));
+                  var body = '';
+
+                  req.on('data', function(data) {
+                    body = body + data;
+                  });
+
+                  req.on('end', function() {
+                    grunt.file.write('test/coverage/reports/' + name + '.json', body);
+                    res.end();
+                  });
+
+                  return;
+                }
+
+                // redirect requests form the `require`d components to their instrumented versions
+                if (req.url.match(/^\/(src|lib)\//)) {
+                  req.url = '/test/coverage/instrument' + req.url;
+                }
+
+                next();
+              },
+              connect.static(options.base)
+            ];
+          },
+          base: '',
+          port: 9999
+        }
+      }
+    },
+    'saucelabs-custom': {
+      all: {
+        options: {
+          urls:  '<%= env.coverage.urls %>',
+          testname: process.env.CI_BUILD_NUMBER || 'Modernizr Test',
+          browsers: browsers,
+          maxRetries: 3
+        }
+      }
+    },
+    mocha: {
+      test: {
+        options: {
+          urls: '<%= env.coverage.urls %>',
+          log: true
+        },
+      },
+    },
+    // `mocha` runs browser tests, `mochaTest` runs node tests
+    mochaTest: {
+      test: {
+        options: {
+          reporter: 'dot'
+        },
+        src: ['<%= env.nodeTests%>']
+      }
+    },
+    instrument: {
+      files: [
+        'src/**/*.js',
+        'lib/**/*.js'
+      ],
+      options: {
+        basePath: 'test/coverage/instrument/'
+      }
+    },
+    storeCoverage: {
+      options: {
+        dir: 'test/coverage/reports'
+      }
+    },
+    makeReport: {
+      src: 'test/coverage/reports/**/*.json',
+      options: {
+        type: 'lcov',
+        dir: 'test/coverage/reports',
+        print: 'detail'
+      }
+    },
+    coveralls: {
+      all: {
+        src: 'test/coverage/reports/lcov.info',
+        options: {
+          force: true
+        }
+      }
+    }
+  });
+
+  grunt.registerMultiTask('generate', 'Create a version of Modernizr from Grunt', function() {
+    var done = this.async();
+    var config = require('./lib/config-all');
+    var modernizr = require('./lib/cli');
+    var dest = this.data;
+
+    modernizr.build(config, function(output) {
+      grunt.file.write(dest, output);
+      done();
+    });
+  });
+
+  grunt.registerTask('nodeTests', ['mochaTest']);
+
+  grunt.registerTask('browserTests', ['connect', 'mocha']);
+
+  grunt.registerTask('build', ['clean', 'generate']);
+
+  grunt.registerTask('lint', ['jshint', 'jscs']);
+
+  grunt.registerTask('default', ['lint', 'build']);
+
+  var tests = ['clean', 'lint', 'jade', 'instrument', 'env:coverage', 'nodeTests'];
+
+  if (process.env.APPVEYOR) {
+    grunt.registerTask('test', tests);
+  } else if (process.env.BROWSER_COVERAGE !== 'true') {
+    grunt.registerTask('test', tests.concat(['generate', 'browserTests']));
+  } else {
+    grunt.registerTask('test', tests.concat(['generate', 'storeCoverage', 'browserTests', 'saucelabs-custom', 'makeReport', 'coveralls']));
+  }
+};
diff --git a/js/modernizr/feature-detects/a/download.js b/js/modernizr/feature-detects/a/download.js
new file mode 100644 (file)
index 0000000..ef728e5
--- /dev/null
@@ -0,0 +1,19 @@
+/*!
+{
+  "name": "a[download] Attribute",
+  "property": "adownload",
+  "caniuse" : "download",
+  "tags": ["media", "attribute"],
+  "builderAliases": ["a_download"],
+  "notes": [{
+    "name": "WhatWG Reference",
+    "href": "http://developers.whatwg.org/links.html#downloading-resources"
+  }]
+}
+!*/
+/* DOC
+When used on an `<a>`, this attribute signifies that the resource it points to should be downloaded by the browser rather than navigating to it.
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('adownload', !window.externalHost && 'download' in createElement('a'));
+});
diff --git a/js/modernizr/feature-detects/ambientlight.js b/js/modernizr/feature-detects/ambientlight.js
new file mode 100644 (file)
index 0000000..0f9e579
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+{
+  "name": "Ambient Light Events",
+  "property": "ambientlight",
+  "notes": [{
+    "name": "W3C Ambient Light Events",
+    "href": "http://www.w3.org/TR/ambient-light/"
+  }]
+}
+!*/
+/* DOC
+Detects support for the API that provides information about the ambient light levels, as detected by the device's light detector, in terms of lux units.
+*/
+define(['Modernizr', 'hasEvent'], function(Modernizr, hasEvent) {
+  Modernizr.addTest('ambientlight', hasEvent('devicelight', window));
+});
diff --git a/js/modernizr/feature-detects/applicationcache.js b/js/modernizr/feature-detects/applicationcache.js
new file mode 100644 (file)
index 0000000..bec050a
--- /dev/null
@@ -0,0 +1,21 @@
+/*!
+{
+  "name": "Application Cache",
+  "property": "applicationcache",
+  "caniuse": "offline-apps",
+  "tags": ["storage", "offline"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en/docs/HTML/Using_the_application_cache"
+  }],
+  "polyfills": ["html5gears"]
+}
+!*/
+/* DOC
+Detects support for the Application Cache, for storing data to enable web-based applications run offline.
+
+The API has been [heavily criticized](http://alistapart.com/article/application-cache-is-a-douchebag) and discussions are underway to address this.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('applicationcache', 'applicationCache' in window);
+});
diff --git a/js/modernizr/feature-detects/audio.js b/js/modernizr/feature-detects/audio.js
new file mode 100644 (file)
index 0000000..d3e8776
--- /dev/null
@@ -0,0 +1,48 @@
+/*!
+{
+  "name" : "HTML5 Audio Element",
+  "property": "audio",
+  "tags" : ["html5", "audio", "media"]
+}
+!*/
+/* DOC
+Detects the audio element
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  // This tests evaluates support of the audio element, as well as
+  // testing what types of content it supports.
+  //
+  // We're using the Boolean constructor here, so that we can extend the value
+  // e.g.  Modernizr.audio     // true
+  //       Modernizr.audio.ogg // 'probably'
+  //
+  // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
+  //                     thx to NielsLeenheer and zcorpan
+
+  // Note: in some older browsers, "no" was a return value instead of empty string.
+  //   It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
+  //   It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5
+  Modernizr.addTest('audio', function() {
+    /* jshint -W053 */
+    var elem = createElement('audio');
+    var bool = false;
+
+    try {
+      if (bool = !!elem.canPlayType) {
+        bool      = new Boolean(bool);
+        bool.ogg  = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, '');
+        bool.mp3  = elem.canPlayType('audio/mpeg;')               .replace(/^no$/, '');
+        bool.opus  = elem.canPlayType('audio/ogg; codecs="opus"') .replace(/^no$/, '');
+
+        // Mimetypes accepted:
+        //   developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
+        //   bit.ly/iphoneoscodecs
+        bool.wav  = elem.canPlayType('audio/wav; codecs="1"')     .replace(/^no$/, '');
+        bool.m4a  = (elem.canPlayType('audio/x-m4a;')            ||
+                     elem.canPlayType('audio/aac;'))             .replace(/^no$/, '');
+      }
+    } catch (e) { }
+
+    return bool;
+  });
+});
diff --git a/js/modernizr/feature-detects/audio/loop.js b/js/modernizr/feature-detects/audio/loop.js
new file mode 100644 (file)
index 0000000..96a2d77
--- /dev/null
@@ -0,0 +1,13 @@
+/*!
+{
+  "name": "Audio Loop Attribute",
+  "property": "audioloop",
+  "tags": ["audio", "media"]
+}
+!*/
+/* DOC
+Detects if an audio element can automatically restart, once it has finished
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('audioloop', 'loop' in createElement('audio'));
+});
diff --git a/js/modernizr/feature-detects/audio/preload.js b/js/modernizr/feature-detects/audio/preload.js
new file mode 100644 (file)
index 0000000..7bd1caa
--- /dev/null
@@ -0,0 +1,13 @@
+/*!
+{
+  "name": "Audio Preload Attribute",
+  "property": "audiopreload",
+  "tags": ["audio", "media"]
+}
+!*/
+/* DOC
+Detects if audio can be downloaded in the background before it starts playing in the `<audio>` element
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('audiopreload', 'preload' in createElement('audio'));
+});
diff --git a/js/modernizr/feature-detects/audio/webaudio.js b/js/modernizr/feature-detects/audio/webaudio.js
new file mode 100644 (file)
index 0000000..8be1b9b
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+{
+  "name": "Web Audio API",
+  "property": "webaudio",
+  "caniuse": "audio-api",
+  "polyfills": ["xaudiojs", "dynamicaudiojs", "audiolibjs"],
+  "tags": ["audio", "media"],
+  "builderAliases": ["audio_webaudio_api"],
+  "authors": ["Addy Osmani"],
+  "notes": [{
+    "name": "W3 Specification",
+    "href": "https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html"
+  }]
+}
+!*/
+/* DOC
+Detects the older non standard webaudio API, (as opposed to the standards based AudioContext API)
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('webaudio', function() {
+    var prefixed = 'webkitAudioContext' in window;
+    var unprefixed = 'AudioContext' in window;
+
+    if (Modernizr._config.usePrefixes) {
+      return prefixed || unprefixed;
+    }
+    return unprefixed;
+  });
+});
diff --git a/js/modernizr/feature-detects/battery.js b/js/modernizr/feature-detects/battery.js
new file mode 100644 (file)
index 0000000..ac47fa9
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "Battery API",
+  "property": "batteryapi",
+  "aliases": ["battery-api"],
+  "builderAliases": ["battery_api"],
+  "tags": ["device", "media"],
+  "authors": ["Paul Sayre"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en/DOM/window.navigator.mozBattery"
+  }]
+}
+!*/
+/* DOC
+Detect support for the Battery API, for accessing information about the system's battery charge level.
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('batteryapi', !!prefixed('battery', navigator), {aliases: ['battery-api']});
+});
diff --git a/js/modernizr/feature-detects/battery/lowbattery.js b/js/modernizr/feature-detects/battery/lowbattery.js
new file mode 100644 (file)
index 0000000..2ed15b5
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "Low Battery Level",
+  "property": "lowbattery",
+  "tags": ["hardware", "mobile"],
+  "builderAliases": ["battery_level"],
+  "authors": ["Paul Sayre"],
+  "notes": [{
+    "name": "MDN Docs",
+    "href": "http://developer.mozilla.org/en/DOM/window.navigator.mozBattery"
+  }]
+}
+!*/
+/* DOC
+Enable a developer to remove CPU intensive CSS/JS when battery is low
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('lowbattery', function() {
+    var minLevel = 0.20;
+    var battery = prefixed('battery', navigator);
+    return !!(battery && !battery.charging && battery.level <= minLevel);
+  });
+});
diff --git a/js/modernizr/feature-detects/blob.js b/js/modernizr/feature-detects/blob.js
new file mode 100644 (file)
index 0000000..1ebcf08
--- /dev/null
@@ -0,0 +1,28 @@
+/*!
+{
+  "name": "Blob constructor",
+  "property": "blobconstructor",
+  "aliases": ["blob-constructor"],
+  "builderAliases": ["blob_constructor"],
+  "caniuse": "blobbuilder",
+  "notes": [{
+    "name": "W3C spec",
+    "href": "http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob"
+  }],
+  "polyfills": ["blobjs"]
+}
+!*/
+/* DOC
+Detects support for the Blob constructor, for creating file-like objects of immutable, raw data.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('blobconstructor', function() {
+    try {
+      return !!new Blob();
+    } catch (e) {
+      return false;
+    }
+  }, {
+    aliases: ['blob-constructor']
+  });
+});
diff --git a/js/modernizr/feature-detects/canvas.js b/js/modernizr/feature-detects/canvas.js
new file mode 100644 (file)
index 0000000..149ab29
--- /dev/null
@@ -0,0 +1,21 @@
+/*!
+{
+  "name": "Canvas",
+  "property": "canvas",
+  "caniuse": "canvas",
+  "tags": ["canvas", "graphics"],
+  "polyfills": ["flashcanvas", "excanvas", "slcanvas", "fxcanvas"]
+}
+!*/
+/* DOC
+Detects support for the `<canvas>` element for 2D drawing.
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  // On the S60 and BB Storm, getContext exists, but always returns undefined
+  // so we actually have to call getContext() to verify
+  // github.com/Modernizr/Modernizr/issues/issue/97/
+  Modernizr.addTest('canvas', function() {
+    var elem = createElement('canvas');
+    return !!(elem.getContext && elem.getContext('2d'));
+  });
+});
diff --git a/js/modernizr/feature-detects/canvas/blending.js b/js/modernizr/feature-detects/canvas/blending.js
new file mode 100644 (file)
index 0000000..de87854
--- /dev/null
@@ -0,0 +1,35 @@
+/*!
+{
+  "name": "canvas blending support",
+  "property": "canvasblending",
+  "tags": ["canvas"],
+  "async" : false,
+  "notes": [{
+      "name": "HTML5 Spec",
+      "href": "https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blending"
+    },
+    {
+      "name": "Article",
+      "href": "http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas"
+    }]
+}
+!*/
+/* DOC
+Detects if Photoshop style blending modes are available in canvas.
+*/
+define(['Modernizr', 'createElement', 'test/canvas'], function(Modernizr, createElement) {
+
+  Modernizr.addTest('canvasblending', function() {
+    if (Modernizr.canvas === false) {
+      return false;
+    }
+    var ctx = createElement('canvas').getContext('2d');
+    // firefox 3 throws an error when setting an invalid `globalCompositeOperation`
+    try {
+      ctx.globalCompositeOperation = 'screen';
+    } catch (e) {}
+
+    return ctx.globalCompositeOperation === 'screen';
+  });
+
+});
diff --git a/js/modernizr/feature-detects/canvas/todataurl.js b/js/modernizr/feature-detects/canvas/todataurl.js
new file mode 100644 (file)
index 0000000..25bff37
--- /dev/null
@@ -0,0 +1,35 @@
+/*!
+{
+  "name": "canvas.toDataURL type support",
+  "property": ["todataurljpeg", "todataurlpng", "todataurlwebp"],
+  "tags": ["canvas"],
+  "builderAliases": ["canvas_todataurl_type"],
+  "async" : false,
+  "notes": [{
+    "name": "MDN article",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement.toDataURL"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement', 'test/canvas'], function(Modernizr, createElement) {
+
+  var canvas = createElement('canvas');
+
+  Modernizr.addTest('todataurljpeg', function() {
+    return !!Modernizr.canvas && canvas.toDataURL('image/jpeg').indexOf('data:image/jpeg') === 0;
+  });
+  Modernizr.addTest('todataurlpng', function() {
+    return !!Modernizr.canvas && canvas.toDataURL('image/png').indexOf('data:image/png') === 0;
+  });
+  Modernizr.addTest('todataurlwebp', function() {
+    var supports = false;
+
+    // firefox 3 throws an error when you use an "invalid" toDataUrl
+    try {
+      supports = !!Modernizr.canvas && canvas.toDataURL('image/webp').indexOf('data:image/webp') === 0;
+    } catch (e) {}
+
+    return supports;
+  });
+
+});
diff --git a/js/modernizr/feature-detects/canvas/winding.js b/js/modernizr/feature-detects/canvas/winding.js
new file mode 100644 (file)
index 0000000..2c9e777
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+{
+  "name": "canvas winding support",
+  "property": ["canvaswinding"],
+  "tags": ["canvas"],
+  "async" : false,
+  "notes": [{
+    "name": "Article",
+    "href": "http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/"
+  }]
+}
+!*/
+/* DOC
+Determines if winding rules, which controls if a path can go clockwise or counterclockwise
+*/
+define(['Modernizr', 'createElement', 'test/canvas'], function(Modernizr, createElement) {
+
+  Modernizr.addTest('canvaswinding', function() {
+    if (Modernizr.canvas === false) {
+      return false;
+    }
+    var ctx = createElement('canvas').getContext('2d');
+
+    ctx.rect(0, 0, 10, 10);
+    ctx.rect(2, 2, 6, 6);
+    return ctx.isPointInPath(5, 5, 'evenodd') === false;
+  });
+
+});
diff --git a/js/modernizr/feature-detects/canvastext.js b/js/modernizr/feature-detects/canvastext.js
new file mode 100644 (file)
index 0000000..ea2e1b5
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "Canvas text",
+  "property": "canvastext",
+  "caniuse": "canvas-text",
+  "tags": ["canvas", "graphics"],
+  "polyfills": ["canvastext"]
+}
+!*/
+/* DOC
+Detects support for the text APIs for `<canvas>` elements.
+*/
+define(['Modernizr', 'createElement', 'test/canvas'], function(Modernizr, createElement) {
+  Modernizr.addTest('canvastext',  function() {
+    if (Modernizr.canvas  === false) {
+      return false;
+    }
+    return typeof createElement('canvas').getContext('2d').fillText == 'function';
+  });
+});
index 6543666..8581546 100644 (file)
@@ -1,9 +1,30 @@
-// contentEditable
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#contenteditable
+/*!
+{
+  "name": "Content Editable",
+  "property": "contenteditable",
+  "caniuse": "contenteditable",
+  "notes": [{
+    "name": "WHATWG spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#contenteditable"
+  }]
+}
+!*/
+/* DOC
+Detects support for the `contenteditable` attribute of elements, allowing their DOM text contents to be edited directly by the user.
+*/
+define(['Modernizr', 'createElement', 'docElement'], function(Modernizr, createElement, docElement) {
+  Modernizr.addTest('contenteditable', function() {
+    // early bail out
+    if (!('contentEditable' in docElement)) {
+      return;
+    }
 
-// this is known to false positive in some mobile browsers
-// here is a whitelist of verified working browsers:
-// https://github.com/NielsLeenheer/html5test/blob/549f6eac866aa861d9649a0707ff2c0157895706/scripts/engine.js#L2083
+    // some mobile browsers (android < 3.0, iOS < 5) claim to support
+    // contentEditable, but but don't really. This test checks to see
+    // confirms whether or not it actually supports it.
 
-Modernizr.addTest('contenteditable',
-        'contentEditable' in document.documentElement);
+    var div = createElement('div');
+    div.contentEditable = true;
+    return div.contentEditable === 'true';
+  });
+});
index dd8182f..f4b897a 100644 (file)
@@ -1,11 +1,24 @@
-// http://www.w3.org/TR/html5/interactive-elements.html#context-menus
-// Demo at http://thewebrocks.com/demos/context-menu/
-Modernizr.addTest(
-  'contextmenu', 
-  ('contextMenu' in document.documentElement && 'HTMLMenuItemElement' in window) 
-);
-
-
-
-
-
+/*!
+{
+  "name": "Context menus",
+  "property": "contextmenu",
+  "caniuse": "menu",
+  "notes": [{
+    "name": "W3C spec",
+    "href": "http://www.w3.org/TR/html5/interactive-elements.html#context-menus"
+  },{
+    "name": "thewebrocks.com Demo",
+    "href": "http://thewebrocks.com/demos/context-menu/"
+  }],
+  "polyfills": ["jquery-contextmenu"]
+}
+!*/
+/* DOC
+Detects support for custom context menus.
+*/
+define(['Modernizr', 'docElement'], function(Modernizr, docElement) {
+  Modernizr.addTest(
+    'contextmenu',
+    ('contextMenu' in docElement && 'HTMLMenuItemElement' in window)
+  );
+});
index 6a2f9d4..0075b50 100644 (file)
@@ -1,15 +1,37 @@
+/*!
+{
+  "name": "Cookies",
+  "property": "cookies",
+  "tags": ["storage"],
+  "authors": ["tauren"]
+}
+!*/
+/* DOC
+Detects whether cookie support is enabled.
+*/
+define(['Modernizr'], function(Modernizr) {
+  // https://github.com/Modernizr/Modernizr/issues/191
 
-// by tauren
-// https://github.com/Modernizr/Modernizr/issues/191
+  Modernizr.addTest('cookies', function() {
+    // navigator.cookieEnabled cannot detect custom or nuanced cookie blocking
+    // configurations. For example, when blocking cookies via the Advanced
+    // Privacy Settings in IE9, it always returns true. And there have been
+    // issues in the past with site-specific exceptions.
+    // Don't rely on it.
 
-Modernizr.addTest('cookies', function () {
-  // Quick test if browser has cookieEnabled host property
-  if (navigator.cookieEnabled) return true;
-  // Create cookie
-  document.cookie = "cookietest=1";
-  var ret = document.cookie.indexOf("cookietest=") != -1;
-  // Delete cookie
-  document.cookie = "cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT";
-  return ret;
+    // try..catch because some in situations `document.cookie` is exposed but throws a
+    // SecurityError if you try to access it; e.g. documents created from data URIs
+    // or in sandboxed iframes (depending on flags/context)
+    try {
+      // Create cookie
+      document.cookie = 'cookietest=1';
+      var ret = document.cookie.indexOf('cookietest=') != -1;
+      // Delete cookie
+      document.cookie = 'cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT';
+      return ret;
+    }
+    catch (e) {
+      return false;
+    }
+  });
 });
-
index 286d717..27e7b88 100644 (file)
@@ -1,3 +1,19 @@
-// cors
-// By Theodoor van Donge
-Modernizr.addTest('cors', !!(window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest()));
\ No newline at end of file
+/*!
+{
+  "name": "Cross-Origin Resource Sharing",
+  "property": "cors",
+  "caniuse": "cors",
+  "authors": ["Theodoor van Donge"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS"
+  }],
+  "polyfills": ["pmxdr", "ppx", "flxhr"]
+}
+!*/
+/* DOC
+Detects support for Cross-Origin Resource Sharing: method of performing XMLHttpRequests across domains.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('cors', 'XMLHttpRequest' in window && 'withCredentials' in new XMLHttpRequest());
+});
diff --git a/js/modernizr/feature-detects/crypto/getrandomvalues.js b/js/modernizr/feature-detects/crypto/getrandomvalues.js
new file mode 100644 (file)
index 0000000..b0beba0
--- /dev/null
@@ -0,0 +1,35 @@
+/*!
+{
+  "name": "getRandomValues",
+  "property": "getrandomvalues",
+  "caniuse": "window.crypto.getRandomValues",
+  "tags": ["crypto"],
+  "authors": ["komachi"],
+  "notes": [{
+    "name": "W3C Editor’s Draft",
+    "href": "https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#RandomSource-method-getRandomValues"
+  }],
+  "polyfills": [
+    "polycrypt"
+  ]
+}
+!*/
+/* DOC
+Detects support for the window.crypto.getRandomValues for generate cryptographically secure random numbers
+*/
+define(['Modernizr', 'prefixed', 'is'], function(Modernizr, prefixed, is) {
+  // In Safari <=5.0 `window.crypto` exists (for some reason) but is `undefined`, so we have to check
+  // it’s truthy before checking for existence of `getRandomValues`
+  var crypto = prefixed('crypto', window);
+  var supportsGetRandomValues;
+
+  // Safari 6.0 supports crypto.getRandomValues, but does not return the array,
+  // which is required by the spec, so we need to actually check.
+  if (crypto && 'getRandomValues' in crypto && 'Uint32Array' in window) {
+    var array = new Uint32Array(10);
+    var values = crypto.getRandomValues(array);
+    supportsGetRandomValues = values && is(values[0], 'number');
+  }
+
+  Modernizr.addTest('getrandomvalues', !!supportsGetRandomValues);
+});
diff --git a/js/modernizr/feature-detects/css/all.js b/js/modernizr/feature-detects/css/all.js
new file mode 100644 (file)
index 0000000..98f5ca3
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+{
+  "name": "cssall",
+  "property": "cssall",
+  "notes": [{
+    "name": "Spec",
+    "href": "http://dev.w3.org/csswg/css-cascade/#all-shorthand"
+  }]
+}
+!*/
+/* DOC
+Detects support for the `all` css property, which is a shorthand to reset all css properties (except direction and unicode-bidi) to their original value
+*/
+
+define(['Modernizr', 'docElement'], function(Modernizr, docElement) {
+  Modernizr.addTest('cssall', 'all' in docElement.style);
+});
diff --git a/js/modernizr/feature-detects/css/animations.js b/js/modernizr/feature-detects/css/animations.js
new file mode 100644 (file)
index 0000000..c6e7d41
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "CSS Animations",
+  "property": "cssanimations",
+  "caniuse": "css-animation",
+  "polyfills": ["transformie", "csssandpaper"],
+  "tags": ["css"],
+  "warnings": ["Android < 4 will pass this test, but can only animate a single property at a time"],
+  "notes": [{
+    "name" : "Article: 'Dispelling the Android CSS animation myths'",
+    "href": "http://goo.gl/OGw5Gm"
+  }]
+}
+!*/
+/* DOC
+Detects whether or not elements can be animated using CSS
+*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('cssanimations', testAllProps('animationName', 'a', true));
+});
diff --git a/js/modernizr/feature-detects/css/appearance.js b/js/modernizr/feature-detects/css/appearance.js
new file mode 100644 (file)
index 0000000..f6bc7dd
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "Appearance",
+  "property": "appearance",
+  "caniuse": "css-appearance",
+  "tags": ["css"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-appearance"
+  },{
+    "name": "CSS-Tricks CSS Almanac: appearance",
+    "href": "http://css-tricks.com/almanac/properties/a/appearance/"
+  }]
+}
+!*/
+/* DOC
+Detects support for the `appearance` css property, which is used to make an
+element inherit the style of a standard user interface element. It can also be
+used to remove the default styles of an element, such as input and buttons.
+*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('appearance', testAllProps('appearance'));
+});
diff --git a/js/modernizr/feature-detects/css/backgroundblendmode.js b/js/modernizr/feature-detects/css/backgroundblendmode.js
new file mode 100644 (file)
index 0000000..15162fd
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "CSS Background Blend Mode",
+  "property": "backgroundblendmode",
+  "caniuse": "css-backgroundblendmode",
+  "tags": ["css"],
+  "notes": [
+    {
+      "name": "CSS Blend Modes could be the next big thing in Web Design",
+      "href": " https://medium.com/@bennettfeely/css-blend-modes-could-be-the-next-big-thing-in-web-design-6b51bf53743a"
+    }, {
+      "name": "Demo",
+      "href": "http://bennettfeely.com/gradients/"
+    }
+  ]
+}
+!*/
+/* DOC
+Detects the ability for the browser to composite backgrounds using blending modes similar to ones found in Photoshop or Illustrator.
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('backgroundblendmode', prefixed('backgroundBlendMode', 'text'));
+});
diff --git a/js/modernizr/feature-detects/css/backgroundcliptext.js b/js/modernizr/feature-detects/css/backgroundcliptext.js
new file mode 100644 (file)
index 0000000..10f3f89
--- /dev/null
@@ -0,0 +1,31 @@
+/*!
+{
+  "name": "CSS Background Clip Text",
+  "property": "backgroundcliptext",
+  "authors": ["ausi"],
+  "tags": ["css"],
+  "notes": [
+    {
+      "name": "CSS Tricks Article",
+      "href": "http://css-tricks.com/image-under-text/"
+    },
+    {
+      "name": "MDN Docs",
+      "href": "http://developer.mozilla.org/en/CSS/background-clip"
+    },
+    {
+      "name": "Related Github Issue",
+      "href": "http://github.com/Modernizr/Modernizr/issues/199"
+    }
+  ]
+}
+!*/
+/* DOC
+Detects the ability to control specifies whether or not an element's background
+extends beyond its border in CSS
+*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('backgroundcliptext', function() {
+    return testAllProps('backgroundClip', 'text');
+  });
+});
diff --git a/js/modernizr/feature-detects/css/backgroundposition-shorthand.js b/js/modernizr/feature-detects/css/backgroundposition-shorthand.js
new file mode 100644 (file)
index 0000000..9113a45
--- /dev/null
@@ -0,0 +1,33 @@
+/*!
+{
+  "name": "Background Position Shorthand",
+  "property": "bgpositionshorthand",
+  "tags": ["css"],
+  "builderAliases": ["css_backgroundposition_shorthand"],
+  "notes": [{
+    "name": "MDN Docs",
+    "href": "https://developer.mozilla.org/en/CSS/background-position"
+  }, {
+    "name": "W3 Spec",
+    "href": "http://www.w3.org/TR/css3-background/#background-position"
+  }, {
+    "name": "Demo",
+    "href": "http://jsfiddle.net/Blink/bBXvt/"
+  }]
+}
+!*/
+/* DOC
+Detects if you can use the shorthand method to define multiple parts of an
+element's background-position simultaniously.
+
+eg `background-position: right 10px bottom 10px`
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('bgpositionshorthand', function() {
+    var elem = createElement('a');
+    var eStyle = elem.style;
+    var val = 'right 10px bottom 10px';
+    eStyle.cssText = 'background-position: ' + val + ';';
+    return (eStyle.backgroundPosition === val);
+  });
+});
diff --git a/js/modernizr/feature-detects/css/backgroundposition-xy.js b/js/modernizr/feature-detects/css/backgroundposition-xy.js
new file mode 100644 (file)
index 0000000..24a82b9
--- /dev/null
@@ -0,0 +1,24 @@
+/*!
+{
+  "name": "Background Position XY",
+  "property": "bgpositionxy",
+  "tags": ["css"],
+  "builderAliases": ["css_backgroundposition_xy"],
+  "authors": ["Allan Lei", "Brandom Aaron"],
+  "notes": [{
+    "name": "Demo",
+    "href": "http://jsfiddle.net/allanlei/R8AYS/"
+  }, {
+    "name": "Adapted From",
+    "href": "https://github.com/brandonaaron/jquery-cssHooks/blob/master/bgpos.js"
+  }]
+}
+!*/
+/* DOC
+Detects the ability to control an element's background position using css
+*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('bgpositionxy', function() {
+    return testAllProps('backgroundPositionX', '3px', true) && testAllProps('backgroundPositionY', '5px', true);
+  });
+});
diff --git a/js/modernizr/feature-detects/css/backgroundrepeat.js b/js/modernizr/feature-detects/css/backgroundrepeat.js
new file mode 100644 (file)
index 0000000..3742c51
--- /dev/null
@@ -0,0 +1,27 @@
+/*!
+{
+  "name": "Background Repeat",
+  "property": ["bgrepeatspace", "bgrepeatround"],
+  "tags": ["css"],
+  "builderAliases": ["css_backgroundrepeat"],
+  "authors": ["Ryan Seddon"],
+  "notes": [{
+    "name": "MDN Docs",
+    "href": "http://developer.mozilla.org/en/CSS/background-repeat"
+  }, {
+    "name": "Test Page",
+    "href": "http://jsbin.com/uzesun/"
+  }, {
+    "name": "Demo",
+    "href": "http://jsfiddle.net/ryanseddon/yMLTQ/6/"
+  }]
+}
+!*/
+/* DOC
+Detects the ability to use round and space as properties for background-repeat
+*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  // Must value-test these
+  Modernizr.addTest('bgrepeatround', testAllProps('backgroundRepeat', 'round'));
+  Modernizr.addTest('bgrepeatspace', testAllProps('backgroundRepeat', 'space'));
+});
diff --git a/js/modernizr/feature-detects/css/backgroundsize.js b/js/modernizr/feature-detects/css/backgroundsize.js
new file mode 100644 (file)
index 0000000..acdd52d
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+{
+  "name": "Background Size",
+  "property": "backgroundsize",
+  "tags": ["css"],
+  "knownBugs": ["This will false positive in Opera Mini - http://github.com/Modernizr/Modernizr/issues/396"],
+  "notes": [{
+    "name": "Related Issue",
+    "href": "http://github.com/Modernizr/Modernizr/issues/396"
+  }]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('backgroundsize', testAllProps('backgroundSize', '100%', true));
+});
diff --git a/js/modernizr/feature-detects/css/backgroundsizecover.js b/js/modernizr/feature-detects/css/backgroundsizecover.js
new file mode 100644 (file)
index 0000000..f0a55e0
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+{
+  "name": "Background Size Cover",
+  "property": "bgsizecover",
+  "tags": ["css"],
+  "builderAliases": ["css_backgroundsizecover"],
+  "notes": [{
+    "name" : "MDN Docs",
+    "href": "http://developer.mozilla.org/en/CSS/background-size"
+  }]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  // Must test value, as this specifically tests the `cover` value
+  Modernizr.addTest('bgsizecover', testAllProps('backgroundSize', 'cover'));
+});
diff --git a/js/modernizr/feature-detects/css/borderimage.js b/js/modernizr/feature-detects/css/borderimage.js
new file mode 100644 (file)
index 0000000..34d68c8
--- /dev/null
@@ -0,0 +1,13 @@
+/*!
+{
+  "name": "Border Image",
+  "property": "borderimage",
+  "caniuse": "border-image",
+  "polyfills": ["css3pie"],
+   "knownBugs": ["Android < 2.0 is true, but has a broken implementation"],
+  "tags": ["css"]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('borderimage', testAllProps('borderImage', 'url() 1', true));
+});
diff --git a/js/modernizr/feature-detects/css/borderradius.js b/js/modernizr/feature-detects/css/borderradius.js
new file mode 100644 (file)
index 0000000..3e8450f
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+{
+  "name": "Border Radius",
+  "property": "borderradius",
+  "caniuse": "border-radius",
+  "polyfills": ["css3pie"],
+  "tags": ["css"],
+  "notes": [{
+    "name": "Comprehensive Compat Chart",
+    "href": "http://muddledramblings.com/table-of-css3-border-radius-compliance"
+  }]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('borderradius', testAllProps('borderRadius', '0px', true));
+});
diff --git a/js/modernizr/feature-detects/css/boxshadow.js b/js/modernizr/feature-detects/css/boxshadow.js
new file mode 100644 (file)
index 0000000..d342ea2
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+{
+  "name": "Box Shadow",
+  "property": "boxshadow",
+  "caniuse": "css-boxshadow",
+  "tags": ["css"],
+  "knownBugs": [
+    "WebOS false positives on this test.",
+    "The Kindle Silk browser false positives"
+  ]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('boxshadow', testAllProps('boxShadow', '1px 1px', true));
+});
diff --git a/js/modernizr/feature-detects/css/boxsizing.js b/js/modernizr/feature-detects/css/boxsizing.js
new file mode 100644 (file)
index 0000000..7038b6b
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "Box Sizing",
+  "property": "boxsizing",
+  "caniuse": "css3-boxsizing",
+  "polyfills": ["borderboxmodel", "boxsizingpolyfill", "borderbox"],
+  "tags": ["css"],
+  "builderAliases": ["css_boxsizing"],
+  "notes": [{
+    "name": "MDN Docs",
+    "href": "http://developer.mozilla.org/en/CSS/box-sizing"
+  },{
+    "name": "Related Github Issue",
+    "href": "http://github.com/Modernizr/Modernizr/issues/248"
+  }]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('boxsizing', testAllProps('boxSizing', 'border-box', true) && (document.documentMode === undefined || document.documentMode > 7));
+});
diff --git a/js/modernizr/feature-detects/css/calc.js b/js/modernizr/feature-detects/css/calc.js
new file mode 100644 (file)
index 0000000..2cf2d10
--- /dev/null
@@ -0,0 +1,30 @@
+/*!
+{
+  "name": "CSS Calc",
+  "property": "csscalc",
+  "caniuse": "calc",
+  "tags": ["css"],
+  "builderAliases": ["css_calc"],
+  "authors": ["@calvein"]
+}
+!*/
+/* DOC
+Method of allowing calculated values for length units. For example:
+
+```css
+//lem {
+  width: calc(100% - 3em);
+}
+```
+*/
+define(['Modernizr', 'createElement', 'prefixes'], function(Modernizr, createElement, prefixes) {
+  Modernizr.addTest('csscalc', function() {
+    var prop = 'width:';
+    var value = 'calc(10px);';
+    var el = createElement('a');
+
+    el.style.cssText = prop + prefixes.join(value + prop);
+
+    return !!el.style.length;
+  });
+});
diff --git a/js/modernizr/feature-detects/css/checked.js b/js/modernizr/feature-detects/css/checked.js
new file mode 100644 (file)
index 0000000..4541364
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "CSS :checked pseudo-selector",
+  "caniuse": "css-sel3",
+  "property": "checked",
+  "tags": ["css"],
+  "notes": [{
+    "name": "Related Github Issue",
+    "href": "https://github.com/Modernizr/Modernizr/pull/879"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement', 'testStyles'], function(Modernizr, createElement, testStyles) {
+  Modernizr.addTest('checked', function() {
+    return testStyles('#modernizr {position:absolute} #modernizr input {margin-left:10px} #modernizr :checked {margin-left:20px;display:block}', function(elem) {
+      var cb = createElement('input');
+      cb.setAttribute('type', 'checkbox');
+      cb.setAttribute('checked', 'checked');
+      elem.appendChild(cb);
+      return cb.offsetLeft === 20;
+    });
+  });
+});
diff --git a/js/modernizr/feature-detects/css/chunit.js b/js/modernizr/feature-detects/css/chunit.js
new file mode 100644 (file)
index 0000000..8bedcbf
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+{
+  "name": "CSS Font ch Units",
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "property": "csschunit",
+  "tags": ["css"],
+  "notes": [{
+    "name": "W3C Spec",
+    "href": "http://www.w3.org/TR/css3-values/#font-relative-lengths"
+  }]
+}
+!*/
+define(['Modernizr', 'modElem'], function(Modernizr, modElem) {
+  Modernizr.addTest('csschunit', function() {
+    var elemStyle = modElem.elem.style;
+    var supports;
+    try {
+      elemStyle.fontSize = '3ch';
+      supports = elemStyle.fontSize.indexOf('ch') !== -1;
+    } catch (e) {
+      supports = false;
+    }
+    return supports;
+  });
+});
diff --git a/js/modernizr/feature-detects/css/columns.js b/js/modernizr/feature-detects/css/columns.js
new file mode 100644 (file)
index 0000000..f1912cf
--- /dev/null
@@ -0,0 +1,45 @@
+/*!
+{
+  "name": "CSS Columns",
+  "property": "csscolumns",
+  "caniuse": "multicolumn",
+  "polyfills": ["css3multicolumnjs"],
+  "tags": ["css"]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+
+  (function() {
+
+    /* jshint -W053 */
+    Modernizr.addTest('csscolumns', function() {
+      var bool = false;
+      var test = testAllProps('columnCount');
+      try {
+        if (bool = !!test) {
+          bool = new Boolean(bool);
+        }
+      } catch (e) {}
+
+      return bool;
+    });
+
+    var props = ['Width', 'Span', 'Fill', 'Gap', 'Rule', 'RuleColor', 'RuleStyle', 'RuleWidth', 'BreakBefore', 'BreakAfter', 'BreakInside'];
+    var name, test;
+
+    for (var i = 0; i < props.length; i++) {
+      name = props[i].toLowerCase();
+      test = testAllProps('column' + props[i]);
+
+      // break-before, break-after & break-inside are not "column"-prefixed in spec
+      if (name === 'breakbefore' || name === 'breakafter' || name == 'breakinside') {
+        test = test || testAllProps(props[i]);
+      }
+
+      Modernizr.addTest('csscolumns.' + name, test);
+    }
+
+
+  })();
+
+});
diff --git a/js/modernizr/feature-detects/css/cubicbezierrange.js b/js/modernizr/feature-detects/css/cubicbezierrange.js
new file mode 100644 (file)
index 0000000..4a53911
--- /dev/null
@@ -0,0 +1,22 @@
+/*!
+{
+  "name": "CSS Cubic Bezier Range",
+  "property": "cubicbezierrange",
+  "tags": ["css"],
+  "builderAliases": ["css_cubicbezierrange"],
+  "doc" : null,
+  "authors": ["@calvein"],
+  "warnings": ["cubic-bezier values can't be > 1 for Webkit until [bug #45761](https://bugs.webkit.org/show_bug.cgi?id=45761) is fixed"],
+  "notes": [{
+    "name": "Comprehensive Compat Chart",
+    "href": "http://muddledramblings.com/table-of-css3-border-radius-compliance"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement', 'prefixes'], function(Modernizr, createElement, prefixes) {
+  Modernizr.addTest('cubicbezierrange', function() {
+    var el = createElement('a');
+    el.style.cssText = prefixes.join('transition-timing-function:cubic-bezier(1,0,0,1.1); ');
+    return !!el.style.length;
+  });
+});
diff --git a/js/modernizr/feature-detects/css/displayrunin.js b/js/modernizr/feature-detects/css/displayrunin.js
new file mode 100644 (file)
index 0000000..a82efef
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "CSS Display run-in",
+  "property": "display-runin",
+  "authors": ["alanhogan"],
+  "tags": ["css"],
+  "builderAliases": ["css_displayrunin"],
+  "notes": [{
+    "name": "CSS Tricks Article",
+    "href": "http://css-tricks.com/596-run-in/"
+  },{
+    "name": "Related Github Issue",
+    "href": "https://github.com/Modernizr/Modernizr/issues/198"
+  }]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('displayrunin', testAllProps('display', 'run-in'),
+    {aliases: ['display-runin']});
+});
diff --git a/js/modernizr/feature-detects/css/displaytable.js b/js/modernizr/feature-detects/css/displaytable.js
new file mode 100644 (file)
index 0000000..ebb4723
--- /dev/null
@@ -0,0 +1,27 @@
+/*!
+{
+  "name": "CSS Display table",
+  "property": "displaytable",
+  "caniuse": "css-table",
+  "authors": ["scottjehl"],
+  "tags": ["css"],
+  "builderAliases": ["css_displaytable"],
+  "notes": [{
+    "name": "Detects for all additional table display values",
+    "href": "http://pastebin.com/Gk9PeVaQ"
+  }]
+}
+!*/
+/* DOC
+`display: table` and `table-cell` test. (both are tested under one name `table-cell` )
+*/
+define(['Modernizr', 'testStyles'], function(Modernizr, testStyles) {
+  // If a document is in rtl mode this test will fail so we force ltr mode on the injeced
+  // element https://github.com/Modernizr/Modernizr/issues/716
+  testStyles('#modernizr{display: table; direction: ltr}#modernizr div{display: table-cell; padding: 10px}', function(elem) {
+    var ret;
+    var child = elem.childNodes;
+    ret = child[0].offsetLeft < child[1].offsetLeft;
+    Modernizr.addTest('displaytable', ret, {aliases: ['display-table']});
+  }, 2);
+});
diff --git a/js/modernizr/feature-detects/css/ellipsis.js b/js/modernizr/feature-detects/css/ellipsis.js
new file mode 100644 (file)
index 0000000..5b161ac
--- /dev/null
@@ -0,0 +1,14 @@
+/*!
+{
+  "name": "CSS text-overflow ellipsis",
+  "property": "ellipsis",
+  "caniuse": "text-overflow",
+  "polyfills": [
+    "text-overflow"
+  ],
+  "tags": ["css"]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('ellipsis', testAllProps('textOverflow', 'ellipsis'));
+});
diff --git a/js/modernizr/feature-detects/css/escape.js b/js/modernizr/feature-detects/css/escape.js
new file mode 100644 (file)
index 0000000..a26ed98
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "CSS.escape()",
+  "property": "cssescape",
+  "polyfills": [
+    "css-escape"
+  ],
+  "tags": [
+    "css",
+    "cssom"
+  ]
+}
+!*/
+/* DOC
+Tests for `CSS.escape()` support.
+*/
+define(['Modernizr'], function(Modernizr) {
+  var CSS = window.CSS;
+  Modernizr.addTest('cssescape', CSS ? typeof CSS.escape == 'function' : false);
+});
diff --git a/js/modernizr/feature-detects/css/exunit.js b/js/modernizr/feature-detects/css/exunit.js
new file mode 100644 (file)
index 0000000..781eee3
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+{
+  "name": "CSS Font ex Units",
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "property": "cssexunit",
+  "tags": ["css"],
+  "notes": [{
+    "name": "W3C Spec",
+    "href": "http://www.w3.org/TR/css3-values/#font-relative-lengths"
+  }]
+}
+!*/
+define(['Modernizr', 'modElem'], function(Modernizr, modElem) {
+  Modernizr.addTest('cssexunit', function() {
+    var elemStyle = modElem.elem.style;
+    var supports;
+    try {
+      elemStyle.fontSize = '3ex';
+      supports = elemStyle.fontSize.indexOf('ex') !== -1;
+    } catch (e) {
+      supports = false;
+    }
+    return supports;
+  });
+});
diff --git a/js/modernizr/feature-detects/css/filters.js b/js/modernizr/feature-detects/css/filters.js
new file mode 100644 (file)
index 0000000..3e22b27
--- /dev/null
@@ -0,0 +1,28 @@
+/*!
+{
+  "name": "CSS Filters",
+  "property": "cssfilters",
+  "caniuse": "css-filters",
+  "polyfills": ["polyfilter"],
+  "tags": ["css"],
+  "builderAliases": ["css_filters"],
+  "notes": [{
+    "name": "MDN article on CSS filters",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/filter"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement', 'prefixes', 'testAllProps', 'test/css/supports'], function(Modernizr, createElement, testAllProps, prefixes) {
+  Modernizr.addTest('cssfilters', function() {
+    if (Modernizr.supports) {
+      return testAllProps('filter', 'blur(2px)');
+    } else {
+      var el = createElement('a');
+      el.style.cssText = prefixes.join('filter:blur(2px); ');
+      // https://github.com/Modernizr/Modernizr/issues/615
+      // documentMode is needed for false positives in oldIE, please see issue above
+      return !!el.style.length && ((document.documentMode === undefined || document.documentMode > 9));
+    }
+  });
+
+});
diff --git a/js/modernizr/feature-detects/css/flexbox.js b/js/modernizr/feature-detects/css/flexbox.js
new file mode 100644 (file)
index 0000000..d1a0793
--- /dev/null
@@ -0,0 +1,21 @@
+/*!
+{
+  "name": "Flexbox",
+  "property": "flexbox",
+  "caniuse": "flexbox",
+  "tags": ["css"],
+  "notes": [{
+    "name": "The _new_ flexbox",
+    "href": "http://dev.w3.org/csswg/css3-flexbox"
+  }],
+  "warnings": [
+    "A `true` result for this detect does not imply that the `flex-wrap` property is supported; see the `flexwrap` detect."
+  ]
+}
+!*/
+/* DOC
+Detects support for the Flexible Box Layout model, a.k.a. Flexbox, which allows easy manipulation of layout order and sizing within a container.
+*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('flexbox', testAllProps('flexBasis', '1px', true));
+});
diff --git a/js/modernizr/feature-detects/css/flexboxlegacy.js b/js/modernizr/feature-detects/css/flexboxlegacy.js
new file mode 100644 (file)
index 0000000..f125b91
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+{
+  "name": "Flexbox (legacy)",
+  "property": "flexboxlegacy",
+  "tags": ["css"],
+  "polyfills": ["flexie"],
+  "notes": [{
+    "name": "The _old_ flexbox",
+    "href": "http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/"
+  }]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('flexboxlegacy', testAllProps('boxDirection', 'reverse', true));
+});
diff --git a/js/modernizr/feature-detects/css/flexboxtweener.js b/js/modernizr/feature-detects/css/flexboxtweener.js
new file mode 100644 (file)
index 0000000..e8448aa
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+{
+  "name": "Flexbox (tweener)",
+  "property": "flexboxtweener",
+  "tags": ["css"],
+  "polyfills": ["flexie"],
+  "notes": [{
+    "name": "The _inbetween_ flexbox",
+    "href": "http://www.w3.org/TR/2011/WD-css3-flexbox-20111129/"
+  }],
+  "warnings": ["This represents an old syntax, not the latest standard syntax."]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('flexboxtweener', testAllProps('flexAlign', 'end', true));
+});
diff --git a/js/modernizr/feature-detects/css/flexwrap.js b/js/modernizr/feature-detects/css/flexwrap.js
new file mode 100644 (file)
index 0000000..3feb88e
--- /dev/null
@@ -0,0 +1,31 @@
+/*!
+{
+  "name": "Flex Line Wrapping",
+  "property": "flexwrap",
+  "tags": ["css", "flexbox"],
+  "notes": [{
+    "name": "W3C Flexible Box Layout spec",
+    "href": "http://dev.w3.org/csswg/css3-flexbox"
+  }],
+  "warnings": [
+    "Does not imply a modern implementation – see documentation."
+  ]
+}
+!*/
+/* DOC
+Detects support for the `flex-wrap` CSS property, part of Flexbox, which isn’t present in all Flexbox implementations (notably Firefox).
+
+This featured in both the 'tweener' syntax (implemented by IE10) and the 'modern' syntax (implemented by others). This detect will return `true` for either of these implementations, as long as the `flex-wrap` property is supported. So to ensure the modern syntax is supported, use together with `Modernizr.flexbox`:
+
+```javascript
+if (Modernizr.flexbox && Modernizr.flexwrap) {
+  // Modern Flexbox with `flex-wrap` supported
+}
+else {
+  // Either old Flexbox syntax, or `flex-wrap` not supported
+}
+```
+*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('flexwrap', testAllProps('flexWrap', 'wrap', true));
+});
diff --git a/js/modernizr/feature-detects/css/fontface.js b/js/modernizr/feature-detects/css/fontface.js
new file mode 100644 (file)
index 0000000..5c4171a
--- /dev/null
@@ -0,0 +1,49 @@
+/*!
+{
+  "name": "@font-face",
+  "property": "fontface",
+  "authors": ["Diego Perini", "Mat Marquis"],
+  "tags": ["css"],
+  "knownBugs": [
+    "False Positive: WebOS http://github.com/Modernizr/Modernizr/issues/342",
+    "False Postive: WP7 http://github.com/Modernizr/Modernizr/issues/538"
+  ],
+  "notes": [{
+    "name": "@font-face detection routine by Diego Perini",
+    "href": "http://javascript.nwbox.com/CSSSupport/"
+  },{
+    "name": "Filament Group @font-face compatibility research",
+    "href": "https://docs.google.com/presentation/d/1n4NyG4uPRjAA8zn_pSQ_Ket0RhcWC6QlZ6LMjKeECo0/edit#slide=id.p"
+  },{
+    "name": "Filament Grunticon/@font-face device testing results",
+    "href": "https://docs.google.com/spreadsheet/ccc?key=0Ag5_yGvxpINRdHFYeUJPNnZMWUZKR2ItMEpRTXZPdUE#gid=0"
+  },{
+    "name": "CSS fonts on Android",
+    "href": "http://stackoverflow.com/questions/3200069/css-fonts-on-android"
+  },{
+    "name": "@font-face and Android",
+    "href": "http://archivist.incutio.com/viewlist/css-discuss/115960"
+  }]
+}
+!*/
+define(['Modernizr', 'testStyles'], function(Modernizr, testStyles) {
+  var blacklist = (function() {
+    var ua = navigator.userAgent;
+    var wkvers = ua.match(/applewebkit\/([0-9]+)/gi) && parseFloat(RegExp.$1);
+    var webos = ua.match(/w(eb)?osbrowser/gi);
+    var wppre8 = ua.match(/windows phone/gi) && ua.match(/iemobile\/([0-9])+/gi) && parseFloat(RegExp.$1) >= 9;
+    var oldandroid = wkvers < 533 && ua.match(/android/gi);
+    return webos || oldandroid || wppre8;
+  }());
+  if (blacklist) {
+    Modernizr.addTest('fontface', false);
+  } else {
+    testStyles('@font-face {font-family:"font";src:url("https://")}', function(node, rule) {
+      var style = document.getElementById('smodernizr');
+      var sheet = style.sheet || style.styleSheet;
+      var cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : '';
+      var bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0;
+      Modernizr.addTest('fontface', bool);
+    });
+  }
+});
diff --git a/js/modernizr/feature-detects/css/generatedcontent.js b/js/modernizr/feature-detects/css/generatedcontent.js
new file mode 100644 (file)
index 0000000..a5105a3
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "CSS Generated Content",
+  "property": "generatedcontent",
+  "tags": ["css"],
+  "warnings": ["Android won't return correct height for anything below 7px #738"],
+  "notes": [{
+    "name": "W3C CSS Selectors Level 3 spec",
+    "href": "http://www.w3.org/TR/css3-selectors/#gen-content"
+  },{
+    "name": "MDN article on :before",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/::before"
+  },{
+    "name": "MDN article on :after",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/::before"
+  }]
+}
+!*/
+define(['Modernizr', 'testStyles'], function(Modernizr, testStyles) {
+  testStyles('#modernizr{font:0/0 a}#modernizr:after{content:":)";visibility:hidden;font:7px/1 a}', function(node) {
+    Modernizr.addTest('generatedcontent', node.offsetHeight >= 7);
+  });
+});
diff --git a/js/modernizr/feature-detects/css/gradients.js b/js/modernizr/feature-detects/css/gradients.js
new file mode 100644 (file)
index 0000000..c65a63b
--- /dev/null
@@ -0,0 +1,45 @@
+/*!
+{
+  "name": "CSS Gradients",
+  "caniuse": "css-gradients",
+  "property": "cssgradients",
+  "tags": ["css"],
+  "knownBugs": ["False-positives on webOS (https://github.com/Modernizr/Modernizr/issues/202)"],
+  "notes": [{
+    "name": "Webkit Gradient Syntax",
+    "href": "http://webkit.org/blog/175/introducing-css-gradients/"
+  },{
+    "name": "Mozilla Linear Gradient Syntax",
+    "href": "http://developer.mozilla.org/en/CSS/-moz-linear-gradient"
+  },{
+    "name": "Mozilla Radial Gradient Syntax",
+    "href": "http://developer.mozilla.org/en/CSS/-moz-radial-gradient"
+  },{
+    "name": "W3C Gradient Spec",
+    "href": "dev.w3.org/csswg/css3-images/#gradients-"
+  }]
+}
+!*/
+define(['Modernizr', 'prefixes', 'createElement'], function(Modernizr, prefixes, createElement) {
+
+  Modernizr.addTest('cssgradients', function() {
+
+    var str1 = 'background-image:';
+    var str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));';
+    var str3 = 'linear-gradient(left top,#9f9, white);';
+
+    // standard syntax             // trailing 'background-image:'
+    var css = str1 + prefixes.join(str3 + str1).slice(0, -str1.length);
+    if (Modernizr._config.usePrefixes) {
+    // legacy webkit syntax (FIXME: remove when syntax not in use anymore)
+      css += str1 + '-webkit-' + str2;
+    }
+
+    var elem = createElement('a');
+    var style = elem.style;
+    style.cssText = css;
+
+    // IE6 returns undefined so cast to string
+    return ('' + style.backgroundImage).indexOf('gradient') > -1;
+  });
+});
diff --git a/js/modernizr/feature-detects/css/hsla.js b/js/modernizr/feature-detects/css/hsla.js
new file mode 100644 (file)
index 0000000..75cf0b7
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+{
+  "name": "CSS HSLA Colors",
+  "caniuse": "css3-colors",
+  "property": "hsla",
+  "tags": ["css"]
+}
+!*/
+define(['Modernizr', 'createElement', 'contains'], function(Modernizr, createElement, contains) {
+  Modernizr.addTest('hsla', function() {
+    var style = createElement('a').style;
+    style.cssText = 'background-color:hsla(120,40%,100%,.5)';
+    return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
+  });
+});
diff --git a/js/modernizr/feature-detects/css/hyphens.js b/js/modernizr/feature-detects/css/hyphens.js
new file mode 100644 (file)
index 0000000..bb36611
--- /dev/null
@@ -0,0 +1,223 @@
+/*!
+{
+  "name": "CSS Hyphens",
+  "caniuse": "css-hyphens",
+  "property": ["csshyphens", "softhyphens", "softhyphensfind"],
+  "tags": ["css"],
+  "builderAliases": ["css_hyphens"],
+  "async" : true,
+  "authors": ["David Newton"],
+  "warnings": [
+    "These tests currently require document.body to be present",
+    "If loading Hyphenator.js via yepnope, be cautious of issue 158: http://code.google.com/p/hyphenator/issues/detail?id=158",
+    "This is very large – only include it if you absolutely need it"
+    ],
+  "notes": [{
+    "name": "The Current State of Hyphenation on the Web.",
+    "href": "http://davidnewton.ca/the-current-state-of-hyphenation-on-the-web"
+  },{
+    "name": "Hyphenation Test Page",
+    "href": "http://davidnewton.ca/demos/hyphenation/test.html"
+  },{
+    "name": "Hyphenation is Language Specific",
+    "href": " http://code.google.com/p/hyphenator/source/diff?spec=svn975&r=975&format=side&path=/trunk/Hyphenator.js#sc_svn975_313"
+  },{
+    "name": "Related Modernizr Issue",
+    "href": "https://github.com/Modernizr/Modernizr/issues/312"
+  }]
+}
+!*/
+define(['Modernizr', 'prefixes', 'createElement', 'testAllProps', 'addTest'], function(Modernizr, prefixes, createElement, testAllProps, addTest) {
+
+  Modernizr.addAsyncTest(function() {
+    var waitTime = 300;
+    setTimeout(runHyphenTest, waitTime);
+    // Wait 1000ms so we can hope for document.body
+    function runHyphenTest() {
+      if (!document.body && !document.getElementsByTagName('body')[0]) {
+        setTimeout(runHyphenTest, waitTime);
+        return;
+      }
+
+      // functional test of adding hyphens:auto
+      function test_hyphens_css() {
+        try {
+          /* create a div container and a span within that
+           * these have to be appended to document.body, otherwise some browsers can give false negative */
+          var div = createElement('div');
+          var span = createElement('span');
+          var divStyle = div.style;
+          var spanHeight = 0;
+          var spanWidth = 0;
+          var result = false;
+          var firstChild = document.body.firstElementChild || document.body.firstChild;
+
+          div.appendChild(span);
+          span.innerHTML = 'Bacon ipsum dolor sit amet jerky velit in culpa hamburger et. Laborum dolor proident, enim dolore duis commodo et strip steak. Salami anim et, veniam consectetur dolore qui tenderloin jowl velit sirloin. Et ad culpa, fatback cillum jowl ball tip ham hock nulla short ribs pariatur aute. Pig pancetta ham bresaola, ut boudin nostrud commodo flank esse cow tongue culpa. Pork belly bresaola enim pig, ea consectetur nisi. Fugiat officia turkey, ea cow jowl pariatur ullamco proident do laborum velit sausage. Magna biltong sint tri-tip commodo sed bacon, esse proident aliquip. Ullamco ham sint fugiat, velit in enim sed mollit nulla cow ut adipisicing nostrud consectetur. Proident dolore beef ribs, laborum nostrud meatball ea laboris rump cupidatat labore culpa. Shankle minim beef, velit sint cupidatat fugiat tenderloin pig et ball tip. Ut cow fatback salami, bacon ball tip et in shank strip steak bresaola. In ut pork belly sed mollit tri-tip magna culpa veniam, short ribs qui in andouille ham consequat. Dolore bacon t-bone, velit short ribs enim strip steak nulla. Voluptate labore ut, biltong swine irure jerky. Cupidatat excepteur aliquip salami dolore. Ball tip strip steak in pork dolor. Ad in esse biltong. Dolore tenderloin exercitation ad pork loin t-bone, dolore in chicken ball tip qui pig. Ut culpa tongue, sint ribeye dolore ex shank voluptate hamburger. Jowl et tempor, boudin pork chop labore ham hock drumstick consectetur tri-tip elit swine meatball chicken ground round. Proident shankle mollit dolore. Shoulder ut duis t-bone quis reprehenderit. Meatloaf dolore minim strip steak, laboris ea aute bacon beef ribs elit shank in veniam drumstick qui. Ex laboris meatball cow tongue pork belly. Ea ball tip reprehenderit pig, sed fatback boudin dolore flank aliquip laboris eu quis. Beef ribs duis beef, cow corned beef adipisicing commodo nisi deserunt exercitation. Cillum dolor t-bone spare ribs, ham hock est sirloin. Brisket irure meatloaf in, boudin pork belly sirloin ball tip. Sirloin sint irure nisi nostrud aliqua. Nostrud nulla aute, enim officia culpa ham hock. Aliqua reprehenderit dolore sunt nostrud sausage, ea boudin pork loin ut t-bone ham tempor. Tri-tip et pancetta drumstick laborum. Ham hock magna do nostrud in proident. Ex ground round fatback, venison non ribeye in.';
+
+          document.body.insertBefore(div, firstChild);
+
+          /* get size of unhyphenated text */
+          divStyle.cssText = 'position:absolute;top:0;left:0;width:5em;text-align:justify;text-justification:newspaper;';
+          spanHeight = span.offsetHeight;
+          spanWidth = span.offsetWidth;
+
+          /* compare size with hyphenated text */
+          divStyle.cssText = 'position:absolute;top:0;left:0;width:5em;text-align:justify;' +
+            'text-justification:newspaper;' +
+            prefixes.join('hyphens:auto; ');
+
+          result = (span.offsetHeight != spanHeight || span.offsetWidth != spanWidth);
+
+          /* results and cleanup */
+          document.body.removeChild(div);
+          div.removeChild(span);
+
+          return result;
+        } catch (e) {
+          return false;
+        }
+      }
+
+      // for the softhyphens test
+      function test_hyphens(delimiter, testWidth) {
+        try {
+          /* create a div container and a span within that
+           * these have to be appended to document.body, otherwise some browsers can give false negative */
+          var div = createElement('div');
+          var span = createElement('span');
+          var divStyle = div.style;
+          var spanSize = 0;
+          var result = false;
+          var result1 = false;
+          var result2 = false;
+          var firstChild = document.body.firstElementChild || document.body.firstChild;
+
+          divStyle.cssText = 'position:absolute;top:0;left:0;overflow:visible;width:1.25em;';
+          div.appendChild(span);
+          document.body.insertBefore(div, firstChild);
+
+
+          /* get height of unwrapped text */
+          span.innerHTML = 'mm';
+          spanSize = span.offsetHeight;
+
+          /* compare height w/ delimiter, to see if it wraps to new line */
+          span.innerHTML = 'm' + delimiter + 'm';
+          result1 = (span.offsetHeight > spanSize);
+
+          /* if we're testing the width too (i.e. for soft-hyphen, not zws),
+           * this is because tested Blackberry devices will wrap the text but not display the hyphen */
+          if (testWidth) {
+            /* get width of wrapped, non-hyphenated text */
+            span.innerHTML = 'm<br />m';
+            spanSize = span.offsetWidth;
+
+            /* compare width w/ wrapped w/ delimiter to see if hyphen is present */
+            span.innerHTML = 'm' + delimiter + 'm';
+            result2 = (span.offsetWidth > spanSize);
+          } else {
+            result2 = true;
+          }
+
+          /* results and cleanup */
+          if (result1 === true && result2 === true) { result = true; }
+          document.body.removeChild(div);
+          div.removeChild(span);
+
+          return result;
+        } catch (e) {
+          return false;
+        }
+      }
+
+      // testing if in-browser Find functionality will work on hyphenated text
+      function test_hyphens_find(delimiter) {
+        try {
+          /* create a dummy input for resetting selection location, and a div container
+           * these have to be appended to document.body, otherwise some browsers can give false negative
+           * div container gets the doubled testword, separated by the delimiter
+           * Note: giving a width to div gives false positive in iOS Safari */
+          var dummy = createElement('input');
+          var div = createElement('div');
+          var testword = 'lebowski';
+          var result = false;
+          var textrange;
+          var firstChild = document.body.firstElementChild || document.body.firstChild;
+
+          div.innerHTML = testword + delimiter + testword;
+
+          document.body.insertBefore(div, firstChild);
+          document.body.insertBefore(dummy, div);
+
+
+          /* reset the selection to the dummy input element, i.e. BEFORE the div container
+           *   stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area */
+          if (dummy.setSelectionRange) {
+            dummy.focus();
+            dummy.setSelectionRange(0, 0);
+          } else if (dummy.createTextRange) {
+            textrange = dummy.createTextRange();
+            textrange.collapse(true);
+            textrange.moveEnd('character', 0);
+            textrange.moveStart('character', 0);
+            textrange.select();
+          }
+
+          /* try to find the doubled testword, without the delimiter */
+          if (window.find) {
+            result = window.find(testword + testword);
+          } else {
+            try {
+              textrange = window.self.document.body.createTextRange();
+              result = textrange.findText(testword + testword);
+            } catch (e) {
+              result = false;
+            }
+          }
+
+          document.body.removeChild(div);
+          document.body.removeChild(dummy);
+
+          return result;
+        } catch (e) {
+          return false;
+        }
+      }
+
+      addTest('csshyphens', function() {
+
+        if (!testAllProps('hyphens', 'auto', true)) {
+          return false;
+        }
+
+        /* Chrome lies about its hyphens support so we need a more robust test
+           crbug.com/107111
+           */
+        try {
+          return test_hyphens_css();
+        } catch (e) {
+          return false;
+        }
+      });
+
+      addTest('softhyphens', function() {
+        try {
+          // use numeric entity instead of &shy; in case it's XHTML
+          return test_hyphens('&#173;', true) && test_hyphens('&#8203;', false);
+        } catch (e) {
+          return false;
+        }
+      });
+
+      addTest('softhyphensfind', function() {
+        try {
+          return test_hyphens_find('&#173;') && test_hyphens_find('&#8203;');
+        } catch (e) {
+          return false;
+        }
+      });
+
+    }
+  });
+});
diff --git a/js/modernizr/feature-detects/css/invalid.js b/js/modernizr/feature-detects/css/invalid.js
new file mode 100644 (file)
index 0000000..80d321a
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "CSS :invalid pseudo-class",
+  "property": "cssinvalid",
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/:invalid"
+  }]
+}
+!*/
+/* DOC
+  Detects support for the ':invalid' CSS pseudo-class.
+*/
+define(['Modernizr', 'testStyles', 'createElement'], function(Modernizr, testStyles, createElement) {
+  Modernizr.addTest('cssinvalid', function() {
+    return testStyles('#modernizr input{height:0;border:0;padding:0;margin:0;width:10px} #modernizr input:invalid{width:50px}', function(elem) {
+      var input = createElement('input');
+      input.required = true;
+      elem.appendChild(input);
+      return input.clientWidth > 10;
+    });
+  });
+});
diff --git a/js/modernizr/feature-detects/css/lastchild.js b/js/modernizr/feature-detects/css/lastchild.js
new file mode 100644 (file)
index 0000000..2d4f449
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "CSS :last-child pseudo-selector",
+  "caniuse": "css-sel3",
+  "property": "lastchild",
+  "tags": ["css"],
+  "builderAliases": ["css_lastchild"],
+  "notes": [{
+    "name": "Related Github Issue",
+    "href": "https://github.com/Modernizr/Modernizr/pull/304"
+  }]
+}
+!*/
+define(['Modernizr', 'testStyles'], function(Modernizr, testStyles) {
+  testStyles('#modernizr div {width:100px} #modernizr :last-child{width:200px;display:block}', function(elem) {
+    Modernizr.addTest('lastchild', elem.lastChild.offsetWidth > elem.firstChild.offsetWidth);
+  }, 2);
+});
diff --git a/js/modernizr/feature-detects/css/mask.js b/js/modernizr/feature-detects/css/mask.js
new file mode 100644 (file)
index 0000000..96f1615
--- /dev/null
@@ -0,0 +1,30 @@
+/*!
+{
+  "name": "CSS Mask",
+  "caniuse": "css-masks",
+  "property": "cssmask",
+  "tags": ["css"],
+  "builderAliases": ["css_mask"],
+  "notes": [
+    {
+      "name": "Webkit blog on CSS Masks",
+      "href": "http://www.webkit.org/blog/181/css-masks/"
+    },
+    {
+      "name": "Safari Docs",
+      "href": "http://developer.apple.com/library/safari/#documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Masks/Masks.html"
+    },
+    {
+      "name": "Mozilla css svg mask (not this)",
+      "href": "http://developer.mozilla.org/en/CSS/mask"
+    },
+    {
+      "name": "Combine with clippaths for awesomeness",
+      "href": "http://generic.cx/for/webkit/test.html"
+    }
+  ]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('cssmask', testAllProps('maskRepeat', 'repeat-x', true));
+});
diff --git a/js/modernizr/feature-detects/css/mediaqueries.js b/js/modernizr/feature-detects/css/mediaqueries.js
new file mode 100644 (file)
index 0000000..7ddd823
--- /dev/null
@@ -0,0 +1,12 @@
+/*!
+{
+  "name": "CSS Media Queries",
+  "caniuse": "css-mediaqueries",
+  "property": "mediaqueries",
+  "tags": ["css"],
+  "builderAliases": ["css_mediaqueries"]
+}
+!*/
+define(['Modernizr', 'mq'], function(Modernizr, mq) {
+  Modernizr.addTest('mediaqueries', mq('only all'));
+});
diff --git a/js/modernizr/feature-detects/css/multiplebgs.js b/js/modernizr/feature-detects/css/multiplebgs.js
new file mode 100644 (file)
index 0000000..0f756df
--- /dev/null
@@ -0,0 +1,22 @@
+/*!
+{
+  "name": "CSS Multiple Backgrounds",
+  "caniuse": "multibackgrounds",
+  "property": "multiplebgs",
+  "tags": ["css"]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  // Setting multiple images AND a color on the background shorthand property
+  // and then querying the style.background property value for the number of
+  // occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
+
+  Modernizr.addTest('multiplebgs', function() {
+    var style = createElement('a').style;
+    style.cssText = 'background:url(https://),url(https://),red url(https://)';
+
+    // If the UA supports multiple backgrounds, there should be three occurrences
+    // of the string "url(" in the return value for elemStyle.background
+    return (/(url\s*\(.*?){3}/).test(style.background);
+  });
+});
diff --git a/js/modernizr/feature-detects/css/nthchild.js b/js/modernizr/feature-detects/css/nthchild.js
new file mode 100644 (file)
index 0000000..4428b0b
--- /dev/null
@@ -0,0 +1,41 @@
+/*!
+{
+  "name": "CSS :nth-child pseudo-selector",
+  "caniuse": "css-sel3",
+  "property": "nthchild",
+  "tags": ["css"],
+  "notes": [
+    {
+      "name": "Related Github Issue",
+      "href": "https://github.com/Modernizr/Modernizr/pull/685"
+    },
+    {
+      "name": "Sitepoint :nth-child documentation",
+      "href": "http://reference.sitepoint.com/css/pseudoclass-nthchild"
+    }
+  ],
+  "authors": ["@emilchristensen"],
+  "warnings": ["Known false negative in Safari 3.1 and Safari 3.2.2"]
+}
+!*/
+/* DOC
+Detects support for the ':nth-child()' CSS pseudo-selector.
+*/
+define(['Modernizr', 'testStyles'], function(Modernizr, testStyles) {
+  // 5 `<div>` elements with `1px` width are created.
+  // Then every other element has its `width` set to `2px`.
+  // A Javascript loop then tests if the `<div>`s have the expected width
+  // using the modulus operator.
+  testStyles('#modernizr div {width:1px} #modernizr div:nth-child(2n) {width:2px;}', function(elem) {
+    Modernizr.addTest('nthchild', function() {
+      var elems = elem.getElementsByTagName('div'),
+      test = true;
+
+      for (var i = 0; i < 5; i++) {
+        test = test && elems[i].offsetWidth === i % 2 + 1;
+      }
+
+      return test;
+    });
+  }, 5);
+});
diff --git a/js/modernizr/feature-detects/css/objectfit.js b/js/modernizr/feature-detects/css/objectfit.js
new file mode 100644 (file)
index 0000000..a3a110e
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+{
+  "name": "CSS Object Fit",
+  "caniuse": "object-fit",
+  "property": "objectfit",
+  "tags": ["css"],
+  "builderAliases": ["css_objectfit"],
+  "notes": [{
+    "name": "Opera Article on Object Fit",
+    "href": "http://dev.opera.com/articles/view/css3-object-fit-object-position/"
+  }]
+}
+!*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('objectfit', !!prefixed('objectFit'), {aliases: ['object-fit']});
+});
diff --git a/js/modernizr/feature-detects/css/opacity.js b/js/modernizr/feature-detects/css/opacity.js
new file mode 100644 (file)
index 0000000..3aa97c0
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "CSS Opacity",
+  "caniuse": "css-opacity",
+  "property": "opacity",
+  "tags": ["css"]
+}
+!*/
+define(['Modernizr', 'createElement', 'prefixes'], function(Modernizr, createElement, prefixes) {
+  // Browsers that actually have CSS Opacity implemented have done so
+  // according to spec, which means their return values are within the
+  // range of [0.0,1.0] - including the leading zero.
+
+  Modernizr.addTest('opacity', function() {
+    var style = createElement('a').style;
+    style.cssText = prefixes.join('opacity:.55;');
+
+    // The non-literal . in this regex is intentional:
+    // German Chrome returns this value as 0,55
+    // github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
+    return (/^0.55$/).test(style.opacity);
+  });
+});
diff --git a/js/modernizr/feature-detects/css/overflow-scrolling.js b/js/modernizr/feature-detects/css/overflow-scrolling.js
new file mode 100644 (file)
index 0000000..006392b
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+{
+  "name": "CSS Overflow Scrolling",
+  "property": "overflowscrolling",
+  "tags": ["css"],
+  "builderAliases": ["css_overflow_scrolling"],
+  "warnings": ["Introduced in iOS5b2. API is subject to change."],
+  "notes": [{
+    "name": "Article on iOS overflow scrolling",
+    "href": "http://css-tricks.com/snippets/css/momentum-scrolling-on-ios-overflow-elements/"
+  }]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('overflowscrolling', testAllProps('overflowScrolling', 'touch', true));
+});
diff --git a/js/modernizr/feature-detects/css/pointerevents.js b/js/modernizr/feature-detects/css/pointerevents.js
new file mode 100644 (file)
index 0000000..235b480
--- /dev/null
@@ -0,0 +1,33 @@
+/*!
+{
+  "name": "CSS Pointer Events",
+  "caniuse": "pointer-events",
+  "property": "csspointerevents",
+  "authors": ["ausi"],
+  "tags": ["css"],
+  "builderAliases": ["css_pointerevents"],
+  "notes": [
+    {
+      "name": "MDN Docs",
+      "href": "http://developer.mozilla.org/en/CSS/pointer-events"
+    },{
+      "name": "Test Project Page",
+      "href": "http://ausi.github.com/Feature-detection-technique-for-pointer-events/"
+    },{
+      "name": "Test Project Wiki",
+      "href": "http://github.com/ausi/Feature-detection-technique-for-pointer-events/wiki"
+    },
+    {
+      "name": "Related Github Issue",
+      "href": "http://github.com/Modernizr/Modernizr/issues/80"
+    }
+  ]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('csspointerevents', function() {
+    var style = createElement('a').style;
+    style.cssText = 'pointer-events:auto';
+    return style.pointerEvents === 'auto';
+  });
+});
diff --git a/js/modernizr/feature-detects/css/positionsticky.js b/js/modernizr/feature-detects/css/positionsticky.js
new file mode 100644 (file)
index 0000000..c4cc0b3
--- /dev/null
@@ -0,0 +1,27 @@
+/*!
+{
+  "name": "CSS position: sticky",
+  "property": "csspositionsticky",
+  "tags": ["css"],
+  "builderAliases": ["css_positionsticky"],
+  "notes": [{
+    "name": "Chrome bug report",
+    "href":"https://code.google.com/p/chromium/issues/detail?id=322972"
+  }],
+  "warnings": [ "using position:sticky on anything but top aligned elements is buggy in Chrome < 37 and iOS <=7+" ]
+}
+!*/
+define(['Modernizr', 'createElement', 'prefixes'], function(Modernizr, createElement, prefixes) {
+  // Sticky positioning - constrains an element to be positioned inside the
+  // intersection of its container box, and the viewport.
+  Modernizr.addTest('csspositionsticky', function() {
+    var prop = 'position:';
+    var value = 'sticky';
+    var el = createElement('a');
+    var mStyle = el.style;
+
+    mStyle.cssText = prop + prefixes.join(value + ';' + prop).slice(0, -prop.length);
+
+    return mStyle.position.indexOf(value) !== -1;
+  });
+});
diff --git a/js/modernizr/feature-detects/css/pseudoanimations.js b/js/modernizr/feature-detects/css/pseudoanimations.js
new file mode 100644 (file)
index 0000000..1ee3292
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+{
+  "name": "CSS Generated Content Animations",
+  "property": "csspseudoanimations",
+  "tags": ["css"]
+}
+!*/
+define(['Modernizr', 'testStyles', 'test/css/animations'], function(Modernizr) {
+  Modernizr.addTest('csspseudoanimations', function() {
+    var result = false;
+
+    if (!Modernizr.cssanimations || !window.getComputedStyle) {
+      return result;
+    }
+
+    var styles = [
+      '@', Modernizr._prefixes.join('keyframes csspseudoanimations { from { font-size: 10px; } }@').replace(/\@$/, ''),
+      '#modernizr:before { content:" "; font-size:5px;',
+      Modernizr._prefixes.join('animation:csspseudoanimations 1ms infinite;'),
+      '}'
+    ].join('');
+
+    Modernizr.testStyles(styles, function(elem) {
+      result = window.getComputedStyle(elem, ':before').getPropertyValue('font-size') === '10px';
+    });
+
+    return result;
+  });
+});
diff --git a/js/modernizr/feature-detects/css/pseudotransitions.js b/js/modernizr/feature-detects/css/pseudotransitions.js
new file mode 100644 (file)
index 0000000..e3c6ec8
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+{
+  "name": "CSS Generated Content Transitions",
+  "property": "csspseudotransitions",
+  "tags": ["css"]
+}
+!*/
+define(['Modernizr', 'testStyles', 'test/css/transitions'], function(Modernizr) {
+  Modernizr.addTest('csspseudotransitions', function() {
+    var result = false;
+
+    if (!Modernizr.csstransitions || !window.getComputedStyle) {
+      return result;
+    }
+
+    var styles =
+      '#modernizr:before { content:" "; font-size:5px;' + Modernizr._prefixes.join('transition:0s 100s;') + '}' +
+      '#modernizr.trigger:before { font-size:10px; }';
+
+    Modernizr.testStyles(styles, function(elem) {
+      // Force rendering of the element's styles so that the transition will trigger
+      window.getComputedStyle(elem, ':before').getPropertyValue('font-size');
+      elem.className += 'trigger';
+      result = window.getComputedStyle(elem, ':before').getPropertyValue('font-size') === '5px';
+    });
+
+    return result;
+  });
+});
diff --git a/js/modernizr/feature-detects/css/reflections.js b/js/modernizr/feature-detects/css/reflections.js
new file mode 100644 (file)
index 0000000..fb947a3
--- /dev/null
@@ -0,0 +1,11 @@
+/*!
+{
+  "name": "CSS Reflections",
+  "caniuse": "css-reflections",
+  "property": "cssreflections",
+  "tags": ["css"]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('cssreflections', testAllProps('boxReflect', 'above', true));
+});
diff --git a/js/modernizr/feature-detects/css/regions.js b/js/modernizr/feature-detects/css/regions.js
new file mode 100644 (file)
index 0000000..e140875
--- /dev/null
@@ -0,0 +1,94 @@
+/*!
+{
+  "name": "CSS Regions",
+  "caniuse": "css-regions",
+  "authors": ["Mihai Balan"],
+  "property": "regions",
+  "tags": ["css"],
+  "builderAliases": ["css_regions"],
+  "notes": [{
+    "name": "W3C Specification",
+    "href": "http://www.w3.org/TR/css3-regions/"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement', 'docElement', 'isSVG'], function(Modernizr, createElement, docElement, isSVG) {
+  // We start with a CSS parser test then we check page geometry to see if it's affected by regions
+  // Later we might be able to retire the second part, as WebKit builds with the false positives die out
+
+  Modernizr.addTest('regions', function() {
+
+    if (isSVG) {
+      // css regions don't work inside of SVG elements. Rather than update the
+      // below test to work in an SVG context, just exit early to save bytes
+      return false;
+    }
+
+    /* Get the 'flowFrom' property name available in the browser. Either default or vendor prefixed.
+       If the property name can't be found we'll get Boolean 'false' and fail quickly */
+    var flowFromProperty = Modernizr.prefixed('flowFrom');
+    var flowIntoProperty = Modernizr.prefixed('flowInto');
+    var result = false;
+
+    if (!flowFromProperty || !flowIntoProperty) {
+      return result;
+    }
+
+    /* If CSS parsing is there, try to determine if regions actually work. */
+    var iframeContainer = createElement('iframe');
+    var container = createElement('div');
+    var content = createElement('div');
+    var region = createElement('div');
+
+    /* we create a random, unlikely to be generated flow number to make sure we don't
+       clash with anything more vanilla, like 'flow', or 'article', or 'f1' */
+    var flowName = 'modernizr_flow_for_regions_check';
+
+    /* First create a div with two adjacent divs inside it. The first will be the
+       content, the second will be the region. To be able to distinguish between the two,
+       we'll give the region a particular padding */
+    content.innerText = 'M';
+    container.style.cssText = 'top: 150px; left: 150px; padding: 0px;';
+    region.style.cssText = 'width: 50px; height: 50px; padding: 42px;';
+
+    region.style[flowFromProperty] = flowName;
+    container.appendChild(content);
+    container.appendChild(region);
+    docElement.appendChild(container);
+
+    /* Now compute the bounding client rect, before and after attempting to flow the
+       content div in the region div. If regions are enabled, the after bounding rect
+       should reflect the padding of the region div.*/
+    var flowedRect, delta;
+    var plainRect = content.getBoundingClientRect();
+
+
+    content.style[flowIntoProperty] = flowName;
+    flowedRect = content.getBoundingClientRect();
+
+    delta = parseInt(flowedRect.left - plainRect.left, 10);
+    docElement.removeChild(container);
+
+    if (delta == 42) {
+      result = true;
+    } else {
+      /* IE only allows for the content to come from iframes. This has the
+       * side effect of automatic collapsing of iframes once they get the flow-into
+       * property set. checking for a change on the height allows us to detect this
+       * in a sync way, without having to wait for a frame to load */
+
+      docElement.appendChild(iframeContainer);
+      plainRect = iframeContainer.getBoundingClientRect();
+      iframeContainer.style[flowIntoProperty] = flowName;
+      flowedRect = iframeContainer.getBoundingClientRect();
+
+      if (plainRect.height > 0 && plainRect.height !== flowedRect.height && flowedRect.height === 0) {
+        result = true;
+      }
+    }
+
+    content = region = container = iframeContainer = undefined;
+
+    return result;
+  });
+});
diff --git a/js/modernizr/feature-detects/css/remunit.js b/js/modernizr/feature-detects/css/remunit.js
new file mode 100644 (file)
index 0000000..68b5ba9
--- /dev/null
@@ -0,0 +1,31 @@
+/*!
+{
+  "name": "CSS Font rem Units",
+  "caniuse": "rem",
+  "authors": ["nsfmc"],
+  "property": "cssremunit",
+  "tags": ["css"],
+  "builderAliases": ["css_remunit"],
+  "notes": [{
+    "name": "W3C Spec",
+    "href": "http://www.w3.org/TR/css3-values/#relative0"
+  },{
+    "name": "Font Size with rem by Jonathan Snook",
+    "href": "http://snook.ca/archives/html_and_css/font-size-with-rem"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  // "The 'rem' unit ('root em') is relative to the computed
+  // value of the 'font-size' value of the root element."
+  // you can test by checking if the prop was ditched
+
+  Modernizr.addTest('cssremunit', function() {
+    var style = createElement('a').style;
+    try {
+      style.fontSize = '3rem';
+    }
+    catch (e) {}
+    return (/rem/).test(style.fontSize);
+  });
+});
diff --git a/js/modernizr/feature-detects/css/resize.js b/js/modernizr/feature-detects/css/resize.js
new file mode 100644 (file)
index 0000000..1774d8e
--- /dev/null
@@ -0,0 +1,22 @@
+/*!
+{
+  "name": "CSS UI Resize",
+  "property": "cssresize",
+  "caniuse": "css-resize",
+  "tags": ["css"],
+  "builderAliases": ["css_resize"],
+  "notes": [{
+    "name": "W3C Specification",
+    "href": "http://www.w3.org/TR/css3-ui/#resize"
+  },{
+    "name": "MDN Docs",
+    "href": "https://developer.mozilla.org/en/CSS/resize"
+  }]
+}
+!*/
+/* DOC
+Test for CSS 3 UI "resize" property
+*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('cssresize', testAllProps('resize', 'both', true));
+});
diff --git a/js/modernizr/feature-detects/css/rgba.js b/js/modernizr/feature-detects/css/rgba.js
new file mode 100644 (file)
index 0000000..3a31834
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "CSS rgba",
+  "caniuse": "css3-colors",
+  "property": "rgba",
+  "tags": ["css"],
+  "notes": [{
+    "name": "CSSTricks Tutorial",
+    "href": "http://css-tricks.com/rgba-browser-support/"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('rgba', function() {
+    var style = createElement('a').style;
+    style.cssText = 'background-color:rgba(150,255,150,.5)';
+
+    return ('' + style.backgroundColor).indexOf('rgba') > -1;
+  });
+});
diff --git a/js/modernizr/feature-detects/css/scrollbars.js b/js/modernizr/feature-detects/css/scrollbars.js
new file mode 100644 (file)
index 0000000..feba6a7
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "CSS Stylable Scrollbars",
+  "property": "cssscrollbar",
+  "tags": ["css"],
+  "builderAliases": ["css_scrollbars"]
+}
+!*/
+define(['Modernizr', 'testStyles', 'prefixes'], function(Modernizr, testStyles, prefixes) {
+  testStyles('#modernizr{overflow: scroll; width: 40px; height: 40px; }#' + prefixes
+    .join('scrollbar{width:0px}' + ' #modernizr::')
+    .split('#')
+    .slice(1)
+    .join('#') + 'scrollbar{width:0px}',
+  function(node) {
+    Modernizr.addTest('cssscrollbar', node.scrollWidth == 40);
+  });
+});
diff --git a/js/modernizr/feature-detects/css/shapes.js b/js/modernizr/feature-detects/css/shapes.js
new file mode 100644 (file)
index 0000000..5d532b4
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "CSS Shapes",
+  "property": "shapes",
+  "tags": ["css"],
+  "notes": [{
+    "name": "CSS Shapes W3C specification",
+    "href": "http://www.w3.org/TR/css-shapes"
+  },{
+    "name": "Examples from Adobe",
+    "href": "http://html.adobe.com/webplatform/layout/shapes"
+  }, {
+    "name": "Samples showcasing uses of Shapes",
+    "href": "http://codepen.io/collection/qFesk"
+  }]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('shapes', testAllProps('shapeOutside', 'content-box', true));
+});
diff --git a/js/modernizr/feature-detects/css/siblinggeneral.js b/js/modernizr/feature-detects/css/siblinggeneral.js
new file mode 100644 (file)
index 0000000..b5b4140
--- /dev/null
@@ -0,0 +1,19 @@
+/*!
+{
+  "name": "CSS general sibling selector",
+  "caniuse": "css-sel3",
+  "property": "siblinggeneral",
+  "tags": ["css"],
+  "notes": [{
+    "name": "Related Github Issue",
+    "href": "https://github.com/Modernizr/Modernizr/pull/889"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement', 'testStyles'], function(Modernizr, createElement, testStyles) {
+  Modernizr.addTest('siblinggeneral', function() {
+    return testStyles('#modernizr div {width:100px} #modernizr div ~ div {width:200px;display:block}', function(elem) {
+      return elem.lastChild.offsetWidth == 200;
+    }, 2);
+  });
+});
diff --git a/js/modernizr/feature-detects/css/subpixelfont.js b/js/modernizr/feature-detects/css/subpixelfont.js
new file mode 100644 (file)
index 0000000..efb202f
--- /dev/null
@@ -0,0 +1,33 @@
+/*!
+{
+  "name": "CSS Subpixel Fonts",
+  "property": "subpixelfont",
+  "tags": ["css"],
+  "builderAliases": ["css_subpixelfont"],
+  "authors": [
+    "@derSchepp",
+    "@gerritvanaaken",
+    "@rodneyrehm",
+    "@yatil",
+    "@ryanseddon"
+  ],
+  "notes": [{
+    "name": "Origin Test",
+    "href": "https://github.com/gerritvanaaken/subpixeldetect"
+  }]
+}
+!*/
+define(['Modernizr', 'testStyles'], function(Modernizr, testStyles) {
+  /*
+   * (to infer if GDI or DirectWrite is used on Windows)
+   */
+  testStyles(
+    '#modernizr{position: absolute; top: -10em; visibility:hidden; font: normal 10px arial;}#subpixel{float: left; font-size: 33.3333%;}',
+  function(elem) {
+    var subpixel = elem.firstChild;
+    subpixel.innerHTML = 'This is a text written in Arial';
+    Modernizr.addTest('subpixelfont', window.getComputedStyle ?
+      window.getComputedStyle(subpixel, null).getPropertyValue('width') !== '44px'
+    : false);
+  }, 1, ['subpixel']);
+});
diff --git a/js/modernizr/feature-detects/css/supports.js b/js/modernizr/feature-detects/css/supports.js
new file mode 100644 (file)
index 0000000..6e4a186
--- /dev/null
@@ -0,0 +1,24 @@
+/*!
+{
+  "name": "CSS Supports",
+  "property": "supports",
+  "caniuse": "css-featurequeries",
+  "tags": ["css"],
+  "builderAliases": ["css_supports"],
+  "notes": [{
+    "name": "W3 Spec",
+    "href": "http://dev.w3.org/csswg/css3-conditional/#at-supports"
+  },{
+    "name": "Related Github Issue",
+    "href": "github.com/Modernizr/Modernizr/issues/648"
+  },{
+    "name": "W3 Info",
+    "href": "http://dev.w3.org/csswg/css3-conditional/#the-csssupportsrule-interface"
+  }]
+}
+!*/
+define(['Modernizr'], function(Modernizr) {
+  var newSyntax = 'CSS' in window && 'supports' in window.CSS;
+  var oldSyntax = 'supportsCSS' in window;
+  Modernizr.addTest('supports', newSyntax || oldSyntax);
+});
diff --git a/js/modernizr/feature-detects/css/target.js b/js/modernizr/feature-detects/css/target.js
new file mode 100644 (file)
index 0000000..73b6a1d
--- /dev/null
@@ -0,0 +1,33 @@
+/*!
+{
+  "name": "CSS :target pseudo-class",
+  "caniuse": "css-sel3",
+  "property": "target",
+  "tags": ["css"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/:target"
+  }],
+  "authors": ["@zachleat"],
+  "warnings": ["Opera Mini supports :target but doesn't update the hash for anchor links."]
+}
+!*/
+/* DOC
+Detects support for the ':target' CSS pseudo-class.
+*/
+define(['Modernizr'], function(Modernizr) {
+  // querySelector
+  Modernizr.addTest('target', function() {
+    var doc = window.document;
+    if (!('querySelectorAll' in doc)) {
+      return false;
+    }
+
+    try {
+      doc.querySelectorAll(':target');
+      return true;
+    } catch (e) {
+      return false;
+    }
+  });
+});
diff --git a/js/modernizr/feature-detects/css/textalignlast.js b/js/modernizr/feature-detects/css/textalignlast.js
new file mode 100644 (file)
index 0000000..3a05617
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "CSS text-align-last",
+  "property": "textalignlast",
+  "tags": ["css"],
+  "knownBugs": ["IE does not support the 'start' or 'end' values."],
+  "notes": [{
+      "name": "Quicksmode",
+      "href": "http://www.quirksmode.org/css/text/textalignlast.html"
+    },{
+      "name": "MDN",
+      "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/text-align-last"
+    }]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('textalignlast', testAllProps('textAlignLast'));
+});
diff --git a/js/modernizr/feature-detects/css/textshadow.js b/js/modernizr/feature-detects/css/textshadow.js
new file mode 100644 (file)
index 0000000..b5ac9b6
--- /dev/null
@@ -0,0 +1,12 @@
+/*!
+{
+  "name": "CSS textshadow",
+  "property": "textshadow",
+  "caniuse": "css-textshadow",
+  "tags": ["css"],
+  "knownBugs": ["FF3.0 will false positive on this test"]
+}
+!*/
+define(['Modernizr', 'testProp'], function(Modernizr, testProp) {
+  Modernizr.addTest('textshadow', testProp('textShadow', '1px 1px'));
+});
diff --git a/js/modernizr/feature-detects/css/transforms.js b/js/modernizr/feature-detects/css/transforms.js
new file mode 100644 (file)
index 0000000..8d683e3
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+{
+  "name": "CSS Transforms",
+  "property": "csstransforms",
+  "caniuse": "transforms2d",
+  "tags": ["css"]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('csstransforms', function() {
+    // Android < 3.0 is buggy, so we sniff and blacklist
+    // http://git.io/hHzL7w
+    return navigator.userAgent.indexOf('Android 2.') === -1 &&
+           testAllProps('transform', 'scale(1)', true);
+  });
+});
diff --git a/js/modernizr/feature-detects/css/transforms3d.js b/js/modernizr/feature-detects/css/transforms3d.js
new file mode 100644 (file)
index 0000000..48b74ee
--- /dev/null
@@ -0,0 +1,44 @@
+/*!
+{
+  "name": "CSS Transforms 3D",
+  "property": "csstransforms3d",
+  "caniuse": "transforms3d",
+  "tags": ["css"],
+  "warnings": [
+    "Chrome may occassionally fail this test on some systems; more info: https://code.google.com/p/chromium/issues/detail?id=129004"
+  ]
+}
+!*/
+define(['Modernizr', 'testAllProps', 'testStyles', 'docElement', 'test/css/supports'], function(Modernizr, testAllProps, testStyles, docElement) {
+  Modernizr.addTest('csstransforms3d', function() {
+    var ret = !!testAllProps('perspective', '1px', true);
+    var usePrefix = Modernizr._config.usePrefixes;
+
+    // Webkit's 3D transforms are passed off to the browser's own graphics renderer.
+    //   It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
+    //   some conditions. As a result, Webkit typically recognizes the syntax but
+    //   will sometimes throw a false positive, thus we must do a more thorough check:
+    if (ret && (!usePrefix || 'webkitPerspective' in docElement.style)) {
+      var mq;
+      // Use CSS Conditional Rules if available
+      if (Modernizr.supports) {
+        mq = '@supports (perspective: 1px)';
+      } else {
+        // Otherwise, Webkit allows this media query to succeed only if the feature is enabled.
+        // `@media (transform-3d),(-webkit-transform-3d){ ... }`
+        mq = '@media (transform-3d)';
+        if (usePrefix) {
+          mq += ',(-webkit-transform-3d)';
+        }
+      }
+      // If loaded inside the body tag and the test element inherits any padding, margin or borders it will fail #740
+      mq += '{#modernizr{left:9px;position:absolute;height:5px;margin:0;padding:0;border:0}}';
+
+      testStyles(mq, function(elem) {
+        ret = elem.offsetLeft === 9 && elem.offsetHeight === 5;
+      });
+    }
+
+    return ret;
+  });
+});
diff --git a/js/modernizr/feature-detects/css/transformstylepreserve3d.js b/js/modernizr/feature-detects/css/transformstylepreserve3d.js
new file mode 100644 (file)
index 0000000..c76f552
--- /dev/null
@@ -0,0 +1,21 @@
+/*!
+{
+  "name": "CSS Transform Style preserve-3d",
+  "property": "preserve3d",
+  "authors": ["edmellum"],
+  "tags": ["css"],
+  "notes": [{
+    "name": "MDN Docs",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/transform-style"
+  },{
+    "name": "Related Github Issue",
+    "href": "https://github.com/Modernizr/Modernizr/issues/762"
+  }]
+}
+!*/
+/* DOC
+Detects support for `transform-style: preserve-3d`, for getting a proper 3D perspective on elements.
+*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('preserve3d', testAllProps('transformStyle', 'preserve-3d'));
+});
diff --git a/js/modernizr/feature-detects/css/transitions.js b/js/modernizr/feature-detects/css/transitions.js
new file mode 100644 (file)
index 0000000..ed7d22a
--- /dev/null
@@ -0,0 +1,11 @@
+/*!
+{
+  "name": "CSS Transitions",
+  "property": "csstransitions",
+  "caniuse": "css-transitions",
+  "tags": ["css"]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  Modernizr.addTest('csstransitions', testAllProps('transition', 'all', true));
+});
diff --git a/js/modernizr/feature-detects/css/userselect.js b/js/modernizr/feature-detects/css/userselect.js
new file mode 100644 (file)
index 0000000..258498b
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "CSS user-select",
+  "property": "userselect",
+  "caniuse": "user-select-none",
+  "authors": ["ryan seddon"],
+  "tags": ["css"],
+  "builderAliases": ["css_userselect"],
+  "notes": [{
+    "name": "Related Modernizr Issue",
+    "href": "https://github.com/Modernizr/Modernizr/issues/250"
+  }]
+}
+!*/
+define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
+  //https://github.com/Modernizr/Modernizr/issues/250
+  Modernizr.addTest('userselect', testAllProps('userSelect', 'none', true));
+});
diff --git a/js/modernizr/feature-detects/css/valid.js b/js/modernizr/feature-detects/css/valid.js
new file mode 100644 (file)
index 0000000..20e3f5b
--- /dev/null
@@ -0,0 +1,22 @@
+/*!
+{
+  "name": "CSS :valid pseudo-class",
+  "property": "cssvalid",
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/:valid"
+  }]
+}
+!*/
+/* DOC
+  Detects support for the ':valid' CSS pseudo-class.
+*/
+define(['Modernizr', 'testStyles', 'createElement'], function(Modernizr, testStyles, createElement) {
+  Modernizr.addTest('cssvalid', function() {
+    return testStyles('#modernizr input{height:0;border:0;padding:0;margin:0;width:10px} #modernizr input:valid{width:50px}', function(elem) {
+      var input = createElement('input');
+      elem.appendChild(input);
+      return input.clientWidth > 10;
+    });
+  });
+});
diff --git a/js/modernizr/feature-detects/css/vhunit.js b/js/modernizr/feature-detects/css/vhunit.js
new file mode 100644 (file)
index 0000000..14fd352
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+{
+  "name": "CSS vh unit",
+  "property": "cssvhunit",
+  "caniuse": "viewport-units",
+  "tags": ["css"],
+  "builderAliases": ["css_vhunit"],
+  "notes": [{
+    "name": "Related Modernizr Issue",
+    "href": "https://github.com/Modernizr/Modernizr/issues/572"
+  },{
+    "name": "Similar JSFiddle",
+    "href": "http://jsfiddle.net/FWeinb/etnYC/"
+  }]
+}
+!*/
+define(['Modernizr', 'testStyles'], function(Modernizr, testStyles) {
+  testStyles('#modernizr { height: 50vh; }', function(elem) {
+    var height = parseInt(window.innerHeight / 2, 10);
+    var compStyle = parseInt((window.getComputedStyle ?
+                              getComputedStyle(elem, null) :
+                              elem.currentStyle)['height'], 10);
+    Modernizr.addTest('cssvhunit', compStyle == height);
+  });
+});
diff --git a/js/modernizr/feature-detects/css/vmaxunit.js b/js/modernizr/feature-detects/css/vmaxunit.js
new file mode 100644 (file)
index 0000000..90efb71
--- /dev/null
@@ -0,0 +1,32 @@
+/*!
+{
+  "name": "CSS vmax unit",
+  "property": "cssvmaxunit",
+  "caniuse": "viewport-units",
+  "tags": ["css"],
+  "builderAliases": ["css_vmaxunit"],
+  "notes": [{
+    "name": "Related Modernizr Issue",
+    "href": "https://github.com/Modernizr/Modernizr/issues/572"
+  },{
+    "name": "JSFiddle Example",
+    "href": "http://jsfiddle.net/glsee/JDsWQ/4/"
+  }]
+}
+!*/
+define(['Modernizr', 'docElement', 'testStyles', 'roundedEquals'], function(Modernizr, docElement, testStyles, roundedEquals) {
+  testStyles('#modernizr1{width: 50vmax}#modernizr2{width:50px;height:50px;overflow:scroll}', function(node) {
+    var elem = node.childNodes[1];
+    var scroller = node.childNodes[0];
+    var scrollbarWidth = parseInt((scroller.offsetWidth - scroller.clientWidth) / 2, 10);
+
+    var one_vw = docElement.clientWidth / 100;
+    var one_vh = docElement.clientHeight / 100;
+    var expectedWidth = parseInt(Math.max(one_vw, one_vh) * 50, 10);
+    var compWidth = parseInt((window.getComputedStyle ?
+                          getComputedStyle(elem, null) :
+                          elem.currentStyle)['width'], 10);
+
+    Modernizr.addTest('cssvmaxunit', roundedEquals(expectedWidth, compWidth) || roundedEquals(expectedWidth, compWidth - scrollbarWidth));
+  }, 2);
+});
diff --git a/js/modernizr/feature-detects/css/vminunit.js b/js/modernizr/feature-detects/css/vminunit.js
new file mode 100644 (file)
index 0000000..3cab276
--- /dev/null
@@ -0,0 +1,32 @@
+/*!
+{
+  "name": "CSS vmin unit",
+  "property": "cssvminunit",
+  "caniuse": "viewport-units",
+  "tags": ["css"],
+  "builderAliases": ["css_vminunit"],
+  "notes": [{
+    "name": "Related Modernizr Issue",
+    "href": "https://github.com/Modernizr/Modernizr/issues/572"
+  },{
+    "name": "JSFiddle Example",
+    "href": "http://jsfiddle.net/glsee/JRmdq/8/"
+  }]
+}
+!*/
+define(['Modernizr', 'docElement', 'testStyles', 'roundedEquals'], function(Modernizr, docElement, testStyles, roundedEquals) {
+  testStyles('#modernizr1{width: 50vm;width:50vmin}#modernizr2{width:50px;height:50px;overflow:scroll}', function(node) {
+    var elem = node.childNodes[1];
+    var scroller = node.childNodes[0];
+    var scrollbarWidth = parseInt((scroller.offsetWidth - scroller.clientWidth) / 2, 10);
+
+    var one_vw = docElement.clientWidth / 100;
+    var one_vh = docElement.clientHeight / 100;
+    var expectedWidth = parseInt(Math.min(one_vw, one_vh) * 50, 10);
+    var compWidth = parseInt((window.getComputedStyle ?
+                          getComputedStyle(elem, null) :
+                          elem.currentStyle)['width'], 10);
+
+    Modernizr.addTest('cssvminunit', roundedEquals(expectedWidth, compWidth) || roundedEquals(expectedWidth, compWidth - scrollbarWidth));
+  }, 2);
+});
diff --git a/js/modernizr/feature-detects/css/vwunit.js b/js/modernizr/feature-detects/css/vwunit.js
new file mode 100644 (file)
index 0000000..2305ff7
--- /dev/null
@@ -0,0 +1,26 @@
+/*!
+{
+  "name": "CSS vw unit",
+  "property": "cssvwunit",
+  "caniuse": "viewport-units",
+  "tags": ["css"],
+  "builderAliases": ["css_vwunit"],
+  "notes": [{
+    "name": "Related Modernizr Issue",
+    "href": "https://github.com/Modernizr/Modernizr/issues/572"
+  },{
+    "name": "JSFiddle Example",
+    "href": "http://jsfiddle.net/FWeinb/etnYC/"
+  }]
+}
+!*/
+define(['Modernizr', 'testStyles'], function(Modernizr, testStyles) {
+  testStyles('#modernizr { width: 50vw; }', function(elem) {
+    var width = parseInt(window.innerWidth / 2, 10);
+    var compStyle = parseInt((window.getComputedStyle ?
+                              getComputedStyle(elem, null) :
+                              elem.currentStyle).width, 10);
+
+    Modernizr.addTest('cssvwunit', compStyle == width);
+  });
+});
diff --git a/js/modernizr/feature-detects/css/will-change.js b/js/modernizr/feature-detects/css/will-change.js
new file mode 100644 (file)
index 0000000..84efbe6
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+{
+  "name": "will-change",
+  "property": "willchange",
+  "notes": [{
+    "name": "Spec",
+    "href": "http://tabatkins.github.io/specs/css-will-change/"
+  }]
+}
+!*/
+/* DOC
+Detects support for the `will-change` css property, which formally signals to the
+browser that an element will be animating.
+*/
+define(['Modernizr', 'docElement'], function(Modernizr, docElement) {
+  Modernizr.addTest('willchange', 'willChange' in docElement.style);
+});
diff --git a/js/modernizr/feature-detects/css/wrapflow.js b/js/modernizr/feature-detects/css/wrapflow.js
new file mode 100644 (file)
index 0000000..9a2169b
--- /dev/null
@@ -0,0 +1,51 @@
+/*!
+{
+  "name": "CSS wrap-flow",
+  "property": "wrapflow",
+  "tags": ["css"],
+  "notes": [
+    {
+      "name": "W3C Exclusions spec",
+      "href": "http://www.w3.org/TR/css3-exclusions"
+    },
+    {
+      "name": "Example by Adobe",
+      "href": "http://html.adobe.com/webstandards/cssexclusions"
+    }
+  ]
+}
+!*/
+define(['Modernizr', 'prefixed', 'docElement', 'createElement', 'isSVG'], function(Modernizr, prefixed, docElement, createElement, isSVG) {
+  Modernizr.addTest('wrapflow', function() {
+    var prefixedProperty = prefixed('wrapFlow');
+    if (!prefixedProperty || isSVG) {
+      return false;
+    }
+
+    var wrapFlowProperty = prefixedProperty.replace(/([A-Z])/g, function(str, m1) { return '-' + m1.toLowerCase(); }).replace(/^ms-/, '-ms-');
+
+    /* If the CSS parsing is there we need to determine if wrap-flow actually works to avoid false positive cases, e.g. the browser parses
+       the property, but it hasn't got the implementation for the functionality yet. */
+    var container = createElement('div');
+    var exclusion = createElement('div');
+    var content = createElement('span');
+
+    /* First we create a div with two adjacent divs inside it. The first div will be the content, the second div will be the exclusion area.
+       We use the "wrap-flow: end" property to test the actual behavior. (http://dev.w3.org/csswg/css3-exclusions/#wrap-flow-property)
+       The wrap-flow property is applied to the exclusion area what has a 50px left offset and a 100px width.
+       If the wrap-flow property is working correctly then the content should start after the exclusion area, so the content's left offset should be 150px. */
+    exclusion.style.cssText = 'position: absolute; left: 50px; width: 100px; height: 20px;' + wrapFlowProperty + ':end;';
+    content.innerText = 'X';
+
+    container.appendChild(exclusion);
+    container.appendChild(content);
+    docElement.appendChild(container);
+
+    var leftOffset = content.offsetLeft;
+
+    docElement.removeChild(container);
+    exclusion = content = container = undefined;
+
+    return (leftOffset == 150);
+  });
+});
index 2534189..291d12b 100644 (file)
@@ -1,10 +1,40 @@
-/*
-       Custom protocol handler support
-       http://developers.whatwg.org/timers.html#custom-handlers
-       
-       Added by @benschwarz
+/*!
+{
+  "name": "Custom protocol handler",
+  "property": "customprotocolhandler",
+  "authors": ["Ben Schwarz"],
+  "builderAliases": ["custom_protocol_handler"],
+  "notes": [{
+    "name": "WHATWG overview",
+    "href": "http://developers.whatwg.org/timers.html#custom-handlers"
+  },{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/API/navigator.registerProtocolHandler"
+  }],
+  "warnings": [],
+  "polyfills": []
+}
+!*/
+/* DOC
+Detects support for the `window.registerProtocolHandler()` API to allow websites to register themselves as possible handlers for particular protocols.
 */
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('customprotocolhandler', function() {
+    // early bailout where it doesn't exist at all
+    if (!navigator.registerProtocolHandler) {
+      return false;
+    }
 
-Modernizr.addTest('customprotocolhandler', function () {
-    return !!navigator.registerProtocolHandler;
+    // registerProtocolHandler was stubbed in webkit for a while, and didn't
+    // actually do anything. We intentionally set it improperly to test for
+    // the proper sort of failure
+    try {
+      navigator.registerProtocolHandler('thisShouldFail');
+    }
+    catch (e) {
+      return e instanceof TypeError;
+    }
+
+    return false;
+  });
 });
diff --git a/js/modernizr/feature-detects/customevent.js b/js/modernizr/feature-detects/customevent.js
new file mode 100644 (file)
index 0000000..eb10d61
--- /dev/null
@@ -0,0 +1,24 @@
+/*!
+{
+  "name": "CustomEvent",
+  "property": "customevent",
+  "tags": ["customevent"],
+  "authors": ["Alberto Elias"],
+  "notes": [{
+    "name": "W3C DOM reference",
+    "href": "http://www.w3.org/TR/DOM-Level-3-Events/#interface-CustomEvent"
+  }, {
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en/docs/Web/API/CustomEvent"
+  }],
+  "polyfills": ["eventlistener"]
+}
+!*/
+/* DOC
+
+Detects support for CustomEvent.
+
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('customevent', 'CustomEvent' in window && typeof window.CustomEvent === 'function');
+});
index 9a8bc82..bbbf750 100644 (file)
@@ -1,6 +1,17 @@
-// Dart
-// By Theodoor van Donge
-
-// https://chromiumcodereview.appspot.com/9232049/
-
-Modernizr.addTest('dart', !!Modernizr.prefixed('startDart', navigator));
+/*!
+{
+  "name": "Dart",
+  "property": "dart",
+  "authors": ["Theodoor van Donge"],
+  "notes": [{
+    "name": "Language website",
+    "href": "http://www.dartlang.org/"
+  }]
+}
+!*/
+/* DOC
+Detects native support for the Dart programming language.
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('dart', !!prefixed('startDart', navigator));
+});
index 249bfff..b9371fd 100644 (file)
@@ -1,4 +1,19 @@
-// DataView 
-// https://developer.mozilla.org/en/JavaScript_typed_arrays/DataView
-// By Addy Osmani
-Modernizr.addTest('dataview', (typeof DataView !== 'undefined' && 'getFloat64' in DataView.prototype));
\ No newline at end of file
+/*!
+{
+  "name": "DataView",
+  "property": "dataview",
+  "authors": ["Addy Osmani"],
+  "builderAliases": ["dataview_api"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en/JavaScript_typed_arrays/DataView"
+  }],
+  "polyfills": ["jdataview"]
+}
+!*/
+/* DOC
+Detects support for the DataView interface for reading data from an ArrayBuffer as part of the Typed Array spec.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('dataview', (typeof DataView !== 'undefined' && 'getFloat64' in DataView.prototype));
+});
diff --git a/js/modernizr/feature-detects/dom/classlist.js b/js/modernizr/feature-detects/dom/classlist.js
new file mode 100644 (file)
index 0000000..dbbe483
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+{
+  "name": "classList",
+  "caniuse": "classlist",
+  "property": "classlist",
+  "tags": ["dom"],
+  "builderAliases": ["dataview_api"],
+  "notes": [{
+    "name": "MDN Docs",
+    "href": "https://developer.mozilla.org/en/DOM/element.classList"
+  }]
+}
+!*/
+define(['Modernizr', 'docElement'], function(Modernizr, docElement) {
+  Modernizr.addTest('classlist', 'classList' in docElement);
+});
diff --git a/js/modernizr/feature-detects/dom/createElement-attrs.js b/js/modernizr/feature-detects/dom/createElement-attrs.js
new file mode 100644 (file)
index 0000000..ad88ff5
--- /dev/null
@@ -0,0 +1,24 @@
+/*!
+{
+  "name": "createElement with Attributes",
+  "property": ["createelementattrs", "createelement-attrs"],
+  "tags": ["dom"],
+  "builderAliases": ["dom_createElement_attrs"],
+  "authors": ["James A. Rosen"],
+  "notes": [{
+    "name": "Related Github Issue",
+    "href": "https://github.com/Modernizr/Modernizr/issues/258"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('createelementattrs', function() {
+    try {
+      return createElement('<input name="test" />').getAttribute('name') == 'test';
+    } catch (e) {
+      return false;
+    }
+  }, {
+    aliases: ['createelement-attrs']
+  });
+});
diff --git a/js/modernizr/feature-detects/dom/dataset.js b/js/modernizr/feature-detects/dom/dataset.js
new file mode 100644 (file)
index 0000000..02a04d3
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "dataset API",
+  "caniuse": "dataset",
+  "property": "dataset",
+  "tags": ["dom"],
+  "builderAliases": ["dom_dataset"],
+  "authors": ["@phiggins42"]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  // dataset API for data-* attributes
+  Modernizr.addTest('dataset', function() {
+    var n = createElement('div');
+    n.setAttribute('data-a-b', 'c');
+    return !!(n.dataset && n.dataset.aB === 'c');
+  });
+});
diff --git a/js/modernizr/feature-detects/dom/documentfragment.js b/js/modernizr/feature-detects/dom/documentfragment.js
new file mode 100644 (file)
index 0000000..3740a8a
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+{
+  "name": "Document Fragment",
+  "property": "documentfragment",
+  "notes": [{
+    "name": "W3C DOM Level 1 Reference",
+    "href": "http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-B63ED1A3"
+  }, {
+    "name": "SitePoint Reference",
+    "href": "http://reference.sitepoint.com/javascript/DocumentFragment"
+  }, {
+    "name": "QuirksMode Compatibility Tables",
+    "href": "http://www.quirksmode.org/m/w3c_core.html#t112"
+  }],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "knownBugs": ["false-positive on Blackberry 9500, see QuirksMode note"],
+  "tags": []
+}
+!*/
+/* DOC
+Append multiple elements to the DOM within a single insertion.
+*/
+define(['Modernizr', 'docElement'], function(Modernizr, docElement) {
+  Modernizr.addTest('documentfragment', function() {
+    return 'createDocumentFragment' in document &&
+      'appendChild' in docElement;
+  });
+});
+
diff --git a/js/modernizr/feature-detects/dom/hidden.js b/js/modernizr/feature-detects/dom/hidden.js
new file mode 100644 (file)
index 0000000..4c223fa
--- /dev/null
@@ -0,0 +1,22 @@
+/*!
+{
+  "name": "[hidden] Attribute",
+  "property": "hidden",
+  "tags": ["dom"],
+  "notes": [{
+    "name": "WHATWG: The hidden attribute",
+    "href": "http://developers.whatwg.org/editing.html#the-hidden-attribute"
+  }, {
+    "name": "original implementation of detect code",
+    "href": "https://github.com/aFarkas/html5shiv/blob/bf4fcc4/src/html5shiv.js#L38"
+  }],
+  "polyfills": ["html5shiv"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"]
+}
+!*/
+/* DOC
+Does the browser support the HTML5 [hidden] attribute?
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('hidden', 'hidden' in createElement('a'));
+});
diff --git a/js/modernizr/feature-detects/dom/microdata.js b/js/modernizr/feature-detects/dom/microdata.js
new file mode 100644 (file)
index 0000000..3c69fe6
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+{
+  "name": "microdata",
+  "property": "microdata",
+  "tags": ["dom"],
+  "builderAliases": ["dom_microdata"],
+  "notes": [{
+    "name": "W3 Spec",
+    "href": "http://www.w3.org/TR/html5/microdata.html"
+  }]
+}
+!*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('microdata', 'getItems' in document);
+});
diff --git a/js/modernizr/feature-detects/dom/mutationObserver.js b/js/modernizr/feature-detects/dom/mutationObserver.js
new file mode 100644 (file)
index 0000000..e31a153
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "DOM4 MutationObserver",
+  "property": "mutationobserver",
+  "caniuse": "mutationobserver",
+  "tags": ["dom"],
+  "authors": ["Karel Sedláček (@ksdlck)"],
+  "polyfills": ["mutationobservers"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver"
+  }]
+}
+!*/
+/* DOC
+
+Determines if DOM4 MutationObserver support is available.
+
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('mutationobserver',
+    !!window.MutationObserver || !!window.WebKitMutationObserver);
+});
diff --git a/js/modernizr/feature-detects/elem/datalist.js b/js/modernizr/feature-detects/elem/datalist.js
new file mode 100644 (file)
index 0000000..2b68b99
--- /dev/null
@@ -0,0 +1,26 @@
+/*!
+{
+  "name": "datalist Element",
+  "caniuse": "datalist",
+  "property": "datalistelem",
+  "tags": ["elem"],
+  "builderAliases": ["elem_datalist"],
+  "warnings": ["This test is a dupe of Modernizr.input.list. Only around for legacy reasons."],
+  "notes": [{
+    "name": "CSS Tricks Article",
+    "href": "http://css-tricks.com/15346-relevant-dropdowns-polyfill-for-datalist/"
+  },{
+    "name": "Mike Taylor Test",
+    "href": "http://miketaylr.com/test/datalist.html"
+  },{
+    "name": "Mike Taylor Code",
+    "href": "http://miketaylr.com/code/datalist.html"
+  }]
+}
+!*/
+define(['Modernizr', 'test/input'], function(Modernizr) {
+  // lol. we already have a test for datalist built in! silly you.
+  // Leaving it around in case anyone's using it
+
+  Modernizr.addTest('datalistelem', Modernizr.input.list);
+});
diff --git a/js/modernizr/feature-detects/elem/details.js b/js/modernizr/feature-detects/elem/details.js
new file mode 100644 (file)
index 0000000..63e9bc2
--- /dev/null
@@ -0,0 +1,36 @@
+/*!
+{
+  "name": "details Element",
+  "caniuse": "details",
+  "property": "details",
+  "tags": ["elem"],
+  "builderAliases": ["elem_details"],
+  "authors": ["@mathias"],
+  "notes": [{
+    "name": "Mathias' Original",
+    "href": "http://mths.be/axh"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement', 'docElement', 'testStyles'], function(Modernizr, createElement, docElement, testStyles) {
+  Modernizr.addTest('details', function() {
+    var el = createElement('details');
+    var diff;
+
+    // return early if possible; thanks @aFarkas!
+    if (!('open' in el)) {
+      return false;
+    }
+
+    testStyles('#modernizr details{display:block}', function(node) {
+      node.appendChild(el);
+      el.innerHTML = '<summary>a</summary>b';
+      diff = el.offsetHeight;
+      el.open = true;
+      diff = diff != el.offsetHeight;
+    });
+
+
+    return diff;
+  });
+});
diff --git a/js/modernizr/feature-detects/elem/output.js b/js/modernizr/feature-detects/elem/output.js
new file mode 100644 (file)
index 0000000..5babcbe
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+{
+  "name": "output Element",
+  "property": "outputelem",
+  "tags": ["elem"],
+  "builderAliases": ["elem_output"],
+  "notes": [{
+    "name": "WhatWG Spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-output-element"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('outputelem', 'value' in createElement('output'));
+});
diff --git a/js/modernizr/feature-detects/elem/picture.js b/js/modernizr/feature-detects/elem/picture.js
new file mode 100644 (file)
index 0000000..69a331c
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "picture Element",
+  "property": "picture",
+  "tags": ["elem"],
+  "authors": ["Scott Jehl", "Mat Marquis"],
+  "notes": [{
+    "name": "Specification",
+    "href": "http://picture.responsiveimages.org"
+  },{
+    "name": "Relevant spec issue",
+    "href": "https://github.com/ResponsiveImagesCG/picture-element/issues/87"
+  }]
+}
+!*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('picture', 'HTMLPictureElement' in window);
+});
diff --git a/js/modernizr/feature-detects/elem/progress-meter.js b/js/modernizr/feature-detects/elem/progress-meter.js
new file mode 100644 (file)
index 0000000..1560abc
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+{
+  "name": "progress Element",
+  "caniuse": "progressmeter",
+  "property": ["progressbar", "meter"],
+  "tags": ["elem"],
+  "builderAliases": ["elem_progress_meter"],
+  "authors": ["Stefan Wallin"]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  // Tests for progressbar-support. All browsers that don't support progressbar returns undefined =)
+  Modernizr.addTest('progressbar', createElement('progress').max !== undefined);
+
+  // Tests for meter-support. All browsers that don't support meters returns undefined =)
+  Modernizr.addTest('meter', createElement('meter').max !== undefined);
+});
diff --git a/js/modernizr/feature-detects/elem/ruby.js b/js/modernizr/feature-detects/elem/ruby.js
new file mode 100644 (file)
index 0000000..9693d4a
--- /dev/null
@@ -0,0 +1,65 @@
+/*!
+{
+  "name": "ruby, rp, rt Elements",
+  "caniuse": "ruby",
+  "property": "ruby",
+  "tags": ["elem"],
+  "builderAliases": ["elem_ruby"],
+  "authors": ["Cătălin Mariș"],
+  "notes": [{
+    "name": "WHATWG Specification",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-ruby-element"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement', 'docElement'], function(Modernizr, createElement, docElement) {
+  Modernizr.addTest('ruby', function() {
+
+    var ruby = createElement('ruby');
+    var rt = createElement('rt');
+    var rp = createElement('rp');
+    var displayStyleProperty = 'display';
+    // 'fontSize' - because it`s only used for IE6 and IE7
+    var fontSizeStyleProperty = 'fontSize';
+
+    ruby.appendChild(rp);
+    ruby.appendChild(rt);
+    docElement.appendChild(ruby);
+
+    // browsers that support <ruby> hide the <rp> via "display:none"
+    if (getStyle(rp, displayStyleProperty) == 'none' ||                                                        // for non-IE browsers
+         // but in IE browsers <rp> has "display:inline" so, the test needs other conditions:
+         getStyle(ruby, displayStyleProperty) == 'ruby' && getStyle(rt, displayStyleProperty) == 'ruby-text' || // for IE8+
+         getStyle(rp, fontSizeStyleProperty) == '6pt' && getStyle(rt, fontSizeStyleProperty) == '6pt') {       // for IE6 & IE7
+
+      cleanUp();
+      return true;
+
+    } else {
+      cleanUp();
+      return false;
+    }
+
+    function getStyle(element, styleProperty) {
+      var result;
+
+      if (window.getComputedStyle) {     // for non-IE browsers
+        result = document.defaultView.getComputedStyle(element, null).getPropertyValue(styleProperty);
+      } else if (element.currentStyle) { // for IE
+        result = element.currentStyle[styleProperty];
+      }
+
+      return result;
+    }
+
+    function cleanUp() {
+      docElement.removeChild(ruby);
+      // the removed child node still exists in memory, so ...
+      ruby = null;
+      rt = null;
+      rp = null;
+    }
+
+  });
+
+});
diff --git a/js/modernizr/feature-detects/elem/template.js b/js/modernizr/feature-detects/elem/template.js
new file mode 100644 (file)
index 0000000..fbe2257
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+{
+  "name": "Template Tag",
+  "property": "template",
+  "tags": ["elem"],
+  "notes": [{
+    "name": "HTML5Rocks Article",
+    "href": "http://www.html5rocks.com/en/tutorials/webcomponents/template/"
+  },{
+    "name": "W3 Spec",
+    "href": "https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('template', 'content' in createElement('template'));
+});
diff --git a/js/modernizr/feature-detects/elem/time.js b/js/modernizr/feature-detects/elem/time.js
new file mode 100644 (file)
index 0000000..9827616
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+{
+  "name": "time Element",
+  "property": "time",
+  "tags": ["elem"],
+  "builderAliases": ["elem_time"],
+  "notes": [{
+    "name": "WhatWG Spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-time-element"
+  }]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('time', 'valueAsDate' in createElement('time'));
+});
diff --git a/js/modernizr/feature-detects/elem/track.js b/js/modernizr/feature-detects/elem/track.js
new file mode 100644 (file)
index 0000000..6a650bb
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "Track element and Timed Text Track",
+  "property": ["texttrackapi", "track"],
+  "tags": ["elem"],
+  "builderAliases": ["elem_track"],
+  "authors": ["Addy Osmani"],
+  "notes": [{
+    "name": "W3 track Element Spec",
+    "href": "http://www.w3.org/TR/html5/video.html#the-track-element"
+  },{
+    "name": "W3 track API Spec",
+    "href": "http://www.w3.org/TR/html5/media-elements.html#text-track-api"
+  }],
+  "warnings": ["While IE10 has implemented the track element, IE10 does not expose the underlying APIs to create timed text tracks by JS (really sad)"]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('texttrackapi', typeof (createElement('video').addTextTrack) === 'function');
+
+  // a more strict test for track including UI support: document.createElement('track').kind === 'subtitles'
+  Modernizr.addTest('track', 'kind' in createElement('track'));
+});
diff --git a/js/modernizr/feature-detects/elem/unknown.js b/js/modernizr/feature-detects/elem/unknown.js
new file mode 100644 (file)
index 0000000..153850f
--- /dev/null
@@ -0,0 +1,26 @@
+/*!
+{
+  "name": "Unknown Elements",
+  "property": "unknownelements",
+  "tags": ["elem"],
+  "notes": [{
+    "name": "The Story of the HTML5 Shiv",
+    "href": "http://www.paulirish.com/2011/the-history-of-the-html5-shiv/"
+  }, {
+    "name": "original implementation of detect code",
+    "href": "https://github.com/aFarkas/html5shiv/blob/bf4fcc4/src/html5shiv.js#L36"
+  }],
+  "polyfills": ["html5shiv"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"]
+}
+!*/
+/* DOC
+Does the browser support HTML with non-standard / new elements?
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('unknownelements', function() {
+    var a = createElement('a');
+    a.innerHTML = '<xyz></xyz>';
+    return a.childNodes.length === 1;
+  });
+});
index 271db65..d8923c8 100644 (file)
@@ -1,11 +1,25 @@
-// Requires a Modernizr build with `canvastext` included
-// http://www.modernizr.com/download/#-canvas-canvastext
-Modernizr.addTest('emoji', function() {
-  if (!Modernizr.canvastext) return false;
-  var node = document.createElement('canvas'),
-      ctx = node.getContext('2d');
-  ctx.textBaseline = 'top';
-  ctx.font = '32px Arial';
-  ctx.fillText('\ud83d\ude03', 0, 0); // "smiling face with open mouth" emoji
-  return ctx.getImageData(16, 16, 1, 1).data[0] !== 0;
-});
\ No newline at end of file
+/*!
+{
+  "name": "Emoji",
+  "property": "emoji"
+}
+!*/
+/* DOC
+Detects support for emoji character sets.
+*/
+define(['Modernizr', 'createElement', 'test/canvastext'], function(Modernizr, createElement) {
+  Modernizr.addTest('emoji', function() {
+    if (!Modernizr.canvastext) {
+      return false;
+    }
+    var pixelRatio = window.devicePixelRatio || 1;
+    var offset = 12 * pixelRatio;
+    var node = createElement('canvas');
+    var ctx = node.getContext('2d');
+    ctx.fillStyle = '#f00';
+    ctx.textBaseline = 'top';
+    ctx.font = '32px Arial';
+    ctx.fillText('\ud83d\udc28', 0, 0); // U+1F428 KOALA
+    return ctx.getImageData(offset, offset, 1, 1).data[0] !== 0;
+  });
+});
diff --git a/js/modernizr/feature-detects/es5/array.js b/js/modernizr/feature-detects/es5/array.js
new file mode 100644 (file)
index 0000000..bbbff9e
--- /dev/null
@@ -0,0 +1,31 @@
+/*!
+{
+  "name": "ES5 Array",
+  "property": "es5array",
+  "notes": [{
+    "name": "ECMAScript 5.1 Language Specification",
+    "href": "http://www.ecma-international.org/ecma-262/5.1/"
+  }],
+  "polyfills": ["es5shim"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "tags": ["es5"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 5 Array per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es5array', function() {
+    return !!(Array.prototype &&
+      Array.prototype.every &&
+      Array.prototype.filter &&
+      Array.prototype.forEach &&
+      Array.prototype.indexOf &&
+      Array.prototype.lastIndexOf &&
+      Array.prototype.map &&
+      Array.prototype.some &&
+      Array.prototype.reduce &&
+      Array.prototype.reduceRight &&
+      Array.isArray);
+  });
+});
diff --git a/js/modernizr/feature-detects/es5/date.js b/js/modernizr/feature-detects/es5/date.js
new file mode 100644 (file)
index 0000000..6c7a30b
--- /dev/null
@@ -0,0 +1,32 @@
+/*!
+{
+  "name": "ES5 Date",
+  "property": "es5date",
+  "notes": [{
+    "name": "ECMAScript 5.1 Language Specification",
+    "href": "http://www.ecma-international.org/ecma-262/5.1/"
+  }],
+  "polyfills": ["es5shim"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "tags": ["es5"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 5 Date per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es5date', function() {
+    var isoDate = '2013-04-12T06:06:37.307Z',
+      canParseISODate = false;
+    try {
+      canParseISODate = !!Date.parse(isoDate);
+    } catch (e) {
+      // no ISO date parsing yet
+    }
+    return !!(Date.now &&
+      Date.prototype &&
+      Date.prototype.toISOString &&
+      Date.prototype.toJSON &&
+      canParseISODate);
+  });
+});
diff --git a/js/modernizr/feature-detects/es5/function.js b/js/modernizr/feature-detects/es5/function.js
new file mode 100644 (file)
index 0000000..eb09f42
--- /dev/null
@@ -0,0 +1,21 @@
+/*!
+{
+  "name": "ES5 Function",
+  "property": "es5function",
+  "notes": [{
+    "name": "ECMAScript 5.1 Language Specification",
+    "href": "http://www.ecma-international.org/ecma-262/5.1/"
+  }],
+  "polyfills": ["es5shim"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "tags": ["es5"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 5 Function per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es5function', function() {
+    return !!(Function.prototype && Function.prototype.bind);
+  });
+});
diff --git a/js/modernizr/feature-detects/es5/object.js b/js/modernizr/feature-detects/es5/object.js
new file mode 100644 (file)
index 0000000..e04d514
--- /dev/null
@@ -0,0 +1,33 @@
+/*!
+{
+  "name": "ES5 Object",
+  "property": "es5object",
+  "notes": [{
+    "name": "ECMAScript 5.1 Language Specification",
+    "href": "http://www.ecma-international.org/ecma-262/5.1/"
+  }],
+  "polyfills": ["es5shim", "es5sham"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "tags": ["es5"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 5 Object per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es5object', function() {
+    return !!(Object.keys &&
+      Object.create &&
+      Object.getPrototypeOf &&
+      Object.getOwnPropertyNames &&
+      Object.isSealed &&
+      Object.isFrozen &&
+      Object.isExtensible &&
+      Object.getOwnPropertyDescriptor &&
+      Object.defineProperty &&
+      Object.defineProperties &&
+      Object.seal &&
+      Object.freeze &&
+      Object.preventExtensions);
+  });
+});
diff --git a/js/modernizr/feature-detects/es5/specification.js b/js/modernizr/feature-detects/es5/specification.js
new file mode 100644 (file)
index 0000000..6912122
--- /dev/null
@@ -0,0 +1,31 @@
+/*!
+{
+  "name": "ES5",
+  "property": "es5",
+  "notes": [{
+    "name": "ECMAScript 5.1 Language Specification",
+    "href": "http://www.ecma-international.org/ecma-262/5.1/"
+  }],
+  "polyfills": ["es5shim", "es5sham"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "tags": ["es5"]
+}
+!*/
+/* DOC
+Check if browser implements everything as specified in ECMAScript 5.
+*/
+define(['Modernizr', 'test/es5/array', 'test/es5/date', 'test/es5/function', 'test/es5/object', 'test/es5/strictmode', 'test/es5/string', 'test/json', 'test/es5/syntax', 'test/es5/undefined'], function(Modernizr) {
+  Modernizr.addTest('es5', function() {
+    return !!(
+      Modernizr.es5array &&
+      Modernizr.es5date &&
+      Modernizr.es5function &&
+      Modernizr.es5object &&
+      Modernizr.strictmode &&
+      Modernizr.es5string &&
+      Modernizr.json &&
+      Modernizr.es5syntax &&
+      Modernizr.es5undefined
+    );
+  });
+});
diff --git a/js/modernizr/feature-detects/es5/strictmode.js b/js/modernizr/feature-detects/es5/strictmode.js
new file mode 100644 (file)
index 0000000..e539495
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "ES5 Strict Mode",
+  "property": "strictmode",
+  "caniuse": "sctrict-mode",
+  "notes": [{
+    "name": "ECMAScript 5.1 Language Specification",
+    "href": "http://www.ecma-international.org/ecma-262/5.1/"
+  }],
+  "authors": ["@kangax"],
+  "tags": ["es5"],
+  "builderAliases": ["es5_strictmode"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 5 Object strict mode.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('strictmode', (function() {'use strict'; return !this; })());
+});
diff --git a/js/modernizr/feature-detects/es5/string.js b/js/modernizr/feature-detects/es5/string.js
new file mode 100644 (file)
index 0000000..d47a6e3
--- /dev/null
@@ -0,0 +1,21 @@
+/*!
+{
+  "name": "ES5 String",
+  "property": "es5string",
+  "notes": [{
+    "name": "ECMAScript 5.1 Language Specification",
+    "href": "http://www.ecma-international.org/ecma-262/5.1/"
+  }],
+  "polyfills": ["es5shim"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "tags": ["es5"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 5 String per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es5string', function() {
+    return !!(String.prototype && String.prototype.trim);
+  });
+});
diff --git a/js/modernizr/feature-detects/es5/syntax.js b/js/modernizr/feature-detects/es5/syntax.js
new file mode 100644 (file)
index 0000000..15305c8
--- /dev/null
@@ -0,0 +1,42 @@
+/*!
+{
+  "name": "ES5 Syntax",
+  "property": "es5syntax",
+  "notes": [{
+    "name": "ECMAScript 5.1 Language Specification",
+    "href": "http://www.ecma-international.org/ecma-262/5.1/"
+  }, {
+    "name": "original implementation of detect code",
+    "href": "http://kangax.github.io/es5-compat-table/"
+  }],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "warnings": ["This detect uses `eval()`, so CSP may be a problem."],
+  "tags": ["es5"]
+}
+!*/
+/* DOC
+Check if browser accepts ECMAScript 5 syntax.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es5syntax', function() {
+    var value, obj, stringAccess, getter, setter, reservedWords, zeroWidthChars;
+    try {
+      // Property access on strings
+      stringAccess = eval('"foobar"[3] === "b"');
+      // Getter in property initializer
+      getter = eval('({ get x(){ return 1 } }).x === 1');
+      eval('({ set x(v){ value = v; } }).x = 1');
+      // Setter in property initializer
+      setter = value === 1;
+      // Reserved words as property names
+      eval('obj = ({ if: 1 })');
+      reservedWords = obj['if'] === 1;
+      // Zero-width characters in identifiers
+      zeroWidthChars = eval('_\u200c\u200d = true');
+
+      return stringAccess && getter && setter && reservedWords && zeroWidthChars;
+    } catch (ignore) {
+      return false;
+    }
+  });
+});
diff --git a/js/modernizr/feature-detects/es5/undefined.js b/js/modernizr/feature-detects/es5/undefined.js
new file mode 100644 (file)
index 0000000..fad02a8
--- /dev/null
@@ -0,0 +1,32 @@
+/*!
+{
+  "name": "ES5 Immutable Undefined",
+  "property": "es5undefined",
+  "notes": [{
+    "name": "ECMAScript 5.1 Language Specification",
+    "href": "http://www.ecma-international.org/ecma-262/5.1/"
+  }, {
+    "name": "original implementation of detect code",
+    "href": "http://kangax.github.io/es5-compat-table/"
+  }],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "tags": ["es5"]
+}
+!*/
+/* DOC
+Check if browser prevents assignment to global `undefined` per ECMAScript 5.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es5undefined', function() {
+    var result, originalUndefined;
+    try {
+      originalUndefined = window.undefined;
+      window.undefined = 12345;
+      result = typeof window.undefined === 'undefined';
+      window.undefined = originalUndefined;
+    } catch (e) {
+      return false;
+    }
+    return result;
+  });
+});
diff --git a/js/modernizr/feature-detects/es6/array.js b/js/modernizr/feature-detects/es6/array.js
new file mode 100644 (file)
index 0000000..93c75e8
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+{
+  "name": "ES6 Array",
+  "property": "es6array",
+  "notes": [{
+    "name": "unofficial ECMAScript 6 draft specification",
+    "href": "http://people.mozilla.org/~jorendorff/es6-draft.html"
+  }],
+  "polyfills": ["es6shim"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."],
+  "tags": ["es6"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 6 Array per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es6array', !!(Array.prototype &&
+    Array.prototype.copyWithin &&
+    Array.prototype.fill &&
+    Array.prototype.find &&
+    Array.prototype.findIndex &&
+    Array.prototype.keys &&
+    Array.prototype.entries &&
+    Array.prototype.values &&
+    Array.from &&
+    Array.of));
+});
diff --git a/js/modernizr/feature-detects/es6/contains.js b/js/modernizr/feature-detects/es6/contains.js
new file mode 100644 (file)
index 0000000..f8e8493
--- /dev/null
@@ -0,0 +1,14 @@
+/*!
+{
+  "name": "ES5 String.prototype.contains",
+  "property": "contains",
+  "authors": ["Robert Kowalski"],
+  "tags": ["es6"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 6 `String.prototype.contains` per specification.
+*/
+define(['Modernizr', 'is'], function(Modernizr, is) {
+  Modernizr.addTest('contains', is(String.prototype.contains, 'function'));
+});
diff --git a/js/modernizr/feature-detects/es6/generators.js b/js/modernizr/feature-detects/es6/generators.js
new file mode 100644 (file)
index 0000000..bffb259
--- /dev/null
@@ -0,0 +1,22 @@
+/*!
+{
+  "name": "ES6 Generators",
+  "property": "generators",
+  "authors": ["Michael Kachanovskyi"],
+  "tags": ["es6"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 6 Generators per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('generators', function() {
+    try {
+      /* jshint evil: true */
+      new Function('function* test() {}')();
+    } catch (e) {
+      return false;
+    }
+    return true;
+  });
+});
diff --git a/js/modernizr/feature-detects/es6/math.js b/js/modernizr/feature-detects/es6/math.js
new file mode 100644 (file)
index 0000000..9dad6b6
--- /dev/null
@@ -0,0 +1,37 @@
+/*!
+{
+  "name": "ES6 Math",
+  "property": "es6math",
+  "notes": [{
+    "name": "unofficial ECMAScript 6 draft specification",
+    "href": "http://people.mozilla.org/~jorendorff/es6-draft.html"
+  }],
+  "polyfills": ["es6shim"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."],
+  "tags": ["es6"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 6 Math per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es6math', !!(Math &&
+    Math.clz32 &&
+    Math.cbrt &&
+    Math.imul &&
+    Math.sign &&
+    Math.log10 &&
+    Math.log2 &&
+    Math.log1p &&
+    Math.expm1 &&
+    Math.cosh &&
+    Math.sinh &&
+    Math.tanh &&
+    Math.acosh &&
+    Math.asinh &&
+    Math.atanh &&
+    Math.hypot &&
+    Math.trunc &&
+    Math.fround));
+});
diff --git a/js/modernizr/feature-detects/es6/number.js b/js/modernizr/feature-detects/es6/number.js
new file mode 100644 (file)
index 0000000..75ece77
--- /dev/null
@@ -0,0 +1,28 @@
+/*!
+{
+  "name": "ES6 Number",
+  "property": "es6number",
+  "notes": [{
+    "name": "unofficial ECMAScript 6 draft specification",
+    "href": "http://people.mozilla.org/~jorendorff/es6-draft.html"
+  }],
+  "polyfills": ["es6shim"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."],
+  "tags": ["es6"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 6 Number per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es6number', !!(Number.isFinite &&
+    Number.isInteger &&
+    Number.isSafeInteger &&
+    Number.isNaN &&
+    Number.parseInt &&
+    Number.parseFloat &&
+    Number.isInteger(Number.MAX_SAFE_INTEGER) &&
+    Number.isInteger(Number.MIN_SAFE_INTEGER) &&
+    Number.isFinite(Number.EPSILON)));
+});
diff --git a/js/modernizr/feature-detects/es6/object.js b/js/modernizr/feature-detects/es6/object.js
new file mode 100644 (file)
index 0000000..b1fdda9
--- /dev/null
@@ -0,0 +1,22 @@
+/*!
+{
+  "name": "ES6 Object",
+  "property": "es6object",
+  "notes": [{
+    "name": "unofficial ECMAScript 6 draft specification",
+    "href": "http://people.mozilla.org/~jorendorff/es6-draft.html"
+  }],
+  "polyfills": ["es6shim"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."],
+  "tags": ["es6"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 6 Object per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es6object', !!(Object.assign &&
+    Object.is &&
+    Object.setPrototypeOf));
+});
diff --git a/js/modernizr/feature-detects/es6/promises.js b/js/modernizr/feature-detects/es6/promises.js
new file mode 100644 (file)
index 0000000..e412132
--- /dev/null
@@ -0,0 +1,41 @@
+/*!
+{
+  "name": "ES6 Promises",
+  "property": "promises",
+  "caniuse": "promises",
+  "polyfills": ["es6promises"],
+  "authors": ["Krister Kari", "Jake Archibald"],
+  "tags": ["es6"],
+  "notes": [{
+    "name": "The ES6 promises spec",
+    "href": "https://github.com/domenic/promises-unwrapping"
+  },{
+    "name": "Chromium dashboard - ES6 Promises",
+    "href": "http://www.chromestatus.com/features/5681726336532480"
+  },{
+    "name": "JavaScript Promises: There and back again - HTML5 Rocks",
+    "href": "http://www.html5rocks.com/en/tutorials/es6/promises/"
+  }]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 6 Promises per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('promises', function() {
+    return 'Promise' in window &&
+    // Some of these methods are missing from
+    // Firefox/Chrome experimental implementations
+    'resolve' in window.Promise &&
+    'reject' in window.Promise &&
+    'all' in window.Promise &&
+    'race' in window.Promise &&
+    // Older version of the spec had a resolver object
+    // as the arg rather than a function
+    (function() {
+      var resolve;
+      new window.Promise(function(r) { resolve = r; });
+      return typeof resolve === 'function';
+    }());
+  });
+});
diff --git a/js/modernizr/feature-detects/es6/string.js b/js/modernizr/feature-detects/es6/string.js
new file mode 100644 (file)
index 0000000..f65f10b
--- /dev/null
@@ -0,0 +1,26 @@
+/*!
+{
+  "name": "ES6 String",
+  "property": "es6string",
+  "notes": [{
+    "name": "unofficial ECMAScript 6 draft specification",
+    "href": "http://people.mozilla.org/~jorendorff/es6-draft.html"
+  }],
+  "polyfills": ["es6shim"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."],
+  "tags": ["es6"]
+}
+!*/
+/* DOC
+Check if browser implements ECMAScript 6 String per specification.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('es6string', !!(String.fromCodePoint &&
+    String.raw &&
+    String.prototype.codePointAt &&
+    String.prototype.repeat &&
+    String.prototype.startsWith &&
+    String.prototype.endsWith &&
+    String.prototype.contains));
+});
diff --git a/js/modernizr/feature-detects/event/deviceorientation-motion.js b/js/modernizr/feature-detects/event/deviceorientation-motion.js
new file mode 100644 (file)
index 0000000..a21fc5a
--- /dev/null
@@ -0,0 +1,31 @@
+/*!
+{
+  "name": "Orientation and Motion Events",
+  "property": ["devicemotion", "deviceorientation"],
+  "caniuse": "deviceorientation",
+  "notes": [{
+    "name": "W3C Editor's Draft",
+    "href": "http://dev.w3.org/geo/api/spec-source-orientation.html"
+  },{
+    "name": "Implementation by iOS Safari (Orientation)",
+    "href": "http://goo.gl/fhce3"
+  },{
+    "name": "Implementation by iOS Safari (Motion)",
+    "href": "http://goo.gl/rLKz8"
+  }],
+  "authors": ["Shi Chuan"],
+  "tags": ["event"],
+  "builderAliases": ["event_deviceorientation_motion"]
+}
+!*/
+/* DOC
+Part of Device Access aspect of HTML5, same category as geolocation.
+
+`devicemotion` tests for Device Motion Event support, returns boolean value true/false.
+
+`deviceorientation` tests for Device Orientation Event support, returns boolean value true/false
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('devicemotion', 'DeviceMotionEvent' in window);
+  Modernizr.addTest('deviceorientation', 'DeviceOrientationEvent' in window);
+});
diff --git a/js/modernizr/feature-detects/event/oninput.js b/js/modernizr/feature-detects/event/oninput.js
new file mode 100644 (file)
index 0000000..6a8ebc0
--- /dev/null
@@ -0,0 +1,58 @@
+/*!
+{
+  "name": "onInput Event",
+  "property": "oninput",
+  "notes": [{
+    "name": "MDN article",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.oninput"
+  },{
+    "name": "WHATWG spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#common-event-behaviors"
+  },{
+    "name": "Detecting onInput support",
+    "href": "http://danielfriesen.name/blog/2010/02/16/html5-browser-maze-oninput-support"
+  }],
+  "authors": ["Patrick Kettner"],
+  "tags": ["event"]
+}
+!*/
+/* DOC
+`oninput` tests if the browser is able to detect the input event
+*/
+define(['Modernizr', 'docElement', 'createElement', 'testStyles', 'hasEvent'], function(Modernizr, docElement, createElement, testStyles, hasEvent) {
+
+  Modernizr.addTest('oninput', function() {
+    var input = createElement('input');
+    var supportsOnInput;
+    input.setAttribute('oninput', 'return');
+
+    if (hasEvent('oninput', docElement) || typeof input.oninput == 'function') {
+      return true;
+    }
+
+    // IE doesn't support onInput, so we wrap up the non IE APIs
+    // (createEvent, addEventListener) in a try catch, rather than test for
+    // their trident equivalent.
+    try {
+      // Older Firefox didn't map oninput attribute to oninput property
+      var testEvent  = document.createEvent('KeyboardEvent');
+      supportsOnInput = false;
+      var handler = function(e) {
+        supportsOnInput = true;
+        e.preventDefault();
+        e.stopPropagation();
+      };
+
+      testEvent.initKeyEvent('keypress', true, true, window, false, false, false, false, 0, 'e'.charCodeAt(0));
+      docElement.appendChild(input);
+      input.addEventListener('input', handler, false);
+      input.focus();
+      input.dispatchEvent(testEvent);
+      input.removeEventListener('input', handler, false);
+      docElement.removeChild(input);
+    } catch (e) {
+      supportsOnInput = false;
+    }
+      return supportsOnInput;
+  });
+});
diff --git a/js/modernizr/feature-detects/eventlistener.js b/js/modernizr/feature-detects/eventlistener.js
new file mode 100644 (file)
index 0000000..5069f45
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "Event Listener",
+  "property": "eventlistener",
+  "authors": ["Andrew Betts (@triblondon)"],
+  "notes": [{
+    "name": "W3C Spec",
+    "href": "http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Registration-interfaces"
+  }],
+  "polyfills": ["eventlistener"]
+}
+!*/
+/* DOC
+Detects native support for addEventListener
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('eventlistener', 'addEventListener' in window);
+});
index 994c13d..1bc866c 100644 (file)
@@ -1,32 +1,42 @@
-// EXIF Orientation test
-
-// iOS looks at the EXIF Orientation flag in jpgs and rotates the image
-// accordingly. Looks like most desktop browsers just ignore this data.
-
-// description: www.impulseadventure.com/photo/exif-orientation.html
-
-// Bug trackers:
-//    bugzil.la/298619 (unimplemented)
-//    crbug.com/56845 (looks incomplete)
-//    webk.it/19688 (available upstream but its up all ports to turn on individually)
-//
-
-// detect by Paul Sayre
-
-
-(function(){
-
-  var img = new Image();
-
-  img.onerror = function() {
-      Modernizr.addTest('exif-orientation', function () { return false; });
-  };
-
-  img.onload = function() {
-      Modernizr.addTest('exif-orientation', function () { return img.width !== 2; });
-  };
-
-  // There may be a way to shrink this more, it's a 1x2 white jpg with the orientation flag set to 6
-  img.src = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAASUkqAAgAAAABABIBAwABAAAABgASAAAAAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAABAAIDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+/iiiigD/2Q==";
-
-})();
+/*!
+{
+  "name": "EXIF Orientation",
+  "property": "exiforientation",
+  "tags": ["image"],
+  "builderAliases": ["exif_orientation"],
+  "async": true,
+  "authors": ["Paul Sayre"],
+  "notes": [{
+    "name": "Article by Dave Perrett",
+    "href": "http://recursive-design.com/blog/2012/07/28/exif-orientation-handling-is-a-ghetto/"
+  },{
+    "name": "Article by Calvin Hass",
+    "href": "http://www.impulseadventure.com/photo/exif-orientation.html"
+  }]
+}
+!*/
+/* DOC
+Detects support for EXIF Orientation in JPEG images.
+
+iOS looks at the EXIF Orientation flag in JPEGs and rotates the image accordingly. Most desktop browsers just ignore this data.
+*/
+define(['Modernizr', 'addTest'], function(Modernizr, addTest) {
+  // Bug trackers:
+  //    bugzil.la/298619 (unimplemented)
+  //    crbug.com/56845 (looks incomplete)
+  //    webk.it/19688 (available upstream but its up all ports to turn on individually)
+  Modernizr.addAsyncTest(function() {
+    var img = new Image();
+
+    img.onerror = function() {
+      addTest('exiforientation', false, {aliases: ['exif-orientation']});
+    };
+
+    img.onload = function() {
+      addTest('exiforientation', img.width !== 2, {aliases: ['exif-orientation']});
+    };
+
+    // There may be a way to shrink this more, it's a 1x2 white jpg with the orientation flag set to 6
+    img.src = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAASUkqAAgAAAABABIBAwABAAAABgASAAAAAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAABAAIDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+/iiiigD/2Q==';
+  });
+});
diff --git a/js/modernizr/feature-detects/file/api.js b/js/modernizr/feature-detects/file/api.js
new file mode 100644 (file)
index 0000000..29d530c
--- /dev/null
@@ -0,0 +1,24 @@
+/*!
+{
+  "name": "File API",
+  "property": "filereader",
+  "caniuse": "fileapi",
+  "notes": [{
+    "name": "W3C Working Draft",
+    "href": "http://www.w3.org/TR/FileAPI/"
+  }],
+  "tags": ["file"],
+  "builderAliases": ["file_api"],
+  "knownBugs": ["Will fail in Safari 5 due to its lack of support for the standards defined FileReader object"]
+}
+!*/
+/* DOC
+`filereader` tests for the File API specification
+
+Tests for objects specific to the File API W3C specification without
+being redundant (don't bother testing for Blob since it is assumed
+to be the File object's prototype.)
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('filereader', !!(window.File && window.FileList && window.FileReader));
+});
diff --git a/js/modernizr/feature-detects/file/filesystem.js b/js/modernizr/feature-detects/file/filesystem.js
new file mode 100644 (file)
index 0000000..2221e5a
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "Filesystem API",
+  "property": "filesystem",
+  "caniuse": "filesystem",
+  "notes": [{
+    "name": "W3 Draft",
+    "href": "dev.w3.org/2009/dap/file-system/file-dir-sys.html"
+  }],
+  "authors": ["Eric Bidelman (@ebidel)"],
+  "tags": ["file"],
+  "builderAliases": ["file_filesystem"],
+  "knownBugs": ["The API will be present in Chrome incognito, but will throw an exception. See crbug.com/93417"]
+}
+!*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('filesystem', !!prefixed('requestFileSystem', window));
+});
diff --git a/js/modernizr/feature-detects/flash.js b/js/modernizr/feature-detects/flash.js
new file mode 100644 (file)
index 0000000..a7a0402
--- /dev/null
@@ -0,0 +1,114 @@
+/*!
+  {
+  "name": "Flash",
+  "property": "flash",
+  "tags": ["flash"],
+  "polyfills": ["shumway"]
+  }
+  !*/
+/* DOC
+Detects support flash, as well as flash blocking plugins
+*/
+define(['Modernizr', 'createElement', 'docElement', 'addTest', 'getBody', 'isSVG'], function(Modernizr, createElement, docElement, addTest, getBody, isSVG) {
+  Modernizr.addAsyncTest(function() {
+    /* jshint -W053 */
+
+    var removeFakeBody = function(body) {
+      // If we’re rockin’ an attached fake body, clean it up
+      if (body.fake && body.parentNode) {
+        body.parentNode.removeChild(body);
+      }
+    };
+    var runTest = function(result, embed) {
+      var bool = !!result;
+      if (bool) {
+        bool = new Boolean(bool);
+        bool.blocked = (result === 'blocked');
+      }
+      addTest('flash', function() { return bool; });
+
+      if (embed && body.contains(embed)) {
+
+        // in case embed has been wrapped, as with ClickToPlugin
+        while (embed.parentNode !== body) {
+          embed = embed.parentNode;
+        }
+
+        body.removeChild(embed);
+      }
+
+    };
+    var easy_detect;
+    var activex;
+    // we wrap activex in a try/catch because when flash is disabled through
+    // ActiveX controls, it throws an error.
+    try {
+      // Pan is an API that exists for flash objects.
+      activex = 'ActiveXObject' in window && 'Pan' in new window.ActiveXObject('ShockwaveFlash.ShockwaveFlash');
+    } catch (e) {}
+
+    easy_detect = !(('plugins' in navigator && 'Shockwave Flash' in navigator.plugins) || activex);
+
+    if (easy_detect || isSVG) {
+      runTest(false);
+    }
+    else {
+      // flash seems to be installed, but it might be blocked. We have to
+      // actually create an element to see what happens to it.
+      var embed = createElement('embed');
+      var body = getBody();
+      var blockedDetect;
+      var inline_style;
+
+      embed.type = 'application/x-shockwave-flash';
+
+      // Need to do this in the body (fake or otherwise) otherwise IE8 complains
+      body.appendChild(embed);
+      docElement.appendChild(body);
+
+      // Pan doesn't exist in the embed if its IE (its on the ActiveXObjeect)
+      // so this check is for all other browsers.
+      if (!('Pan' in embed) && !activex) {
+        runTest('blocked', embed);
+        removeFakeBody(body);
+        return;
+      }
+
+      blockedDetect = function() {
+        // if we used a fake body originally, we need to restart this test, since
+        // we haven't been attached to the DOM, and therefore none of the blockers
+        // have had time to work.
+        if (!docElement.contains(body)) {
+          body = document.body || body;
+          embed = createElement('embed');
+          embed.type = 'application/x-shockwave-flash';
+          body.appendChild(embed);
+          return setTimeout(blockedDetect, 1000);
+        }
+        if (!docElement.contains(embed)) {
+          runTest('blocked');
+        }
+        else {
+          inline_style = embed.style.cssText;
+          if (inline_style !== '') {
+            // the style of the element has changed automatically. This is a
+            // really poor heuristic, but for lower end flash blocks, it the
+            // only change they can make.
+            runTest('blocked', embed);
+          }
+          else {
+            runTest(true, embed);
+          }
+        }
+        removeFakeBody(body);
+      };
+
+      // If we have got this far, there is still a chance a userland plugin
+      // is blocking us (either changing the styles, or automatically removing
+      // the element). Both of these require us to take a step back for a moment
+      // to allow for them to get time of the thread, hence a setTimeout.
+      //
+      setTimeout(blockedDetect, 10);
+    }
+  });
+});
diff --git a/js/modernizr/feature-detects/forms/capture.js b/js/modernizr/feature-detects/forms/capture.js
new file mode 100644 (file)
index 0000000..5a9696e
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "input[capture] Attribute",
+  "property": "capture",
+  "tags": ["video", "image", "audio", "media", "attribute"],
+  "notes": [{
+    "name": "W3C draft: HTML Media Capture",
+    "href": "http://www.w3.org/TR/html-media-capture/"
+  }]
+}
+!*/
+/* DOC
+When used on an `<input>`, this attribute signifies that the resource it takes should be generated via device's camera, camcorder, sound recorder.
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  // testing for capture attribute in inputs
+  Modernizr.addTest('capture', ('capture' in createElement('input')));
+});
diff --git a/js/modernizr/feature-detects/forms/fileinput.js b/js/modernizr/feature-detects/forms/fileinput.js
new file mode 100644 (file)
index 0000000..c71a0bd
--- /dev/null
@@ -0,0 +1,24 @@
+/*!
+{
+  "name": "input[file] Attribute",
+  "property": "fileinput",
+  "caniuse" : "forms",
+  "tags": ["file", "forms", "input"],
+  "builderAliases": ["forms_fileinput"]
+}
+!*/
+/* DOC
+Detects whether input type="file" is available on the platform
+
+E.g. iOS < 6 and some android version don't support this
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('fileinput', function() {
+    if (navigator.userAgent.match(/(Android (1.0|1.1|1.5|1.6|2.0|2.1))|(Windows Phone (OS 7|8.0))|(XBLWP)|(ZuneWP)|(w(eb)?OSBrowser)|(webOS)|(Kindle\/(1.0|2.0|2.5|3.0))/)) {
+      return false;
+    }
+    var elem = createElement('input');
+    elem.type = 'file';
+    return !elem.disabled;
+  });
+});
diff --git a/js/modernizr/feature-detects/forms/fileinputdirectory.js b/js/modernizr/feature-detects/forms/fileinputdirectory.js
new file mode 100644 (file)
index 0000000..4d3fc90
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+{
+  "name": "input[directory] Attribute",
+  "property": "directory",
+  "authors": ["silverwind"],
+  "tags": ["file", "input", "attribute"]
+}
+!*/
+/* DOC
+When used on an `<input type="file">`, the `directory` attribute instructs
+the user agent to present a directory selection dialog instead of the usual
+file selection dialog.
+*/
+define(['Modernizr', 'createElement', 'domPrefixes'], function(Modernizr, createElement, domPrefixes) {
+  Modernizr.addTest('fileinputdirectory', function() {
+    var elem = createElement('input'), dir = 'directory';
+    elem.type = 'file';
+    if (dir in elem) {
+      return true;
+    } else {
+      for (var i = 0, len = domPrefixes.length; i < len; i++) {
+        if (domPrefixes[i] + dir in elem) {
+          return true;
+        }
+      }
+    }
+    return false;
+  });
+});
diff --git a/js/modernizr/feature-detects/forms/formattribute.js b/js/modernizr/feature-detects/forms/formattribute.js
new file mode 100644 (file)
index 0000000..20595c3
--- /dev/null
@@ -0,0 +1,47 @@
+/*!
+{
+  "name": "input[form] Attribute",
+  "property": "formattribute",
+  "tags": ["attribute", "forms", "input"],
+  "builderAliases": ["forms_formattribute"]
+}
+!*/
+/* DOC
+Detects whether input form="form_id" is available on the platform
+E.g. IE 10 (and below), don't support this
+*/
+define(['Modernizr', 'createElement', 'docElement'], function(Modernizr, createElement, docElement) {
+
+  Modernizr.addTest('formattribute', function() {
+    var form = createElement('form');
+    var input = createElement('input');
+    var div = createElement('div');
+    var id = 'formtest' + (new Date()).getTime();
+    var attr;
+    var bool = false;
+
+    form.id = id;
+
+    //IE6/7 confuses the form idl attribute and the form content attribute, so we use document.createAttribute
+    try {
+      input.setAttribute('form', id);
+    }
+    catch (e) {
+      if (document.createAttribute) {
+        attr = document.createAttribute('form');
+        attr.nodeValue = id;
+        input.setAttributeNode(attr);
+      }
+    }
+
+    div.appendChild(form);
+    div.appendChild(input);
+
+    docElement.appendChild(div);
+
+    bool = form.elements && form.elements.length === 1 && input.form == form;
+
+    div.parentNode.removeChild(div);
+    return bool;
+  });
+});
diff --git a/js/modernizr/feature-detects/forms/inputnumber-l10n.js b/js/modernizr/feature-detects/forms/inputnumber-l10n.js
new file mode 100644 (file)
index 0000000..72369af
--- /dev/null
@@ -0,0 +1,48 @@
+/*!
+{
+  "name": "input[type=\"number\"] Localization",
+  "property": "localizednumber",
+  "tags": ["forms", "localization", "attribute"],
+  "authors": ["Peter Janes"],
+  "notes": [{
+    "name": "Webkit Bug Tracker Listing",
+    "href": "https://bugs.webkit.org/show_bug.cgi?id=42484"
+  },{
+    "name": "Based on This",
+    "href": "http://trac.webkit.org/browser/trunk/LayoutTests/fast/forms/script-tests/input-number-keyoperation.js?rev=80096#L9"
+  }],
+  "knownBugs": ["Only ever returns true if the browser/OS is configured to use comma as a decimal separator. This is probably fine for most use cases."]
+}
+!*/
+/* DOC
+Detects whether input type="number" is capable of receiving and displaying localized numbers, e.g. with comma separator.
+*/
+define(['Modernizr', 'createElement', 'docElement', 'getBody', 'test/inputtypes', 'test/forms/validation'], function(Modernizr, createElement, docElement, getBody) {
+  Modernizr.addTest('localizednumber', function() {
+    // this extends our testing of input[type=number], so bomb out if that's missing
+    if (!Modernizr.inputtypes.number) { return false; }
+    // we rely on checkValidity later, so bomb out early if we don't have it
+    if (!Modernizr.formvalidation) { return false; }
+
+    var el = createElement('div');
+    var diff;
+    var body = getBody();
+
+    var root = (function() {
+      return docElement.insertBefore(body, docElement.firstElementChild || docElement.firstChild);
+    }());
+    el.innerHTML = '<input type="number" value="1.0" step="0.1"/>';
+    var input = el.childNodes[0];
+    root.appendChild(el);
+    input.focus();
+    try {
+      document.execCommand('InsertText', false, '1,1');
+    } catch (e) { // prevent warnings in IE
+    }
+    diff = input.type === 'number' && input.valueAsNumber === 1.1 && input.checkValidity();
+    root.removeChild(el);
+    body.fake && root.parentNode.removeChild(root);
+    return diff;
+  });
+
+});
diff --git a/js/modernizr/feature-detects/forms/placeholder.js b/js/modernizr/feature-detects/forms/placeholder.js
new file mode 100644 (file)
index 0000000..c03bdac
--- /dev/null
@@ -0,0 +1,14 @@
+/*!
+{
+  "name": "placeholder attribute",
+  "property": "placeholder",
+  "tags": ["forms", "attribute"],
+  "builderAliases": ["forms_placeholder"]
+}
+!*/
+/* DOC
+Tests for placeholder attribute in inputs and textareas
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('placeholder', ('placeholder' in createElement('input') && 'placeholder' in createElement('textarea')));
+});
diff --git a/js/modernizr/feature-detects/forms/requestautocomplete.js b/js/modernizr/feature-detects/forms/requestautocomplete.js
new file mode 100644 (file)
index 0000000..d07d9e4
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "form#requestAutocomplete()",
+  "property": "requestautocomplete",
+  "tags": ["form", "forms", "requestAutocomplete", "payments"],
+  "notes": [{
+    "name": "WHATWG proposed spec",
+    "href": "http://wiki.whatwg.org/wiki/RequestAutocomplete"
+  }]
+}
+!*/
+/* DOC
+When used with input[autocomplete] to annotate a form, form.requestAutocomplete() shows a dialog in Chrome that speeds up
+checkout flows (payments specific for now).
+*/
+define(['Modernizr', 'createElement', 'prefixed'], function(Modernizr, createElement, prefixed) {
+  Modernizr.addTest('requestautocomplete', !!prefixed('requestAutocomplete', createElement('form')));
+});
diff --git a/js/modernizr/feature-detects/forms/validation.js b/js/modernizr/feature-detects/forms/validation.js
new file mode 100644 (file)
index 0000000..7264447
--- /dev/null
@@ -0,0 +1,66 @@
+/*!
+{
+  "name": "Form Validation",
+  "property": "formvalidation",
+  "tags": ["forms", "validation", "attribute"],
+  "builderAliases": ["forms_validation"]
+}
+!*/
+/* DOC
+This implementation only tests support for interactive form validation.
+To check validation for a specific type or a specific other constraint,
+the test can be combined:
+
+- `Modernizr.inputtypes.number && Modernizr.formvalidation` (browser supports rangeOverflow, typeMismatch etc. for type=number)
+- `Modernizr.input.required && Modernizr.formvalidation` (browser supports valueMissing)
+*/
+define(['Modernizr', 'createElement', 'docElement', 'testStyles'], function(Modernizr, createElement, docElement, testStyles) {
+  Modernizr.addTest('formvalidation', function() {
+    var form = createElement('form');
+    if (!('checkValidity' in form) || !('addEventListener' in form)) {
+      return false;
+    }
+    if ('reportValidity' in form) {
+      return true;
+    }
+    var invalidFired = false;
+    var input;
+
+    Modernizr.formvalidationapi =  true;
+
+    // Prevent form from being submitted
+    form.addEventListener('submit', function(e) {
+      //Opera does not validate form, if submit is prevented
+      if (!window.opera) {
+        e.preventDefault();
+      }
+      e.stopPropagation();
+    }, false);
+
+    // Calling form.submit() doesn't trigger interactive validation,
+    // use a submit button instead
+    //older opera browsers need a name attribute
+    form.innerHTML = '<input name="modTest" required><button></button>';
+
+    testStyles('#modernizr form{position:absolute;top:-99999em}', function(node) {
+      node.appendChild(form);
+
+      input = form.getElementsByTagName('input')[0];
+
+      // Record whether "invalid" event is fired
+      input.addEventListener('invalid', function(e) {
+        invalidFired = true;
+        e.preventDefault();
+        e.stopPropagation();
+      }, false);
+
+      //Opera does not fully support the validationMessage property
+      Modernizr.formvalidationmessage = !!input.validationMessage;
+
+      // Submit form by clicking submit button
+      form.getElementsByTagName('button')[0].click();
+    });
+
+    return invalidFired;
+  });
+});
index 7432571..ec2948f 100644 (file)
@@ -1,10 +1,20 @@
-Modernizr.addTest('fullscreen',function(){
-     for(var i = 0; i < Modernizr._domPrefixes.length; i++) {
-        if( document[Modernizr._domPrefixes[i].toLowerCase() + 'CancelFullScreen'])
-            return true;
-     }
-     return !!document['cancelFullScreen'] || false;
+/*!
+{
+  "name": "Fullscreen API",
+  "property": "fullscreen",
+  "caniuse": "fullscreen",
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en/API/Fullscreen"
+  }],
+  "polyfills": ["screenfulljs"],
+  "builderAliases": ["fullscreen_api"]
+}
+!*/
+/* DOC
+Detects support for the ability to make the current website take over the user's entire screen
+*/
+define(['Modernizr', 'domPrefixes', 'prefixed'], function(Modernizr, domPrefixes, prefixed) {
+  // github.com/Modernizr/Modernizr/issues/739
+  Modernizr.addTest('fullscreen', !!(prefixed('exitFullscreen', document, false) || prefixed('cancelFullScreen', document, false)));
 });
-
-// http://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/ControllingMediaWithJavaScript/ControllingMediaWithJavaScript.html#//apple_ref/doc/uid/TP40009523-CH3-SW20
-// https://developer.mozilla.org/en/API/Fullscreen
index 0756289..f65e1b5 100644 (file)
@@ -1,12 +1,24 @@
-// GamePad API
-// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html
-// By Eric Bidelman
+/*!
+{
+  "name": "GamePad API",
+  "property": "gamepads",
+  "authors": ["Eric Bidelman"],
+  "tags": ["media"],
+  "notes": [{
+    "name": "W3C spec",
+    "href": "http://www.w3.org/TR/gamepad/"
+  },{
+    "name": "HTML5 Rocks tutorial",
+    "href": "http://www.html5rocks.com/en/tutorials/doodles/gamepad/#toc-featuredetect"
+  }],
+  "warnings": [],
+  "polyfills": []
+}
+!*/
+/* DOC
+Detects support for the Gamepad API, for access to gamepads and controllers.
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
 
-// FF has Gamepad API support only in special builds, but not in any release (even behind a flag)
-// Their current implementation has no way to feature detect, only events to bind to.
-//   http://www.html5rocks.com/en/tutorials/doodles/gamepad/#toc-featuredetect
-
-// but a patch will bring them up to date with the spec when it lands (and they'll pass this test)
-//   https://bugzilla.mozilla.org/show_bug.cgi?id=690935
-
-Modernizr.addTest('gamepads', !!Modernizr.prefixed('getGamepads', navigator));
+  Modernizr.addTest('gamepads', !!prefixed('getGamepads', navigator));
+});
diff --git a/js/modernizr/feature-detects/geolocation.js b/js/modernizr/feature-detects/geolocation.js
new file mode 100644 (file)
index 0000000..f8ac017
--- /dev/null
@@ -0,0 +1,34 @@
+/*!
+{
+  "name": "Geolocation API",
+  "property": "geolocation",
+  "caniuse": "geolocation",
+  "tags": ["media"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/WebAPI/Using_geolocation"
+  }],
+  "polyfills": [
+    "joshuabell-polyfill",
+    "webshims",
+    "geo-location-javascript",
+    "geolocation-api-polyfill"
+  ]
+}
+!*/
+/* DOC
+Detects support for the Geolocation API for users to provide their location to web applications.
+*/
+define(['Modernizr'], function(Modernizr) {
+  // geolocation is often considered a trivial feature detect...
+  // Turns out, it's quite tricky to get right:
+  //
+  // Using !!navigator.geolocation does two things we don't want. It:
+  //   1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513
+  //   2. Disables page caching in WebKit: webk.it/43956
+  //
+  // Meanwhile, in Firefox < 8, an about:config setting could expose
+  // a false positive that would throw an exception: bugzil.la/688158
+
+  Modernizr.addTest('geolocation', 'geolocation' in navigator);
+});
diff --git a/js/modernizr/feature-detects/hashchange.js b/js/modernizr/feature-detects/hashchange.js
new file mode 100644 (file)
index 0000000..47eb7fb
--- /dev/null
@@ -0,0 +1,33 @@
+/*!
+{
+  "name": "Hashchange event",
+  "property": "hashchange",
+  "caniuse": "hashchange",
+  "tags": ["history"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/API/window.onhashchange"
+  }],
+  "polyfills": [
+    "jquery-hashchange",
+    "moo-historymanager",
+    "jquery-ajaxy",
+    "hasher",
+    "shistory"
+  ]
+}
+!*/
+/* DOC
+Detects support for the `hashchange` event, fired when the current location fragment changes.
+*/
+define(['Modernizr', 'hasEvent'], function(Modernizr, hasEvent) {
+  Modernizr.addTest('hashchange', function() {
+    if (hasEvent('hashchange', window) === false) {
+      return false;
+    }
+
+    // documentMode logic from YUI to filter out IE8 Compat Mode
+    //   which false positives.
+    return (document.documentMode === undefined || document.documentMode > 7);
+  });
+});
diff --git a/js/modernizr/feature-detects/hiddenscroll.js b/js/modernizr/feature-detects/hiddenscroll.js
new file mode 100644 (file)
index 0000000..bb2ca38
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+{
+  "name": "Hidden Scrollbar",
+  "property": "hiddenscroll",
+  "authors": ["Oleg Korsunsky"]
+}
+!*/
+/* DOC
+Detects whether scrollbars on overflowed blocks are hidden (a-la iPhone)
+*/
+define(['Modernizr', 'testStyles'], function(Modernizr, testStyles) {
+  Modernizr.addTest('hiddenscroll', function() {
+    return testStyles('#modernizr {width:100px;height:100px;overflow:scroll}', function(elem) {
+      return elem.offsetWidth === elem.clientWidth;
+    });
+  });
+});
diff --git a/js/modernizr/feature-detects/history.js b/js/modernizr/feature-detects/history.js
new file mode 100644 (file)
index 0000000..94e13a8
--- /dev/null
@@ -0,0 +1,42 @@
+/*!
+{
+  "name": "History API",
+  "property": "history",
+  "caniuse": "history",
+  "tags": ["history"],
+  "authors": ["Hay Kranen", "Alexander Farkas"],
+  "notes": [{
+    "name": "W3C Spec",
+    "href": "http://www.w3.org/TR/html51/browsers.html#the-history-interface"
+  }, {
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/API/window.history"
+  }],
+  "polyfills": ["historyjs", "html5historyapi"]
+}
+!*/
+/* DOC
+Detects support for the History API for manipulating the browser session history.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('history', function() {
+    // Issue #733
+    // The stock browser on Android 2.2 & 2.3, and 4.0.x returns positive on history support
+    // Unfortunately support is really buggy and there is no clean way to detect
+    // these bugs, so we fall back to a user agent sniff :(
+    var ua = navigator.userAgent;
+
+    // We only want Android 2 and 4.0, stock browser, and not Chrome which identifies
+    // itself as 'Mobile Safari' as well, nor Windows Phone (issue #1471).
+    if ((ua.indexOf('Android 2.') !== -1 ||
+        (ua.indexOf('Android 4.0') !== -1)) &&
+        ua.indexOf('Mobile Safari') !== -1 &&
+        ua.indexOf('Chrome') === -1 &&
+        ua.indexOf('Windows Phone') === -1) {
+      return false;
+    }
+
+    // Return the regular check
+    return (window.history && 'pushState' in window.history);
+  });
+});
diff --git a/js/modernizr/feature-detects/htmlimports.js b/js/modernizr/feature-detects/htmlimports.js
new file mode 100644 (file)
index 0000000..234073f
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+{
+  "name": "HTML Imports",
+  "notes": [
+    {
+      "name": "W3C HTML Imports Specification",
+      "href": "http://w3c.github.io/webcomponents/spec/imports/"
+    },
+    {
+      "name": "HTML Imports - #include for the web",
+      "href": "http://www.html5rocks.com/en/tutorials/webcomponents/imports/"
+    }
+  ],
+  "polyfills": ["polymer-htmlimports"],
+  "property": "htmlimports",
+  "tags": ["html", "import"]
+}
+!*/
+/* DOC
+Detects support for HTML import, a feature that is used for loading in Web Components.
+ */
+
+define(['addTest', 'createElement'], function(addTest, createElement) {
+  addTest('htmlimports', 'import' in createElement('link'));
+});
index c95e56a..6f6aa53 100644 (file)
@@ -1,12 +1,18 @@
+/*!
+{
+  "name": "IE8 compat mode",
+  "property": "ie8compat",
+  "authors": ["Erich Ocean"]
+}
+!*/
+/* DOC
+Detects whether or not the current browser is IE8 in compatibility mode (i.e. acting as IE7).
+*/
+define(['Modernizr'], function(Modernizr) {
+  // In this case, IE8 will be acting as IE7. You may choose to remove features in this case.
 
-// IE8 compat mode aka Fake IE7
-// by Erich Ocean
+  // related:
+  // james.padolsey.com/javascript/detect-ie-in-js-using-conditional-comments/
 
-// In this case, IE8 will be acting as IE7. You may choose to remove features in this case.
-
-// related:
-// james.padolsey.com/javascript/detect-ie-in-js-using-conditional-comments/
-
-Modernizr.addTest('ie8compat',function(){
-    return (!window.addEventListener && document.documentMode && document.documentMode === 7);
+  Modernizr.addTest('ie8compat', (!window.addEventListener && !!document.documentMode && document.documentMode === 7));
 });
diff --git a/js/modernizr/feature-detects/iframe/sandbox.js b/js/modernizr/feature-detects/iframe/sandbox.js
new file mode 100644 (file)
index 0000000..ca4cb77
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "iframe[sandbox] Attribute",
+  "property": "sandbox",
+  "tags": ["iframe"],
+  "builderAliases": ["iframe_sandbox"],
+  "notes": [
+  {
+    "name": "WhatWG Spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#attr-iframe-sandbox"
+  }],
+  "knownBugs": [ "False-positive on Firefox < 29" ]
+}
+!*/
+/* DOC
+Test for `sandbox` attribute in iframes.
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('sandbox', 'sandbox' in createElement('iframe'));
+});
diff --git a/js/modernizr/feature-detects/iframe/seamless.js b/js/modernizr/feature-detects/iframe/seamless.js
new file mode 100644 (file)
index 0000000..5c809ae
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "iframe[seamless] Attribute",
+  "property": "seamless",
+  "tags": ["iframe"],
+  "builderAliases": ["iframe_seamless"],
+  "notes": [{
+    "name": "WhatWG Spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#attr-iframe-seamless"
+  }]
+}
+!*/
+/* DOC
+Test for `seamless` attribute in iframes.
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('seamless', 'seamless' in createElement('iframe'));
+});
diff --git a/js/modernizr/feature-detects/iframe/srcdoc.js b/js/modernizr/feature-detects/iframe/srcdoc.js
new file mode 100644 (file)
index 0000000..285cc47
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "iframe[srcdoc] Attribute",
+  "property": "srcdoc",
+  "tags": ["iframe"],
+  "builderAliases": ["iframe_srcdoc"],
+  "notes": [{
+    "name": "WhatWG Spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#attr-iframe-srcdoc"
+  }]
+}
+!*/
+/* DOC
+Test for `srcdoc` attribute in iframes.
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('srcdoc', 'srcdoc' in createElement('iframe'));
+});
diff --git a/js/modernizr/feature-detects/img/apng.js b/js/modernizr/feature-detects/img/apng.js
new file mode 100644 (file)
index 0000000..2ebb716
--- /dev/null
@@ -0,0 +1,41 @@
+/*!
+{
+  "name": "Animated PNG",
+  "async": true,
+  "property": "apng",
+  "tags": ["image"],
+  "builderAliases": ["img_apng"],
+  "notes": [{
+    "name": "Wikipedia Article",
+    "href": "http://en.wikipedia.org/wiki/APNG"
+  }]
+}
+!*/
+/* DOC
+Test for animated png support.
+*/
+define(['Modernizr', 'createElement', 'addTest', 'test/canvas'], function(Modernizr, createElement, addTest) {
+  Modernizr.addAsyncTest(function() {
+    if (!Modernizr.canvas) {
+      return false;
+    }
+
+    var image = new Image();
+    var canvas = createElement('canvas');
+    var ctx = canvas.getContext('2d');
+
+    image.onload = function() {
+      addTest('apng', function() {
+        if (typeof canvas.getContext == 'undefined') {
+          return false;
+        }
+        else {
+          ctx.drawImage(image, 0, 0);
+          return ctx.getImageData(0, 0, 1, 1).data[3] === 0;
+        }
+      });
+    };
+
+    image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACGFjVEwAAAABAAAAAcMq2TYAAAANSURBVAiZY2BgYPgPAAEEAQB9ssjfAAAAGmZjVEwAAAAAAAAAAQAAAAEAAAAAAAAAAAD6A+gBAbNU+2sAAAARZmRBVAAAAAEImWNgYGBgAAAABQAB6MzFdgAAAABJRU5ErkJggg==';
+  });
+});
diff --git a/js/modernizr/feature-detects/img/jpegxr.js b/js/modernizr/feature-detects/img/jpegxr.js
new file mode 100644 (file)
index 0000000..46b74f4
--- /dev/null
@@ -0,0 +1,28 @@
+/*!
+{
+  "name": "JPEG XR (extended range)",
+  "async": true,
+  "aliases": ["jpeg-xr"],
+  "property": "jpegxr",
+  "tags": ["image"],
+  "notes": [{
+    "name": "Wikipedia Article",
+    "href": "http://en.wikipedia.org/wiki/JPEG_XR"
+  }]
+}
+!*/
+/* DOC
+Test for JPEG XR support
+*/
+define(['Modernizr', 'addTest'], function(Modernizr, addTest) {
+
+  Modernizr.addAsyncTest(function() {
+    var image = new Image();
+
+    image.onload = image.onerror = function() {
+      addTest('jpegxr', image.width == 1, {aliases: ['jpeg-xr']});
+    };
+
+    image.src = 'data:image/vnd.ms-photo;base64,SUm8AQgAAAAFAAG8AQAQAAAASgAAAIC8BAABAAAAAQAAAIG8BAABAAAAAQAAAMC8BAABAAAAWgAAAMG8BAABAAAAHwAAAAAAAAAkw91vA07+S7GFPXd2jckNV01QSE9UTwAZAYBxAAAAABP/gAAEb/8AAQAAAQAAAA==';
+  });
+});
diff --git a/js/modernizr/feature-detects/img/sizes.js b/js/modernizr/feature-detects/img/sizes.js
new file mode 100644 (file)
index 0000000..b07dd79
--- /dev/null
@@ -0,0 +1,21 @@
+/*!
+{
+  "name": "sizes attribute",
+  "property": "sizes",
+  "tags": ["image"],
+  "authors": ["Mat Marquis"],
+  "notes": [{
+    "name": "Spec",
+    "href": "http://picture.responsiveimages.org/#parse-sizes-attr"
+    },{
+    "name": "Usage Details",
+    "href": "http://ericportis.com/posts/2014/srcset-sizes/"
+    }]
+}
+!*/
+/* DOC
+Test for the `sizes` attribute on images
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('sizes', 'sizes' in createElement('img'));
+});
diff --git a/js/modernizr/feature-detects/img/srcset.js b/js/modernizr/feature-detects/img/srcset.js
new file mode 100644 (file)
index 0000000..693f629
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "srcset attribute",
+  "property": "srcset",
+  "tags": ["image"],
+  "notes": [{
+    "name": "Smashing Magazine Article",
+    "href": "http://en.wikipedia.org/wiki/APNG"
+    },{
+    "name": "Generate multi-resolution images for srcset with Grunt",
+    "href": "http://addyosmani.com/blog/generate-multi-resolution-images-for-srcset-with-grunt/"
+    }]
+}
+!*/
+/* DOC
+Test for the srcset attribute of images
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('srcset', 'srcset' in createElement('img'));
+});
diff --git a/js/modernizr/feature-detects/img/webp-alpha.js b/js/modernizr/feature-detects/img/webp-alpha.js
new file mode 100644 (file)
index 0000000..b71e007
--- /dev/null
@@ -0,0 +1,38 @@
+/*!
+{
+  "name": "Webp Alpha",
+  "async": true,
+  "property": "webpalpha",
+  "aliases": ["webp-alpha"],
+  "tags": ["image"],
+  "authors": ["Krister Kari", "Rich Bradshaw", "Ryan Seddon", "Paul Irish"],
+  "notes": [{
+    "name": "WebP Info",
+    "href": "http://code.google.com/speed/webp/"
+  },{
+    "name": "Article about WebP support on Android browsers",
+    "href": "http://www.wope-framework.com/en/2013/06/24/webp-support-on-android-browsers/"
+  },{
+    "name": "Chromium WebP announcement",
+    "href": "http://blog.chromium.org/2011/11/lossless-and-transparency-encoding-in.html?m=1"
+  }]
+}
+!*/
+/* DOC
+Tests for transparent webp support.
+*/
+define(['Modernizr', 'addTest'], function(Modernizr, addTest) {
+  Modernizr.addAsyncTest(function() {
+    var image = new Image();
+
+    image.onerror = function() {
+      addTest('webpalpha', false, {aliases: ['webp-alpha']});
+    };
+
+    image.onload = function() {
+      addTest('webpalpha', image.width == 1, {aliases: ['webp-alpha']});
+    };
+
+    image.src = 'data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA==';
+  });
+});
diff --git a/js/modernizr/feature-detects/img/webp-animation.js b/js/modernizr/feature-detects/img/webp-animation.js
new file mode 100644 (file)
index 0000000..1d8265c
--- /dev/null
@@ -0,0 +1,35 @@
+/*!
+{
+  "name": "Webp Animation",
+  "async": true,
+  "property": "webpanimation",
+  "aliases": ["webp-animation"],
+  "tags": ["image"],
+  "authors": ["Krister Kari", "Rich Bradshaw", "Ryan Seddon", "Paul Irish"],
+  "notes": [{
+    "name": "WebP Info",
+    "href": "http://code.google.com/speed/webp/"
+  },{
+    "name": "Chromium blog - Chrome 32 Beta: Animated WebP images and faster Chrome for Android touch input",
+    "href": "http://blog.chromium.org/2013/11/chrome-32-beta-animated-webp-images-and.html"
+  }]
+}
+!*/
+/* DOC
+Tests for animated webp support.
+*/
+define(['Modernizr', 'addTest'], function(Modernizr, addTest) {
+  Modernizr.addAsyncTest(function() {
+    var image = new Image();
+
+    image.onerror = function() {
+      addTest('webpanimation', false, {aliases: ['webp-animation']});
+    };
+
+    image.onload = function() {
+      addTest('webpanimation', image.width == 1, {aliases: ['webp-animation']});
+    };
+
+    image.src = 'data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA';
+  });
+});
diff --git a/js/modernizr/feature-detects/img/webp-lossless.js b/js/modernizr/feature-detects/img/webp-lossless.js
new file mode 100644 (file)
index 0000000..a76a340
--- /dev/null
@@ -0,0 +1,34 @@
+/*!
+{
+  "name": "Webp Lossless",
+  "async": true,
+  "property": ["webplossless", "webp-lossless"],
+  "tags": ["image"],
+  "authors": ["@amandeep", "Rich Bradshaw", "Ryan Seddon", "Paul Irish"],
+  "notes": [{
+    "name": "Webp Info",
+    "href": "http://code.google.com/speed/webp/"
+  },{
+    "name": "Webp Lossless Spec",
+    "href": "https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification"
+  }]
+}
+!*/
+/* DOC
+Tests for non-alpha lossless webp support.
+*/
+define(['Modernizr', 'addTest'], function(Modernizr, addTest) {
+  Modernizr.addAsyncTest(function() {
+    var image = new Image();
+
+    image.onerror = function() {
+      addTest('webplossless', false, {aliases: ['webp-lossless']});
+    };
+
+    image.onload = function() {
+      addTest('webplossless', image.width == 1, {aliases: ['webp-lossless']});
+    };
+
+    image.src = 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=';
+  });
+});
diff --git a/js/modernizr/feature-detects/img/webp.js b/js/modernizr/feature-detects/img/webp.js
new file mode 100644 (file)
index 0000000..fa08f06
--- /dev/null
@@ -0,0 +1,94 @@
+/*!
+{
+  "name": "Webp",
+  "async": true,
+  "property": "webp",
+  "tags": ["image"],
+  "builderAliases": ["img_webp"],
+  "authors": ["Krister Kari", "@amandeep", "Rich Bradshaw", "Ryan Seddon", "Paul Irish"],
+  "notes": [{
+    "name": "Webp Info",
+    "href": "http://code.google.com/speed/webp/"
+  }, {
+    "name": "Chormium blog - Chrome 32 Beta: Animated WebP images and faster Chrome for Android touch input",
+    "href": "http://blog.chromium.org/2013/11/chrome-32-beta-animated-webp-images-and.html"
+  }, {
+    "name": "Webp Lossless Spec",
+    "href": "https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification"
+  }, {
+    "name": "Article about WebP support on Android browsers",
+    "href": "http://www.wope-framework.com/en/2013/06/24/webp-support-on-android-browsers/"
+  }, {
+    "name": "Chormium WebP announcement",
+    "href": "http://blog.chromium.org/2011/11/lossless-and-transparency-encoding-in.html?m=1"
+  }]
+}
+!*/
+/* DOC
+Tests for lossy, non-alpha webp support.
+
+Tests for all forms of webp support (lossless, lossy, alpha, and animated)..
+
+  Modernizr.webp              // Basic support (lossy)
+  Modernizr.webp.lossless     // Lossless
+  Modernizr.webp.alpha        // Alpha (both lossy and lossless)
+  Modernizr.webp.animation    // Animated WebP
+
+*/
+define(['Modernizr', 'addTest'], function(Modernizr, addTest) {
+
+  Modernizr.addAsyncTest(function() {
+
+    var webpTests = [{
+      'uri': 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA=',
+      'name': 'webp'
+    }, {
+      'uri': 'data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA==',
+      'name': 'webp.alpha'
+    }, {
+      'uri': 'data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA',
+      'name': 'webp.animation'
+    }, {
+      'uri': 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=',
+      'name': 'webp.lossless'
+    }];
+
+    var webp = webpTests.shift();
+    function test(name, uri, cb) {
+
+      var image = new Image();
+
+      function addResult(event) {
+        // if the event is from 'onload', check the see if the image's width is
+        // 1 pixel (which indiciates support). otherwise, it fails
+
+        var result = event && event.type === 'load' ? image.width == 1 : false;
+        var baseTest = name === 'webp';
+
+        /* jshint -W053 */
+        addTest(name, baseTest ? new Boolean(result) : result);
+
+        if (cb) {
+          cb(event);
+        }
+      }
+
+      image.onerror = addResult;
+      image.onload = addResult;
+
+      image.src = uri;
+    }
+
+    // test for webp support in general
+    test(webp.name, webp.uri, function(e) {
+      // if the webp test loaded, test everything else.
+      if (e && e.type === 'load') {
+        for (var i = 0; i < webpTests.length; i++) {
+          test(webpTests[i].name, webpTests[i].uri);
+        }
+      }
+    });
+
+  });
+
+});
diff --git a/js/modernizr/feature-detects/indexeddb.js b/js/modernizr/feature-detects/indexeddb.js
new file mode 100644 (file)
index 0000000..fdab4d7
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+{
+  "name": "IndexedDB",
+  "property": "indexeddb",
+  "caniuse": "indexeddb",
+  "tags": ["storage"],
+  "polyfills": ["indexeddb"]
+}
+!*/
+/* DOC
+Detects support for the IndexedDB client-side storage API (final spec).
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  // Vendors had inconsistent prefixing with the experimental Indexed DB:
+  // - Webkit's implementation is accessible through webkitIndexedDB
+  // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
+  // For speed, we don't test the legacy (and beta-only) indexedDB
+
+  var indexeddb = prefixed('indexedDB', window);
+  Modernizr.addTest('indexeddb', !!indexeddb);
+
+  if (!!indexeddb) {
+    Modernizr.addTest('indexeddb.deletedatabase', 'deleteDatabase' in indexeddb);
+  }
+});
diff --git a/js/modernizr/feature-detects/indexeddbblob.js b/js/modernizr/feature-detects/indexeddbblob.js
new file mode 100644 (file)
index 0000000..9fdc3ac
--- /dev/null
@@ -0,0 +1,57 @@
+/*!
+{
+  "name": "IndexedDB Blob",
+  "property": "indexeddbblob"
+}
+!*/
+/* DOC
+Detects if the browser can save File/Blob objects to IndexedDB
+*/
+define(['Modernizr', 'addTest', 'prefixed', 'test/indexeddb'], function(Modernizr, addTest, prefixed) {
+  // Vendors had inconsistent prefixing with the experimental Indexed DB:
+  // - Webkit's implementation is accessible through webkitIndexedDB
+  // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
+  // For speed, we don't test the legacy (and beta-only) indexedDB
+
+  Modernizr.addAsyncTest(function() {
+    /* jshint -W053 */
+    var indexeddb = prefixed('indexedDB', window);
+    var dbname = 'detect-blob-support';
+    var supportsBlob = false;
+    var request;
+    var db;
+
+    if (!(Modernizr.indexeddb && Modernizr.indexeddb.deleteDatabase)) {
+      return false;
+    }
+
+    // Calling `deleteDatabase` in a try…catch because some contexts (e.g. data URIs)
+    // will throw a `SecurityError`
+    try {
+      indexeddb.deleteDatabase(dbname).onsuccess = function() {
+        request = indexeddb.open(dbname, 1);
+        request.onupgradeneeded = function() {
+          request.result.createObjectStore('store');
+        };
+        request.onsuccess = function() {
+          db = request.result;
+          try {
+            db.transaction('store', 'readwrite').objectStore('store').put(new Blob(), 'key');
+            supportsBlob = true;
+          }
+          catch (e) {
+            supportsBlob = false;
+          }
+          finally {
+            addTest('indexeddbblob', supportsBlob);
+            db.close();
+            indexeddb.deleteDatabase(dbname);
+          }
+        };
+      };
+    }
+    catch (e) {
+      addTest('indexeddbblob', false);
+    }
+  });
+});
diff --git a/js/modernizr/feature-detects/input.js b/js/modernizr/feature-detects/input.js
new file mode 100644 (file)
index 0000000..a4a766e
--- /dev/null
@@ -0,0 +1,54 @@
+/*!
+{
+  "name": "Input attributes",
+  "property": "input",
+  "tags": ["forms"],
+  "authors": ["Mike Taylor"],
+  "notes": [{
+    "name": "WHATWG spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary"
+  }],
+  "knownBugs": ["Some blackberry devices report false positive for input.multiple"]
+}
+!*/
+/* DOC
+Detects support for HTML5 `<input>` element attributes and exposes Boolean subproperties with the results:
+
+```javascript
+Modernizr.input.autocomplete
+Modernizr.input.autofocus
+Modernizr.input.list
+Modernizr.input.max
+Modernizr.input.min
+Modernizr.input.multiple
+Modernizr.input.pattern
+Modernizr.input.placeholder
+Modernizr.input.required
+Modernizr.input.step
+```
+*/
+define(['Modernizr', 'createElement', 'inputElem'], function(Modernizr, createElement, inputElem) {
+  // Run through HTML5's new input attributes to see if the UA understands any.
+  // Mike Taylr has created a comprehensive resource for testing these attributes
+  //   when applied to all input types:
+  //   miketaylr.com/code/input-type-attr.html
+
+  // Only input placeholder is tested while textarea's placeholder is not.
+  // Currently Safari 4 and Opera 11 have support only for the input placeholder
+  // Both tests are available in feature-detects/forms-placeholder.js
+
+  var inputattrs = 'autocomplete autofocus list placeholder max min multiple pattern required step'.split(' ');
+  var attrs = {};
+
+  Modernizr['input'] = (function(props) {
+    for (var i = 0, len = props.length; i < len; i++) {
+      attrs[ props[i] ] = !!(props[i] in inputElem);
+    }
+    if (attrs.list) {
+      // safari false positive's on datalist: webk.it/74252
+      // see also github.com/Modernizr/Modernizr/issues/146
+      attrs.list = !!(createElement('datalist') && window.HTMLDataListElement);
+    }
+    return attrs;
+  })(inputattrs);
+});
diff --git a/js/modernizr/feature-detects/input/formaction.js b/js/modernizr/feature-detects/input/formaction.js
new file mode 100644 (file)
index 0000000..d9aef84
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "input formaction",
+  "property": "inputformaction",
+  "aliases": ["input-formaction"],
+  "notes": [{
+    "name": "WHATWG Spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#attr-fs-formaction"
+  }, {
+    "name": "Wufoo demo",
+    "href": "http://www.wufoo.com/html5/attributes/13-formaction.html"
+  }],
+  "polyfills": [
+    "webshims"
+  ]
+}
+!*/
+/* DOC
+Detect support for the formaction attribute on form inputs
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('inputformaction', !!('formAction' in createElement('input')), {aliases: ['input-formaction']});
+});
diff --git a/js/modernizr/feature-detects/input/formenctype.js b/js/modernizr/feature-detects/input/formenctype.js
new file mode 100644 (file)
index 0000000..17e8102
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "input formenctype",
+  "property": "inputformenctype",
+  "aliases": ["input-formenctype"],
+  "notes": [{
+    "name": "WHATWG Spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#attr-fs-formenctype"
+  }, {
+    "name": "Wufoo demo",
+    "href": "http://www.wufoo.com/html5/attributes/16-formenctype.html"
+  }],
+  "polyfills": [
+    "html5formshim"
+  ]
+}
+!*/
+/* DOC
+Detect support for the formenctype attribute on form inputs, which overrides the form enctype attribute
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('inputformenctype', !!('formEnctype' in createElement('input')), {aliases: ['input-formenctype']});
+});
diff --git a/js/modernizr/feature-detects/input/formmethod.js b/js/modernizr/feature-detects/input/formmethod.js
new file mode 100644 (file)
index 0000000..74289c6
--- /dev/null
@@ -0,0 +1,22 @@
+/*!
+{
+  "name": "input formmethod",
+  "property": "inputformmethod",
+  "notes": [{
+    "name": "WHATWG Spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#attr-fs-formmethod"
+  }, {
+    "name": "Wufoo demo",
+    "href": "http://www.wufoo.com/html5/attributes/14-formmethod.html"
+  }],
+  "polyfills": [
+    "webshims"
+  ]
+}
+!*/
+/* DOC
+Detect support for the formmethod attribute on form inputs
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('inputformmethod', !!('formMethod' in createElement('input')));
+});
diff --git a/js/modernizr/feature-detects/input/formtarget.js b/js/modernizr/feature-detects/input/formtarget.js
new file mode 100644 (file)
index 0000000..8e9aecc
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+{
+  "name": "input formtarget",
+  "property": "inputformtarget",
+  "aliases": ["input-formtarget"],
+  "notes": [{
+    "name": "WHATWG Spec",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#attr-fs-formtarget"
+  }, {
+    "name": "Wufoo demo",
+    "href": "http://www.wufoo.com/html5/attributes/15-formtarget.html"
+  }],
+  "polyfills": [
+    "html5formshim"
+  ]
+}
+!*/
+/* DOC
+Detect support for the formtarget attribute on form inputs, which overrides the form target attribute
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('inputformtarget', !!('formtarget' in createElement('input')), {aliases: ['input-formtarget']});
+});
diff --git a/js/modernizr/feature-detects/inputsearchevent.js b/js/modernizr/feature-detects/inputsearchevent.js
new file mode 100644 (file)
index 0000000..ff7f647
--- /dev/null
@@ -0,0 +1,21 @@
+/*!
+{
+  "name": "input[search] search event",
+  "property": "search",
+  "tags": ["input","search"],
+  "authors": ["Calvin Webster"],
+  "notes": [{
+    "name": "Wufoo demo",
+    "href": "http://www.wufoo.com/html5/types/5-search.html?"
+  }, {
+    "name": "CSS Tricks",
+    "href": "http://css-tricks.com/webkit-html5-search-inputs/"
+  }]
+}
+!*/
+/* DOC
+There is a custom `search` event implemented in webkit browsers when using an `input[search]` element.
+*/
+define(['Modernizr', 'hasEvent'], function(Modernizr, hasEvent) {
+  Modernizr.addTest('inputsearchevent',  hasEvent('search'));
+});
diff --git a/js/modernizr/feature-detects/inputtypes.js b/js/modernizr/feature-detects/inputtypes.js
new file mode 100644 (file)
index 0000000..ef3f9b2
--- /dev/null
@@ -0,0 +1,108 @@
+/*!
+{
+  "name": "Form input types",
+  "property": "inputtypes",
+  "caniuse": "forms",
+  "tags": ["forms"],
+  "authors": ["Mike Taylor"],
+  "polyfills": [
+    "jquerytools",
+    "webshims",
+    "h5f",
+    "webforms2",
+    "nwxforms",
+    "fdslider",
+    "html5slider",
+    "galleryhtml5forms",
+    "jscolor",
+    "html5formshim",
+    "selectedoptionsjs",
+    "formvalidationjs"
+  ]
+}
+!*/
+/* DOC
+Detects support for HTML5 form input types and exposes Boolean subproperties with the results:
+
+```javascript
+Modernizr.inputtypes.color
+Modernizr.inputtypes.date
+Modernizr.inputtypes.datetime
+Modernizr.inputtypes['datetime-local']
+Modernizr.inputtypes.email
+Modernizr.inputtypes.month
+Modernizr.inputtypes.number
+Modernizr.inputtypes.range
+Modernizr.inputtypes.search
+Modernizr.inputtypes.tel
+Modernizr.inputtypes.time
+Modernizr.inputtypes.url
+Modernizr.inputtypes.week
+```
+*/
+define(['Modernizr', 'inputElem', 'docElement'], function(Modernizr, inputElem, docElement) {
+  // Run through HTML5's new input types to see if the UA understands any.
+  //   This is put behind the tests runloop because it doesn't return a
+  //   true/false like all the other tests; instead, it returns an object
+  //   containing each input type with its corresponding true/false value
+
+  // Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/
+  var inputtypes = 'search tel url email datetime date month week time datetime-local number range color'.split(' ');
+  var inputs = {};
+
+  Modernizr['inputtypes'] = (function(props) {
+    var len = props.length;
+    var smile = ':)';
+    var inputElemType;
+    var defaultView;
+    var bool;
+
+    for (var i = 0; i < len; i++) {
+
+      inputElem.setAttribute('type', inputElemType = props[i]);
+      bool = inputElem.type !== 'text' && 'style' in inputElem;
+
+      // We first check to see if the type we give it sticks..
+      // If the type does, we feed it a textual value, which shouldn't be valid.
+      // If the value doesn't stick, we know there's input sanitization which infers a custom UI
+      if (bool) {
+
+        inputElem.value         = smile;
+        inputElem.style.cssText = 'position:absolute;visibility:hidden;';
+
+        if (/^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined) {
+
+          docElement.appendChild(inputElem);
+          defaultView = document.defaultView;
+
+          // Safari 2-4 allows the smiley as a value, despite making a slider
+          bool =  defaultView.getComputedStyle &&
+            defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
+            // Mobile android web browser has false positive, so must
+            // check the height to see if the widget is actually there.
+            (inputElem.offsetHeight !== 0);
+
+          docElement.removeChild(inputElem);
+
+        } else if (/^(search|tel)$/.test(inputElemType)) {
+          // Spec doesn't define any special parsing or detectable UI
+          //   behaviors so we pass these through as true
+
+          // Interestingly, opera fails the earlier test, so it doesn't
+          //  even make it here.
+
+        } else if (/^(url|email|number)$/.test(inputElemType)) {
+          // Real url and email support comes with prebaked validation.
+          bool = inputElem.checkValidity && inputElem.checkValidity() === false;
+
+        } else {
+          // If the upgraded input compontent rejects the :) text, we got a winner
+          bool = inputElem.value != smile;
+        }
+      }
+
+      inputs[ props[i] ] = !!bool;
+    }
+    return inputs;
+  })(inputtypes);
+});
diff --git a/js/modernizr/feature-detects/intl.js b/js/modernizr/feature-detects/intl.js
new file mode 100644 (file)
index 0000000..9358e55
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+ {
+ "name": "Internationalization API",
+ "property": "intl",
+ "notes": [{
+ "name": "MDN documentation",
+ "href": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl"
+ },{
+ "name": "ECMAScript spec",
+ "href": "http://www.ecma-international.org/ecma-402/1.0/"
+ }]
+ }
+ !*/
+/* DOC
+Detects support for the Internationalization API which allow easy formatting of number and dates and sorting string
+based on a locale
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('intl', !!prefixed('Intl', window));
+});
index af58064..e45be4d 100644 (file)
@@ -1,7 +1,21 @@
-// native JSON support.
-// developer.mozilla.org/en/JSON
+/*!
+{
+  "name": "JSON",
+  "property": "json",
+  "caniuse": "json",
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "http://developer.mozilla.org/en/JSON"
+  }],
+  "polyfills": ["json2"]
+}
+!*/
+/* DOC
+Detects native support for JSON handling functions.
+*/
+define(['Modernizr'], function(Modernizr) {
+  // this will also succeed if you've loaded the JSON2.js polyfill ahead of time
+  //   ... but that should be obvious. :)
 
-// this will also succeed if you've loaded the JSON2.js polyfill ahead of time
-//   ... but that should be obvious. :)
-
-Modernizr.addTest('json', !!window.JSON && !!JSON.parse);
+  Modernizr.addTest('json', 'JSON' in window && 'parse' in JSON && 'stringify' in JSON);
+});
index 22fd92c..5248606 100644 (file)
@@ -1,6 +1,17 @@
-
-// impressivewebs.com/reverse-ordered-lists-html5
-// polyfill: github.com/impressivewebs/HTML5-Reverse-Ordered-Lists
-
-
-Modernizr.addTest('olreversed', 'reversed' in document.createElement('ol'));
+/*!
+{
+  "name": "Reverse Ordered Lists",
+  "property": "olreversed",
+  "notes": [{
+    "name": "Impressive Webs article",
+    "href": "http://impressivewebs.com/reverse-ordered-lists-html5"
+  }],
+  "builderAliases": ["lists_reversed"]
+}
+!*/
+/* DOC
+Detects support for the `reversed` attribute on the `<ol>` element.
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('olreversed', 'reversed' in createElement('ol'));
+});
index e1c907a..1a67579 100644 (file)
@@ -1,23 +1,33 @@
-// MathML
-// http://www.w3.org/Math/ 
-// By Addy Osmani
-// Based on work by Davide (@dpvc) and David (@davidcarlisle)
-// in https://github.com/mathjax/MathJax/issues/182
+/*!
+{
+  "name": "MathML",
+  "property": "mathml",
+  "caniuse": "mathml",
+  "authors": ["Addy Osmani", "Davide P. Cervone", "David Carlisle"],
+  "knownBugs": ["Firefox < 4 will likely return a false, however it does support MathML inside XHTML documents"],
+  "notes": [{
+    "name": "W3C spec",
+    "href": "http://www.w3.org/Math/"
+  }],
+  "polyfills": ["mathjax"]
+}
+!*/
+/* DOC
+Detects support for MathML, for mathematic equations in web pages.
+*/
+define(['Modernizr', 'testStyles'], function(Modernizr, testStyles) {
+  // Based on work by Davide (@dpvc) and David (@davidcarlisle)
+  // in https://github.com/mathjax/MathJax/issues/182
 
-Modernizr.addTest('mathml', function(){
-       var hasMathML = false;
-       if ( document.createElementNS ) {
-       var ns = "http://www.w3.org/1998/Math/MathML",
-           div = document.createElement("div");
-           div.style.position = "absolute"; 
-       var mfrac = div.appendChild(document.createElementNS(ns,"math"))
-                      .appendChild(document.createElementNS(ns,"mfrac"));
-       mfrac.appendChild(document.createElementNS(ns,"mi"))
-            .appendChild(document.createTextNode("xx"));
-       mfrac.appendChild(document.createElementNS(ns,"mi"))
-            .appendChild(document.createTextNode("yy"));
-       document.body.appendChild(div);
-       hasMathML = div.offsetHeight > div.offsetWidth;
-       }
-       return hasMathML;
-});
\ No newline at end of file
+  Modernizr.addTest('mathml', function() {
+    var ret;
+
+    testStyles('#modernizr{position:absolute;display:inline-block}', function(node) {
+      node.innerHTML += '<math><mfrac><mi>xx</mi><mi>yy</mi></mfrac></math>';
+
+      ret = node.offsetHeight > node.offsetWidth;
+    });
+
+    return ret;
+  });
+});
diff --git a/js/modernizr/feature-detects/network/beacon.js b/js/modernizr/feature-detects/network/beacon.js
new file mode 100644 (file)
index 0000000..5b3d256
--- /dev/null
@@ -0,0 +1,21 @@
+/*!
+{
+  "name": "Beacon API",
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/API/navigator.sendBeacon"
+  },{
+    "name": "W3C specification",
+    "href": "https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/Beacon/Overview.html"
+  }],
+  "property": "beacon",
+  "tags": ["beacon", "network"],
+  "authors": ["Cătălin Mariș"]
+}
+!*/
+/* DOC
+Detects support for an API that allows for asynchronous transfer of small HTTP data from the client to a server.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('beacon', 'sendBeacon' in navigator);
+});
diff --git a/js/modernizr/feature-detects/network/connection.js b/js/modernizr/feature-detects/network/connection.js
new file mode 100644 (file)
index 0000000..3aeac89
--- /dev/null
@@ -0,0 +1,36 @@
+/*!
+{
+  "name": "Low Bandwidth Connection",
+  "property": "lowbandwidth",
+  "tags": ["network"],
+  "builderAliases": ["network_connection"]
+}
+!*/
+/* DOC
+Tests for determining low-bandwidth via `navigator.connection`
+
+There are two iterations of the `navigator.connection` interface.
+
+The first is present in Android 2.2+ and only in the Browser (not WebView)
+
+- http://docs.phonegap.com/en/1.2.0/phonegap_connection_connection.md.html#connection.type
+- http://davidbcalhoun.com/2010/using-navigator-connection-android
+
+The second is specced at http://dev.w3.org/2009/dap/netinfo/ and perhaps landing in WebKit
+
+- http://bugs.webkit.org/show_bug.cgi?id=73528
+
+Unknown devices are assumed as fast
+
+For more rigorous network testing, consider boomerang.js: http://github.com/bluesmoon/boomerang/
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('lowbandwidth', function() {
+    // polyfill
+    var connection = navigator.connection || {type: 0};
+
+    return connection.type == 3 || // connection.CELL_2G
+      connection.type == 4 || // connection.CELL_3G
+      /^[23]g$/.test(connection.type); // string value in new spec
+  });
+});
diff --git a/js/modernizr/feature-detects/network/eventsource.js b/js/modernizr/feature-detects/network/eventsource.js
new file mode 100644 (file)
index 0000000..378a768
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "Server Sent Events",
+  "property": "eventsource",
+  "tags": ["network"],
+  "builderAliases": ["network_eventsource"],
+  "notes": [{
+    "name": "W3 Spec",
+    "href": "http://dev.w3.org/html5/eventsource/"
+  }]
+}
+!*/
+/* DOC
+Tests for server sent events aka eventsource.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('eventsource', 'EventSource' in window);
+});
diff --git a/js/modernizr/feature-detects/network/fetch.js b/js/modernizr/feature-detects/network/fetch.js
new file mode 100644 (file)
index 0000000..26584d0
--- /dev/null
@@ -0,0 +1,19 @@
+/*!
+{
+  "name": "Fetch API",
+  "property": "fetch",
+  "tags": ["network"],
+  "caniuse": "fetch",
+  "notes": [{
+    "name": "Fetch Living Standard",
+    "href": "https://fetch.spec.whatwg.org/"
+  }],
+  "polyfills": ["fetch"]
+}
+!*/
+/* DOC
+Detects support for the fetch API, a modern replacement for XMLHttpRequest.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('fetch', 'fetch' in window);
+});
diff --git a/js/modernizr/feature-detects/network/xhr-responsetype-arraybuffer.js b/js/modernizr/feature-detects/network/xhr-responsetype-arraybuffer.js
new file mode 100644 (file)
index 0000000..70b018e
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+{
+  "name": "XHR responseType='arraybuffer'",
+  "property": "xhrresponsetypearraybuffer",
+  "tags": ["network"],
+  "notes": [{
+    "name": "XMLHttpRequest Living Standard",
+    "href": "http://xhr.spec.whatwg.org/#the-responsetype-attribute"
+  }]
+}
+!*/
+/* DOC
+Tests for XMLHttpRequest xhr.responseType='arraybuffer'.
+*/
+define(['Modernizr', 'testXhrType'], function(Modernizr, testXhrType) {
+  Modernizr.addTest('xhrresponsetypearraybuffer', testXhrType('arraybuffer'));
+});
diff --git a/js/modernizr/feature-detects/network/xhr-responsetype-blob.js b/js/modernizr/feature-detects/network/xhr-responsetype-blob.js
new file mode 100644 (file)
index 0000000..540ac60
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+{
+  "name": "XHR responseType='blob'",
+  "property": "xhrresponsetypeblob",
+  "tags": ["network"],
+  "notes": [{
+    "name": "XMLHttpRequest Living Standard",
+    "href": "http://xhr.spec.whatwg.org/#the-responsetype-attribute"
+  }]
+}
+!*/
+/* DOC
+Tests for XMLHttpRequest xhr.responseType='blob'.
+*/
+define(['Modernizr', 'testXhrType'], function(Modernizr, testXhrType) {
+  Modernizr.addTest('xhrresponsetypeblob', testXhrType('blob'));
+});
diff --git a/js/modernizr/feature-detects/network/xhr-responsetype-document.js b/js/modernizr/feature-detects/network/xhr-responsetype-document.js
new file mode 100644 (file)
index 0000000..13a2531
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+{
+  "name": "XHR responseType='document'",
+  "property": "xhrresponsetypedocument",
+  "tags": ["network"],
+  "notes": [{
+    "name": "XMLHttpRequest Living Standard",
+    "href": "http://xhr.spec.whatwg.org/#the-responsetype-attribute"
+  }]
+}
+!*/
+/* DOC
+Tests for XMLHttpRequest xhr.responseType='document'.
+*/
+define(['Modernizr', 'testXhrType'], function(Modernizr, testXhrType) {
+  Modernizr.addTest('xhrresponsetypedocument', testXhrType('document'));
+});
diff --git a/js/modernizr/feature-detects/network/xhr-responsetype-json.js b/js/modernizr/feature-detects/network/xhr-responsetype-json.js
new file mode 100644 (file)
index 0000000..291c0a9
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "XHR responseType='json'",
+  "property": "xhrresponsetypejson",
+  "tags": ["network"],
+  "notes": [{
+    "name": "XMLHttpRequest Living Standard",
+    "href": "http://xhr.spec.whatwg.org/#the-responsetype-attribute"
+  },{
+    "name": "Explanation of xhr.responseType='json'",
+    "href": "http://mathiasbynens.be/notes/xhr-responsetype-json"
+  }]
+}
+!*/
+/* DOC
+Tests for XMLHttpRequest xhr.responseType='json'.
+*/
+define(['Modernizr', 'testXhrType'], function(Modernizr, testXhrType) {
+  Modernizr.addTest('xhrresponsetypejson', testXhrType('json'));
+});
diff --git a/js/modernizr/feature-detects/network/xhr-responsetype-text.js b/js/modernizr/feature-detects/network/xhr-responsetype-text.js
new file mode 100644 (file)
index 0000000..4cbe62b
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+{
+  "name": "XHR responseType='text'",
+  "property": "xhrresponsetypetext",
+  "tags": ["network"],
+  "notes": [{
+    "name": "XMLHttpRequest Living Standard",
+    "href": "http://xhr.spec.whatwg.org/#the-responsetype-attribute"
+  }]
+}
+!*/
+/* DOC
+Tests for XMLHttpRequest xhr.responseType='text'.
+*/
+define(['Modernizr', 'testXhrType'], function(Modernizr, testXhrType) {
+  Modernizr.addTest('xhrresponsetypetext', testXhrType('text'));
+});
diff --git a/js/modernizr/feature-detects/network/xhr-responsetype.js b/js/modernizr/feature-detects/network/xhr-responsetype.js
new file mode 100644 (file)
index 0000000..3c60089
--- /dev/null
@@ -0,0 +1,24 @@
+/*!
+{
+  "name": "XHR responseType",
+  "property": "xhrresponsetype",
+  "tags": ["network"],
+  "notes": [{
+    "name": "XMLHttpRequest Living Standard",
+    "href": "http://xhr.spec.whatwg.org/#the-responsetype-attribute"
+  }]
+}
+!*/
+/* DOC
+Tests for XMLHttpRequest xhr.responseType.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('xhrresponsetype', (function() {
+    if (typeof XMLHttpRequest == 'undefined') {
+      return false;
+    }
+    var xhr = new XMLHttpRequest();
+    xhr.open('get', '/', true);
+    return 'response' in xhr;
+  }()));
+});
diff --git a/js/modernizr/feature-detects/network/xhr2.js b/js/modernizr/feature-detects/network/xhr2.js
new file mode 100644 (file)
index 0000000..def8541
--- /dev/null
@@ -0,0 +1,24 @@
+/*!
+{
+  "name": "XML HTTP Request Level 2 XHR2",
+  "property": "xhr2",
+  "tags": ["network"],
+  "builderAliases": ["network_xhr2"],
+  "notes": [{
+    "name": "W3 Spec",
+    "href": "http://www.w3.org/TR/XMLHttpRequest2/"
+  },{
+    "name": "Details on Related Github Issue",
+    "href": "http://github.com/Modernizr/Modernizr/issues/385"
+  }]
+}
+!*/
+/* DOC
+Tests for XHR2.
+*/
+define(['Modernizr'], function(Modernizr) {
+  // all three of these details report consistently across all target browsers:
+  //   !!(window.ProgressEvent);
+  //   'XMLHttpRequest' in window && 'withCredentials' in new XMLHttpRequest
+  Modernizr.addTest('xhr2', 'XMLHttpRequest' in window && 'withCredentials' in new XMLHttpRequest());
+});
index 92d1eef..06b38ec 100644 (file)
@@ -1,10 +1,22 @@
-// Notifications
-// By Theodoor van Donge
-
-// window.webkitNotifications is only used by Chrome 
-//     http://www.html5rocks.com/en/tutorials/notifications/quick/
-
-// window.Notification only exist in the draft specs 
-//     http://dev.w3.org/2006/webapi/WebNotifications/publish/Notifications.html#idl-if-Notification
-
-Modernizr.addTest('notification', 'Notification' in window && 'permission' in window.Notification && 'requestPermission' in window.Notification);
+/*!
+{
+  "name": "Notification",
+  "property": "notification",
+  "caniuse": "notifications",
+  "authors": ["Theodoor van Donge", "Hendrik Beskow"],
+  "notes": [{
+    "name": "HTML5 Rocks tutorial",
+    "href": "http://www.html5rocks.com/en/tutorials/notifications/quick/"
+  },{
+    "name": "W3C spec",
+    "href": "www.w3.org/TR/notifications/"
+  }],
+  "polyfills": ["desktop-notify", "html5-notifications"]
+}
+!*/
+/* DOC
+Detects support for the Notifications API
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('notification', 'Notification' in window && 'permission' in window.Notification && 'requestPermission' in window.Notification);
+});
diff --git a/js/modernizr/feature-detects/pagevisibility-api.js b/js/modernizr/feature-detects/pagevisibility-api.js
new file mode 100644 (file)
index 0000000..573fe1f
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+{
+  "name": "Page Visibility API",
+  "property": "pagevisibility",
+  "caniuse": "pagevisibility",
+  "tags": ["performance"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/DOM/Using_the_Page_Visibility_API"
+  },{
+    "name": "W3C spec",
+    "href": "http://www.w3.org/TR/2011/WD-page-visibility-20110602/"
+  },{
+    "name": "HTML5 Rocks tutorial",
+    "href": "http://www.html5rocks.com/en/tutorials/pagevisibility/intro/"
+  }],
+  "polyfills": ["visibilityjs", "visiblyjs", "jquery-visibility"]
+}
+!*/
+/* DOC
+Detects support for the Page Visibility API, which can be used to disable unnecessary actions and otherwise improve user experience.
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('pagevisibility', !!prefixed('hidden', document, false));
+});
index 903c5c9..2626d5e 100644 (file)
@@ -1,5 +1,23 @@
-// Navigation Timing (Performance)
-// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/
-// http://www.html5rocks.com/en/tutorials/webperformance/basics/
-// By Scott Murphy (uxder)
-Modernizr.addTest('performance', !!Modernizr.prefixed('performance', window));
\ No newline at end of file
+/*!
+{
+  "name": "Navigation Timing API",
+  "property": "performance",
+  "caniuse": "nav-timing",
+  "tags": ["performance"],
+  "authors": ["Scott Murphy (@uxder)"],
+  "notes": [{
+    "name": "W3C Spec",
+    "href": "http://www.w3.org/TR/navigation-timing/"
+  },{
+    "name": "HTML5 Rocks article",
+    "href": "http://www.html5rocks.com/en/tutorials/webperformance/basics/"
+  }],
+  "polyfills": ["perfnow"]
+}
+!*/
+/* DOC
+Detects support for the Navigation Timing API, for measuring browser and connection performance.
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('performance', !!prefixed('performance', window));
+});
diff --git a/js/modernizr/feature-detects/pointerevents.js b/js/modernizr/feature-detects/pointerevents.js
new file mode 100644 (file)
index 0000000..2591f4a
--- /dev/null
@@ -0,0 +1,38 @@
+/*!
+{
+  "name": "DOM Pointer Events API",
+  "property": "pointerevents",
+  "tags": ["input"],
+  "authors": ["Stu Cox"],
+  "notes": [
+    {
+      "name": "W3C spec",
+      "href": "http://www.w3.org/TR/pointerevents/"
+    }
+  ],
+  "warnings": ["This property name now refers to W3C DOM PointerEvents: https://github.com/Modernizr/Modernizr/issues/548#issuecomment-12812099"],
+  "polyfills": ["handjs"]
+}
+!*/
+/* DOC
+Detects support for the DOM Pointer Events API, which provides a unified event interface for pointing input devices, as implemented in IE10+.
+*/
+define(['Modernizr', 'domPrefixes', 'hasEvent'], function(Modernizr, domPrefixes, hasEvent) {
+  // **Test name hijacked!**
+  // Now refers to W3C DOM PointerEvents spec rather than the CSS pointer-events property.
+  Modernizr.addTest('pointerevents', function() {
+    // Cannot use `.prefixed()` for events, so test each prefix
+    var bool = false,
+    i = domPrefixes.length;
+
+    // Don't forget un-prefixed...
+    bool = Modernizr.hasEvent('pointerdown');
+
+    while (i-- && !bool) {
+      if (hasEvent(domPrefixes[i] + 'pointerdown')) {
+        bool = true;
+      }
+    }
+    return bool;
+  });
+});
index 07eb07e..f6412c1 100644 (file)
@@ -1,4 +1,18 @@
-// https://developer.mozilla.org/en-US/docs/API/Pointer_Lock_API
-
-Modernizr.addTest('pointerlock',!!Modernizr.prefixed('pointerLockElement', document));
-
+/*!
+{
+  "name": "Pointer Lock API",
+  "property": "pointerlock",
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/API/Pointer_Lock_API"
+  }],
+  "builderAliases": ["pointerlock_api"]
+}
+!*/
+/* DOC
+Detects support the pointer lock API which allows you to lock the mouse cursor to the browser window.
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  // https://developer.mozilla.org/en-US/docs/API/Pointer_Lock_API
+  Modernizr.addTest('pointerlock', !!prefixed('exitPointerLock', document));
+});
diff --git a/js/modernizr/feature-detects/postmessage.js b/js/modernizr/feature-detects/postmessage.js
new file mode 100644 (file)
index 0000000..0271ac3
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "postMessage",
+  "property": "postmessage",
+  "caniuse": "x-doc-messaging",
+  "notes": [{
+    "name": "W3C Spec",
+    "href": "http://www.w3.org/TR/html5/comms.html#posting-messages"
+  }],
+  "polyfills": ["easyxdm", "postmessage-jquery"]
+}
+!*/
+/* DOC
+Detects support for the `window.postMessage` protocol for cross-document messaging.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('postmessage', 'postMessage' in window);
+});
diff --git a/js/modernizr/feature-detects/proximity.js b/js/modernizr/feature-detects/proximity.js
new file mode 100644 (file)
index 0000000..84a42e4
--- /dev/null
@@ -0,0 +1,61 @@
+/*!
+{
+  "authors": ["Cătălin Mariș"],
+  "caniuse": "proximity",
+  "name": "Proximity API",
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/API/Proximity_Events"
+  },{
+    "name": "W3C specification",
+    "href": "http://www.w3.org/TR/proximity/"
+  }],
+  "property": "proximity",
+  "tags": ["events", "proximity"]
+}
+!*/
+/* DOC
+Detects support for an API that allows users to get proximity related information from the device's proximity sensor.
+*/
+define(['Modernizr', 'addTest'], function(Modernizr, addTest) {
+
+  Modernizr.addAsyncTest(function() {
+
+    var timeout;
+    var timeoutTime = 300;
+
+    function advertiseSupport() {
+
+      // Clean up after ourselves
+      clearTimeout(timeout);
+      window.removeEventListener('deviceproximity', advertiseSupport);
+
+      // Advertise support as the browser supports
+      // the API and the device has a proximity sensor
+      addTest('proximity', true);
+
+    }
+
+    // Check if the browser has support for the API
+    if ('ondeviceproximity' in window && 'onuserproximity' in window) {
+
+      // Check if the device has a proximity sensor
+      // ( devices without such a sensor support the events but
+      //   will never fire them resulting in a false positive )
+      window.addEventListener('deviceproximity', advertiseSupport);
+
+      // If the event doesn't fire in a reasonable amount of time,
+      // it means that the device doesn't have a proximity sensor,
+      // thus, we can advertise the "lack" of support
+      timeout = setTimeout(function() {
+        window.removeEventListener('deviceproximity', advertiseSupport);
+        addTest('proximity', false);
+      }, timeoutTime);
+
+    } else {
+      addTest('proximity', false);
+    }
+
+  });
+
+});
diff --git a/js/modernizr/feature-detects/queryselector.js b/js/modernizr/feature-detects/queryselector.js
new file mode 100644 (file)
index 0000000..612d920
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "QuerySelector",
+  "property": "queryselector",
+  "caniuse": "queryselector",
+  "tags": ["queryselector"],
+  "authors": ["Andrew Betts (@triblondon)"],
+  "notes": [{
+    "name" : "W3C Selectors reference",
+    "href": "http://www.w3.org/TR/selectors-api/#queryselectorall"
+  }],
+  "polyfills": ["css-selector-engine"]
+}
+!*/
+/* DOC
+Detects support for querySelector.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('queryselector', 'querySelector' in document && 'querySelectorAll' in document);
+});
index 5ce2b02..634119e 100644 (file)
@@ -1,11 +1,23 @@
-// Quota Storage Management API
-// This API can be used to check how much quota an origin is using and request more
+/*!
+{
+  "name": "Quota Storage Management API",
+  "property": "quotamanagement",
+  "tags": ["storage"],
+  "builderAliases": ["quota_management_api"],
+  "notes": [{
+    "name": "W3C Spec",
+    "href": "http://www.w3.org/TR/quota-api/"
+  }]
+}
+!*/
+/* DOC
+Detects the ability to request a specific amount of space for filesystem access
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('quotamanagement', function() {
+    var tempStorage = prefixed('temporaryStorage', navigator);
+    var persStorage = prefixed('persistentStorage', navigator);
 
-// Currently only implemented in Chrome.
-// https://developers.google.com/chrome/whitepapers/storage
-// By Addy Osmani
-
-Modernizr.addTest('quotamanagement', function(){
-  var storage = Modernizr.prefixed('StorageInfo', window);
-  return !!(storage && 'TEMPORARY' in storage && 'PERSISTENT' in storage);
+    return !!(tempStorage && persStorage);
+  });
 });
index 5ac4bcf..77acb15 100644 (file)
@@ -1,7 +1,21 @@
-
-// requestAnimationFrame
-// Offload animation repainting to browser for optimized performance. 
-// http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/RequestAnimationFrame/Overview.html
-// By Addy Osmani
-
-Modernizr.addTest('raf', !!Modernizr.prefixed('requestAnimationFrame', window));
\ No newline at end of file
+/*!
+{
+  "name": "requestAnimationFrame",
+  "property": "requestanimationframe",
+  "aliases": ["raf"],
+  "caniuse": "requestanimationframe",
+  "tags": ["animation"],
+  "authors": ["Addy Osmani"],
+  "notes": [{
+    "name": "W3C spec",
+    "href": "http://www.w3.org/TR/animation-timing/"
+  }],
+  "polyfills": ["raf"]
+}
+!*/
+/* DOC
+Detects support for the `window.requestAnimationFrame` API, for offloading animation repainting to the browser for optimized performance.
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('requestanimationframe', !!prefixed('requestAnimationFrame', window), {aliases: ['raf']});
+});
diff --git a/js/modernizr/feature-detects/script/async.js b/js/modernizr/feature-detects/script/async.js
new file mode 100644 (file)
index 0000000..fe9a4ac
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+{
+  "name": "script[async]",
+  "property": "scriptasync",
+  "caniuse": "script-async",
+  "tags": ["script"],
+  "builderAliases": ["script_async"],
+  "authors": ["Theodoor van Donge"]
+}
+!*/
+/* DOC
+Detects support for the `async` attribute on the `<script>` element.
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('scriptasync', 'async' in createElement('script'));
+});
diff --git a/js/modernizr/feature-detects/script/defer.js b/js/modernizr/feature-detects/script/defer.js
new file mode 100644 (file)
index 0000000..481a4fc
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "script[defer]",
+  "property": "scriptdefer",
+  "caniuse": "script-defer",
+  "tags": ["script"],
+  "builderAliases": ["script_defer"],
+  "authors": ["Theodoor van Donge"],
+  "warnings": ["Browser implementation of the `defer` attribute vary: http://stackoverflow.com/questions/3952009/defer-attribute-chrome#answer-3982619"],
+  "knownBugs": ["False positive in Opera 12"]
+}
+!*/
+/* DOC
+Detects support for the `defer` attribute on the `<script>` element.
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('scriptdefer', 'defer' in createElement('script'));
+});
diff --git a/js/modernizr/feature-detects/serviceworker.js b/js/modernizr/feature-detects/serviceworker.js
new file mode 100644 (file)
index 0000000..be6bc63
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+{
+  "name": "ServiceWorker API",
+  "property": "serviceworker",
+  "notes": [{
+    "name": "ServiceWorkers Explained",
+    "href": "https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md"
+  }]
+}
+!*/
+/* DOC
+ServiceWorkers (formerly Navigation Controllers) are a way to persistently cache resources to built apps that work better offline.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('serviceworker', 'serviceWorker' in navigator);
+});
diff --git a/js/modernizr/feature-detects/speech/speech-recognition.js b/js/modernizr/feature-detects/speech/speech-recognition.js
new file mode 100644 (file)
index 0000000..4eaadb9
--- /dev/null
@@ -0,0 +1,22 @@
+/*!
+{
+  "authors": ["Cătălin Mariș"],
+  "name": "Speech Recognition API",
+  "notes": [
+    {
+      "name": "W3C Web Speech API Specification - The SpeechRecognition Interface",
+      "href": "https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-section"
+    },
+    {
+      "name": "Introduction to the Web Speech API",
+      "href": "http://updates.html5rocks.com/2013/01/Voice-Driven-Web-Apps-Introduction-to-the-Web-Speech-API"
+    }
+  ],
+  "property": "speechrecognition",
+  "tags": ["input", "speech"]
+}
+!*/
+
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('speechrecognition', !!prefixed('SpeechRecognition', window));
+});
diff --git a/js/modernizr/feature-detects/speech/speech-synthesis.js b/js/modernizr/feature-detects/speech/speech-synthesis.js
new file mode 100644 (file)
index 0000000..6f7826c
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "authors": ["Cătălin Mariș"],
+  "name": "Speech Synthesis API",
+  "notes": [
+    {
+      "name": "W3C Web Speech API Specification - The SpeechSynthesis Interface",
+      "href": "https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section"
+    }
+  ],
+  "property": "speechsynthesis",
+  "tags": ["input", "speech"]
+}
+!*/
+
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('speechsynthesis', 'SpeechSynthesisUtterance' in window);
+});
diff --git a/js/modernizr/feature-detects/storage/localstorage.js b/js/modernizr/feature-detects/storage/localstorage.js
new file mode 100644 (file)
index 0000000..08c807d
--- /dev/null
@@ -0,0 +1,47 @@
+/*!
+{
+  "name": "Local Storage",
+  "property": "localstorage",
+  "caniuse": "namevalue-storage",
+  "tags": ["storage"],
+  "knownBugs": [],
+  "notes": [],
+  "warnings": [],
+  "polyfills": [
+    "joshuabell-polyfill",
+    "cupcake",
+    "storagepolyfill",
+    "amplifyjs",
+    "yui-cacheoffline"
+  ]
+}
+!*/
+define(['Modernizr'], function(Modernizr) {
+  // In FF4, if disabled, window.localStorage should === null.
+
+  // Normally, we could not test that directly and need to do a
+  //   `('localStorage' in window) && ` test first because otherwise Firefox will
+  //   throw bugzil.la/365772 if cookies are disabled
+
+  // Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem
+  // will throw the exception:
+  //   QUOTA_EXCEEDED_ERROR DOM Exception 22.
+  // Peculiarly, getItem and removeItem calls do not throw.
+
+  // Because we are forced to try/catch this, we'll go aggressive.
+
+  // Just FWIW: IE8 Compat mode supports these features completely:
+  //   www.quirksmode.org/dom/html5.html
+  // But IE8 doesn't support either with local files
+
+  Modernizr.addTest('localstorage', function() {
+    var mod = 'modernizr';
+    try {
+      localStorage.setItem(mod, mod);
+      localStorage.removeItem(mod);
+      return true;
+    } catch (e) {
+      return false;
+    }
+  });
+});
diff --git a/js/modernizr/feature-detects/storage/sessionstorage.js b/js/modernizr/feature-detects/storage/sessionstorage.js
new file mode 100644 (file)
index 0000000..1e2df82
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+{
+  "name": "Session Storage",
+  "property": "sessionstorage",
+  "tags": ["storage"],
+  "polyfills": ["joshuabell-polyfill", "cupcake", "sessionstorage"]
+}
+!*/
+define(['Modernizr'], function(Modernizr) {
+  // Because we are forced to try/catch this, we'll go aggressive.
+
+  // Just FWIW: IE8 Compat mode supports these features completely:
+  //   www.quirksmode.org/dom/html5.html
+  // But IE8 doesn't support either with local files
+  Modernizr.addTest('sessionstorage', function() {
+    var mod = 'modernizr';
+    try {
+      sessionStorage.setItem(mod, mod);
+      sessionStorage.removeItem(mod);
+      return true;
+    } catch (e) {
+      return false;
+    }
+  });
+});
diff --git a/js/modernizr/feature-detects/storage/websqldatabase.js b/js/modernizr/feature-detects/storage/websqldatabase.js
new file mode 100644 (file)
index 0000000..f50caf2
--- /dev/null
@@ -0,0 +1,13 @@
+/*!
+{
+  "name": "Web SQL Database",
+  "property": "websqldatabase",
+  "caniuse": "sql-storage",
+  "tags": ["storage"]
+}
+!*/
+define(['Modernizr'], function(Modernizr) {
+  // Chrome incognito mode used to throw an exception when using openDatabase
+  // It doesn't anymore.
+  Modernizr.addTest('websqldatabase', 'openDatabase' in window);
+});
diff --git a/js/modernizr/feature-detects/style/scoped.js b/js/modernizr/feature-detects/style/scoped.js
new file mode 100644 (file)
index 0000000..412a5b8
--- /dev/null
@@ -0,0 +1,21 @@
+/*!
+{
+  "name": "style[scoped]",
+  "property": "stylescoped",
+  "caniuse": "style-scoped",
+  "tags": ["dom"],
+  "builderAliases": ["style_scoped"],
+  "authors": ["Cătălin Mariș"],
+  "notes": [{
+    "name": "WHATWG Specification",
+    "href": "http://www.whatwg.org/specs/web-apps/current-work/multipage/semantics.html#attr-style-scoped"
+  }],
+  "polyfills": ["scoped-styles"]
+}
+!*/
+/* DOC
+Support for the `scoped` attribute of the `<style>` element.
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('stylescoped', 'scoped' in createElement('style'));
+});
diff --git a/js/modernizr/feature-detects/svg.js b/js/modernizr/feature-detects/svg.js
new file mode 100644 (file)
index 0000000..3359d92
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+{
+  "name": "SVG",
+  "property": "svg",
+  "caniuse": "svg",
+  "tags": ["svg"],
+  "authors": ["Erik Dahlstrom"],
+  "polyfills": [
+    "svgweb",
+    "raphael",
+    "amplesdk",
+    "canvg",
+    "svg-boilerplate",
+    "sie",
+    "dojogfx",
+    "fabricjs"
+  ]
+}
+!*/
+/* DOC
+Detects support for SVG in `<embed>` or `<object>` elements.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('svg', !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect);
+});
diff --git a/js/modernizr/feature-detects/svg/asimg.js b/js/modernizr/feature-detects/svg/asimg.js
new file mode 100644 (file)
index 0000000..50047be
--- /dev/null
@@ -0,0 +1,26 @@
+/*!
+{
+  "name": "SVG as an <img> tag source",
+  "property": "svgasimg",
+  "caniuse" : "svg-img",
+  "tags": ["svg"],
+  "authors": ["Chris Coyier"],
+  "notes": [{
+    "name": "HTML5 Spec",
+    "href": "http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element"
+  }]
+}
+!*/
+define(['Modernizr', 'addTest'], function(Modernizr) {
+
+  // Original Async test by Stu Cox
+  // https://gist.github.com/chriscoyier/8774501
+
+  // Now a Sync test based on good results here
+  // http://codepen.io/chriscoyier/pen/bADFx
+
+  // Note http://www.w3.org/TR/SVG11/feature#Image is *supposed* to represent
+  // support for the `<image>` tag in SVG, not an SVG file linked from an `<img>`
+  // tag in HTML – but it’s a heuristic which works
+  Modernizr.addTest('svgasimg', document.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#Image', '1.1'));
+});
diff --git a/js/modernizr/feature-detects/svg/clippaths.js b/js/modernizr/feature-detects/svg/clippaths.js
new file mode 100644 (file)
index 0000000..fd746ae
--- /dev/null
@@ -0,0 +1,22 @@
+/*!
+{
+  "name": "SVG clip paths",
+  "property": "svgclippaths",
+  "tags": ["svg"],
+  "notes": [{
+    "name": "Demo",
+    "href": "http://srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg"
+  }]
+}
+!*/
+/* DOC
+Detects support for clip paths in SVG (only, not on HTML content).
+
+See [this discussion](http://github.com/Modernizr/Modernizr/issues/213) regarding applying SVG clip paths to HTML content.
+*/
+define(['Modernizr', 'toStringFn'], function(Modernizr, toStringFn) {
+  Modernizr.addTest('svgclippaths', function() {
+    return !!document.createElementNS &&
+      /SVGClipPath/.test(toStringFn.call(document.createElementNS('http://www.w3.org/2000/svg', 'clipPath')));
+  });
+});
diff --git a/js/modernizr/feature-detects/svg/filters.js b/js/modernizr/feature-detects/svg/filters.js
new file mode 100644 (file)
index 0000000..ef299f2
--- /dev/null
@@ -0,0 +1,26 @@
+/*!
+{
+  "name": "SVG filters",
+  "property": "svgfilters",
+  "caniuse": "svg-filters",
+  "tags": ["svg"],
+  "builderAliases": ["svg_filters"],
+  "authors": ["Erik Dahlstrom"],
+  "notes": [{
+    "name": "W3C Spec",
+    "href": "http://www.w3.org/TR/SVG11/filters.html"
+  }]
+}
+!*/
+define(['Modernizr'], function(Modernizr) {
+  // Should fail in Safari: http://stackoverflow.com/questions/9739955/feature-detecting-support-for-svg-filters.
+  Modernizr.addTest('svgfilters', function() {
+    var result = false;
+    try {
+      result = 'SVGFEColorMatrixElement' in window &&
+        SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_SATURATE == 2;
+    }
+    catch (e) {}
+    return result;
+  });
+});
diff --git a/js/modernizr/feature-detects/svg/foreignobject.js b/js/modernizr/feature-detects/svg/foreignobject.js
new file mode 100644 (file)
index 0000000..2283178
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "SVG foreignObject",
+  "property": "svgforeignobject",
+  "tags": ["svg"],
+  "notes": [{
+    "name": "W3C Spec",
+    "href": "http://www.w3.org/TR/SVG11/extend.html"
+  }]
+}
+!*/
+/* DOC
+Detects support for foreignObject tag in SVG.
+*/
+define(['Modernizr', 'toStringFn'], function(Modernizr, toStringFn) {
+  Modernizr.addTest('svgforeignobject', function() {
+    return !!document.createElementNS &&
+      /SVGForeignObject/.test(toStringFn.call(document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject')));
+  });
+});
diff --git a/js/modernizr/feature-detects/svg/inline.js b/js/modernizr/feature-detects/svg/inline.js
new file mode 100644 (file)
index 0000000..3e1227e
--- /dev/null
@@ -0,0 +1,27 @@
+/*!
+{
+  "name": "Inline SVG",
+  "property": "inlinesvg",
+  "caniuse": "svg-html5",
+  "tags": ["svg"],
+  "notes": [{
+    "name": "Test page",
+    "href": "http://paulirish.com/demo/inline-svg"
+  }, {
+    "name": "Test page and results",
+    "href": "http://codepen.io/eltonmesquita/full/GgXbvo/"
+  }],
+  "polyfills": ["inline-svg-polyfill"],
+  "knownBugs": ["False negative on some Chromia browsers."]
+}
+!*/
+/* DOC
+Detects support for inline SVG in HTML (not within XHTML).
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('inlinesvg', function() {
+    var div = createElement('div');
+    div.innerHTML = '<svg/>';
+    return (typeof SVGRect != 'undefined' && div.firstChild && div.firstChild.namespaceURI) == 'http://www.w3.org/2000/svg';
+  });
+});
diff --git a/js/modernizr/feature-detects/svg/smil.js b/js/modernizr/feature-detects/svg/smil.js
new file mode 100644 (file)
index 0000000..3063a5f
--- /dev/null
@@ -0,0 +1,19 @@
+/*!
+{
+  "name": "SVG SMIL animation",
+  "property": "smil",
+  "caniuse": "svg-smil",
+  "tags": ["svg"],
+  "notes": [{
+  "name": "W3C Synchronised Multimedia spec",
+  "href": "http://www.w3.org/AudioVideo/"
+  }]
+}
+!*/
+define(['Modernizr', 'toStringFn'], function(Modernizr, toStringFn) {
+  // SVG SMIL animation
+  Modernizr.addTest('smil', function() {
+    return !!document.createElementNS &&
+      /SVGAnimate/.test(toStringFn.call(document.createElementNS('http://www.w3.org/2000/svg', 'animate')));
+  });
+});
diff --git a/js/modernizr/feature-detects/templatestrings.js b/js/modernizr/feature-detects/templatestrings.js
new file mode 100644 (file)
index 0000000..07f89f6
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+{
+  "name": "Template strings",
+  "property": "templatestrings",
+  "notes": [{
+    "name": "MDN Reference",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings#Browser_compatibility"
+  }]
+}
+!*/
+/* DOC
+Template strings are string literals allowing embedded expressions.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('templatestrings', function() {
+    var supports;
+    try {
+      // A number of tools, including uglifyjs and require, break on a raw "`", so
+      // use an eval to get around that.
+      eval('``');
+      supports = true;
+    } catch (e) {}
+    return !!supports;
+  });
+});
diff --git a/js/modernizr/feature-detects/textarea/maxlength.js b/js/modernizr/feature-detects/textarea/maxlength.js
new file mode 100644 (file)
index 0000000..6811887
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+{
+  "name": "textarea maxlength",
+  "property": "textareamaxlength",
+  "aliases": ["textarea-maxlength"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea"
+  }],
+  "polyfills": [
+    "maxlength"
+  ]
+}
+!*/
+/* DOC
+Detect support for the maxlength attribute of a textarea element
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('textareamaxlength', !!('maxLength' in createElement('textarea')));
+});
diff --git a/js/modernizr/feature-detects/touchevents.js b/js/modernizr/feature-detects/touchevents.js
new file mode 100644 (file)
index 0000000..4b4912d
--- /dev/null
@@ -0,0 +1,50 @@
+/*!
+{
+  "name": "Touch Events",
+  "property": "touchevents",
+  "caniuse" : "touch",
+  "tags": ["media", "attribute"],
+  "notes": [{
+    "name": "Touch Events spec",
+    "href": "http://www.w3.org/TR/2013/WD-touch-events-20130124/"
+  }],
+  "warnings": [
+    "Indicates if the browser supports the Touch Events spec, and does not necessarily reflect a touchscreen device"
+  ],
+  "knownBugs": [
+    "False-positive on some configurations of Nokia N900",
+    "False-positive on some BlackBerry 6.0 builds – https://github.com/Modernizr/Modernizr/issues/372#issuecomment-3112695"
+  ]
+}
+!*/
+/* DOC
+Indicates if the browser supports the W3C Touch Events API.
+
+This *does not* necessarily reflect a touchscreen device:
+
+* Older touchscreen devices only emulate mouse events
+* Modern IE touch devices implement the Pointer Events API instead: use `Modernizr.pointerevents` to detect support for that
+* Some browsers & OS setups may enable touch APIs when no touchscreen is connected
+* Future browsers may implement other event models for touch interactions
+
+See this article: [You Can't Detect A Touchscreen](http://www.stucox.com/blog/you-cant-detect-a-touchscreen/).
+
+It's recommended to bind both mouse and touch/pointer events simultaneously – see [this HTML5 Rocks tutorial](http://www.html5rocks.com/en/mobile/touchandmouse/).
+
+This test will also return `true` for Firefox 4 Multitouch support.
+*/
+define(['Modernizr', 'prefixes', 'testStyles'], function(Modernizr, prefixes, testStyles) {
+  // Chrome (desktop) used to lie about its support on this, but that has since been rectified: http://crbug.com/36415
+  Modernizr.addTest('touchevents', function() {
+    var bool;
+    if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
+      bool = true;
+    } else {
+      var query = ['@media (', prefixes.join('touch-enabled),('), 'heartz', ')', '{#modernizr{top:9px;position:absolute}}'].join('');
+      testStyles(query, function(node) {
+        bool = node.offsetTop === 9;
+      });
+    }
+    return bool;
+  });
+});
diff --git a/js/modernizr/feature-detects/typed-arrays.js b/js/modernizr/feature-detects/typed-arrays.js
new file mode 100644 (file)
index 0000000..f9002c6
--- /dev/null
@@ -0,0 +1,36 @@
+/*!
+{
+  "name": "Typed arrays",
+  "property": "typedarrays",
+  "caniuse": "typedarrays",
+  "tags": ["js"],
+  "authors": ["Stanley Stuart (@fivetanley)"],
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/JavaScript_typed_arrays"
+  },{
+    "name": "Kronos spec",
+    "href": "http://www.khronos.org/registry/typedarray/specs/latest/"
+  }],
+  "polyfills": ["joshuabell-polyfill"]
+}
+!*/
+/* DOC
+Detects support for native binary data manipulation via Typed Arrays in JavaScript.
+
+Does not check for DataView support; use `Modernizr.dataview` for that.
+*/
+define(['Modernizr'], function(Modernizr) {
+  // Should fail in:
+  // Internet Explorer <= 9
+  // Firefox <= 3.6
+  // Chrome <= 6.0
+  // iOS Safari < 4.2
+  // Safari < 5.1
+  // Opera < 11.6
+  // Opera Mini, <= 7.0
+  // Android Browser < 4.0
+  // Blackberry Browser < 10.0
+
+  Modernizr.addTest('typedarrays', 'ArrayBuffer' in window);
+});
diff --git a/js/modernizr/feature-detects/unicode-range.js b/js/modernizr/feature-detects/unicode-range.js
new file mode 100644 (file)
index 0000000..2ccbe13
--- /dev/null
@@ -0,0 +1,37 @@
+/*!
+{
+  "name": "Unicode Range",
+  "property": "unicoderange",
+  "notes": [{
+    "name" : "W3C reference",
+    "href": "http://www.w3.org/TR/2013/CR-css-fonts-3-20131003/#descdef-unicode-range"
+  }, {
+    "name" : "24 Way article",
+    "href": "http://24ways.org/2011/creating-custom-font-stacks-with-unicode-range"
+  }]
+}
+!*/
+define(['Modernizr', 'testStyles', 'createElement'], function(Modernizr, testStyles, createElement) {
+  Modernizr.addTest('unicoderange', function() {
+
+    return Modernizr.testStyles('@font-face{font-family:"unicodeRange";src:local("Arial");unicode-range:U+0020,U+002E}#modernizr span{font-size:20px;display:inline-block;font-family:"unicodeRange",monospace}#modernizr .mono{font-family:monospace}', function(elem) {
+
+      // we use specify a unicode-range of 002E (the `.` glyph,
+      // and a monospace font as the fallback. If the first of
+      // these test glyphs is a different width than the other
+      // the other three (which are all monospace), then we
+      // have a winner.
+      var testGlyphs = ['.', '.', 'm', 'm'];
+
+      for (var i = 0; i < testGlyphs.length; i++) {
+        var elm = createElement('span');
+        elm.innerHTML = testGlyphs[i];
+        elm.className = i % 2 ? 'mono' : '';
+        elem.appendChild(elm);
+        testGlyphs[i] = elm.clientWidth;
+      }
+
+      return (testGlyphs[0] !== testGlyphs[1] && testGlyphs[2] === testGlyphs[3]);
+    });
+  });
+});
index 39908bf..6c1be3e 100644 (file)
@@ -1,32 +1,41 @@
-/**
- * Unicode special character support
- * 
- * Detection is made by testing missing glyph box rendering against star character
- * If widths are the same, this "probably" means the browser didn't support the star character and rendered a glyph box instead
- * Just need to ensure the font characters have different widths
- * 
- * Warning : positive Unicode support doesn't mean you can use it inside <title>, this seams more related to OS & Language packs
- */
-Modernizr.addTest('unicode', function() {
-       
-       
-       var bool,
+/*!
+{
+  "name": "Unicode characters",
+  "property": "unicode",
+  "tags": ["encoding"],
+  "warnings": [
+    "positive Unicode support doesn't mean you can use it inside <title>, this seems more related to OS & Language packs"
+  ]
+}
+!*/
+/* DOC
+Detects if unicode characters are supported in the current document.
+*/
+define(['Modernizr', 'createElement', 'testStyles', 'isSVG'], function(Modernizr, createElement, testStyles, isSVG) {
+  /**
+   * Unicode special character support
+   *
+   * Detection is made by testing missing glyph box rendering against star character
+   * If widths are the same, this "probably" means the browser didn't support the star character and rendered a glyph box instead
+   * Just need to ensure the font characters have different widths
+   */
+  Modernizr.addTest('unicode', function() {
+    var bool;
+    var missingGlyph = createElement('span');
+    var star = createElement('span');
 
-               missingGlyph = document.createElement('span'),
-               
-               star = document.createElement('span');
+    testStyles('#modernizr{font-family:Arial,sans;font-size:300em;}', function(node) {
 
-       Modernizr.testStyles('#modernizr{font-family:Arial,sans;font-size:300em;}', function(node) {
+      missingGlyph.innerHTML = isSVG ? '\u5987' : '&#5987';
+      star.innerHTML = isSVG ? '\u2606' : '&#9734';
 
-               missingGlyph.innerHTML = '&#5987';
-               star.innerHTML = '&#9734';              
-               
-               node.appendChild(missingGlyph);
-               node.appendChild(star);
-               
-               bool = 'offsetWidth' in missingGlyph && missingGlyph.offsetWidth !== star.offsetWidth;
-       });
+      node.appendChild(missingGlyph);
+      node.appendChild(star);
 
-       return bool;
+      bool = 'offsetWidth' in missingGlyph && missingGlyph.offsetWidth !== star.offsetWidth;
+    });
 
-});
\ No newline at end of file
+    return bool;
+
+  });
+});
diff --git a/js/modernizr/feature-detects/url/bloburls.js b/js/modernizr/feature-detects/url/bloburls.js
new file mode 100644 (file)
index 0000000..e94d25e
--- /dev/null
@@ -0,0 +1,21 @@
+/*!
+{
+  "name": "Blob URLs",
+  "property": "bloburls",
+  "caniuse": "bloburls",
+  "notes": [{
+    "name": "W3C Working Draft",
+    "href": "http://www.w3.org/TR/FileAPI/#creating-revoking"
+  }],
+  "tags": ["file", "url"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"]
+}
+!*/
+/* DOC
+Detects support for creating Blob URLs
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  var url = prefixed('URL', window, false);
+  url = url && window[url];
+  Modernizr.addTest('bloburls', url && 'revokeObjectURL' in url && 'createObjectURL' in url);
+});
diff --git a/js/modernizr/feature-detects/url/data-uri.js b/js/modernizr/feature-detects/url/data-uri.js
new file mode 100644 (file)
index 0000000..1ddfb7f
--- /dev/null
@@ -0,0 +1,80 @@
+/*!
+{
+  "name": "Data URI",
+  "property": "datauri",
+  "caniuse": "datauri",
+  "tags": ["url"],
+  "builderAliases": ["url_data_uri"],
+  "async": true,
+  "notes": [{
+    "name": "Wikipedia article",
+    "href": "http://en.wikipedia.org/wiki/Data_URI_scheme"
+  }],
+  "warnings": ["Support in Internet Explorer 8 is limited to images and linked resources like CSS files, not HTML files"]
+}
+!*/
+/* DOC
+Detects support for data URIs. Provides a subproperty to report support for data URIs over 32kb in size:
+
+```javascript
+Modernizr.datauri           // true
+Modernizr.datauri.over32kb  // false in IE8
+```
+*/
+define(['Modernizr', 'addTest'], function(Modernizr, addTest) {
+  // https://github.com/Modernizr/Modernizr/issues/14
+  Modernizr.addAsyncTest(function() {
+    /* jshint -W053 */
+
+    // IE7 throw a mixed content warning on HTTPS for this test, so we'll
+    // just blacklist it (we know it doesn't support data URIs anyway)
+    // https://github.com/Modernizr/Modernizr/issues/362
+    if (navigator.userAgent.indexOf('MSIE 7.') !== -1) {
+      // Keep the test async
+      setTimeout(function() {
+        addTest('datauri', false);
+      }, 10);
+    }
+
+    var datauri = new Image();
+
+    datauri.onerror = function() {
+      addTest('datauri', false);
+    };
+    datauri.onload = function() {
+      if (datauri.width == 1 && datauri.height == 1) {
+        testOver32kb();
+      }
+      else {
+        addTest('datauri', false);
+      }
+    };
+
+    datauri.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
+
+    // Once we have datauri, let's check to see if we can use data URIs over
+    // 32kb (IE8 can't). https://github.com/Modernizr/Modernizr/issues/321
+    function testOver32kb() {
+
+      var datauriBig = new Image();
+
+      datauriBig.onerror = function() {
+        addTest('datauri', true);
+        Modernizr.datauri = new Boolean(true);
+        Modernizr.datauri.over32kb = false;
+      };
+      datauriBig.onload = function() {
+        addTest('datauri', true);
+        Modernizr.datauri = new Boolean(true);
+        Modernizr.datauri.over32kb = (datauriBig.width == 1 && datauriBig.height == 1);
+      };
+
+      var base64str = 'R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
+      while (base64str.length < 33000) {
+        base64str = '\r\n' + base64str;
+      }
+      datauriBig.src = 'data:image/gif;base64,' + base64str;
+    }
+
+  });
+});
diff --git a/js/modernizr/feature-detects/url/parser.js b/js/modernizr/feature-detects/url/parser.js
new file mode 100644 (file)
index 0000000..6c7891b
--- /dev/null
@@ -0,0 +1,28 @@
+/*!
+{
+  "name": "URL parser",
+  "property": "urlparser",
+  "notes": [{
+    "name": "URL",
+    "href": "https://dvcs.w3.org/hg/url/raw-file/tip/Overview.html"
+  }],
+  "polyfills": ["urlparser"],
+  "authors": ["Ron Waldon (@jokeyrhyme)"],
+  "tags": ["url"]
+}
+!*/
+/* DOC
+Check if browser implements the URL constructor for parsing URLs.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('urlparser', function() {
+    var url;
+    try {
+      // have to actually try use it, because Safari defines a dud constructor
+      url = new URL('http://modernizr.com/');
+      return url.href === 'http://modernizr.com/';
+    } catch (e) {
+      return false;
+    }
+  });
+});
index 79d921e..0599b65 100644 (file)
@@ -1,7 +1,18 @@
-// test if IE userdata supported
-// msdn.microsoft.com/en-us/library/ms531424(v=vs.85).aspx
-// test by @stereobooster
-
-Modernizr.addTest('userdata', function(){
-  return !!document.createElement('div').addBehavior;
+/*!
+{
+  "name": "IE User Data API",
+  "property": "userdata",
+  "tags": ["storage"],
+  "authors": ["@stereobooster"],
+  "notes": [{
+    "name": "MSDN Documentation",
+    "href": "http://msdn.microsoft.com/en-us/library/ms531424(v=vs.85).aspx"
+  }]
+}
+!*/
+/* DOC
+Detects support for IE userData for persisting data, an API similar to localStorage but supported since IE5.
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('userdata', !!createElement('div').addBehavior);
 });
index 034c25d..d26efcb 100644 (file)
@@ -1,4 +1,19 @@
-// Vibration API
-// http://www.w3.org/TR/vibration/
-// https://developer.mozilla.org/en/DOM/window.navigator.mozVibrate
-Modernizr.addTest('vibrate', !!Modernizr.prefixed('vibrate', navigator));
\ No newline at end of file
+/*!
+{
+  "name": "Vibration API",
+  "property": "vibrate",
+  "notes": [{
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en/DOM/window.navigator.mozVibrate"
+  },{
+    "name": "W3C spec",
+    "href": "http://www.w3.org/TR/vibration/"
+  }]
+}
+!*/
+/* DOC
+Detects support for the API that provides access to the vibration mechanism of the hosting device, to provide tactile feedback.
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('vibrate', !!prefixed('vibrate', navigator));
+});
diff --git a/js/modernizr/feature-detects/video.js b/js/modernizr/feature-detects/video.js
new file mode 100644 (file)
index 0000000..55937bd
--- /dev/null
@@ -0,0 +1,62 @@
+/*!
+{
+  "name": "HTML5 Video",
+  "property": "video",
+  "caniuse": "video",
+  "tags": ["html5"],
+  "knownBugs": [
+    "Without QuickTime, `Modernizr.video.h264` will be `undefined`; http://github.com/Modernizr/Modernizr/issues/546"
+  ],
+  "polyfills": [
+    "html5media",
+    "mediaelementjs",
+    "sublimevideo",
+    "videojs",
+    "leanbackplayer",
+    "videoforeverybody"
+  ]
+}
+!*/
+/* DOC
+Detects support for the video element, as well as testing what types of content it supports.
+
+Subproperties are provided to describe support for `ogg`, `h264` and `webm` formats, e.g.:
+
+```javascript
+Modernizr.video         // true
+Modernizr.video.ogg     // 'probably'
+```
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
+  //                     thx to NielsLeenheer and zcorpan
+
+  // Note: in some older browsers, "no" was a return value instead of empty string.
+  //   It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
+  //   It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5
+
+  Modernizr.addTest('video', function() {
+    /* jshint -W053 */
+    var elem = createElement('video');
+    var bool = false;
+
+    // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
+    try {
+      if (bool = !!elem.canPlayType) {
+        bool = new Boolean(bool);
+        bool.ogg = elem.canPlayType('video/ogg; codecs="theora"').replace(/^no$/, '');
+
+        // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
+        bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/, '');
+
+        bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/, '');
+
+        bool.vp9 = elem.canPlayType('video/webm; codecs="vp9"').replace(/^no$/, '');
+
+        bool.hls = elem.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(/^no$/, '');
+      }
+    } catch (e) {}
+
+    return bool;
+  });
+});
diff --git a/js/modernizr/feature-detects/video/autoplay.js b/js/modernizr/feature-detects/video/autoplay.js
new file mode 100644 (file)
index 0000000..c30891d
--- /dev/null
@@ -0,0 +1,68 @@
+/*!
+{
+  "name": "Video Autoplay",
+  "property": "videoautoplay",
+  "tags": ["video"],
+  "async" : true,
+  "warnings": ["This test is very large – only include it if you absolutely need it"],
+  "knownBugs": ["crashes with an alert on iOS7 when added to homescreen"]
+}
+!*/
+/* DOC
+Checks for support of the autoplay attribute of the video element.
+*/
+define(['Modernizr', 'addTest', 'docElement', 'createElement', 'test/video'], function(Modernizr, addTest, docElement, createElement) {
+
+  Modernizr.addAsyncTest(function() {
+    var timeout;
+    var waitTime = 300;
+    var elem = createElement('video');
+    var elemStyle = elem.style;
+
+    function testAutoplay(arg) {
+      clearTimeout(timeout);
+      elem.removeEventListener('playing', testAutoplay, false);
+      addTest('videoautoplay', arg && arg.type === 'playing' || elem.currentTime !== 0);
+      elem.parentNode.removeChild(elem);
+    }
+
+    //skip the test if video itself, or the autoplay
+    //element on it isn't supported
+    if (!Modernizr.video || !('autoplay' in elem)) {
+      addTest('videoautoplay', false);
+      return;
+    }
+
+    elemStyle.position = 'absolute';
+    elemStyle.height = 0;
+    elemStyle.width = 0;
+
+    try {
+      if (Modernizr.video.ogg) {
+        elem.src = 'data:video/ogg;base64,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';
+      }
+      else if (Modernizr.video.h264) {
+        elem.src = 'data:video/mp4;base64,AAAAHGZ0eXBtcDQyAAAAAG1wNDJpc29tYXZjMQAAAz5tb292AAAAbG12aGQAAAAAzaNacc2jWnEAAV+QAAFfkAABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAGGlvZHMAAAAAEICAgAcAT////3//AAACQ3RyYWsAAABcdGtoZAAAAAHNo1pxzaNacQAAAAEAAAAAAAFfkAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAEAAAABAAAAAAAd9tZGlhAAAAIG1kaGQAAAAAzaNacc2jWnEAAV+QAAFfkFXEAAAAAAAhaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAAAAAAGWbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAABVnN0YmwAAACpc3RzZAAAAAAAAAABAAAAmWF2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAEAAQAEgAAABIAAAAAAAAAAEOSlZUL0FWQyBDb2RpbmcAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAxYXZjQwH0AAr/4QAZZ/QACq609NQYBBkAAAMAAQAAAwAKjxImoAEABWjOAa8gAAAAEmNvbHJuY2xjAAYAAQAGAAAAGHN0dHMAAAAAAAAAAQAAAAUAAEZQAAAAKHN0c3oAAAAAAAAAAAAAAAUAAAIqAAAACAAAAAgAAAAIAAAACAAAAChzdHNjAAAAAAAAAAIAAAABAAAABAAAAAEAAAACAAAAAQAAAAEAAAAYc3RjbwAAAAAAAAACAAADYgAABaQAAAAUc3RzcwAAAAAAAAABAAAAAQAAABFzZHRwAAAAAAREREREAAAAb3VkdGEAAABnbWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcgAAAAAAAAAAAAAAAAAAAAA6aWxzdAAAADKpdG9vAAAAKmRhdGEAAAABAAAAAEhhbmRCcmFrZSAwLjkuOCAyMDEyMDcxODAwAAACUm1kYXQAAAHkBgX/4NxF6b3m2Ui3lizYINkj7u94MjY0IC0gY29yZSAxMjAgLSBILjI2NC9NUEVHLTQgQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDExIC0gaHR0cDovL3d3dy52aWRlb2xhbi5vcmcveDI2NC5odG1sIC0gb3B0aW9uczogY2FiYWM9MCByZWY9MSBkZWJsb2NrPTE6MDowIGFuYWx5c2U9MHgxOjAgbWU9ZXNhIHN1Ym1lPTkgcHN5PTAgbWl4ZWRfcmVmPTAgbWVfcmFuZ2U9NCBjaHJvbWFfbWU9MSB0cmVsbGlzPTAgOHg4ZGN0PTAgY3FtPTAgZGVhZHpvbmU9MjEsMTEgZmFzdF9wc2tpcD0wIGNocm9tYV9xcF9vZmZzZXQ9MCB0aHJlYWRzPTYgc2xpY2VkX3RocmVhZHM9MCBucj0wIGRlY2ltYXRlPTEgaW50ZXJsYWNlZD0wIGJsdXJheV9jb21wYXQ9MCBjb25zdHJhaW5lZF9pbnRyYT0wIGJmcmFtZXM9MCB3ZWlnaHRwPTAga2V5aW50PTUwIGtleWludF9taW49NSBzY2VuZWN1dD00MCBpbnRyYV9yZWZyZXNoPTAgcmM9Y3FwIG1idHJlZT0wIHFwPTAAgAAAAD5liISscR8A+E4ACAACFoAAITAAAgsAAPgYCoKgoC+L4vi+KAvi+L4YfAEAACMzgABF9AAEUGUgABDJiXnf4AAAAARBmiKUAAAABEGaQpQAAAAEQZpilAAAAARBmoKU';
+      }
+      else {
+        addTest('videoautoplay', false);
+        return;
+      }
+    }
+
+    catch (e) {
+      addTest('videoautoplay', false);
+      return;
+    }
+
+    elem.setAttribute('autoplay', '');
+    elem.style.cssText = 'display:none';
+    docElement.appendChild(elem);
+    // wait for the next tick to add the listener, otherwise the element may
+    // not have time to play in high load situations (e.g. the test suite)
+    setTimeout(function() {
+      elem.addEventListener('playing', testAutoplay, false);
+      timeout = setTimeout(testAutoplay, waitTime);
+    }, 0);
+  });
+});
diff --git a/js/modernizr/feature-detects/video/loop.js b/js/modernizr/feature-detects/video/loop.js
new file mode 100644 (file)
index 0000000..9cfa5af
--- /dev/null
@@ -0,0 +1,10 @@
+/*!
+{
+  "name": "Video Loop Attribute",
+  "property": "videoloop",
+  "tags": ["video", "media"]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('videoloop', 'loop' in createElement('video'));
+});
diff --git a/js/modernizr/feature-detects/video/preload.js b/js/modernizr/feature-detects/video/preload.js
new file mode 100644 (file)
index 0000000..3ab95a8
--- /dev/null
@@ -0,0 +1,10 @@
+/*!
+{
+  "name": "Video Preload Attribute",
+  "property": "videopreload",
+  "tags": ["video", "media"]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('videopreload', 'preload' in createElement('video'));
+});
diff --git a/js/modernizr/feature-detects/vml.js b/js/modernizr/feature-detects/vml.js
new file mode 100644 (file)
index 0000000..54c972f
--- /dev/null
@@ -0,0 +1,35 @@
+/*!
+{
+  "name": "VML",
+  "property": "vml",
+  "caniuse": "vml",
+  "tags": ["vml"],
+  "authors": ["Craig Andrews (@candrews)"],
+  "notes": [{
+    "name" : "W3C VML reference",
+    "href": "http://www.w3.org/TR/NOTE-VML"
+  },{
+    "name" : "Microsoft VML reference",
+    "href": "http://msdn.microsoft.com/en-us/library/bb263898%28VS.85%29.aspx"
+  }]
+}
+!*/
+/* DOC
+Detects support for VML.
+*/
+define(['Modernizr', 'createElement', 'isSVG'], function(Modernizr, createElement, isSVG) {
+  Modernizr.addTest('vml', function() {
+    var containerDiv = createElement('div');
+    var supports = false;
+    var shape;
+
+    if (!isSVG) {
+      containerDiv.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
+      shape = containerDiv.firstChild;
+      shape.style.behavior = 'url(#default#VML)';
+      supports = shape ? typeof shape.adj == 'object' : true;
+    }
+
+    return supports;
+  });
+});
index d0557fe..02994d5 100644 (file)
@@ -1,6 +1,22 @@
-// Tests for the ability to use Web Intents (http://webintents.org).
-// By Eric Bidelman
+/*!
+{
+  "name": "Web Intents",
+  "property": "webintents",
+  "authors": ["Eric Bidelman"],
+  "notes": [{
+    "name": "Web Intents project site",
+    "href": "http://webintents.org/"
+  }],
+  "polyfills": ["webintents"],
+  "builderAliases": ["web_intents"]
+}
+!*/
+/* DOC
+Detects native support for the Web Intents APIs for service discovery and inter-application communication.
 
-Modernizr.addTest('webintents', function() {
-  return !!Modernizr.prefixed('startActivity', navigator);
+Chrome added support for this in v19, but [removed it again in v24](http://lists.w3.org/Archives/Public/public-web-intents/2012Nov/0000.html) because of "a number of areas for
+development in both the API and specific user experience in Chrome". No other browsers currently support it, however a [JavaScript shim](http://webintents.org/#javascriptshim) is available.
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('webintents', !!prefixed('startActivity', navigator));
 });
diff --git a/js/modernizr/feature-detects/webanimations.js b/js/modernizr/feature-detects/webanimations.js
new file mode 100644 (file)
index 0000000..1b61bcf
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+{
+  "name": "Web Animation API",
+  "property": "animation",
+  "tags": ["webanimations"],
+  "polyfills": ["webanimationsjs"],
+  "notes": [{
+    "name": "Introducing Web Animations",
+    "href": "http://brian.sol1.net/svg/2013/06/26/introducing-web-animations/"
+  }]
+}
+!*/
+/* DOC
+Detects support for the Web Animation API, a way to create css animations in js
+*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('webanimations', 'animate' in createElement('div'));
+});
diff --git a/js/modernizr/feature-detects/webgl.js b/js/modernizr/feature-detects/webgl.js
new file mode 100644 (file)
index 0000000..79a4671
--- /dev/null
@@ -0,0 +1,19 @@
+/*!
+{
+  "name": "WebGL",
+  "property": "webgl",
+  "caniuse": "webgl",
+  "tags": ["webgl", "graphics"],
+  "polyfills": ["jebgl", "cwebgl", "iewebgl"]
+}
+!*/
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  Modernizr.addTest('webgl', function() {
+    var canvas = createElement('canvas');
+    var supports = 'probablySupportsContext' in canvas ? 'probablySupportsContext' :  'supportsContext';
+    if (supports in canvas) {
+      return canvas[supports]('webgl') || canvas[supports]('experimental-webgl');
+    }
+    return 'WebGLRenderingContext' in window;
+  });
+});
diff --git a/js/modernizr/feature-detects/webgl/extensions.js b/js/modernizr/feature-detects/webgl/extensions.js
new file mode 100644 (file)
index 0000000..aacea99
--- /dev/null
@@ -0,0 +1,66 @@
+/*!
+{
+  "name": "WebGL Extensions",
+  "property": "webglextensions",
+  "tags": ["webgl", "graphics"],
+  "builderAliases": ["webgl_extensions"],
+  "async" : true,
+  "authors": ["Ilmari Heikkinen"],
+  "knownBugs": [],
+  "notes": [{
+    "name": "Kronos extensions registry",
+    "href": "http://www.khronos.org/registry/webgl/extensions/"
+  }]
+}
+!*/
+/* DOC
+Detects support for OpenGL extensions in WebGL. It's `true` if the [WebGL extensions API](https://developer.mozilla.org/en-US/docs/Web/WebGL/Using_Extensions) is supported, then exposes the supported extensions as subproperties, e.g.:
+
+```javascript
+if (Modernizr.webglextensions) {
+  // WebGL extensions API supported
+}
+if ('OES_vertex_array_object' in Modernizr.webglextensions) {
+  // Vertex Array Objects extension supported
+}
+```
+*/
+define(['Modernizr', 'createElement', 'test/webgl'], function(Modernizr, createElement) {
+  // based on code from ilmari heikkinen
+  // code.google.com/p/graphics-detect/source/browse/js/detect.js
+
+  // Not Async but handles it's own self
+  Modernizr.addAsyncTest(function() {
+    /* jshint -W053 */
+
+    // Not a good candidate for css classes, so we avoid addTest stuff
+    Modernizr.webglextensions = new Boolean(false);
+
+    if (!Modernizr.webgl) {
+      return;
+    }
+
+    var canvas;
+    var ctx;
+    var exts;
+
+    try {
+      canvas = createElement('canvas');
+      ctx = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
+      exts = ctx.getSupportedExtensions();
+    }
+    catch (e) {
+      return;
+    }
+
+    if (ctx !== undefined) {
+      Modernizr.webglextensions = new Boolean(true);
+    }
+
+    for (var i = -1, len = exts.length; ++i < len;) {
+      Modernizr.webglextensions[exts[i]] = true;
+    }
+
+    canvas = undefined;
+  });
+});
diff --git a/js/modernizr/feature-detects/webrtc/datachannel.js b/js/modernizr/feature-detects/webrtc/datachannel.js
new file mode 100644 (file)
index 0000000..8c7979a
--- /dev/null
@@ -0,0 +1,34 @@
+/*!
+{
+  "name": "RTC Data Channel",
+  "property": "datachannel",
+  "notes": [{
+    "name": "HTML5 Rocks! Article",
+    "href": "http://www.html5rocks.com/en/tutorials/webrtc/datachannels/"
+  }]
+}
+!*/
+/* DOC
+Detect for the RTCDataChannel API that allows for transfer data directly from one peer to another
+*/
+define(['Modernizr', 'prefixed', 'domPrefixes', 'test/webrtc/peerconnection'], function(Modernizr, prefixed, domPrefixes) {
+
+  Modernizr.addTest('datachannel', function() {
+    if (!Modernizr.peerconnection) {
+      return false;
+    }
+    for (var i = 0, l = domPrefixes.length; i < l; i++) {
+      var peerConnectionConstructor = window[domPrefixes[i] + 'RTCPeerConnection'];
+
+      if (peerConnectionConstructor) {
+        var peerConnection = new peerConnectionConstructor({
+          'iceServers': [{'url': 'stun:0'}]
+        });
+
+        return 'createDataChannel' in peerConnection;
+      }
+
+    }
+    return false;
+  });
+});
diff --git a/js/modernizr/feature-detects/webrtc/getusermedia.js b/js/modernizr/feature-detects/webrtc/getusermedia.js
new file mode 100644 (file)
index 0000000..2029050
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+{
+  "name": "getUserMedia",
+  "property": "getusermedia",
+  "caniuse": "stream",
+  "tags": ["webrtc"],
+  "authors": ["Eric Bidelman"],
+  "notes": [{
+    "name": "W3C Media Capture and Streams spec",
+    "href": "http://www.w3.org/TR/mediacapture-streams/"
+  }],
+  "polyfills": ["getusermedia"]
+}
+!*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('getusermedia', !!prefixed('getUserMedia', navigator));
+});
diff --git a/js/modernizr/feature-detects/webrtc/peerconnection.js b/js/modernizr/feature-detects/webrtc/peerconnection.js
new file mode 100644 (file)
index 0000000..5a21971
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+{
+  "name": "RTC Peer Connection",
+  "property": "peerconnection",
+  "tags": ["webrtc"],
+  "authors": ["Ankur Oberoi"],
+  "notes": [{
+    "name": "W3C Web RTC spec",
+    "href": "http://www.w3.org/TR/webrtc/"
+  }]
+}
+!*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('peerconnection', !!prefixed('RTCPeerConnection', window));
+});
diff --git a/js/modernizr/feature-detects/websockets.js b/js/modernizr/feature-detects/websockets.js
new file mode 100644 (file)
index 0000000..6c1218f
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+{
+  "name": "WebSockets Support",
+  "property": "websockets",
+  "authors": ["Phread [fearphage]", "Mike Sherov [mikesherov]", "Burak Yigit Kaya [BYK]"],
+  "caniuse": "websockets",
+  "tags": ["html5"],
+  "warnings": [
+    "This test will reject any old version of WebSockets even if it is not prefixed such as in Safari 5.1"
+  ],
+  "notes": [{
+    "name": "CLOSING State and Spec",
+    "href": "http://www.w3.org/TR/websockets/#the-websocket-interface"
+  }],
+  "polyfills": [
+    "sockjs",
+    "socketio",
+    "kaazing-websocket-gateway",
+    "websocketjs",
+    "atmosphere",
+    "graceful-websocket",
+    "portal",
+    "datachannel"
+  ]
+}
+!*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('websockets', 'WebSocket' in window && window.WebSocket.CLOSING === 2);
+});
diff --git a/js/modernizr/feature-detects/websockets/binary.js b/js/modernizr/feature-detects/websockets/binary.js
new file mode 100644 (file)
index 0000000..189dad6
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+{
+  "name": "Binary WebSockets",
+  "property": "websocketsbinary",
+  "tags": ["websockets"],
+  "builderAliases": ["websockets_binary"]
+}
+!*/
+define(['Modernizr'], function(Modernizr) {
+  // binaryType is truthy if there is support.. returns "blob" in new-ish chrome.
+  // plus.google.com/115535723976198353696/posts/ERN6zYozENV
+  // github.com/Modernizr/Modernizr/issues/370
+
+  Modernizr.addTest('websocketsbinary', function() {
+    var protocol = 'https:' == location.protocol ? 'wss' : 'ws',
+    protoBin;
+
+    if ('WebSocket' in window) {
+      if (protoBin = 'binaryType' in WebSocket.prototype) {
+        return protoBin;
+      }
+      try {
+        return !!(new WebSocket(protocol + '://.').binaryType);
+      } catch (e) {}
+    }
+
+    return false;
+  });
+});
diff --git a/js/modernizr/feature-detects/window/framed.js b/js/modernizr/feature-detects/window/framed.js
new file mode 100644 (file)
index 0000000..3d3e926
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+{
+  "name": "Framed window",
+  "property": "framed",
+  "tags": ["window"],
+  "builderAliases": ["window_framed"]
+}
+!*/
+/* DOC
+Tests if page is iframed.
+*/
+define(['Modernizr'], function(Modernizr) {
+  // github.com/Modernizr/Modernizr/issues/242
+
+  Modernizr.addTest('framed', window.location != top.location);
+});
diff --git a/js/modernizr/feature-detects/window/matchmedia.js b/js/modernizr/feature-detects/window/matchmedia.js
new file mode 100644 (file)
index 0000000..d59d7db
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+{
+  "name": "matchMedia",
+  "property": "matchmedia",
+  "caniuse" : "matchmedia",
+  "tags": ["matchmedia"],
+  "authors": ["Alberto Elias"],
+  "notes": [{
+    "name": "W3C CSSOM View Module",
+    "href": "http://dev.w3.org/csswg/cssom-view/#the-mediaquerylist-interface"
+  }, {
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/API/Window.matchMedia"
+  }],
+  "polyfills": ["matchmediajs"]
+}
+!*/
+/* DOC
+
+Detects support for matchMedia.
+
+*/
+define(['Modernizr', 'prefixed'], function(Modernizr, prefixed) {
+  Modernizr.addTest('matchmedia', !!prefixed('matchMedia', window));
+});
diff --git a/js/modernizr/feature-detects/workers/blobworkers.js b/js/modernizr/feature-detects/workers/blobworkers.js
new file mode 100644 (file)
index 0000000..c51f6e6
--- /dev/null
@@ -0,0 +1,83 @@
+/*!
+{
+  "name": "Workers from Blob URIs",
+  "property": "blobworkers",
+  "tags": ["performance", "workers"],
+  "builderAliases": ["workers_blobworkers"],
+  "notes": [{
+    "name": "W3C Reference",
+    "href": "http://www.w3.org/TR/workers/"
+  }],
+  "knownBugs": ["This test may output garbage to console."],
+  "authors": ["Jussi Kalliokoski"],
+  "async": true
+}
+!*/
+/* DOC
+Detects support for creating Web Workers from Blob URIs.
+*/
+define(['Modernizr', 'addTest'], function(Modernizr, addTest) {
+  Modernizr.addAsyncTest(function() {
+    try {
+      // we're avoiding using Modernizr._domPrefixes as the prefix capitalization on
+      // these guys are notoriously peculiar.
+      var BlobBuilder = window.BlobBuilder;
+      var URL         = window.URL;
+      if (Modernizr._config.usePrefix) {
+        BlobBuilder = BlobBuilder || window.MozBlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder || window.OBlobBuilder;
+        URL         = URL || window.MozURL || window.webkitURL || window.MSURL || window.OURL;
+      }
+      var data    = 'Modernizr',
+          blob,
+          bb,
+          worker,
+          url,
+          timeout,
+          scriptText = 'this.onmessage=function(e){postMessage(e.data)}';
+
+      try {
+        blob = new Blob([scriptText], {type:'text/javascript'});
+      } catch (e) {
+        // we'll fall back to the deprecated BlobBuilder
+      }
+      if (!blob) {
+        bb = new BlobBuilder();
+        bb.append(scriptText);
+        blob = bb.getBlob();
+      }
+
+      url = URL.createObjectURL(blob);
+      worker = new Worker(url);
+
+      worker.onmessage = function(e) {
+        addTest('blobworkers', data === e.data);
+        cleanup();
+      };
+
+      // Just in case...
+      worker.onerror = fail;
+      timeout = setTimeout(fail, 200);
+
+      worker.postMessage(data);
+    } catch (e) {
+      fail();
+    }
+
+    function fail() {
+      addTest('blobworkers', false);
+      cleanup();
+    }
+
+    function cleanup() {
+      if (url) {
+        URL.revokeObjectURL(url);
+      }
+      if (worker) {
+        worker.terminate();
+      }
+      if (timeout) {
+        clearTimeout(timeout);
+      }
+    }
+  });
+});
diff --git a/js/modernizr/feature-detects/workers/dataworkers.js b/js/modernizr/feature-detects/workers/dataworkers.js
new file mode 100644 (file)
index 0000000..cb0b449
--- /dev/null
@@ -0,0 +1,48 @@
+/*!
+{
+  "name": "Workers from Data URIs",
+  "property": "dataworkers",
+  "tags": ["performance", "workers"],
+  "builderAliases": ["workers_dataworkers"],
+  "notes": [{
+    "name": "W3C Reference",
+    "href": "http://www.w3.org/TR/workers/"
+  }],
+  "knownBugs": ["This test may output garbage to console."],
+  "authors": ["Jussi Kalliokoski"],
+  "async": true
+}
+!*/
+/* DOC
+Detects support for creating Web Workers from Data URIs.
+*/
+define(['Modernizr', 'addTest'], function(Modernizr, addTest) {
+  Modernizr.addAsyncTest(function() {
+    try {
+      var data    = 'Modernizr',
+      worker  = new Worker('data:text/javascript;base64,dGhpcy5vbm1lc3NhZ2U9ZnVuY3Rpb24oZSl7cG9zdE1lc3NhZ2UoZS5kYXRhKX0=');
+
+      worker.onmessage = function(e) {
+        worker.terminate();
+        addTest('dataworkers', data === e.data);
+        worker = null;
+      };
+
+      // Just in case...
+      worker.onerror = function() {
+        addTest('dataworkers', false);
+        worker = null;
+      };
+
+      setTimeout(function() {
+        addTest('dataworkers', false);
+      }, 200);
+
+      worker.postMessage(data);
+    } catch (e) {
+      setTimeout(function() {
+        addTest('dataworkers', false);
+      }, 0);
+    }
+  });
+});
diff --git a/js/modernizr/feature-detects/workers/sharedworkers.js b/js/modernizr/feature-detects/workers/sharedworkers.js
new file mode 100644 (file)
index 0000000..9c4e51f
--- /dev/null
@@ -0,0 +1,19 @@
+/*!
+{
+  "name": "Shared Workers",
+  "property": "sharedworkers",
+  "caniuse" : "sharedworkers",
+  "tags": ["performance", "workers"],
+  "builderAliases": ["workers_sharedworkers"],
+  "notes": [{
+    "name": "W3C Reference",
+    "href": "http://www.w3.org/TR/workers/"
+  }]
+}
+!*/
+/* DOC
+Detects support for the `SharedWorker` API from the Web Workers spec.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('sharedworkers', 'SharedWorker' in window);
+});
diff --git a/js/modernizr/feature-detects/workers/transferables.js b/js/modernizr/feature-detects/workers/transferables.js
new file mode 100644 (file)
index 0000000..cd10caf
--- /dev/null
@@ -0,0 +1,72 @@
+/*!
+{
+  "name": "Transferables Objects",
+  "property": "transferables",
+  "tags": ["performance", "workers"],
+  "builderAliases": ["transferables"],
+  "notes": [{
+    "name": "HTML5 Rocks article",
+    "href": "http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast"
+  }],
+  "async": true
+}
+!*/
+/* DOC
+Detects whether web workers can use `transferables` objects.
+*/
+define(['Modernizr', 'addTest', 'test/blob', 'test/url/bloburls', 'test/workers/webworkers', 'test/typed-arrays'], function(Modernizr, addTest) {
+  Modernizr.addAsyncTest(function() {
+    var prerequisites = !!(Modernizr.blobconstructor &&
+                           Modernizr.bloburls &&
+                           Modernizr.webworkers &&
+                           Modernizr.typedarrays);
+
+    // Early exit
+    if (!prerequisites) {
+      return addTest('transferables', false);
+    }
+
+    // Proper test if prerequisites are met
+    try {
+      var buffer,
+          scriptText = 'var hello = "world"',
+          blob = new Blob([scriptText], {type: 'text/javascript'}),
+          url = URL.createObjectURL(blob),
+          worker = new Worker(url),
+          timeout;
+
+      // Just in case...
+      worker.onerror = fail;
+      timeout = setTimeout(fail, 200);
+
+      // Building an minimal array buffer to send to the worker
+      buffer = new ArrayBuffer(1);
+
+      // Sending the buffer to the worker
+      worker.postMessage(buffer, [buffer]);
+
+      // If length of buffer is now 0, transferables are working
+      addTest('transferables', buffer.byteLength === 0);
+      cleanup();
+    } catch (e) {
+      fail();
+    }
+
+    function fail() {
+      addTest('transferables', false);
+      cleanup();
+    }
+
+    function cleanup() {
+      if (url) {
+        URL.revokeObjectURL(url);
+      }
+      if (worker) {
+        worker.terminate();
+      }
+      if (timeout) {
+        clearTimeout(timeout);
+      }
+    }
+  });
+});
diff --git a/js/modernizr/feature-detects/workers/webworkers.js b/js/modernizr/feature-detects/workers/webworkers.js
new file mode 100644 (file)
index 0000000..7b92d5b
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+{
+  "name": "Web Workers",
+  "property": "webworkers",
+  "caniuse" : "webworkers",
+  "tags": ["performance", "workers"],
+  "notes": [{
+    "name": "W3C Reference",
+    "href": "http://www.w3.org/TR/workers/"
+  }, {
+    "name": "HTML5 Rocks article",
+    "href": "http://www.html5rocks.com/en/tutorials/workers/basics/"
+  }, {
+    "name": "MDN documentation",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers"
+  }],
+  "polyfills": ["fakeworker", "html5shims"]
+}
+!*/
+/* DOC
+Detects support for the basic `Worker` API from the Web Workers spec. Web Workers provide a simple means for web content to run scripts in background threads.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('webworkers', 'Worker' in window);
+});
diff --git a/js/modernizr/lib/build-query.js b/js/modernizr/lib/build-query.js
new file mode 100644 (file)
index 0000000..21ac8bb
--- /dev/null
@@ -0,0 +1,50 @@
+/*global define*/
+define(['lodash', 'metadata'], function(_, metadata) {
+
+  function getDetectObjByAmdPath(amdPath) {
+    return _.find(metadata, function(detect) {
+      return detect.amdPath == amdPath || detect.amdPath == 'test/' + amdPath;
+    });
+  }
+
+  return function generateBuildQuery(config) {
+    // Format:
+    // ?-<prop1>-<prop2>-…-<propN>-<option1>-<option2>-…<optionN>[-dontmin][-cssclassprefix:<prefix>]
+    // where prop1…N and option1…N are sorted alphabetically (for consistency)
+    var dontmin = !config.minify;
+
+    // Config uses amdPaths, but build query uses property names
+    var props = _.map(config['feature-detects'], function(amdPath) {
+      var detect = getDetectObjByAmdPath(amdPath);
+      var property = detect && detect.property;
+      property = _.isArray(property) ?
+        property.join('_').replace('-', '_') :
+        property.replace('-', '_');
+      return property;
+    });
+
+    // Config uses amdPaths, but the option's just use their names.
+    // A few of the values have to be massaged in order to match
+    // the `value`
+    var opts = _.map(config.options, function(opt) {
+      if (opt == 'setClasses') {
+        return 'cssclasses';
+      }
+      if (opt.indexOf('html5') === 0) {
+        opt = opt.replace('html5', '');
+      }
+      return opt.toLowerCase();
+    });
+
+    var sortedProps = props.sort();
+    var sortedOpts = opts.sort();
+
+    // Options are AMD paths in the config, but need to be converted to
+    var buildQuery = '?-' + sortedProps.concat(sortedOpts).join('-') +
+        (dontmin ? '-dontmin' : '') +
+        ((config.classPrefix) ?
+          '-cssclassprefix:' + config.classPrefix : '');
+
+    return buildQuery;
+  };
+});
diff --git a/js/modernizr/lib/build.js b/js/modernizr/lib/build.js
new file mode 100644 (file)
index 0000000..f531ea4
--- /dev/null
@@ -0,0 +1,158 @@
+// this file configures require.js based on enviroment
+'use strict';
+
+/* jshint -W117 */
+var inBrowser = typeof define == 'function' && typeof define.amd == 'object';
+/* jshint -W117 */
+
+var _extend = function(a, b) {
+  for (var prop in b) {
+    var supplied = b[prop];
+    if (typeof supplied === 'object') {
+      a[prop] == a[prop] || {};
+      _extend(a[prop], supplied);
+    } else {
+      a[prop] = b[prop];
+    }
+  }
+};
+
+
+var requireConfig = {
+  optimize: 'none',
+  generateSourceMaps: false,
+  optimizeCss: 'none',
+  useStrict: true,
+  include: ['modernizr-init'],
+  fileExclusionRegExp: /^(.git|node_modules|modulizr|media|test)$/,
+  wrap: {
+    start: '\n;(function(window, document, undefined){',
+    end: '})(window, document);'
+  },
+  onBuildWrite: function(id, path, contents) {
+    if (this.optimize === 'uglify2') {
+      // strip out documentation comments
+      contents = contents.replace(/\/\*\![\s\S]*\!\*\//m, '');
+    }
+
+    if ((/define\(.*?\{/).test(contents)) {
+      // remove AMD ceremony for use without require.js or almond.js
+      contents = contents.replace(/define\(.*?\{/, '');
+
+      contents = contents.replace(/\}\);\s*?$/, '');
+
+      if (!contents.match(/Modernizr\.add(Async)?Test\(/)) {
+        // remove last return statement and trailing })
+        contents = contents.replace(/return.*[^return]*$/, '');
+      }
+    } else if ((/require\([^\{]*?\{/).test(contents)) {
+      contents = contents.replace(/require[^\{]+\{/, '');
+      contents = contents.replace(/\}\);\s*$/, '');
+    }
+
+    contents = contents.replace(/return addTest;/, '');
+
+    return contents;
+  }
+};
+
+function build(generate, generateBanner, pkg) {
+  return function build(config, cb) {
+    config = config || {};
+    cb = cb || function noop() {};
+    var banner;
+
+    requireConfig.rawText = {
+      'modernizr-init': generate(config)
+    };
+
+    if (config.minify) {
+      banner = generateBanner('compact', config);
+      requireConfig.optimize = 'uglify2';
+      requireConfig.uglify2 = {
+        mangle: {
+          except: ['Modernizr']
+        },
+        beautify: {
+          ascii_only: true
+        }
+      };
+    } else {
+      banner = generateBanner('full', config);
+      requireConfig.optimize = 'none';
+    }
+
+    requireConfig.out = function(output) {
+      output = banner + output;
+
+      // Remove `define('modernizr-init' ...)` and `define('modernizr-build' ...)`
+      output = output.replace(/(,\s*)?define\("modernizr-(init|build)",\s*function\(\)\{\};?\)/g, '');
+      output = output.replace(/__VERSION__/g, pkg.version);
+
+      // Hack the prefix into place. Anything is way too big for something so small.
+      if (config && config.classPrefix) {
+        output = output.replace(/(classPrefix'?\s?:\s?)['""']{2}(,)/, '$1"' + config.classPrefix.replace(/"/g, '\\"') + '"$2');
+      }
+
+      cb(output);
+
+    };
+
+    requirejs.optimize(requireConfig);
+  };
+}
+
+if (inBrowser) {
+  var suppliedConfig = self._modernizrConfig;
+  var metadataUrl = 'i/js/metadata.json';
+  var packageUrl = 'i/js/modernizr-git/package.json';
+  requireConfig.baseUrl = '/i/js/modernizr-git/src';
+  requireConfig.paths = {
+    text: '/i/js/requirejs-plugins/lib/text',
+    lib: '/i/js/modernizr-git/lib',
+    json: '/i/js/requirejs-plugins/src/json',
+    lodash: '/i/js/lodash',
+    test: '/i/js/modernizr-git/feature-detects'
+  };
+
+  if (suppliedConfig) {
+    metadataUrl = suppliedConfig.metadataUrl || metadataUrl;
+    packageUrl = suppliedConfig.packageUrl || packageUrl;
+    _extend(requireConfig, suppliedConfig);
+  }
+
+  if (self._modernizrMetadata) {
+    requirejs.define('metadata', [], function() {return self._modernizrMetadata;});
+  } else {
+    requirejs.define('metadata', ['json!' + metadataUrl], function(pkg) {return pkg;});
+  }
+  requirejs.define('package', ['json!' + packageUrl], function(pkg) {return pkg;});
+} else {
+  var requirejs = require('requirejs');
+  var metadata = require('./metadata')();
+  var pkg = require('../package.json');
+
+  requirejs.define('metadata', [], function() {return metadata;});
+  requirejs.define('package', function() {return pkg;});
+
+  requireConfig.baseUrl = __dirname + '/../src';
+  requireConfig.paths = {
+    lodash: __dirname + '/../node_modules/lodash/index',
+    test: __dirname + '/../feature-detects',
+    lib: __dirname
+  };
+}
+
+requirejs.config(requireConfig);
+
+if (inBrowser) {
+  define('build', ['generate', 'lib/generate-banner', 'package'], build);
+} else {
+  var generateBanner = requirejs(__dirname + '/generate-banner.js');
+  var generate = requirejs('generate');
+  var pkg = requirejs('package');
+  var _build = build;
+  module.exports = function build() {
+    return _build(generate, generateBanner, pkg).apply(undefined, arguments);
+  };
+}
diff --git a/js/modernizr/lib/cli.js b/js/modernizr/lib/cli.js
new file mode 100644 (file)
index 0000000..0bc8ead
--- /dev/null
@@ -0,0 +1,7 @@
+'use strict';
+
+module.exports = {
+  build: require('./build'),
+  metadata: require('./metadata'),
+  options: require('./options'),
+};
diff --git a/js/modernizr/lib/generate-banner.js b/js/modernizr/lib/generate-banner.js
new file mode 100644 (file)
index 0000000..c272fb5
--- /dev/null
@@ -0,0 +1,40 @@
+/*global location, define*/
+define(['lodash', 'package', 'lib/build-query'], function(_, pkg, buildQuery) {
+  var domain = 'modernizr.com';
+  if (typeof location !== 'undefined' && 'host' in location) {
+    domain = location.host;
+  }
+
+  // Return a Modernizr file banner.
+  // Usage:
+  //   require('banners')(type);
+  // Arguments:
+  //   type (String, required): either 'compact' or 'full'.
+
+  return function banners(type, config) {
+    config = config || {};
+    var query = buildQuery(config);
+    if (!type || type === 'compact') {
+      return '/*! ' + pkg.name + ' ' + pkg.version + ' (Custom Build) | ' + pkg.license  + ' *\n' +
+        ' * http://' + domain + '/download/' + query +
+        ' !*/\n';
+    }
+    else if (type === 'full') {
+      return '/*!\n' +
+        ' * ' + pkg.name + ' v' + pkg.version + '\n' +
+        ' * Build http://' + domain + '/download' + query + '\n' +
+        ' *\n' +
+        ' * Copyright (c)\n *  ' + _.pluck(pkg.contributors, 'name').join('\n *  ') + '\n\n' +
+        ' * ' + pkg.license + ' License\n */\n' +
+      '\n' +
+        '/*\n' +
+        ' * Modernizr tests which native CSS3 and HTML5 features are available in the\n' +
+        ' * current UA and makes the results available to you in two ways: as properties on\n' +
+        ' * a global `Modernizr` object, and as classes on the `<html>` element. This\n' +
+        ' * information allows you to progressively enhance your pages with a granular level\n' +
+        ' * of control over the experience.\n*/\n';
+    } else {
+      throw 'banners() must be passed "compact" or "full" as an argument.';
+    }
+  };
+});
diff --git a/js/modernizr/lib/metadata.js b/js/modernizr/lib/metadata.js
new file mode 100644 (file)
index 0000000..a070121
--- /dev/null
@@ -0,0 +1,140 @@
+var fs = require('fs');
+var file = require('file');
+var marked = require('marked');
+var polyfills = require('./polyfills.json');
+var viewRoot = fs.realpathSync(__dirname + '/../feature-detects');
+
+function metadata(cb) {
+  var tests = [];
+  file.walkSync(viewRoot, function(start, dirs, files) {
+    files.forEach(function(file) {
+      if (file === '.DS_Store') {
+        return;
+      }
+      var test = fs.readFileSync(start + '/' + file, 'utf8');
+      // TODO :: make this regex not suck
+      var metaRE = /\/\*\!([\s\S]*)\!\*\//m;
+      var matches = test.match(metaRE);
+      var docRE = /\/\*\sDOC([\s\S]*?)\*\//m;
+      var docmatches = test.match(docRE);
+      var depRE = /define\((\[[^\]]*\]),/;
+      var depMatches = test.match(depRE);
+
+      var metadata;
+
+      if (matches && matches[1]) {
+        try {
+          metadata = JSON.parse(matches[1]);
+        } catch (e) {
+          throw new Error('Error Parsing Metadata: ' + file + '\nInput: `' + matches[1] + '`');
+        }
+      }
+      else {
+        metadata = {};
+      }
+
+      var docs = null;
+
+      if (docmatches && docmatches[1]) {
+        docs = marked(docmatches[1].trim());
+      }
+
+      metadata.doc = docs;
+
+      var deps = [];
+      var matchedDeps;
+
+      if (depMatches && depMatches[1]) {
+        try {
+          matchedDeps = JSON.parse(depMatches[1].replace(/'/g, '"'));
+        } catch (e) {
+          throw new Error('Couldn\'t parse dependencies for `' + file + '`:\n`' + depMatches[1] + '\n`');
+        }
+        matchedDeps.forEach(function(dep) {
+          if (dep === 'Modernizr') {
+            return;
+          }
+          deps.push(dep);
+        });
+      } else {
+        throw new Error('Couldn\'t find the define for `' + file + '`');
+      }
+      metadata.deps = deps;
+
+      var baseDir = __dirname.replace(/lib$/, '');
+      metadata.path = './' + (start + '/' + file).replace(baseDir, '').replace(/\\/g, '/');
+      metadata.amdPath = metadata.path.replace(/^\.\/feature\-detects/, 'test').replace(/\.js$/i, '');
+
+      if (!metadata.name) {
+        metadata.name = metadata.amdPath;
+      }
+
+      var pfs = [];
+      if (metadata.polyfills && metadata.polyfills.length) {
+        metadata.polyfills.forEach(function(polyname) {
+          if (polyfills[polyname]) {
+            pfs.push(polyfills[polyname]);
+          }
+          else {
+            throw new Error(metadata.name + ': Polyfill not found in `' + file + '`: ' + polyname);
+          }
+        });
+      }
+      metadata.polyfills = pfs;
+
+      if (!metadata.async) {
+        metadata.async = false;
+      }
+
+      if (!metadata.notes) {
+        metadata.notes = [];
+      }
+
+      if (!metadata.warnings) {
+        metadata.warnings = [];
+      }
+
+      if (!metadata.caniuse) {
+        metadata.caniuse = null;
+      }
+
+      if (!metadata.cssclass && metadata.property) {
+        metadata.cssclass = metadata.property;
+      } else {
+        metadata.cssclass = null;
+      }
+
+      // Maybe catch a bug
+      if (!metadata.doc && metadata.docs) {
+        metadata.doc = metadata.docs;
+        delete metadata.docs;
+      }
+
+      // If you want markdown parsed code minus the docs and metadata, this'll do it.
+      // Off by default for now.
+      // metadata.code =  marked('```javascript\n' + test.replace(metaRE, '').replace(docRE, '') + '\n```');
+
+      if (!metadata.tags) {
+        metadata.tags = [];
+      }
+
+      if (!metadata.authors) {
+        metadata.authors = [];
+      }
+
+      if (!metadata.knownBugs) {
+        metadata.knownBugs = [];
+      }
+
+      tests.push(metadata);
+    });
+  });
+
+  if (cb && typeof cb == 'function') {
+    return cb(tests);
+  }
+  return tests;
+}
+
+
+module.exports = metadata;
diff --git a/js/modernizr/lib/options.js b/js/modernizr/lib/options.js
new file mode 100644 (file)
index 0000000..f88de84
--- /dev/null
@@ -0,0 +1,93 @@
+var fs = require('fs');
+var _ = require('lodash');
+var file = require('file');
+var jsdoc = require('doctrine');
+var srcRoot = fs.realpathSync(__dirname + '/../src');
+var commentRE = /^(\s+)?(\/\*)?\*(\/)?\s?/mg;
+var jsdocRE = /[^\S\r\n]*\/(?:\*{2})([\W\w]+?)\*\//mg;
+
+var stripComments = function(str) {
+  return str.replace(commentRE, '');
+};
+
+function options(cb, allMetadata) {
+  var opts;
+
+  file.walkSync(srcRoot, function(start, dirs, files) {
+    opts = _.chain(files)
+      .map(function(file) {
+        var srcFile = fs.readFileSync(start + '/' + file, 'utf8');
+        var docs = srcFile.match(jsdocRE);
+
+        if (docs) {
+          docs = docs
+            .map(stripComments)
+            .map(function(str) {
+              return jsdoc.parse(str, {
+                sloppy: true,
+                tags: [
+                  'access',
+                  'author',
+                  'class',
+                  'example',
+                  'function',
+                  'memberOf',
+                  'memberof',
+                  'name',
+                  'optionName',
+                  'optionProp',
+                  'param',
+                  'params',
+                  'preserve',
+                  'private',
+                  'returns',
+                  'type'
+                ]
+              });
+            });
+
+          var option = _.chain(docs)
+            .flatten()
+            .filter(function(doc) {
+              if (allMetadata) {
+                return true;
+              } else {
+                return doc && _.some(doc.tags, {title: 'optionName'});
+              }
+            })
+            .map(function(opt) {
+              if (allMetadata) {
+                return opt;
+              } else {
+                var tags = opt.tags.filter(function(tag) {
+                  return tag.title.indexOf('option') === 0;
+                });
+
+                return {
+                  name: _.where(tags, {title: 'optionName'})[0].description,
+                  property: _.where(tags, {title: 'optionProp'})[0].description
+                };
+              }
+            })
+            .value();
+
+          return option;
+        }
+      })
+      .filter(function(doc) {
+        return doc && doc.length;
+      })
+      .flatten()
+      .value();
+
+  });
+
+  if (cb) {
+    cb(opts);
+  }
+
+  return opts;
+
+}
+
+module.exports = options;
diff --git a/js/modernizr/src/Modernizr.js b/js/modernizr/src/Modernizr.js
new file mode 100644 (file)
index 0000000..fa5499a
--- /dev/null
@@ -0,0 +1,11 @@
+define(['ModernizrProto'], function(ModernizrProto) {
+  // Fake some of Object.create so we can force non test results to be non "own" properties.
+  var Modernizr = function() {};
+  Modernizr.prototype = ModernizrProto;
+
+  // Leak modernizr globally when you `require` it rather than force it here.
+  // Overwrite name so constructor name is nicer :D
+  Modernizr = new Modernizr();
+
+  return Modernizr;
+});
diff --git a/js/modernizr/src/ModernizrProto.js b/js/modernizr/src/ModernizrProto.js
new file mode 100644 (file)
index 0000000..9feeda7
--- /dev/null
@@ -0,0 +1,50 @@
+define(['tests'], function(tests) {
+  /**
+   *
+   * ModernizrProto is the constructor for Modernizr
+   *
+   * @class
+   * @access public
+   */
+
+  var ModernizrProto = {
+    // The current version, dummy
+    _version: '__VERSION__',
+
+    // Any settings that don't work as separate modules
+    // can go in here as configuration.
+    _config: {
+      'classPrefix' : '',
+      'enableClasses' : true,
+      'enableJSClass' : true,
+      'usePrefixes' : true
+    },
+
+    // Queue of tests
+    _q: [],
+
+    // Stub these for people who are listening
+    on: function(test, cb) {
+      // I don't really think people should do this, but we can
+      // safe guard it a bit.
+      // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests.
+      // This is in case people listen to synchronous tests. I would leave it out,
+      // but the code to *disallow* sync tests in the real version of this
+      // function is actually larger than this.
+      var self = this;
+      setTimeout(function() {
+        cb(self[test]);
+      }, 0);
+    },
+
+    addTest: function(name, fn, options) {
+      tests.push({name : name, fn : fn, options : options});
+    },
+
+    addAsyncTest: function(fn) {
+      tests.push({name : null, fn : fn});
+    }
+  };
+
+  return ModernizrProto;
+});
diff --git a/js/modernizr/src/addTest.js b/js/modernizr/src/addTest.js
new file mode 100644 (file)
index 0000000..610b099
--- /dev/null
@@ -0,0 +1,211 @@
+define(['ModernizrProto', 'Modernizr', 'hasOwnProp', 'setClasses'], function(ModernizrProto, Modernizr, hasOwnProp, setClasses) {
+
+   // _l tracks listeners for async tests, as well as tests that execute after the initial run
+  ModernizrProto._l = {};
+
+  /**
+   * Modernizr.on is a way to listen for the completion of async tests. Being
+   * asynchronous, they may not finish before your scripts run. As a result you
+   * will get a possibly false negative `undefined` value.
+   *
+   * @memberof Modernizr
+   * @name Modernizr.on
+   * @access public
+   * @function on
+   * @param {string} feature - String name of the feature detect
+   * @param {function} cb - Callback function returning a Boolean - true if feature is supported, false if not
+   * @example
+   *
+   * ```js
+   * Modernizr.on('flash', function( result ) {
+   *   if (result) {
+   *    // the browser has flash
+   *   } else {
+   *     // the browser does not have flash
+   *   }
+   * });
+   * ```
+   */
+
+  ModernizrProto.on = function(feature, cb) {
+    // Create the list of listeners if it doesn't exist
+    if (!this._l[feature]) {
+      this._l[feature] = [];
+    }
+
+    // Push this test on to the listener list
+    this._l[feature].push(cb);
+
+    // If it's already been resolved, trigger it on next tick
+    if (Modernizr.hasOwnProperty(feature)) {
+      // Next Tick
+      setTimeout(function() {
+        Modernizr._trigger(feature, Modernizr[feature]);
+      }, 0);
+    }
+  };
+
+  /**
+   * _trigger is the private function used to signal test completion and run any
+   * callbacks registered through [Modernizr.on](#modernizr-on)
+   *
+   * @memberof Modernizr
+   * @name Modernizr._trigger
+   * @access private
+   * @function _trigger
+   * @param {string} feature - string name of the feature detect
+   * @param {function|boolean} [res] - A feature detection function, or the boolean =
+   * result of a feature detection function
+   */
+
+  ModernizrProto._trigger = function(feature, res) {
+    if (!this._l[feature]) {
+      return;
+    }
+
+    var cbs = this._l[feature];
+
+    // Force async
+    setTimeout(function() {
+      var i, cb;
+      for (i = 0; i < cbs.length; i++) {
+        cb = cbs[i];
+        cb(res);
+      }
+    }, 0);
+
+    // Don't trigger these again
+    delete this._l[feature];
+  };
+
+  /**
+   * addTest allows you to define your own feature detects that are not currently
+   * included in Modernizr (under the covers it's the exact same code Modernizr
+   * uses for its own [feature detections](https://github.com/Modernizr/Modernizr/tree/master/feature-detects)). Just like the offical detects, the result
+   * will be added onto the Modernizr object, as well as an appropriate className set on
+   * the html element when configured to do so
+   *
+   * @memberof Modernizr
+   * @name Modernizr.addTest
+   * @optionName Modernizr.addTest()
+   * @optionProp addTest
+   * @access public
+   * @function addTest
+   * @param {string|object} feature - The string name of the feature detect, or an
+   * object of feature detect names and test
+   * @param {function|boolean} test - Function returning true if feature is supported,
+   * false if not. Otherwise a boolean representing the results of a feature detection
+   * @example
+   *
+   * The most common way of creating your own feature detects is by calling
+   * `Modernizr.addTest` with a string (preferably just lowercase, without any
+   * punctuation), and a function you want executed that will return a boolean result
+   *
+   * ```js
+   * Modernizr.addTest('itsTuesday', function() {
+   *  var d = new Date();
+   *  return d.getDay() === 2;
+   * });
+   * ```
+   *
+   * When the above is run, it will set Modernizr.itstuesday to `true` when it is tuesday,
+   * and to `false` every other day of the week. One thing to notice is that the names of
+   * feature detect functions are always lowercased when added to the Modernizr object. That
+   * means that `Modernizr.itsTuesday` will not exist, but `Modernizr.itstuesday` will.
+   *
+   *
+   *  Since we only look at the returned value from any feature detection function,
+   *  you do not need to actually use a function. For simple detections, just passing
+   *  in a statement that will return a boolean value works just fine.
+   *
+   * ```js
+   * Modernizr.addTest('hasJquery', 'jQuery' in window);
+   * ```
+   *
+   * Just like before, when the above runs `Modernizr.hasjquery` will be true if
+   * jQuery has been included on the page. Not using a function saves a small amount
+   * of overhead for the browser, as well as making your code much more readable.
+   *
+   * Finally, you also have the ability to pass in an object of feature names and
+   * their tests. This is handy if you want to add multiple detections in one go.
+   * The keys should always be a string, and the value can be either a boolean or
+   * function that returns a boolean.
+   *
+   * ```js
+   * var detects = {
+   *  'hasjquery': 'jQuery' in window,
+   *  'itstuesday': function() {
+   *    var d = new Date();
+   *    return d.getDay() === 2;
+   *  }
+   * }
+   *
+   * Modernizr.addTest(detects);
+   * ```
+   *
+   * There is really no difference between the first methods and this one, it is
+   * just a convenience to let you write more readable code.
+   */
+
+  function addTest(feature, test) {
+
+    if (typeof feature == 'object') {
+      for (var key in feature) {
+        if (hasOwnProp(feature, key)) {
+          addTest(key, feature[ key ]);
+        }
+      }
+    } else {
+
+      feature = feature.toLowerCase();
+      var featureNameSplit = feature.split('.');
+      var last = Modernizr[featureNameSplit[0]];
+
+      // Again, we don't check for parent test existence. Get that right, though.
+      if (featureNameSplit.length == 2) {
+        last = last[featureNameSplit[1]];
+      }
+
+      if (typeof last != 'undefined') {
+        // we're going to quit if you're trying to overwrite an existing test
+        // if we were to allow it, we'd do this:
+        //   var re = new RegExp("\\b(no-)?" + feature + "\\b");
+        //   docElement.className = docElement.className.replace( re, '' );
+        // but, no rly, stuff 'em.
+        return Modernizr;
+      }
+
+      test = typeof test == 'function' ? test() : test;
+
+      // Set the value (this is the magic, right here).
+      if (featureNameSplit.length == 1) {
+        Modernizr[featureNameSplit[0]] = test;
+      } else {
+        // cast to a Boolean, if not one already
+        /* jshint -W053 */
+        if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
+          Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
+        }
+
+        Modernizr[featureNameSplit[0]][featureNameSplit[1]] = test;
+      }
+
+      // Set a single class (either `feature` or `no-feature`)
+      /* jshint -W041 */
+      setClasses([(!!test && test != false ? '' : 'no-') + featureNameSplit.join('-')]);
+      /* jshint +W041 */
+
+      // Trigger the event
+      Modernizr._trigger(feature, test);
+    }
+
+    return Modernizr; // allow chaining.
+  }
+
+  // After all the tests are run, add self to the Modernizr prototype
+  Modernizr._q.push(function() {
+    ModernizrProto.addTest = addTest;
+  });
+
+  return addTest;
+});
diff --git a/js/modernizr/src/atRule.js b/js/modernizr/src/atRule.js
new file mode 100644 (file)
index 0000000..dcab935
--- /dev/null
@@ -0,0 +1,68 @@
+define(['ModernizrProto', 'cssomPrefixes'], function(ModernizrProto, prefixes) {
+  /**
+   * atRule returns a given CSS property at-rule (eg @keyframes), possibly in
+   * some prefixed form, or false, in the case of an unsupported rule
+   *
+   * @memberof Modernizr
+   * @name Modernizr.atRule
+   * @optionName Modernizr.atRule()
+   * @optionProp atRule
+   * @access public
+   * @function atRule
+   * @param {string} prop - String name of the @-rule to test for
+   * @returns {string|false} The string representing the (possibly prefixed)
+   * valid version of the @-rule, or `false` when it is unsupported.
+   * @example
+   * ```js
+   *  var keyframes = Modernizr.atRule('@keyframes');
+   *
+   *  if (keyframes) {
+   *    // keyframes are supported
+   *    // could be `@-webkit-keyframes` or `@keyframes`
+   *  } else {
+   *    // keyframes === `false`
+   *  }
+   * ```
+   *
+   */
+
+  var atRule = function(prop) {
+    var length = prefixes.length;
+    var cssrule = window.CSSRule;
+    var rule;
+
+    if (typeof cssrule === 'undefined') {
+      return undefined;
+    }
+
+    if (!prop) {
+      return false;
+    }
+
+    // remove literal @ from beginning of provided property
+    prop = prop.replace(/^@/, '');
+
+    // CSSRules use underscores instead of dashes
+    rule = prop.replace(/-/g, '_').toUpperCase() + '_RULE';
+
+    if (rule in cssrule) {
+      return '@' + prop;
+    }
+
+    for (var i = 0; i < length; i++) {
+      // prefixes gives us something like -o-, and we want O_
+      var prefix = prefixes[i];
+      var thisRule = prefix.toUpperCase() + '_' + rule;
+
+      if (thisRule in cssrule) {
+        return '@-' + prefix.toLowerCase() + '-' + prop;
+      }
+    }
+
+    return false;
+  };
+
+  ModernizrProto.atRule = atRule;
+
+  return atRule;
+});
diff --git a/js/modernizr/src/classes.js b/js/modernizr/src/classes.js
new file mode 100644 (file)
index 0000000..ea06d38
--- /dev/null
@@ -0,0 +1,4 @@
+define(function() {
+  var classes = [];
+  return classes;
+});
diff --git a/js/modernizr/src/contains.js b/js/modernizr/src/contains.js
new file mode 100644 (file)
index 0000000..c39e1ff
--- /dev/null
@@ -0,0 +1,18 @@
+define(function() {
+
+  /**
+   * contains checks to see if a string contains another string
+   *
+   * @access private
+   * @function contains
+   * @param {string} str - The string we want to check for substrings
+   * @param {string} substr - The substring we want to search the first string for
+   * @returns {boolean}
+   */
+
+  function contains(str, substr) {
+    return !!~('' + str).indexOf(substr);
+  }
+
+  return contains;
+});
diff --git a/js/modernizr/src/createElement.js b/js/modernizr/src/createElement.js
new file mode 100644 (file)
index 0000000..bba2f08
--- /dev/null
@@ -0,0 +1,26 @@
+define(['isSVG'], function(isSVG) {
+  /**
+   * createElement is a convenience wrapper around document.createElement. Since we
+   * use createElement all over the place, this allows for (slightly) smaller code
+   * as well as abstracting away issues with creating elements in contexts other than
+   * HTML documents (e.g. SVG documents).
+   *
+   * @access private
+   * @function createElement
+   * @returns {HTMLElement|SVGElement} An HTML or SVG element
+   */
+
+  function createElement() {
+    if (typeof document.createElement !== 'function') {
+      // This is the case in IE7, where the type of createElement is "object".
+      // For this reason, we cannot call apply() as Object is not a Function.
+      return document.createElement(arguments[0]);
+    } else if (isSVG) {
+      return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]);
+    } else {
+      return document.createElement.apply(document, arguments);
+    }
+  }
+
+  return createElement;
+});
diff --git a/js/modernizr/src/cssToDOM.js b/js/modernizr/src/cssToDOM.js
new file mode 100644 (file)
index 0000000..048e228
--- /dev/null
@@ -0,0 +1,18 @@
+define(function() {
+  /**
+   * cssToDOM takes a kebab-case string and converts it to camelCase
+   * e.g. box-sizing -> boxSizing
+   *
+   * @access private
+   * @function cssToDOM
+   * @param {string} name - String name of kebab-case prop we want to convert
+   * @returns {string} The camelCase version of the supplied name
+   */
+
+  function cssToDOM(name) {
+    return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) {
+      return m1 + m2.toUpperCase();
+    }).replace(/^-/, '');
+  }
+  return cssToDOM;
+});
diff --git a/js/modernizr/src/cssomPrefixes.js b/js/modernizr/src/cssomPrefixes.js
new file mode 100644 (file)
index 0000000..e5b589f
--- /dev/null
@@ -0,0 +1,5 @@
+define(['ModernizrProto', 'omPrefixes'], function(ModernizrProto, omPrefixes) {
+  var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []);
+  ModernizrProto._cssomPrefixes = cssomPrefixes;
+  return cssomPrefixes;
+});
diff --git a/js/modernizr/src/docElement.js b/js/modernizr/src/docElement.js
new file mode 100644 (file)
index 0000000..30c2539
--- /dev/null
@@ -0,0 +1,11 @@
+define(function() {
+  /**
+   * docElement is a convenience wrapper to grab the root element of the document
+   *
+   * @access private
+   * @returns {HTMLElement|SVGElement} The root element of the document
+   */
+
+  var docElement = document.documentElement;
+  return docElement;
+});
diff --git a/js/modernizr/src/domPrefixes.js b/js/modernizr/src/domPrefixes.js
new file mode 100644 (file)
index 0000000..31dd68d
--- /dev/null
@@ -0,0 +1,23 @@
+define(['ModernizrProto', 'omPrefixes'], function(ModernizrProto, omPrefixes) {
+  /**
+   * List of JavaScript DOM values used for tests
+   *
+   * @memberof Modernizr
+   * @name Modernizr._domPrefixes
+   * @optionName Modernizr._domPrefixes
+   * @optionProp domPrefixes
+   * @access public
+   * @example
+   *
+   * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather
+   * than kebab-case properties, all properties are their Capitalized variant
+   *
+   * ```js
+   * Modernizr._domPrefixes === [ "Moz", "O", "ms", "Webkit" ];
+   * ```
+   */
+
+  var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []);
+  ModernizrProto._domPrefixes = domPrefixes;
+  return domPrefixes;
+});
diff --git a/js/modernizr/src/domToCSS.js b/js/modernizr/src/domToCSS.js
new file mode 100644 (file)
index 0000000..7fc7e6b
--- /dev/null
@@ -0,0 +1,18 @@
+define(function() {
+  /**
+   * domToCSS takes a camelCase string and converts it to kebab-case
+   * e.g. boxSizing -> box-sizing
+   *
+   * @access private
+   * @function domToCSS
+   * @param {string} name - String name of camelCase prop we want to convert
+   * @returns {string} The kebab-case version of the supplied name
+   */
+
+  function domToCSS(name) {
+    return name.replace(/([A-Z])/g, function(str, m1) {
+      return '-' + m1.toLowerCase();
+    }).replace(/^ms-/, '-ms-');
+  }
+  return domToCSS;
+});
diff --git a/js/modernizr/src/fnBind.js b/js/modernizr/src/fnBind.js
new file mode 100644 (file)
index 0000000..c4ac554
--- /dev/null
@@ -0,0 +1,19 @@
+define(function() {
+  /**
+   * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill.
+   *
+   * @access private
+   * @function fnBind
+   * @param {function} fn - a function you want to change `this` reference to
+   * @param {object} that - the `this` you want to call the function with
+   * @returns {function} The wrapped version of the supplied function
+   */
+
+  function fnBind(fn, that) {
+    return function() {
+      return fn.apply(that, arguments);
+    };
+  }
+
+  return fnBind;
+});
diff --git a/js/modernizr/src/generate.js b/js/modernizr/src/generate.js
new file mode 100644 (file)
index 0000000..6efde13
--- /dev/null
@@ -0,0 +1,89 @@
+define(['lodash'], function(_) {
+  /**
+   * generate creates the base version of a Modernizr build, before the r.js
+   * optimizer actually generates the final code
+   *
+   * @access private
+   * @function generate
+   * @param {object} [config] - A configuration object
+   * @param {array} [config.options[]] - An array of options to include in the build
+   * @param {array} [config.feature-detects[]] - An array of the feature detects to include
+   * @returns {string} A string of the require.js build
+   */
+
+  return function generate(config) {
+    // Set some defaults
+    if (!config) {
+      config = {};
+    }
+
+    config.options = config.options || [];
+    config['feature-detects'] = config['feature-detects'] || [];
+
+    // Some special cases
+    var setClasses = _.contains(config.options, 'setClasses');
+
+    // Remove the special cases
+    config.options = _.without(config.options, 'setClasses');
+
+    var output = 'require(["ModernizrProto", "Modernizr", "testRunner"';
+
+    // Needed named module requires
+    if (setClasses) {
+      output += ', "setClasses", "classes"';
+    }
+
+    // Only allow one shiv at a time
+    if (_.includes(config.options, 'html5printshiv')) {
+      config.options = _.without(config.options, 'html5shiv');
+    }
+
+    // Load in the rest of the options (they dont return values, so they aren't declared
+    _.forEach(config.options, function(option) {
+      output += ', "' + option + '"';
+    });
+
+    // Load in all the detects
+    _.forEach(config['feature-detects'], function(detect) {
+      detect = detect.indexOf('test/') === 0 ? detect : 'test/' + detect;
+      output += ', "' + detect + '"';
+    });
+
+    output += '], function( ModernizrProto, Modernizr, testRunner';
+
+    // Needed named module declarations
+    if (setClasses) {
+      output += ', setClasses, classes';
+    }
+
+    output += ') {\n' +
+    '  // Run each test\n' +
+    '  testRunner();\n' +
+    '\n';
+
+    // Actually run the setClasses function
+    if (setClasses) {
+      output += '  // Remove the "no-js" class if it exists\n' +
+      '  setClasses(classes);\n' +
+      '\n';
+    }
+
+    output += '  delete ModernizrProto.addTest;\n';
+    output += '  delete ModernizrProto.addAsyncTest;\n' +
+    '\n';
+
+    // TODO:: if there's a way to figure out if there will be no
+    // items in this queue, then we could avoid the code.
+    output += '  // Run the things that are supposed to run after the tests\n' +
+    '  for (var i = 0; i < Modernizr._q.length; i++) {\n' +
+    '    Modernizr._q[i]();\n' +
+    '  }\n\n';
+
+    output += '  // Leak Modernizr namespace\n' +
+    '  window.Modernizr = Modernizr;\n' +
+    '\n' +
+    '});';
+
+    return output;
+  };
+});
diff --git a/js/modernizr/src/getBody.js b/js/modernizr/src/getBody.js
new file mode 100644 (file)
index 0000000..f296096
--- /dev/null
@@ -0,0 +1,26 @@
+define(['createElement', 'isSVG'], function(createElement, isSVG) {
+  /**
+   * getBody returns the body of a document, or an element that can stand in for
+   * the body if a real body does not exist
+   *
+   * @access private
+   * @function getBody
+   * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an
+   * artificially created element that stands in for the body
+   */
+
+  function getBody() {
+    // After page load injecting a fake body doesn't work so check if body exists
+    var body = document.body;
+
+    if (!body) {
+      // Can't use the real body create a fake one.
+      body = createElement(isSVG ? 'svg' : 'body');
+      body.fake = true;
+    }
+
+    return body;
+  }
+
+  return getBody;
+});
diff --git a/js/modernizr/src/hasEvent.js b/js/modernizr/src/hasEvent.js
new file mode 100644 (file)
index 0000000..3e25b9c
--- /dev/null
@@ -0,0 +1,77 @@
+define(['ModernizrProto', 'createElement'], function(ModernizrProto, createElement) {
+  /**
+   * Modernizr.hasEvent() detects support for a given event
+   *
+   * @memberof Modernizr
+   * @name Modernizr.hasEvent
+   * @optionName Modernizr.hasEvent()
+   * @optionProp hasEvent
+   * @access public
+   * @function hasEvent
+   * @param  {string|*}       eventName  is the name of an event to test for (e.g. "resize")
+   * @param  {Element|string} [element=HTMLDivElement] is the element|document|window|tagName to test on
+   * @returns {boolean}
+   * @example
+   *  `Modernizr.hasEvent` lets you determine if the browser supports a supplied event.
+   *  By default, it does this detection on a div element
+   *
+   * ```js
+   *  hasEvent('blur') // true;
+   * ```
+   *
+   * However, you are able to give an object as a second argument to hasEvent to
+   * detect an event on something other than a div.
+   *
+   * ```js
+   *  hasEvent('devicelight', window) // true;
+   * ```
+   *
+   */
+
+  var hasEvent = (function(undefined) {
+
+    // Detect whether event support can be detected via `in`. Test on a DOM element
+    // using the "blur" event b/c it should always exist. bit.ly/event-detection
+    var needsFallback = !('onblur' in document.documentElement);
+
+    function inner(eventName, element) {
+
+      var isSupported;
+      if (!eventName) { return false; }
+      if (!element || typeof element === 'string') {
+        element = createElement(element || 'div');
+      }
+
+      // Testing via the `in` operator is sufficient for modern browsers and IE.
+      // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and
+      // "resize", whereas `in` "catches" those.
+      eventName = 'on' + eventName;
+      isSupported = eventName in element;
+
+      // Fallback technique for old Firefox - bit.ly/event-detection
+      if (!isSupported && needsFallback) {
+        if (!element.setAttribute) {
+          // Switch to generic element if it lacks `setAttribute`.
+          // It could be the `document`, `window`, or something else.
+          element = createElement('div');
+        }
+
+        element.setAttribute(eventName, '');
+        isSupported = typeof element[eventName] === 'function';
+
+        if (element[eventName] !== undefined) {
+          // If property was created, "remove it" by setting value to `undefined`.
+          element[eventName] = undefined;
+        }
+        element.removeAttribute(eventName);
+      }
+
+      return isSupported;
+    }
+    return inner;
+  })();
+
+
+  ModernizrProto.hasEvent = hasEvent;
+  return hasEvent;
+});
diff --git a/js/modernizr/src/hasOwnProp.js b/js/modernizr/src/hasOwnProp.js
new file mode 100644 (file)
index 0000000..88aca8a
--- /dev/null
@@ -0,0 +1,34 @@
+define(['is'], function(is) {
+  /**
+   * hasOwnProp is a shim for hasOwnProperty that is needed for Safari 2.0 support
+   *
+   * @author kangax
+   * @access private
+   * @function hasOwnProp
+   * @param {object} object - The object to check for a property
+   * @param {string} property - The property to check for
+   * @returns {boolean}
+   */
+
+  // hasOwnProperty shim by kangax needed for Safari 2.0 support
+  var hasOwnProp;
+
+  (function() {
+    var _hasOwnProperty = ({}).hasOwnProperty;
+    /* istanbul ignore else */
+    /* we have no way of testing IE 5.5 or safari 2,
+     * so just assume the else gets hit */
+    if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) {
+      hasOwnProp = function(object, property) {
+        return _hasOwnProperty.call(object, property);
+      };
+    }
+    else {
+      hasOwnProp = function(object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
+        return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
+      };
+    }
+  })();
+
+  return hasOwnProp;
+});
diff --git a/js/modernizr/src/html5printshiv.js b/js/modernizr/src/html5printshiv.js
new file mode 100644 (file)
index 0000000..33c26c0
--- /dev/null
@@ -0,0 +1,534 @@
+define(['isSVG'], function(isSVG) {
+/**
+  * @optionName html5printshiv
+  * @optionProp html5printshiv
+  */
+
+  // Take the html5 variable out of the html5shiv scope so we can return it.
+  var html5;
+  if (!isSVG) {
+
+    /**
+     * @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
+     */
+    ;(function(window, document) {
+      /*jshint evil:true */
+      /** version */
+      var version = '3.7.2';
+
+      /** Preset options */
+      var options = window.html5 || {};
+
+      /** Used to skip problem elements */
+      var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
+
+      /** Not all elements can be cloned in IE **/
+      var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
+
+      /** Detect whether the browser supports default html5 styles */
+      var supportsHtml5Styles;
+
+      /** Name of the expando, to work with multiple documents or to re-shiv one document */
+      var expando = '_html5shiv';
+
+      /** The id for the the documents expando */
+      var expanID = 0;
+
+      /** Cached data for each document */
+      var expandoData = {};
+
+      /** Detect whether the browser supports unknown elements */
+      var supportsUnknownElements;
+
+      (function() {
+        try {
+          var a = document.createElement('a');
+          a.innerHTML = '<xyz></xyz>';
+          //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
+          supportsHtml5Styles = ('hidden' in a);
+
+          supportsUnknownElements = a.childNodes.length == 1 || (function() {
+            // assign a false positive if unable to shiv
+            (document.createElement)('a');
+            var frag = document.createDocumentFragment();
+            return (
+              typeof frag.cloneNode == 'undefined' ||
+                typeof frag.createDocumentFragment == 'undefined' ||
+                typeof frag.createElement == 'undefined'
+            );
+          }());
+        } catch(e) {
+          // assign a false positive if detection fails => unable to shiv
+          supportsHtml5Styles = true;
+          supportsUnknownElements = true;
+        }
+
+      }());
+
+      /*--------------------------------------------------------------------------*/
+
+      /**
+       * Creates a style sheet with the given CSS text and adds it to the document.
+       * @private
+       * @param {Document} ownerDocument The document.
+       * @param {String} cssText The CSS text.
+       * @returns {StyleSheet} The style element.
+       */
+      function addStyleSheet(ownerDocument, cssText) {
+        var p = ownerDocument.createElement('p'),
+          parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
+
+        p.innerHTML = 'x<style>' + cssText + '</style>';
+        return parent.insertBefore(p.lastChild, parent.firstChild);
+      }
+
+      /**
+       * Returns the value of `html5.elements` as an array.
+       * @private
+       * @returns {Array} An array of shived element node names.
+       */
+      function getElements() {
+        var elements = html5.elements;
+        return typeof elements == 'string' ? elements.split(' ') : elements;
+      }
+
+      /**
+       * Extends the built-in list of html5 elements
+       * @memberOf html5
+       * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
+       * @param {Document} ownerDocument The context document.
+       */
+      function addElements(newElements, ownerDocument) {
+        var elements = html5.elements;
+        if(typeof elements != 'string'){
+          elements = elements.join(' ');
+        }
+        if(typeof newElements != 'string'){
+          newElements = newElements.join(' ');
+        }
+        html5.elements = elements +' '+ newElements;
+        shivDocument(ownerDocument);
+      }
+
+      /**
+       * Returns the data associated to the given document
+       * @private
+       * @param {Document} ownerDocument The document.
+       * @returns {Object} An object of data.
+       */
+      function getExpandoData(ownerDocument) {
+        var data = expandoData[ownerDocument[expando]];
+        if (!data) {
+          data = {};
+          expanID++;
+          ownerDocument[expando] = expanID;
+          expandoData[expanID] = data;
+        }
+        return data;
+      }
+
+      /**
+       * returns a shived element for the given nodeName and document
+       * @memberOf html5
+       * @param {String} nodeName name of the element
+       * @param {Document} ownerDocument The context document.
+       * @returns {Object} The shived element.
+       */
+      function createElement(nodeName, ownerDocument, data){
+        if (!ownerDocument) {
+          ownerDocument = document;
+        }
+        if(supportsUnknownElements){
+          return ownerDocument.createElement(nodeName);
+        }
+        if (!data) {
+          data = getExpandoData(ownerDocument);
+        }
+        var node;
+
+        if (data.cache[nodeName]) {
+          node = data.cache[nodeName].cloneNode();
+        } else if (saveClones.test(nodeName)) {
+          node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
+        } else {
+          node = data.createElem(nodeName);
+        }
+
+        // Avoid adding some elements to fragments in IE < 9 because
+        // * Attributes like `name` or `type` cannot be set/changed once an element
+        //   is inserted into a document/fragment
+        // * Link elements with `src` attributes that are inaccessible, as with
+        //   a 403 response, will cause the tab/window to crash
+        // * Script elements appended to fragments will execute when their `src`
+        //   or `text` property is set
+        return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
+      }
+
+      /**
+       * returns a shived DocumentFragment for the given document
+       * @memberOf html5
+       * @param {Document} ownerDocument The context document.
+       * @returns {Object} The shived DocumentFragment.
+       */
+      function createDocumentFragment(ownerDocument, data){
+        if (!ownerDocument) {
+          ownerDocument = document;
+        }
+        if(supportsUnknownElements){
+          return ownerDocument.createDocumentFragment();
+        }
+        data = data || getExpandoData(ownerDocument);
+        var clone = data.frag.cloneNode(),
+          i = 0,
+          elems = getElements(),
+          l = elems.length;
+        for(;i<l;i++){
+          clone.createElement(elems[i]);
+        }
+        return clone;
+      }
+
+      /**
+       * Shivs the `createElement` and `createDocumentFragment` methods of the document.
+       * @private
+       * @param {Document|DocumentFragment} ownerDocument The document.
+       * @param {Object} data of the document.
+       */
+      function shivMethods(ownerDocument, data) {
+        if (!data.cache) {
+          data.cache = {};
+          data.createElem = ownerDocument.createElement;
+          data.createFrag = ownerDocument.createDocumentFragment;
+          data.frag = data.createFrag();
+        }
+
+
+        ownerDocument.createElement = function(nodeName) {
+          //abort shiv
+          if (!html5.shivMethods) {
+            return data.createElem(nodeName);
+          }
+          return createElement(nodeName, ownerDocument, data);
+        };
+
+        ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
+                                                        'var n=f.cloneNode(),c=n.createElement;' +
+                                                        'h.shivMethods&&(' +
+                                                        // unroll the `createElement` calls
+                                                        getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
+          data.createElem(nodeName);
+          data.frag.createElement(nodeName);
+          return 'c("' + nodeName + '")';
+        }) +
+          ');return n}'
+                                                       )(html5, data.frag);
+      }
+
+      /*--------------------------------------------------------------------------*/
+
+      /**
+       * Shivs the given document.
+       * @memberOf html5
+       * @param {Document} ownerDocument The document to shiv.
+       * @returns {Document} The shived document.
+       */
+      function shivDocument(ownerDocument) {
+        if (!ownerDocument) {
+          ownerDocument = document;
+        }
+        var data = getExpandoData(ownerDocument);
+
+        if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
+          data.hasCSS = !!addStyleSheet(ownerDocument,
+                                        // corrects block display not defined in IE6/7/8/9
+                                        'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
+                                        // adds styling not present in IE6/7/8/9
+                                        'mark{background:#FF0;color:#000}' +
+                                        // hides non-rendered elements
+                                        'template{display:none}'
+                                       );
+        }
+        if (!supportsUnknownElements) {
+          shivMethods(ownerDocument, data);
+        }
+        return ownerDocument;
+      }
+
+      /*--------------------------------------------------------------------------*/
+
+      /**
+       * The `html5` object is exposed so that more elements can be shived and
+       * existing shiving can be detected on iframes.
+       * @type Object
+       * @example
+       *
+       * // options can be changed before the script is included
+       * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
+       */
+      var html5 = {
+
+        /**
+         * An array or space separated string of node names of the elements to shiv.
+         * @memberOf html5
+         * @type Array|String
+         */
+        'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video',
+
+        /**
+         * current version of html5shiv
+         */
+        'version': version,
+
+        /**
+         * A flag to indicate that the HTML5 style sheet should be inserted.
+         * @memberOf html5
+         * @type Boolean
+         */
+        'shivCSS': (options.shivCSS !== false),
+
+        /**
+         * Is equal to true if a browser supports creating unknown/HTML5 elements
+         * @memberOf html5
+         * @type boolean
+         */
+        'supportsUnknownElements': supportsUnknownElements,
+
+        /**
+         * A flag to indicate that the document's `createElement` and `createDocumentFragment`
+         * methods should be overwritten.
+         * @memberOf html5
+         * @type Boolean
+         */
+        'shivMethods': (options.shivMethods !== false),
+
+        /**
+         * A string to describe the type of `html5` object ("default" or "default print").
+         * @memberOf html5
+         * @type String
+         */
+        'type': 'default',
+
+        // shivs the document according to the specified `html5` object options
+        'shivDocument': shivDocument,
+
+        //creates a shived element
+        createElement: createElement,
+
+        //creates a shived documentFragment
+        createDocumentFragment: createDocumentFragment,
+
+        //extends list of elements
+        addElements: addElements
+      };
+
+      /*--------------------------------------------------------------------------*/
+
+      // expose html5
+      window.html5 = html5;
+
+      // shiv the document
+      shivDocument(document);
+
+      /*------------------------------- Print Shiv -------------------------------*/
+
+      /** Used to filter media types */
+      var reMedia = /^$|\b(?:all|print)\b/;
+
+      /** Used to namespace printable elements */
+      var shivNamespace = 'html5shiv';
+
+      /** Detect whether the browser supports shivable style sheets */
+      var supportsShivableSheets = !supportsUnknownElements && (function() {
+        // assign a false negative if unable to shiv
+        var docEl = document.documentElement;
+        return !(
+          typeof document.namespaces == 'undefined' ||
+            typeof document.parentWindow == 'undefined' ||
+            typeof docEl.applyElement == 'undefined' ||
+            typeof docEl.removeNode == 'undefined' ||
+            typeof window.attachEvent == 'undefined'
+        );
+      }());
+
+      /*--------------------------------------------------------------------------*/
+
+      /**
+       * Wraps all HTML5 elements in the given document with printable elements.
+       * (eg. the "header" element is wrapped with the "html5shiv:header" element)
+       * @private
+       * @param {Document} ownerDocument The document.
+       * @returns {Array} An array wrappers added.
+       */
+      function addWrappers(ownerDocument) {
+        var node,
+        nodes = ownerDocument.getElementsByTagName('*'),
+          index = nodes.length,
+          reElements = RegExp('^(?:' + getElements().join('|') + ')$', 'i'),
+          result = [];
+
+        while (index--) {
+          node = nodes[index];
+          if (reElements.test(node.nodeName)) {
+            result.push(node.applyElement(createWrapper(node)));
+          }
+        }
+        return result;
+      }
+
+      /**
+       * Creates a printable wrapper for the given element.
+       * @private
+       * @param {Element} element The element.
+       * @returns {Element} The wrapper.
+       */
+      function createWrapper(element) {
+        var node,
+        nodes = element.attributes,
+          index = nodes.length,
+          wrapper = element.ownerDocument.createElement(shivNamespace + ':' + element.nodeName);
+
+        // copy element attributes to the wrapper
+        while (index--) {
+          node = nodes[index];
+          node.specified && wrapper.setAttribute(node.nodeName, node.nodeValue);
+        }
+        // copy element styles to the wrapper
+        wrapper.style.cssText = element.style.cssText;
+        return wrapper;
+      }
+
+      /**
+       * Shivs the given CSS text.
+       * (eg. header{} becomes html5shiv\:header{})
+       * @private
+       * @param {String} cssText The CSS text to shiv.
+       * @returns {String} The shived CSS text.
+       */
+      function shivCssText(cssText) {
+        var pair,
+        parts = cssText.split('{'),
+          index = parts.length,
+          reElements = RegExp('(^|[\\s,>+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'),
+          replacement = '$1' + shivNamespace + '\\:$2';
+
+        while (index--) {
+          pair = parts[index] = parts[index].split('}');
+          pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement);
+          parts[index] = pair.join('}');
+        }
+        return parts.join('{');
+      }
+
+      /**
+       * Removes the given wrappers, leaving the original elements.
+       * @private
+       * @params {Array} wrappers An array of printable wrappers.
+       */
+      function removeWrappers(wrappers) {
+        var index = wrappers.length;
+        while (index--) {
+          wrappers[index].removeNode();
+        }
+      }
+
+      /*--------------------------------------------------------------------------*/
+
+      /**
+       * Shivs the given document for print.
+       * @memberOf html5
+       * @param {Document} ownerDocument The document to shiv.
+       * @returns {Document} The shived document.
+       */
+      function shivPrint(ownerDocument) {
+        var shivedSheet,
+        wrappers,
+        data = getExpandoData(ownerDocument),
+          namespaces = ownerDocument.namespaces,
+          ownerWindow = ownerDocument.parentWindow;
+
+        if (!supportsShivableSheets || ownerDocument.printShived) {
+          return ownerDocument;
+        }
+        if (typeof namespaces[shivNamespace] == 'undefined') {
+          namespaces.add(shivNamespace);
+        }
+
+        function removeSheet() {
+          clearTimeout(data._removeSheetTimer);
+          if (shivedSheet) {
+            shivedSheet.removeNode(true);
+          }
+          shivedSheet= null;
+        }
+
+        ownerWindow.attachEvent('onbeforeprint', function() {
+
+          removeSheet();
+
+          var imports,
+          length,
+          sheet,
+          collection = ownerDocument.styleSheets,
+            cssText = [],
+            index = collection.length,
+            sheets = Array(index);
+
+          // convert styleSheets collection to an array
+          while (index--) {
+            sheets[index] = collection[index];
+          }
+          // concat all style sheet CSS text
+          while ((sheet = sheets.pop())) {
+            // IE does not enforce a same origin policy for external style sheets...
+            // but has trouble with some dynamically created stylesheets
+            if (!sheet.disabled && reMedia.test(sheet.media)) {
+
+              try {
+                imports = sheet.imports;
+                length = imports.length;
+              } catch(er){
+                length = 0;
+              }
+
+              for (index = 0; index < length; index++) {
+                sheets.push(imports[index]);
+              }
+
+              try {
+                cssText.push(sheet.cssText);
+              } catch(er){}
+            }
+          }
+
+          // wrap all HTML5 elements with printable elements and add the shived style sheet
+          cssText = shivCssText(cssText.reverse().join(''));
+          wrappers = addWrappers(ownerDocument);
+          shivedSheet = addStyleSheet(ownerDocument, cssText);
+
+        });
+
+        ownerWindow.attachEvent('onafterprint', function() {
+          // remove wrappers, leaving the original elements, and remove the shived style sheet
+          removeWrappers(wrappers);
+          clearTimeout(data._removeSheetTimer);
+          data._removeSheetTimer = setTimeout(removeSheet, 500);
+        });
+
+        ownerDocument.printShived = true;
+        return ownerDocument;
+      }
+
+      /*--------------------------------------------------------------------------*/
+
+      // expose API
+      html5.type += ' print';
+      html5.shivPrint = shivPrint;
+
+      // shiv for print
+      shivPrint(document);
+
+    }(this, document));
+  }
+
+  return html5;
+});
diff --git a/js/modernizr/src/html5shiv.js b/js/modernizr/src/html5shiv.js
new file mode 100644 (file)
index 0000000..5dd71ae
--- /dev/null
@@ -0,0 +1,334 @@
+define(['isSVG'], function(isSVG) {
+/**
+  * @optionName html5shiv
+  * @optionProp html5shiv
+  */
+
+  // Take the html5 variable out of the html5shiv scope so we can return it.
+  var html5;
+  if (!isSVG) {
+    /**
+     * @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
+     */
+    ;(function(window, document) {
+      /*jshint evil:true */
+      /** version */
+      var version = '3.7.2';
+
+      /** Preset options */
+      var options = window.html5 || {};
+
+      /** Used to skip problem elements */
+      var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
+
+      /** Not all elements can be cloned in IE **/
+      var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
+
+      /** Detect whether the browser supports default html5 styles */
+      var supportsHtml5Styles;
+
+      /** Name of the expando, to work with multiple documents or to re-shiv one document */
+      var expando = '_html5shiv';
+
+      /** The id for the the documents expando */
+      var expanID = 0;
+
+      /** Cached data for each document */
+      var expandoData = {};
+
+      /** Detect whether the browser supports unknown elements */
+      var supportsUnknownElements;
+
+      (function() {
+        try {
+          var a = document.createElement('a');
+          a.innerHTML = '<xyz></xyz>';
+          //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
+          supportsHtml5Styles = ('hidden' in a);
+
+          supportsUnknownElements = a.childNodes.length == 1 || (function() {
+            // assign a false positive if unable to shiv
+            (document.createElement)('a');
+            var frag = document.createDocumentFragment();
+            return (
+              typeof frag.cloneNode == 'undefined' ||
+                typeof frag.createDocumentFragment == 'undefined' ||
+                typeof frag.createElement == 'undefined'
+            );
+          }());
+        } catch(e) {
+          // assign a false positive if detection fails => unable to shiv
+          supportsHtml5Styles = true;
+          supportsUnknownElements = true;
+        }
+
+      }());
+
+      /*--------------------------------------------------------------------------*/
+
+      /**
+       * Creates a style sheet with the given CSS text and adds it to the document.
+       * @private
+       * @param {Document} ownerDocument The document.
+       * @param {String} cssText The CSS text.
+       * @returns {StyleSheet} The style element.
+       */
+      function addStyleSheet(ownerDocument, cssText) {
+        var p = ownerDocument.createElement('p'),
+          parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
+
+        p.innerHTML = 'x<style>' + cssText + '</style>';
+        return parent.insertBefore(p.lastChild, parent.firstChild);
+      }
+
+      /**
+       * Returns the value of `html5.elements` as an array.
+       * @private
+       * @returns {Array} An array of shived element node names.
+       */
+      function getElements() {
+        var elements = html5.elements;
+        return typeof elements == 'string' ? elements.split(' ') : elements;
+      }
+
+      /**
+       * Extends the built-in list of html5 elements
+       * @memberOf html5
+       * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
+       * @param {Document} ownerDocument The context document.
+       */
+      function addElements(newElements, ownerDocument) {
+        var elements = html5.elements;
+        if(typeof elements != 'string'){
+          elements = elements.join(' ');
+        }
+        if(typeof newElements != 'string'){
+          newElements = newElements.join(' ');
+        }
+        html5.elements = elements +' '+ newElements;
+        shivDocument(ownerDocument);
+      }
+
+      /**
+       * Returns the data associated to the given document
+       * @private
+       * @param {Document} ownerDocument The document.
+       * @returns {Object} An object of data.
+       */
+      function getExpandoData(ownerDocument) {
+        var data = expandoData[ownerDocument[expando]];
+        if (!data) {
+          data = {};
+          expanID++;
+          ownerDocument[expando] = expanID;
+          expandoData[expanID] = data;
+        }
+        return data;
+      }
+
+      /**
+       * returns a shived element for the given nodeName and document
+       * @memberOf html5
+       * @param {String} nodeName name of the element
+       * @param {Document} ownerDocument The context document.
+       * @returns {Object} The shived element.
+       */
+      function createElement(nodeName, ownerDocument, data){
+        if (!ownerDocument) {
+          ownerDocument = document;
+        }
+        if(supportsUnknownElements){
+          return ownerDocument.createElement(nodeName);
+        }
+        if (!data) {
+          data = getExpandoData(ownerDocument);
+        }
+        var node;
+
+        if (data.cache[nodeName]) {
+          node = data.cache[nodeName].cloneNode();
+        } else if (saveClones.test(nodeName)) {
+          node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
+        } else {
+          node = data.createElem(nodeName);
+        }
+
+        // Avoid adding some elements to fragments in IE < 9 because
+        // * Attributes like `name` or `type` cannot be set/changed once an element
+        //   is inserted into a document/fragment
+        // * Link elements with `src` attributes that are inaccessible, as with
+        //   a 403 response, will cause the tab/window to crash
+        // * Script elements appended to fragments will execute when their `src`
+        //   or `text` property is set
+        return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
+      }
+
+      /**
+       * returns a shived DocumentFragment for the given document
+       * @memberOf html5
+       * @param {Document} ownerDocument The context document.
+       * @returns {Object} The shived DocumentFragment.
+       */
+      function createDocumentFragment(ownerDocument, data){
+        if (!ownerDocument) {
+          ownerDocument = document;
+        }
+        if(supportsUnknownElements){
+          return ownerDocument.createDocumentFragment();
+        }
+        data = data || getExpandoData(ownerDocument);
+        var clone = data.frag.cloneNode(),
+          i = 0,
+          elems = getElements(),
+          l = elems.length;
+        for(;i<l;i++){
+          clone.createElement(elems[i]);
+        }
+        return clone;
+      }
+
+      /**
+       * Shivs the `createElement` and `createDocumentFragment` methods of the document.
+       * @private
+       * @param {Document|DocumentFragment} ownerDocument The document.
+       * @param {Object} data of the document.
+       */
+      function shivMethods(ownerDocument, data) {
+        if (!data.cache) {
+          data.cache = {};
+          data.createElem = ownerDocument.createElement;
+          data.createFrag = ownerDocument.createDocumentFragment;
+          data.frag = data.createFrag();
+        }
+
+
+        ownerDocument.createElement = function(nodeName) {
+          //abort shiv
+          if (!html5.shivMethods) {
+            return data.createElem(nodeName);
+          }
+          return createElement(nodeName, ownerDocument, data);
+        };
+
+        ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
+                                                        'var n=f.cloneNode(),c=n.createElement;' +
+                                                        'h.shivMethods&&(' +
+                                                        // unroll the `createElement` calls
+                                                        getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
+          data.createElem(nodeName);
+          data.frag.createElement(nodeName);
+          return 'c("' + nodeName + '")';
+        }) +
+          ');return n}'
+                                                       )(html5, data.frag);
+      }
+
+      /*--------------------------------------------------------------------------*/
+
+      /**
+       * Shivs the given document.
+       * @memberOf html5
+       * @param {Document} ownerDocument The document to shiv.
+       * @returns {Document} The shived document.
+       */
+      function shivDocument(ownerDocument) {
+        if (!ownerDocument) {
+          ownerDocument = document;
+        }
+        var data = getExpandoData(ownerDocument);
+
+        if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
+          data.hasCSS = !!addStyleSheet(ownerDocument,
+                                        // corrects block display not defined in IE6/7/8/9
+                                        'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
+                                        // adds styling not present in IE6/7/8/9
+                                        'mark{background:#FF0;color:#000}' +
+                                        // hides non-rendered elements
+                                        'template{display:none}'
+                                       );
+        }
+        if (!supportsUnknownElements) {
+          shivMethods(ownerDocument, data);
+        }
+        return ownerDocument;
+      }
+
+      /*--------------------------------------------------------------------------*/
+
+      /**
+       * The `html5` object is exposed so that more elements can be shived and
+       * existing shiving can be detected on iframes.
+       * @type Object
+       * @example
+       *
+       * // options can be changed before the script is included
+       * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
+       */
+      var html5 = {
+
+        /**
+         * An array or space separated string of node names of the elements to shiv.
+         * @memberOf html5
+         * @type Array|String
+         */
+        'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video',
+
+        /**
+         * current version of html5shiv
+         */
+        'version': version,
+
+        /**
+         * A flag to indicate that the HTML5 style sheet should be inserted.
+         * @memberOf html5
+         * @type Boolean
+         */
+        'shivCSS': (options.shivCSS !== false),
+
+        /**
+         * Is equal to true if a browser supports creating unknown/HTML5 elements
+         * @memberOf html5
+         * @type boolean
+         */
+        'supportsUnknownElements': supportsUnknownElements,
+
+        /**
+         * A flag to indicate that the document's `createElement` and `createDocumentFragment`
+         * methods should be overwritten.
+         * @memberOf html5
+         * @type Boolean
+         */
+        'shivMethods': (options.shivMethods !== false),
+
+        /**
+         * A string to describe the type of `html5` object ("default" or "default print").
+         * @memberOf html5
+         * @type String
+         */
+        'type': 'default',
+
+        // shivs the document according to the specified `html5` object options
+        'shivDocument': shivDocument,
+
+        //creates a shived element
+        createElement: createElement,
+
+        //creates a shived documentFragment
+        createDocumentFragment: createDocumentFragment,
+
+        //extends list of elements
+        addElements: addElements
+      };
+
+      /*--------------------------------------------------------------------------*/
+
+      // expose html5
+      window.html5 = html5;
+
+      // shiv the document
+      shivDocument(document);
+
+    }(this, document));
+  }
+return html5;
+});
diff --git a/js/modernizr/src/injectElementWithStyles.js b/js/modernizr/src/injectElementWithStyles.js
new file mode 100644 (file)
index 0000000..2eeda4a
--- /dev/null
@@ -0,0 +1,75 @@
+define(['ModernizrProto', 'docElement', 'createElement', 'getBody'], function(ModernizrProto, docElement, createElement, getBody) {
+  /**
+   * injectElementWithStyles injects an element with style element and some CSS rules
+   *
+   * @access private
+   * @function injectElementWithStyles
+   * @param {string} rule - String representing a css rule
+   * @param {function} callback - A function that is used to test the injected element
+   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
+   * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes
+   * @returns {boolean}
+   */
+
+  function injectElementWithStyles(rule, callback, nodes, testnames) {
+    var mod = 'modernizr';
+    var style;
+    var ret;
+    var node;
+    var docOverflow;
+    var div = createElement('div');
+    var body = getBody();
+
+    if (parseInt(nodes, 10)) {
+      // In order not to give false positives we create a node for each test
+      // This also allows the method to scale for unspecified uses
+      while (nodes--) {
+        node = createElement('div');
+        node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
+        div.appendChild(node);
+      }
+    }
+
+    style = createElement('style');
+    style.type = 'text/css';
+    style.id = 's' + mod;
+
+    // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
+    // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
+    (!body.fake ? div : body).appendChild(style);
+    body.appendChild(div);
+
+    if (style.styleSheet) {
+      style.styleSheet.cssText = rule;
+    } else {
+      style.appendChild(document.createTextNode(rule));
+    }
+    div.id = mod;
+
+    if (body.fake) {
+      //avoid crashing IE8, if background image is used
+      body.style.background = '';
+      //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
+      body.style.overflow = 'hidden';
+      docOverflow = docElement.style.overflow;
+      docElement.style.overflow = 'hidden';
+      docElement.appendChild(body);
+    }
+
+    ret = callback(div, rule);
+    // If this is done after page load we don't want to remove the body so check if body exists
+    if (body.fake) {
+      body.parentNode.removeChild(body);
+      docElement.style.overflow = docOverflow;
+      // Trigger layout so kinetic scrolling isn't disabled in iOS6+
+      docElement.offsetHeight;
+    } else {
+      div.parentNode.removeChild(div);
+    }
+
+    return !!ret;
+
+  }
+
+  return injectElementWithStyles;
+});
diff --git a/js/modernizr/src/inputElem.js b/js/modernizr/src/inputElem.js
new file mode 100644 (file)
index 0000000..3e161e3
--- /dev/null
@@ -0,0 +1,12 @@
+define(['createElement'], function(createElement) {
+  /**
+   * since we have a fairly large number of input tests that don't mutate the input
+   * we create a single element that can be shared with all of those tests for a
+   * minor perf boost
+   *
+   * @access private
+   * @returns {HTMLInputElement}
+   */
+  var inputElem = createElement('input');
+  return inputElem;
+});
diff --git a/js/modernizr/src/is.js b/js/modernizr/src/is.js
new file mode 100644 (file)
index 0000000..9a8c406
--- /dev/null
@@ -0,0 +1,16 @@
+define(function() {
+  /**
+   * is returns a boolean if the typeof an obj is exactly type.
+   *
+   * @access private
+   * @function is
+   * @param {*} obj - A thing we want to check the type of
+   * @param {string} type - A string to compare the typeof against
+   * @returns {boolean}
+   */
+
+  function is(obj, type) {
+    return typeof obj === type;
+  }
+  return is;
+});
diff --git a/js/modernizr/src/isSVG.js b/js/modernizr/src/isSVG.js
new file mode 100644 (file)
index 0000000..0427567
--- /dev/null
@@ -0,0 +1,11 @@
+define(['docElement'], function(docElement) {
+  /**
+   * A convenience helper to check if the document we are running in is an SVG document
+   *
+   * @access private
+   * @returns {boolean}
+   */
+
+  var isSVG = docElement.nodeName.toLowerCase() === 'svg';
+  return isSVG;
+});
diff --git a/js/modernizr/src/load.js b/js/modernizr/src/load.js
new file mode 100644 (file)
index 0000000..2d16110
--- /dev/null
@@ -0,0 +1,39 @@
+define(['ModernizrProto'], function(ModernizrProto) {
+  /**
+   * Previously, Modernizr.load was an alias for yepnope. Since yepnope was
+   * deprecated, we removed it as well. It is not available on the website builder,
+   * this is only included as an improved warning to those who build a custom
+   * version locally.
+   *
+   * @memberof Modernizr
+   * @name Modernizr.load
+   * @access private
+   * @function load
+   *
+   */
+
+  var err = function() {};
+  var warn = function() {};
+
+  if (window.console) {
+    err = function() {
+      var method = console.error ? 'error' : 'log';
+      window.console[method].apply(window.console, Array.prototype.slice.call(arguments));
+    };
+
+    warn = function() {
+      var method = console.warn ? 'warn' : 'log';
+      window.console[method].apply(window.console, Array.prototype.slice.call(arguments));
+    };
+  }
+
+  ModernizrProto.load = function() {
+    if ('yepnope' in window) {
+      warn('yepnope.js (aka Modernizr.load) is no longer included as part of Modernizr. yepnope appears to be available on the page, so we’ll use it to handle this call to Modernizr.load, but please update your code to use yepnope directly.\n See http://github.com/Modernizr/Modernizr/issues/1182 for more information.');
+      window.yepnope.apply(window, [].slice.call(arguments, 0));
+    } else {
+      err('yepnope.js (aka Modernizr.load) is no longer included as part of Modernizr. Get it from http://yepnopejs.com. See http://github.com/Modernizr/Modernizr/issues/1182 for more information.');
+    }
+  };
+
+});
diff --git a/js/modernizr/src/mStyle.js b/js/modernizr/src/mStyle.js
new file mode 100644 (file)
index 0000000..6ae2012
--- /dev/null
@@ -0,0 +1,13 @@
+define(['Modernizr', 'modElem'], function(Modernizr, modElem) {
+  var mStyle = {
+    style : modElem.elem.style
+  };
+
+  // kill ref for gc, must happen before mod.elem is removed, so we unshift on to
+  // the front of the queue.
+  Modernizr._q.unshift(function() {
+    delete mStyle.style;
+  });
+
+  return mStyle;
+});
diff --git a/js/modernizr/src/modElem.js b/js/modernizr/src/modElem.js
new file mode 100644 (file)
index 0000000..d3ac505
--- /dev/null
@@ -0,0 +1,18 @@
+define(['Modernizr', 'createElement'], function(Modernizr, createElement) {
+  /**
+   * Create our "modernizr" element that we do most feature tests on.
+   *
+   * @access private
+   */
+
+  var modElem = {
+    elem : createElement('modernizr')
+  };
+
+  // Clean up this element
+  Modernizr._q.push(function() {
+    delete modElem.elem;
+  });
+
+  return modElem;
+});
diff --git a/js/modernizr/src/mq.js b/js/modernizr/src/mq.js
new file mode 100644 (file)
index 0000000..df16366
--- /dev/null
@@ -0,0 +1,75 @@
+define(['ModernizrProto', 'injectElementWithStyles'], function(ModernizrProto, injectElementWithStyles) {
+  /**
+   * Modernizr.mq tests a given media query, live against the current state of the window
+   * adapted from matchMedia polyfill by Scott Jehl and Paul Irish
+   * gist.github.com/786768
+   *
+   * @memberof Modernizr
+   * @name Modernizr.mq
+   * @optionName Modernizr.mq()
+   * @optionProp mq
+   * @access public
+   * @function mq
+   * @param {string} mq - String of the media query we want to test
+   * @returns {boolean}
+   * @example
+   * Modernizr.mq allows for you to programmatically check if the current browser
+   * window state matches a media query.
+   *
+   * ```js
+   *  var query = Modernizr.mq('(min-width: 900px)');
+   *
+   *  if (query) {
+   *    // the browser window is larger than 900px
+   *  }
+   * ```
+   *
+   * Only valid media queries are supported, therefore you must always include values
+   * with your media query
+   *
+   * ```js
+   * // good
+   *  Modernizr.mq('(min-width: 900px)');
+   *
+   * // bad
+   *  Modernizr.mq('min-width');
+   * ```
+   *
+   * If you would just like to test that media queries are supported in general, use
+   *
+   * ```js
+   *  Modernizr.mq('only all'); // true if MQ are supported, false if not
+   * ```
+   *
+   *
+   * Note that if the browser does not support media queries (e.g. old IE) mq will
+   * always return false.
+   */
+
+  var mq = (function() {
+    var matchMedia = window.matchMedia || window.msMatchMedia;
+    if (matchMedia) {
+      return function(mq) {
+        var mql = matchMedia(mq);
+        return mql && mql.matches || false;
+      };
+    }
+
+    return function(mq) {
+      var bool = false;
+
+      injectElementWithStyles('@media ' + mq + ' { #modernizr { position: absolute; } }', function(node) {
+        bool = (window.getComputedStyle ?
+                window.getComputedStyle(node, null) :
+                node.currentStyle)['position'] == 'absolute';
+      });
+
+      return bool;
+    };
+  })();
+
+
+  ModernizrProto.mq = mq;
+
+  return mq;
+});
diff --git a/js/modernizr/src/nativeTestProps.js b/js/modernizr/src/nativeTestProps.js
new file mode 100644 (file)
index 0000000..25deca0
--- /dev/null
@@ -0,0 +1,42 @@
+define(['injectElementWithStyles', 'domToCSS'], function(injectElementWithStyles, domToCSS) {
+  /**
+   * nativeTestProps allows for us to use native feature detection functionality if available.
+   * some prefixed form, or false, in the case of an unsupported rule
+   *
+   * @access private
+   * @function nativeTestProps
+   * @param {array} props - An array of property names
+   * @param {string} value - A string representing the value we want to check via @supports
+   * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise
+   */
+
+  // Accepts a list of property names and a single value
+  // Returns `undefined` if native detection not available
+  function nativeTestProps (props, value) {
+    var i = props.length;
+    // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface
+    if ('CSS' in window && 'supports' in window.CSS) {
+      // Try every prefixed variant of the property
+      while (i--) {
+        if (window.CSS.supports(domToCSS(props[i]), value)) {
+          return true;
+        }
+      }
+      return false;
+    }
+    // Otherwise fall back to at-rule (for Opera 12.x)
+    else if ('CSSSupportsRule' in window) {
+      // Build a condition string for every prefixed variant
+      var conditionText = [];
+      while (i--) {
+        conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')');
+      }
+      conditionText = conditionText.join(' or ');
+      return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) {
+        return getComputedStyle(node, null).position == 'absolute';
+      });
+    }
+    return undefined;
+  }
+  return nativeTestProps;
+});
diff --git a/js/modernizr/src/omPrefixes.js b/js/modernizr/src/omPrefixes.js
new file mode 100644 (file)
index 0000000..33a14a9
--- /dev/null
@@ -0,0 +1,20 @@
+define(function() {
+  /**
+   * If the browsers follow the spec, then they would expose vendor-specific style as:
+   *   elem.style.WebkitBorderRadius
+   * instead of something like the following, which would be technically incorrect:
+   *   elem.style.webkitBorderRadius
+
+   * Webkit ghosts their properties in lowercase but Opera & Moz do not.
+   * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
+   *   erik.eae.net/archives/2008/03/10/21.48.10/
+
+   * More here: github.com/Modernizr/Modernizr/issues/issue/21
+   *
+   * @access private
+   * @returns {string} The string representing the vendor-specific style properties
+   */
+
+  var omPrefixes = 'Moz O ms Webkit';
+  return omPrefixes;
+});
diff --git a/js/modernizr/src/prefixed.js b/js/modernizr/src/prefixed.js
new file mode 100644 (file)
index 0000000..d0d7962
--- /dev/null
@@ -0,0 +1,84 @@
+define(['ModernizrProto', 'testPropsAll', 'cssToDOM', 'atRule'], function(ModernizrProto, testPropsAll, cssToDOM, atRule) {
+  /**
+   * prefixed returns the prefixed or nonprefixed property name variant of your input
+   *
+   * @memberof Modernizr
+   * @name Modernizr.prefixed
+   * @optionName Modernizr.prefixed()
+   * @optionProp prefixed
+   * @access public
+   * @function prefixed
+   * @param {string} prop - String name of the property to test for
+   * @param {object} [obj]- An object to test for the prefixed properties on
+   * @returns {string|false} The string representing the (possibly prefixed) valid
+   * version of the property, or `false` when it is unsupported.
+   * @example
+   *
+   * Modernizr.prefixed takes a string css value in the DOM style camelCase (as
+   * opposed to the css style kebab-case) form and returns the (possibly prefixed)
+   * version of that property that the browser actually supports.
+   *
+   * For example, in older Firefox...
+   * ```js
+   * prefixed('boxSizing')
+   * ```
+   * returns 'MozBoxSizing'
+   *
+   * In newer Firefox, as well as any other browser that support the unprefixed
+   * version would simply return `boxSizing`. Any browser that does not support
+   * the property at all, it will return `false`.
+   *
+   * By default, prefixed is checked against a DOM element. If you want to check
+   * for a property on another object, just pass it as a second argument
+   *
+   * ```js
+   * var rAF = prefixed('requestAnimationFrame', window);
+   *
+   * raf(function() {
+   *  renderFunction();
+   * })
+   * ```
+   *
+   * Note that this will return _the actual function_ - not the name of the function.
+   * If you need the actual name of the property, pass in `false` as a third argument
+   *
+   * ```js
+   * var rAFProp = prefixed('requestAnimationFrame', window, false);
+   *
+   * rafProp === 'WebkitRequestAnimationFrame' // in older webkit
+   * ```
+   *
+   * One common use case for prefixed is if you're trying to determine which transition
+   * end event to bind to, you might do something like...
+   * ```js
+   * var transEndEventNames = {
+   *     'WebkitTransition' : 'webkitTransitionEnd', * Saf 6, Android Browser
+   *     'MozTransition'    : 'transitionend',       * only for FF < 15
+   *     'transition'       : 'transitionend'        * IE10, Opera, Chrome, FF 15+, Saf 7+
+   * };
+   *
+   * var transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
+   * ```
+   *
+   * If you want a similar lookup, but in kebab-case, you can use [prefixedCSS](#modernizr-prefixedcss).
+   */
+
+  var prefixed = ModernizrProto.prefixed = function(prop, obj, elem) {
+    if (prop.indexOf('@') === 0) {
+      return atRule(prop);
+    }
+
+    if (prop.indexOf('-') != -1) {
+      // Convert kebab-case to camelCase
+      prop = cssToDOM(prop);
+    }
+    if (!obj) {
+      return testPropsAll(prop, 'pfx');
+    } else {
+      // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
+      return testPropsAll(prop, obj, elem);
+    }
+  };
+
+  return prefixed;
+});
diff --git a/js/modernizr/src/prefixedCSS.js b/js/modernizr/src/prefixedCSS.js
new file mode 100644 (file)
index 0000000..4caa581
--- /dev/null
@@ -0,0 +1,35 @@
+define(['ModernizrProto', 'prefixed', 'domToCSS'], function(ModernizrProto, prefixed, domToCSS) {
+  /**
+   * prefixedCSS is just like [prefixed](#modernizr-prefixed), but the returned values are in
+   * kebab-case (e.g. `box-sizing`) rather than camelCase (boxSizing).
+   *
+   * @memberof Modernizr
+   * @name Modernizr.prefixedCSS
+   * @optionName Modernizr.prefixedCSS()
+   * @optionProp prefixedCSS
+   * @access public
+   * @function prefixedCSS
+   * @param {string} prop - String name of the property to test for
+   * @returns {string|false} The string representing the (possibly prefixed)
+   * valid version of the property, or `false` when it is unsupported.
+   * @example
+   *
+   * `Modernizr.prefixedCSS` is like `Modernizr.prefixed`, but returns the result
+   * in hyphenated form
+   *
+   * ```js
+   * Modernizr.prefixedCSS('transition') // '-moz-transition' in old Firefox
+   * ```
+   *
+   * Since it is only useful for CSS style properties, it can only be tested against
+   * an HTMLElement.
+   *
+   * Properties can be passed as both the DOM style camelCase or CSS style kebab-case.
+   */
+
+  var prefixedCSS = ModernizrProto.prefixedCSS = function(prop) {
+    var prefixedProp = prefixed(prop);
+    return prefixedProp && domToCSS(prefixedProp);
+  };
+  return prefixedCSS;
+});
diff --git a/js/modernizr/src/prefixes.js b/js/modernizr/src/prefixes.js
new file mode 100644 (file)
index 0000000..86f8c0e
--- /dev/null
@@ -0,0 +1,40 @@
+define(['ModernizrProto'], function(ModernizrProto) {
+  /**
+   * List of property values to set for css tests. See ticket #21
+   * http://git.io/vUGl4
+   *
+   * @memberof Modernizr
+   * @name Modernizr._prefixes
+   * @optionName Modernizr._prefixes
+   * @optionProp prefixes
+   * @access public
+   * @example
+   *
+   * Modernizr._prefixes is the internal list of prefixes that we test against
+   * inside of things like [prefixed](#modernizr-prefixed) and [prefixedCSS](#-code-modernizr-prefixedcss). It is simply
+   * an array of kebab-case vendor prefixes you can use within your code.
+   *
+   * Some common use cases include
+   *
+   * Generating all possible prefixed version of a CSS property
+   * ```js
+   * var rule = Modernizr._prefixes.join('transform: rotate(20deg); ');
+   *
+   * rule === 'transform: rotate(20deg); webkit-transform: rotate(20deg); moz-transform: rotate(20deg); o-transform: rotate(20deg); ms-transform: rotate(20deg);'
+   * ```
+   *
+   * Generating all possible prefixed version of a CSS value
+   * ```js
+   * rule = 'display:' +  Modernizr._prefixes.join('flex; display:') + 'flex';
+   *
+   * rule === 'display:flex; display:-webkit-flex; display:-moz-flex; display:-o-flex; display:-ms-flex; display:flex'
+   * ```
+   */
+
+  var prefixes = (ModernizrProto._config.usePrefixes ? ' -webkit- -moz- -o- -ms- '.split(' ') : []);
+
+  // expose these for the plugin API. Look in the source for how to join() them against your input
+  ModernizrProto._prefixes = prefixes;
+
+  return prefixes;
+});
diff --git a/js/modernizr/src/roundedEquals.js b/js/modernizr/src/roundedEquals.js
new file mode 100644 (file)
index 0000000..3599923
--- /dev/null
@@ -0,0 +1,17 @@
+define(function() {
+  /**
+   * roundedEquals takes two integers and checks if the first is within 1 of the second
+   *
+   * @access private
+   * @function roundedEquals
+   * @param {number} a
+   * @param {number} b
+   * @returns {boolean}
+   */
+
+  function roundedEquals(a, b) {
+    return a - 1 === b || a === b || a + 1 === b;
+  }
+
+  return roundedEquals;
+});
diff --git a/js/modernizr/src/setClasses.js b/js/modernizr/src/setClasses.js
new file mode 100644 (file)
index 0000000..54a7f10
--- /dev/null
@@ -0,0 +1,36 @@
+define(['Modernizr', 'docElement', 'isSVG'], function(Modernizr, docElement, isSVG) {
+  /**
+   * setClasses takes an array of class names and adds them to the root element
+   *
+   * @access private
+   * @function setClasses
+   * @param {string[]} classes - Array of class names
+   */
+
+  // Pass in an and array of class names, e.g.:
+  //  ['no-webp', 'borderradius', ...]
+  function setClasses(classes) {
+    var className = docElement.className;
+    var classPrefix = Modernizr._config.classPrefix || '';
+
+    if (isSVG) {
+      className = className.baseVal;
+    }
+
+    // Change `no-js` to `js` (independently of the `enableClasses` option)
+    // Handle classPrefix on this too
+    if (Modernizr._config.enableJSClass) {
+      var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)');
+      className = className.replace(reJS, '$1' + classPrefix + 'js$2');
+    }
+
+    if (Modernizr._config.enableClasses) {
+      // Add the new classes
+      className += ' ' + classPrefix + classes.join(' ' + classPrefix);
+      isSVG ? docElement.className.baseVal = className : docElement.className = className;
+    }
+
+  }
+
+  return setClasses;
+});
diff --git a/js/modernizr/src/slice.js b/js/modernizr/src/slice.js
new file mode 100644 (file)
index 0000000..2eeda69
--- /dev/null
@@ -0,0 +1,12 @@
+define(['classes'], function(classes) {
+  /**
+   * slice exposes Array.prototype.slice to convert array-like objects to actual
+   * arrays in a compact format without recreating new arrays over and over again
+   * (which leads to decreased performance)
+   *
+   * @access private
+   */
+
+  var slice = classes.slice;
+  return slice;
+});
diff --git a/js/modernizr/src/testAllProps.js b/js/modernizr/src/testAllProps.js
new file mode 100644 (file)
index 0000000..8446b37
--- /dev/null
@@ -0,0 +1,44 @@
+define(['ModernizrProto', 'testPropsAll'], function(ModernizrProto, testPropsAll) {
+  /**
+   * testAllProps determines whether a given CSS property is supported in the browser
+   *
+   * @memberof Modernizr
+   * @name Modernizr.testAllProps
+   * @optionName Modernizr.testAllProps()
+   * @optionProp testAllProps
+   * @access public
+   * @function testAllProps
+   * @param {string} prop - String naming the property to test (either camelCase or kebab-case)
+   * @param {string} [value] - String of the value to test
+   * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection
+   * @example
+   *
+   * testAllProps determines whether a given CSS property, in some prefixed form,
+   * is supported by the browser.
+   *
+   * ```js
+   * testAllProps('boxSizing')  // true
+   * ```
+   *
+   * It can optionally be given a CSS value in string form to test if a property
+   * value is valid
+   *
+   * ```js
+   * testAllProps('display', 'block') // true
+   * testAllProps('display', 'penguin') // false
+   * ```
+   *
+   * A boolean can be passed as a third parameter to skip the value check when
+   * native detection (@supports) isn't available.
+   *
+   * ```js
+   * testAllProps('shapeOutside', 'content-box', true);
+   * ```
+   */
+
+  function testAllProps (prop, value, skipValueTest) {
+    return testPropsAll(prop, undefined, undefined, value, skipValueTest);
+  }
+  ModernizrProto.testAllProps = testAllProps;
+  return testAllProps;
+});
diff --git a/js/modernizr/src/testDOMProps.js b/js/modernizr/src/testDOMProps.js
new file mode 100644 (file)
index 0000000..3b31e99
--- /dev/null
@@ -0,0 +1,33 @@
+define(['is', 'fnBind'], function(is, fnBind) {
+  /**
+   * testDOMProps is a generic DOM property test; if a browser supports
+   *   a certain property, it won't return undefined for it.
+   */
+  function testDOMProps(props, obj, elem) {
+    var item;
+
+    for (var i in props) {
+      if (props[i] in obj) {
+
+        // return the property name as a string
+        if (elem === false) {
+          return props[i];
+        }
+
+        item = obj[props[i]];
+
+        // let's bind a function
+        if (is(item, 'function')) {
+          // bind to obj unless overriden
+          return fnBind(item, elem || obj);
+        }
+
+        // return the unbound function or obj or value
+        return item;
+      }
+    }
+    return false;
+  }
+
+  return testDOMProps;
+});
diff --git a/js/modernizr/src/testProp.js b/js/modernizr/src/testProp.js
new file mode 100644 (file)
index 0000000..0cd3dd6
--- /dev/null
@@ -0,0 +1,40 @@
+define(['ModernizrProto', 'testProps'], function(ModernizrProto, testProps) {
+  /**
+   * testProp() investigates whether a given style property is recognized
+   * Property names can be provided in either camelCase or kebab-case.
+   *
+   * @memberof Modernizr
+   * @name Modernizr.testProp
+   * @access public
+   * @optionName Modernizr.testProp()
+   * @optionProp testProp
+   * @function testProp
+   * @param {string} prop - Name of the CSS property to check
+   * @param {string} [value] - Name of the CSS value to check
+   * @param {boolean} [useValue] - Whether or not to check the value if @supports isn't supported
+   * @returns {boolean}
+   * @example
+   *
+   * Just like [testAllProps](#modernizr-testallprops), only it does not check any vendor prefixed
+   * version of the string.
+   *
+   * Note that the property name must be provided in camelCase (e.g. boxSizing not box-sizing)
+   *
+   * ```js
+   * Modernizr.testProp('pointerEvents')  // true
+   * ```
+   *
+   * You can also provide a value as an optional second argument to check if a
+   * specific value is supported
+   *
+   * ```js
+   * Modernizr.testProp('pointerEvents', 'none') // true
+   * Modernizr.testProp('pointerEvents', 'penguin') // false
+   * ```
+   */
+
+  var testProp = ModernizrProto.testProp = function(prop, value, useValue) {
+    return testProps([prop], undefined, value, useValue);
+  };
+  return testProp;
+});
diff --git a/js/modernizr/src/testProps.js b/js/modernizr/src/testProps.js
new file mode 100644 (file)
index 0000000..9d9e689
--- /dev/null
@@ -0,0 +1,94 @@
+define(['contains', 'mStyle', 'createElement', 'nativeTestProps', 'is', 'cssToDOM'], function(contains, mStyle, createElement, nativeTestProps, is, cssToDOM) {
+  // testProps is a generic CSS / DOM property test.
+
+  // In testing support for a given CSS property, it's legit to test:
+  //    `elem.style[styleName] !== undefined`
+  // If the property is supported it will return an empty string,
+  // if unsupported it will return undefined.
+
+  // We'll take advantage of this quick test and skip setting a style
+  // on our modernizr element, but instead just testing undefined vs
+  // empty string.
+
+  // Property names can be provided in either camelCase or kebab-case.
+
+  function testProps(props, prefixed, value, skipValueTest) {
+    skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest;
+
+    // Try native detect first
+    if (!is(value, 'undefined')) {
+      var result = nativeTestProps(props, value);
+      if (!is(result, 'undefined')) {
+        return result;
+      }
+    }
+
+    // Otherwise do it properly
+    var afterInit, i, propsLength, prop, before;
+
+    // If we don't have a style element, that means we're running async or after
+    // the core tests, so we'll need to create our own elements to use
+
+    // inside of an SVG element, in certain browsers, the `style` element is only
+    // defined for valid tags. Therefore, if `modernizr` does not have one, we
+    // fall back to a less used element and hope for the best.
+    var elems = ['modernizr', 'tspan'];
+    while (!mStyle.style) {
+      afterInit = true;
+      mStyle.modElem = createElement(elems.shift());
+      mStyle.style = mStyle.modElem.style;
+    }
+
+    // Delete the objects if we created them.
+    function cleanElems() {
+      if (afterInit) {
+        delete mStyle.style;
+        delete mStyle.modElem;
+      }
+    }
+
+    propsLength = props.length;
+    for (i = 0; i < propsLength; i++) {
+      prop = props[i];
+      before = mStyle.style[prop];
+
+      if (contains(prop, '-')) {
+        prop = cssToDOM(prop);
+      }
+
+      if (mStyle.style[prop] !== undefined) {
+
+        // If value to test has been passed in, do a set-and-check test.
+        // 0 (integer) is a valid property value, so check that `value` isn't
+        // undefined, rather than just checking it's truthy.
+        if (!skipValueTest && !is(value, 'undefined')) {
+
+          // Needs a try catch block because of old IE. This is slow, but will
+          // be avoided in most cases because `skipValueTest` will be used.
+          try {
+            mStyle.style[prop] = value;
+          } catch (e) {}
+
+          // If the property value has changed, we assume the value used is
+          // supported. If `value` is empty string, it'll fail here (because
+          // it hasn't changed), which matches how browsers have implemented
+          // CSS.supports()
+          if (mStyle.style[prop] != before) {
+            cleanElems();
+            return prefixed == 'pfx' ? prop : true;
+          }
+        }
+        // Otherwise just return true, or the property name if this is a
+        // `prefixed()` call
+        else {
+          cleanElems();
+          return prefixed == 'pfx' ? prop : true;
+        }
+      }
+    }
+    cleanElems();
+    return false;
+  }
+
+  return testProps;
+});
diff --git a/js/modernizr/src/testPropsAll.js b/js/modernizr/src/testPropsAll.js
new file mode 100644 (file)
index 0000000..46c64cd
--- /dev/null
@@ -0,0 +1,32 @@
+define(['ModernizrProto', 'cssomPrefixes', 'is', 'testProps', 'domPrefixes', 'testDOMProps'], function(ModernizrProto, cssomPrefixes, is, testProps, domPrefixes, testDOMProps) {
+  /**
+   * testPropsAll tests a list of DOM properties we want to check against.
+   * We specify literally ALL possible (known and/or likely) properties on
+   * the element including the non-vendor prefixed one, for forward-
+   * compatibility.
+   */
+  function testPropsAll(prop, prefixed, elem, value, skipValueTest) {
+
+    var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
+    props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
+
+    // did they call .prefixed('boxSizing') or are we just testing a prop?
+    if (is(prefixed, 'string') || is(prefixed, 'undefined')) {
+      return testProps(props, prefixed, value, skipValueTest);
+
+      // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
+    } else {
+      props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
+      return testDOMProps(props, prefixed, elem);
+    }
+  }
+
+  // Modernizr.testAllProps() investigates whether a given style property,
+  // or any of its vendor-prefixed variants, is recognized
+  //
+  // Note that the property names must be provided in the camelCase variant.
+  // Modernizr.testAllProps('boxSizing')
+  ModernizrProto.testAllProps = testPropsAll;
+
+  return testPropsAll;
+});
diff --git a/js/modernizr/src/testRunner.js b/js/modernizr/src/testRunner.js
new file mode 100644 (file)
index 0000000..1935589
--- /dev/null
@@ -0,0 +1,71 @@
+define(['tests', 'Modernizr', 'classes', 'is'], function(tests, Modernizr, classes, is) {
+  /**
+   * Run through all tests and detect their support in the current UA.
+   *
+   * @access private
+   */
+
+  function testRunner() {
+    var featureNames;
+    var feature;
+    var aliasIdx;
+    var result;
+    var nameIdx;
+    var featureName;
+    var featureNameSplit;
+
+    for (var featureIdx in tests) {
+      featureNames = [];
+      feature = tests[featureIdx];
+      // run the test, throw the return value into the Modernizr,
+      // then based on that boolean, define an appropriate className
+      // and push it into an array of classes we'll join later.
+      //
+      // If there is no name, it's an 'async' test that is run,
+      // but not directly added to the object. That should
+      // be done with a post-run addTest call.
+      if (feature.name) {
+        featureNames.push(feature.name.toLowerCase());
+
+        if (feature.options && feature.options.aliases && feature.options.aliases.length) {
+          // Add all the aliases into the names list
+          for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) {
+            featureNames.push(feature.options.aliases[aliasIdx].toLowerCase());
+          }
+        }
+      }
+
+      // Run the test, or use the raw value if it's not a function
+      result = is(feature.fn, 'function') ? feature.fn() : feature.fn;
+
+
+      // Set each of the names on the Modernizr object
+      for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) {
+        featureName = featureNames[nameIdx];
+        // Support dot properties as sub tests. We don't do checking to make sure
+        // that the implied parent tests have been added. You must call them in
+        // order (either in the test, or make the parent test a dependency).
+        //
+        // Cap it to TWO to make the logic simple and because who needs that kind of subtesting
+        // hashtag famous last words
+        featureNameSplit = featureName.split('.');
+
+        if (featureNameSplit.length === 1) {
+          Modernizr[featureNameSplit[0]] = result;
+        } else {
+          // cast to a Boolean, if not one already
+          /* jshint -W053 */
+          if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
+            Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
+          }
+
+          Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result;
+        }
+
+        classes.push((result ? '' : 'no-') + featureNameSplit.join('-'));
+      }
+    }
+  }
+
+  return testRunner;
+});
diff --git a/js/modernizr/src/testStyles.js b/js/modernizr/src/testStyles.js
new file mode 100644 (file)
index 0000000..f027eba
--- /dev/null
@@ -0,0 +1,61 @@
+define(['ModernizrProto', 'injectElementWithStyles'], function(ModernizrProto, injectElementWithStyles) {
+  /**
+   * testStyles injects an element with style element and some CSS rules
+   *
+   * @memberof Modernizr
+   * @name Modernizr.testStyles
+   * @optionName Modernizr.testStyles()
+   * @optionProp testStyles
+   * @access public
+   * @function testStyles
+   * @param {string} rule - String representing a css rule
+   * @param {function} callback - A function that is used to test the injected element
+   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
+   * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes
+   * @returns {boolean}
+   * @example
+   *
+   * `Modernizr.testStyles` takes a CSS rule and injects it onto the current page
+   * along with (possibly multiple) DOM elements. This lets you check for features
+   * that can not be detected by simply checking the [IDL](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Interface_development_guide/IDL_interface_rules).
+   *
+   * ```js
+   * Modernizr.testStyles('#modernizr { width: 9px; color: papayawhip; }', function(elem, rule) {
+   *   // elem is the first DOM node in the page (by default #modernizr)
+   *   // rule is the first argument you supplied - the CSS rule in string form
+   *
+   *   addTest('widthworks', elem.style.width === '9px')
+   * });
+   * ```
+   *
+   * If your test requires multiple nodes, you can include a third argument
+   * indicating how many additional div elements to include on the page. The
+   * additional nodes are injected as children of the `elem` that is returned as
+   * the first argument to the callback.
+   *
+   * ```js
+   * Modernizr.testStyles('#modernizr {width: 1px}; #modernizr2 {width: 2px}', function(elem) {
+   *   document.getElementById('modernizr').style.width === '1px'; // true
+   *   document.getElementById('modernizr2').style.width === '2px'; // true
+   *   elem.firstChild === document.getElementById('modernizr2'); // true
+   * }, 1);
+   * ```
+   *
+   * By default, all of the additional elements have an ID of `modernizr[n]`, where
+   * `n` is its index (e.g. the first additional, second overall is `#modernizr2`,
+   * the second additional is `#modernizr3`, etc.).
+   * If you want to have more meaningful IDs for your function, you can provide
+   * them as the fourth argument, as an array of strings
+   *
+   * ```js
+   * Modernizr.testStyles('#foo {width: 10px}; #bar {height: 20px}', function(elem) {
+   *   elem.firstChild === document.getElementById('foo'); // true
+   *   elem.lastChild === document.getElementById('bar'); // true
+   * }, 2, ['foo', 'bar']);
+   * ```
+   *
+   */
+
+  var testStyles = ModernizrProto.testStyles = injectElementWithStyles;
+  return testStyles;
+});
diff --git a/js/modernizr/src/testXhrType.js b/js/modernizr/src/testXhrType.js
new file mode 100644 (file)
index 0000000..6e22ee1
--- /dev/null
@@ -0,0 +1,28 @@
+define(function() {
+  /**
+   * http://mathiasbynens.be/notes/xhr-responsetype-json#comment-4
+   *
+   * @access private
+   * @function testXhrType
+   * @param {string} type - String name of the XHR type you want to detect
+   * @returns {boolean}
+   * @author Mathias Bynens
+   */
+
+  /* istanbul ignore next */
+  var testXhrType = function(type) {
+    if (typeof XMLHttpRequest == 'undefined') {
+      return false;
+    }
+    var xhr = new XMLHttpRequest();
+    xhr.open('get', '/', true);
+    try {
+      xhr.responseType = type;
+    } catch (error) {
+      return false;
+    }
+    return 'response' in xhr && xhr.responseType == type;
+  };
+
+  return testXhrType;
+});
diff --git a/js/modernizr/src/tests.js b/js/modernizr/src/tests.js
new file mode 100644 (file)
index 0000000..3a022e6
--- /dev/null
@@ -0,0 +1,4 @@
+define(function() {
+  var tests = [];
+  return tests;
+});
diff --git a/js/modernizr/src/toStringFn.js b/js/modernizr/src/toStringFn.js
new file mode 100644 (file)
index 0000000..e0d602b
--- /dev/null
@@ -0,0 +1,14 @@
+define(function() {
+  /**
+   * Object.prototype.toString can be used with every object and allows you to
+   * get its class easily. Abstracting it off of an object prevents situations
+   * where the toString property has been overridden
+   *
+   * @access private
+   * @function toStringFn
+   * @returns {function} An abstracted toString function
+   */
+
+  var toStringFn = ({}).toString;
+  return toStringFn;
+});
diff --git a/js/modernizr/test/browser/integration/bools.js b/js/modernizr/test/browser/integration/bools.js
new file mode 100644 (file)
index 0000000..3d14d17
--- /dev/null
@@ -0,0 +1,30 @@
+describe('bools', function() {
+  it('all properties are lower case', function() {
+    _.every(Modernizr, function(result, name) {
+      return expect(name).to.not.match(/[A-Z]/);
+    });
+  });
+
+  describe('everythings ship shape', function() {
+    _.chain(Modernizr)
+      .keys()
+      .filter()
+      .sort()
+      .forEach(function(name) {
+        var result = Modernizr[name];
+        if (name === 'input' || name === 'inputtypes') {
+          return;
+        }
+
+        it(name + ' is a boolean value or Boolean object', function() {
+          expect(
+            result instanceof Boolean ||
+            result === true ||
+            result === false
+          ).to.be(true);
+        });
+      })
+      .value();
+  });
+
+});
diff --git a/js/modernizr/test/browser/integration/caniuse.js b/js/modernizr/test/browser/integration/caniuse.js
new file mode 100644 (file)
index 0000000..6c074ce
--- /dev/null
@@ -0,0 +1,361 @@
+/* global uaparse */
+window.caniusecb = function(caniuse) {
+  // So Phantom doesn't kill the caniuse.com matching exit out as it's useless anyway within PhantomJS
+  if (window._phantom) {
+    return;
+  }
+  describe('caniuse', function() {
+
+    var ua = uaparse(navigator.userAgent);
+    var unusedModernizr = [];
+    var unusedCaniuse = _.keys(caniuse.data);
+    var map = {
+      adownload: 'download',
+      ambientlight: 'ambient-light',
+      apng: 'apng',
+      appearance: 'css-appearance',
+      applicationcache: 'offline-apps',
+      audio: 'audio',
+      backgroundblendmode: 'css-backgroundblendmode',
+      blobconstructor: 'blobbuilder',
+      bloburls: 'bloburls',
+      borderimage: 'border-image',
+      borderradius: 'border-radius',
+      boxshadow: 'css-boxshadow',
+      boxsizing: 'css3-boxsizing',
+      canvas: 'canvas',
+      canvasblending: 'canvas-blending',
+      canvastext: 'canvas-text',
+      classlist: 'classlist',
+      contenteditable: 'contenteditable',
+      contextmenu: 'menu',
+      cors: 'cors',
+      cssanimations: 'css-animation',
+      csscalc: 'calc',
+      csscolumns: 'multicolumn',
+      cssfilters: 'css-filters',
+      cssgradients: 'css-gradients',
+      csspointerevents: 'pointer-events',
+      csspositionsticky: 'css-sticky',
+      cssreflections: 'css-reflections',
+      cssremunit: 'rem',
+      cssresize: 'css-resize',
+      csstransforms3d: 'transforms3d',
+      csstransforms: 'transforms2d',
+      csstransitions: 'css-transitions',
+      cssvhunit: 'viewport-units',
+      cssvmaxunit: 'viewport-units',
+      cssvminunit: 'viewport-units',
+      cssvwunit: 'viewport-units',
+      datalistelem: 'datalist',
+      datauri: 'datauri',
+      details: 'details',
+      deviceorientation: 'deviceorientation',
+      displaytable: 'css-table',
+      eventsource: 'eventsource',
+      filereader: 'fileapi',
+      filesystem: 'filesystem',
+      flexbox: 'flexbox',
+      flexboxlegacy: 'flexbox',
+      flexboxtweener: 'flexbox',
+      fontface: 'fontface',
+      formvalidationapi: 'form-validation',
+      fullscreen: 'fullscreen',
+      gamepads: 'gamepad',
+      geolocation: 'geolocation',
+      getrandomvalues: 'getrandomvalues',
+      getusermedia: 'stream',
+      hashchange: 'hashchange',
+      hidden: 'hidden',
+      history: 'history',
+      hsla: 'css3-colors',
+      htmlimports: 'imports',
+      indexeddb: 'indexeddb',
+      inlinesvg: 'svg-html5',
+      inputtypes: 'forms',
+      jpegxr: 'jpegxr',
+      json: 'json',
+      localstorage: 'namevalue-storage',
+      mathml: 'mathml',
+      mediaqueries: 'css-mediaqueries',
+      meter: 'progressmeter',
+      multiplebgs: 'multibackgrounds',
+      mutationobserver: 'mutationobserver',
+      notification: 'notifications',
+      objectfit: 'object-fit',
+      opacity: 'css-opacity',
+      pagevisibility: 'pagevisibility',
+      performance: 'nav-timing',
+      picture: 'picture',
+      postmessage: 'x-doc-messaging',
+      progressbar: 'progressmeter',
+      promises: 'promises',
+      queryselector: 'queryselector',
+      regions: 'css-regions',
+      requestanimationframe: 'requestanimationframe',
+      rgba: 'css3-colors',
+      ruby: 'ruby',
+      sandbox: 'iframe-sandbox',
+      scriptasync: 'script-async',
+      scriptdefer: 'script-defer',
+      seamless: 'iframe-seamless',
+      shapes: 'css-shapes',
+      sharedworkers: 'sharedworkers',
+      smil: 'svg-smil',
+      strictmode: 'use-strict',
+      stylescoped: 'style-scoped',
+      supports: 'css-featurequeries',
+      svg: 'svg',
+      svgasimg: 'svg-img',
+      svgfilters: 'svg-filters',
+      template: 'template',
+      textalignlast: 'css-text-align-last',
+      textshadow: 'css-textshadow',
+      typedarrays: 'typedarrays',
+      unicoderange: 'font-unicode-range',
+      userselect: 'user-select-none',
+      vibrate: 'vibration',
+      video: 'video',
+      webanimations: 'web-animation',
+      webaudio: 'audio-api',
+      webgl: 'webgl',
+      webp: 'webp',
+      websockets: 'websockets',
+      websqldatabase: 'sql-storage',
+      webworkers: 'webworkers',
+      willchange: 'will-change',
+      xhr2: 'xhr2'
+    };
+
+    // translate 'y' 'n' or 'a' into a boolean that Modernizr uses
+    function bool(result) {
+      // To handle correctly things like 'y #1' or 'a #2'
+      if (result.indexOf('y') === 0 || result.indexOf('a') === 0) {
+        return true;
+      }
+      // 'p' is for polyfill
+      if (result.indexOf('n') === 0 || result.indexOf('p') === 0) {
+        return false;
+      }
+      throw 'unknown return value from can i use - ' + result;
+    }
+
+    function testify(o) {
+
+      var ciubool = bool(o.caniuseResult);
+
+      /**************************************************************
+      * `o.caniuseResult` maps to the caniuse `stat` property
+      *
+      * y - (Y)es, supported by default
+      * a - (A)lmost supported (aka Partial support)
+      * n - (N)o support, or disabled by default
+      * p - No support, but has (P)olyfill
+      * u - Support (u)nknown
+      * x - Requires prefi(x) to work
+      * d - (D)isabled by default (need to enable flag or something)
+      **************************************************************/
+
+      // caniuse says audio/video are yes/no, Modernizr has more detail which we'll dumb down.
+      if (_.contains(['video', 'audio', 'webglextensions'], o.feature)) {
+        o.result = o.result.valueOf();
+      }
+
+      // webgl `partial` support means that not all users with these browsers have
+      // WebGL access, so we just ignore this test, and only check if the browser
+      // either fully supports or does not support
+      if (o.feature === 'webgl' && o.caniuseResult.indexOf('a') === 0) {
+        return;
+      }
+
+      // change the *documented* false positives
+      if (!ciubool && (o.feature == 'textshadow' && o.browser == 'Firefox' && o.version == 3)) {
+        ciubool = o.fp = true;
+      }
+
+      // firefox does not support unicode-range without a flag
+      if (o.feature === 'unicoderange' && o.caniuseResult.indexOf('y') === 0 && o.browser == 'Firefox' && o.version <= 40) {
+        return;
+      }
+
+      // firefox only supports web animation when a flag is enabled, which we
+      // don't do on sauce
+      if (o.feature === 'webanimations' && o.caniuseResult.indexOf('a d') === 0) {
+        return;
+      }
+
+      // firefox only supports the `url` version of css-filters, which we don't
+      // consider support
+      if (o.feature === 'cssfilters' && o.browser == 'Firefox' && o.caniuseResult.indexOf('a') === 0) {
+        return;
+      }
+
+      // before 4.0, firefox only supports MathML on XHTML documents. Since we
+      // don't run inside of one, we will have a technically false negative
+      if (o.feature === 'mathml' && o.browser == 'Firefox' && o.version < 4) {
+        return;
+      }
+
+      // caniuse bundles viewport units, all of which work in IE 9+, save for vmax
+      // we skip this comparison with a version gate, hoping its fixed in later versions.
+      if (o.feature === 'cssvmaxunit' && o.caniuseResult.indexOf('a') === 0) {
+        return;
+      }
+
+      // safari 5 does not support the `FileReader` API, which we test as a requirement
+      if (o.feature === 'filereader' && o.caniuseResult.indexOf('a') === 0) {
+        return;
+      }
+
+      // safari 5 and 6 only support the old version of WebSockets, which breaks most servers.
+      // As a result, we mark it as not supported, and ignore the caniuse match
+      if (o.feature === 'websockets' && o.caniuseResult.indexOf('a') === 0) {
+        return;
+      }
+
+      // safari 7 recognizes the `seamless` attribute but does not actually support it
+      if (o.feature === 'seamless' && o.browser === 'Safari' && o.version === 7) {
+        return;
+      }
+
+
+      // caniuse counts a partial support for CORS via the XDomainRequest,
+      // but thats not really cors - so skip the comparison.
+      if (o.feature === 'cors' && o.browser == 'IE' && o.version < 10) {
+        return;
+      }
+
+      // Opera 12 has a false positive for `defer`
+      if (o.feature === 'scriptdefer' && o.browser == 'Opera' && parseInt(o.version, 10) === 12) {
+        return;
+      }
+
+      // caniuse bundles forms into one big wad of detects. we check to see if their result matches
+      // atleast some of our inputtypes.
+      if (o.ciufeature === 'forms') {
+        return it('Caniuse result for forms matches Modernizr\'s result for inputtypes', function() {
+          return expect(ciubool).to.be(_.some(Modernizr.inputtypes, function(modernizrResult) {
+            return modernizrResult;
+          }));
+        });
+      }
+
+
+      // we breakout flexbox sniffing into three seperate detects, which borks the caniuse mappings,
+      // since no browser supports all three
+      if (o.ciufeature === 'flexbox') {
+        return it('Caniuse result for flexbox matches Modernizr\'s result for flexbox', function() {
+          return expect([
+            Modernizr.flexbox,
+            Modernizr.flexboxlegacy,
+            Modernizr.flexboxtweener
+          ]).to.contain(ciubool);
+        });
+      }
+
+      // caniuse bundles progress and meter elements, so we do too.
+      if (_.contains(['meter', 'progressbar'], o.feature)) {
+        return it('Caniuse result for ' + o.ciufeature + ' matches Modernizr\'s result for ' + o.feature, function() {
+          return expect([
+            Modernizr.meter,
+            Modernizr.progressbar
+          ]).to.contain(ciubool);
+        });
+      }
+
+      // caniuse counts `filter` opacity as partial support - we don't.
+      if (o.feature === 'opacity' && o.browser === 'IE' && o.version < 9) {
+        return;
+      }
+
+      // if caniuse gave us a 'partial', lets let it pass with a note.
+      if (o.caniuseResult.indexOf('a') === 0) {
+        return it(o.browser + o.version + ': Caniuse reported partial support for ' + o.ciufeature, function() {
+          var modernizrResult = o.result instanceof Boolean ? o.result.valueOf() : !!o.result;
+          expect(ciubool).to.equal(modernizrResult);
+        });
+      }
+
+      // where we actually do most our assertions
+      it(o.browser + o.version + ': Caniuse result for ' + o.ciufeature + ' matches Modernizr\'s ' + (o.fp ? '*false positive*' : 'result') + ' for ' + o.feature, function() {
+        var modernizrResult = o.result instanceof Boolean ? o.result.valueOf() : !!o.result;
+        expect(ciubool).to.equal(modernizrResult);
+      });
+    }
+
+    _.forEach(Modernizr, function(result, feature) {
+
+      var caniuseFeatureName = map[feature];
+
+      if (_.isUndefined(caniuseFeatureName)) {
+        return unusedModernizr.push(feature);
+      }
+
+      var caniuseFeatureData = caniuse.data[caniuseFeatureName];
+
+      if (caniuseFeatureData === undefined) {
+        throw 'unknown key of caniusedata - ' + caniuseFeatureName;
+      }
+
+      unusedCaniuse = _.without(unusedCaniuse, caniuseFeatureName);
+
+      // get results for this feature for all versions of this browser
+      var browserResults = caniuseFeatureData.stats[ua.family.toLowerCase()];
+
+      // let's get our versions in order..
+      var minorver   = ua.minor &&                                  // caniuse doesn't use two digit minors
+        ua.minor.toString().replace(/(\d)\d$/, '$1'); // but opera does.
+
+
+      var majorminor = (ua.major + '.' + minorver)
+        // opera gets grouped in some cases by caniuse
+        .replace(/(9\.(6|5))/ , ua.family == 'opera' ? '9.5-9.6'   : '$1')
+        .replace(/(10\.(0|1))/, ua.family == 'opera' ? '10.0-10.1' : '$1');
+
+      var mmResult   = browserResults[majorminor];
+      var mResult    = browserResults[ua.major];
+
+
+      // check it against the major.minor: eg. FF 3.6
+      if (mmResult && mmResult != 'u') { // 'y' 'n' or 'a'
+
+        // data ends w/ ` x` if its still prefixed in the imp
+        mmResult = mmResult.replace(' x', '');
+
+        // match it against our data.
+        testify({
+          feature: feature,
+          ciufeature: caniuseFeatureName,
+          result: Modernizr[feature],
+          caniuseResult: mmResult,
+          browser: ua.family,
+          version: majorminor
+        });
+
+        return; // don't check the major version
+      }
+
+      // check it against just the major version: eg. FF 3
+      if (mResult) {
+
+        // unknown support from caniuse... He would probably like to know our data, though!
+        if (mResult == 'u') {
+          return;
+        }
+
+        // data ends w/ ` x` if its still prefixed in the imp
+        mResult = mResult.replace(' x', '');
+
+        testify({
+          feature: feature,
+          ciufeature: caniuseFeatureName,
+          result: Modernizr[feature],
+          caniuseResult: mResult,
+          browser: ua.family,
+          version: ua.major
+        });
+      }
+    });
+
+  });
+};
diff --git a/js/modernizr/test/browser/integration/classes.js b/js/modernizr/test/browser/integration/classes.js
new file mode 100644 (file)
index 0000000..96a9e64
--- /dev/null
@@ -0,0 +1,44 @@
+describe('classes', function() {
+  var classes = document.documentElement.className.split(' ');
+
+  it('_version exists', function() {
+    expect(Modernizr._version).to.not.be(undefined);
+  });
+
+  it('_version did not add a class', function() {
+    expect(document.documentElement).to.not.contain('_version');
+  });
+
+  it('all classes are lower case', function() {
+    expect(document.documentElement.className).to.not.match(/[A-Z]/);
+  });
+
+  describe('everythings ship shape', function() {
+    _.chain(classes)
+      .filter()
+      .sort()
+      .forEach(function(name) {
+        var result = name.indexOf('no-') === -1;
+        name = name.replace(/no-/, '');
+        it(name + ' is correctly ' + result + ' in the classes and object', function() {
+          if (_.contains(name, '-')) {
+
+            if (name.replace('-', '') in Modernizr) {
+              name = name.replace('-', '');
+              expect(Modernizr[name]).to.be(result);
+            } else {
+              name = name.split('-');
+              expect(Modernizr[name[0]]).to.not.be(undefined);
+              expect(!!Modernizr[name[0]][name[1]]).to.equal(result);
+            }
+          } else {
+            var test = Modernizr[name];
+            var modernizrResult = test instanceof Boolean ? test.valueOf() : !!test;
+            expect(modernizrResult).to.equal(result);
+          }
+        });
+      })
+      .value();
+  });
+
+});
diff --git a/js/modernizr/test/browser/integration/global.js b/js/modernizr/test/browser/integration/global.js
new file mode 100644 (file)
index 0000000..92ba40e
--- /dev/null
@@ -0,0 +1,7 @@
+describe('basics', function() {
+
+  it('creates a global modernizr object', function() {
+    expect(Modernizr).to.not.be(undefined);
+  });
+
+});
diff --git a/js/modernizr/test/browser/integration/iframe.js b/js/modernizr/test/browser/integration/iframe.js
new file mode 100644 (file)
index 0000000..43c5ac5
--- /dev/null
@@ -0,0 +1,52 @@
+describe('iframe context', function() {
+
+  this.timeout(20000);
+  var iframeWindow;
+  var $iframe;
+
+  before(function(done) {
+    var url = './iframe.html?id=modernizrIframeContext';
+    $iframe = $('<iframe>');
+
+    $(document.body).append($iframe);
+
+    $iframe
+      .css({
+        'height':10,
+        'width':10,
+        'position':'absolute',
+        'top': 0,
+        'left': 0
+      })
+      .attr({
+        'src': url,
+        'id': 'modernizrIframeContext'
+      })
+      .on('lockedAndLoaded', function() {
+        iframeWindow = $(this)[0].contentWindow;
+        done();
+      });
+  });
+
+  it('is able to be loaded in an iframe', function(done) {
+      iframeWindow.$.getScript('../dist/modernizr-build.js')
+        .done(function(build, status) {
+          expect(status).to.equal('success');
+          expect(iframeWindow.Modernizr).to.not.be(undefined);
+          done();
+        })
+        .fail(function(ajaxResponse, errorType, err) {
+          if (err && err.message) {
+            expect(err.message).to.be(undefined);
+          } else {
+            expect(errorType).to.be(undefined);
+          }
+          done();
+        });
+    });
+
+  after(function() {
+    $iframe.remove();
+    iframeWindow = $iframe = undefined;
+  });
+});
diff --git a/js/modernizr/test/browser/integration/prefixed-atRule.js b/js/modernizr/test/browser/integration/prefixed-atRule.js
new file mode 100644 (file)
index 0000000..92f7bfb
--- /dev/null
@@ -0,0 +1,9 @@
+describe('prefixed @rule', function() {
+  it('(Almost) Everyone supports import', function() {
+    expect(['@import', undefined]).to.contain(Modernizr.prefixed('@import'));
+  });
+
+  it('Nobody supports @penguin', function() {
+    expect(!!Modernizr.prefixed('@penguin')).to.equal(false);
+  });
+});
diff --git a/js/modernizr/test/browser/integration/prefixed-autobind.js b/js/modernizr/test/browser/integration/prefixed-autobind.js
new file mode 100644 (file)
index 0000000..4e79f77
--- /dev/null
@@ -0,0 +1,89 @@
+describe('prefixed autobind', function() {
+  var rAFName;
+
+  // quick sniff to find the local rAF prefixed name.
+  var vendors = ['r', 'msR', 'mozR', 'webkitR', 'oR'];
+  _.forEach(vendors, function(vendor) {
+    rAFName = rAFName || (window[vendor + 'equestAnimationFrame'] && vendor + 'equestAnimationFrame');
+  });
+
+  if (rAFName) {
+    // rAF returns a function
+    it('Modernizr.prefixed("requestAnimationFrame", window) returns a function', function() {
+      expect(Modernizr.prefixed('requestAnimationFrame', window)).to.be.a('function');
+    });
+
+    // unless we false it to a string
+    it('Modernizr.prefixed("requestAnimationFrame", window, false) returns a string (the prop name)', function() {
+      expect(Modernizr.prefixed('requestAnimationFrame', window, false)).to.be(rAFName);
+    });
+  }
+
+  if (document.body.webkitMatchesSelector || document.body.mozMatchesSelector) {
+
+    var fn = Modernizr.prefixed('matchesSelector', HTMLElement.prototype, document.body);
+
+    //returns function
+    it('Modernizr.prefixed("matchesSelector", HTMLElement.prototype, document.body) returns a function', function() {
+      expect(fn).to.be.a('function');
+    });
+
+    // fn scoping
+    it('Modernizr.prefixed("matchesSelector", HTMLElement.prototype, document.body) is scoped to the body', function() {
+      expect(fn('body')).to.be(true);
+    });
+  }
+
+  // Webkit only: are there other objects that are prefixed?
+  if (window.webkitNotifications) {
+    // should be an object.
+    it('Modernizr.prefixed("Notifications") returns an object', function() {
+      expect(Modernizr.prefixed('Notifications', window)).to.be.an('object');
+    });
+  }
+
+  // Webkit only:
+  if (!_.isUndefined(document.webkitIsFullScreen)) {
+    // boolean
+    it('Modernizr.prefixed("isFullScreen") returns a boolean', function() {
+      expect(Modernizr.prefixed('isFullScreen', document)).to.be.a('boolean');
+    });
+  }
+
+
+
+  // Moz only:
+  if (!_.isUndefined(document.mozFullScreen)) {
+    // boolean
+
+    it('Modernizr.prefixed("isFullScreen") returns a boolean', function() {
+      expect(Modernizr.prefixed('fullScreen', document)).to.be.a('boolean');
+    });
+  }
+
+
+  // Webkit-only.. takes advantage of Webkit's mixed case of prefixes
+  if (document.body.style.WebkitAnimation) {
+    // string
+
+    it('Modernizr.prefixed("animation", document.body.style) returns value of that, as a string', function() {
+      expect(Modernizr.prefixed('animation', document.body.style)).to.be.a('string');
+    });
+
+    it('Modernizr.prefixed("animation", document.body.style, false) returns the name of the property: webkitAnimation', function() {
+      expect(Modernizr.prefixed('animation', document.body.style, false)).to.equal('webkitAnimation');
+    });
+  }
+
+  it('Modernizr.prefixed("doSomethingAmazing$#$", window) : Gobbledygook with prefixed(str,obj) returns false', function() {
+    expect(Modernizr.prefixed('doSomethingAmazing$#$', window)).to.be(false);
+  });
+
+  it('Modernizr.prefixed("doSomethingAmazing$#$", window) : Gobbledygook with prefixed(str,obj, scope) returns false', function() {
+    expect(Modernizr.prefixed('doSomethingAmazing$#$', window, document.body)).to.be(false);
+  });
+
+  it('Modernizr.prefixed("doSomethingAmazing$#$", window) : Gobbledygook with prefixed(str,obj, false) returns false', function() {
+    expect(Modernizr.prefixed('doSomethingAmazing$#$', window, false)).to.be(false);
+  });
+});
diff --git a/js/modernizr/test/browser/integration/prefixed.js b/js/modernizr/test/browser/integration/prefixed.js
new file mode 100644 (file)
index 0000000..5a96cd2
--- /dev/null
@@ -0,0 +1,70 @@
+describe('prefixed()', function() {
+
+  // Generic control function used for prefixed() and prefixedCSS() tests
+  // https://gist.github.com/523692
+  function gimmePrefix(prop, obj) {
+    var prefixes = ['Moz', 'Khtml', 'Webkit', 'O', 'ms'],
+      domPrefixes = ['moz', 'khtml', 'webkit', 'o', 'ms'],
+      elem     = document.createElement('div'),
+      upper    = prop.charAt(0).toUpperCase() + prop.slice(1),
+      len;
+
+    if (!obj) {
+      if (prop in elem.style) {
+        return prop;
+      }
+
+      for (len = prefixes.length; len--;) {
+        if ((prefixes[len] + upper)  in elem.style) {
+          return (prefixes[len] + upper);
+        }
+      }
+    } else {
+      if (prop in obj) {
+        return prop;
+      }
+
+      for (len = domPrefixes.length; len--;) {
+        if ((domPrefixes[len] + upper)  in obj) {
+          return (domPrefixes[len] + upper);
+        }
+      }
+    }
+
+    return false;
+  }
+
+  function domToCSS (name) {
+    return name.replace(/([A-Z])/g, function(str, m1) {
+      return '-' + m1.toLowerCase();
+    }).replace(/^ms-/, '-ms-');
+  }
+
+  var propArr = ['transition', 'backgroundSize', 'boxSizing', 'borderImage',
+    'borderRadius', 'boxShadow', 'columnCount'];
+
+  var domPropArr = [
+    {'prop': 'requestAnimationFrame',  'obj': window},
+    {'prop': 'querySelectorAll',       'obj': document},
+    {'prop': 'matchesSelector',        'obj': document.createElement('div')}];
+
+  _.forEach(propArr, function(prop) {
+    it('results for ' + prop + ' match the homebaked prefix finder', function() {
+      expect(Modernizr.prefixed(prop)).to.equal(gimmePrefix(prop));
+    });
+  });
+
+  _.forEach(propArr, function(prop) {
+    it('results for ' + prop + ' match the homebaked prefix finder', function() {
+      expect(Modernizr.prefixed(domToCSS(prop))).to.equal(gimmePrefix(prop));
+    });
+  });
+
+  _.forEach(domPropArr, function(prop) {
+    it('results for ' + prop.prop + ' match the homebaked prefix finder', function() {
+      var modernizrVersion = Modernizr.prefixed(prop.prop, prop.obj, false);
+      var localVersion = gimmePrefix(prop.prop, prop.obj);
+      expect(modernizrVersion).to[(_.isString(localVersion) ? 'contain' : 'equal')](localVersion);
+    });
+  });
+});
diff --git a/js/modernizr/test/browser/integration/prefixedCSS.js b/js/modernizr/test/browser/integration/prefixedCSS.js
new file mode 100644 (file)
index 0000000..0dd2c7d
--- /dev/null
@@ -0,0 +1,70 @@
+describe('prefixedCSS', function() {
+  function gimmePrefix(prop, obj) {
+    var prefixes = ['Moz', 'Khtml', 'Webkit', 'O', 'ms'],
+      domPrefixes = ['moz', 'khtml', 'webkit', 'o', 'ms'],
+      elem     = document.createElement('div'),
+      upper    = prop.charAt(0).toUpperCase() + prop.slice(1),
+      len;
+
+    if (!obj) {
+      if (prop in elem.style) {
+        return prop;
+      }
+
+      for (len = prefixes.length; len--;) {
+        if ((prefixes[len] + upper)  in elem.style) {
+          return (prefixes[len] + upper);
+        }
+      }
+    } else {
+      if (prop in obj) {
+        return prop;
+      }
+
+      for (len = domPrefixes.length; len--;) {
+        if ((domPrefixes[len] + upper)  in obj) {
+          return (domPrefixes[len] + upper);
+        }
+      }
+    }
+
+    return false;
+  }
+
+  function domToCSS (name) {
+    return name.replace(/([A-Z])/g, function(str, m1) {
+      return '-' + m1.toLowerCase();
+    }).replace(/^ms-/, '-ms-');
+  }
+
+  function cssToDOM(name) {
+    return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) {
+      return m1 + m2.toUpperCase();
+    }).replace(/^-/, '');
+  }
+
+  function testProp (prop) {
+    var prefixed = gimmePrefix(cssToDOM(prop));
+    if (prefixed) {
+      it('results for ' + prop + ' match the homebaked prefix finder', function() {
+        expect(Modernizr.prefixedCSS(prop)).to.be(domToCSS(prefixed));
+      });
+    } else {
+      it('results for ' + prop + ' match the homebaked prefix finder', function() {
+        expect(Modernizr.prefixedCSS(prop)).to.be(false);
+      });
+    }
+  }
+
+  testProp('animationProperty');
+  testProp('fontFeatureSettings');
+  testProp('flexWrap');
+  testProp('boxSizing');
+  testProp('textShadow');
+  testProp('resize');
+  testProp('animation-property');
+  testProp('font-feature-settings');
+  testProp('flex-wrap');
+  testProp('box-sizing');
+  testProp('text-shadow');
+});
diff --git a/js/modernizr/test/browser/integration/svg.js b/js/modernizr/test/browser/integration/svg.js
new file mode 100644 (file)
index 0000000..ec12ab7
--- /dev/null
@@ -0,0 +1,39 @@
+describe('svg context', function() {
+  var object;
+
+  this.timeout(20000);
+
+  if ('createElementNS' in document) {
+
+    it('is able to be loaded in a SVG file', function(done) {
+      object = document.createElement('object');
+
+      object.data = '../test/img/integration.svg';
+      object.type = 'image/svg+xml';
+      object.id = 'svgContext';
+
+      object.onerror = function() {
+        var arg = Array.prototype.slice.call(arguments).join(' ');
+        try {
+          if (arg.length) {
+            expect(arg).to.be(undefined);
+          }
+        } catch (e) {
+          done(e);
+        }
+      };
+
+      object.onsuccess = function(modernizrRef) {
+        expect(modernizrRef).to.not.be(undefined);
+        done();
+      };
+
+      document.body.appendChild(object);
+    });
+
+    afterEach(function() {
+      object.parentNode.removeChild(object);
+    });
+  }
+
+});
diff --git a/js/modernizr/test/browser/setup.js b/js/modernizr/test/browser/setup.js
new file mode 100644 (file)
index 0000000..41d63fe
--- /dev/null
@@ -0,0 +1,71 @@
+/* globals mocha, __coverage__ */
+$(document).ready(function() {
+  var runner = mocha.run();
+
+  var results = {
+    passed: 0,
+    failed: 0,
+    total: 0,
+    tests: []
+  };
+
+  runner.once('suite', function() {
+    mocha.suite.afterAll('send coverage', function(done) {
+      // ensure timeout errors block normal reporting, to ensure the entire suite is retried
+      if (!window.global_test_results) {
+        // opera 12 can't handle the defualt `window.mochaResults`, so we build
+        // generic test data instead
+        window.global_test_results = results;
+      }
+
+      if (window.__coverage__) {
+        $.ajax({
+          type: 'POST',
+          url: '/coverage/client',
+          data: JSON.stringify(__coverage__),
+          success: function() {
+            done();
+          }
+        });
+      } else {
+        done();
+      }
+    });
+  });
+
+  runner.on('fail', logFailure);
+
+  function logFailure(test, err) {
+    var isTimeout = _.contains(err.toString(), 'Ensure the done() callback is being called in this test.');
+
+    if (isTimeout) {
+      return window.global_test_results = {message: err};
+    }
+
+    if (err) {
+      results.failed += 1;
+    } else {
+      results.passed += 1;
+    }
+
+    results.total += 1;
+
+    var flattenTitles = function(test) {
+      var titles = [];
+      while (test.parent.title) {
+        titles.push(test.parent.title);
+        test = test.parent;
+      }
+      return titles.reverse();
+    };
+
+    results.tests.push({
+      name: test.title,
+      result: err ? false : true,
+      message: err ? err.message : 'passe',
+      stack: err ? err.stack : undefined,
+      titles: flattenTitles(test)
+    });
+  }
+});
+
diff --git a/js/modernizr/test/browser/src/Modernizr.js b/js/modernizr/test/browser/src/Modernizr.js
new file mode 100644 (file)
index 0000000..0ea2f13
--- /dev/null
@@ -0,0 +1,29 @@
+describe('Modernizr Base', function() {
+  var modernizrBase;
+  var cleanup;
+
+  before(function(done) {
+
+    define('package', [], function() {return {};});
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['Modernizr', 'cleanup'], function(_ModernizrBase, _cleanup) {
+      modernizrBase = _ModernizrBase;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('should return an object', function() {
+    expect(modernizrBase).to.be.an('object');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/ModernizrProto.js b/js/modernizr/test/browser/src/ModernizrProto.js
new file mode 100644 (file)
index 0000000..6e2452f
--- /dev/null
@@ -0,0 +1,80 @@
+describe('ModernizrProto', function() {
+  var ModernizrProto;
+  var cleanup;
+  var tests;
+  var req;
+
+  before(function() {
+    define('package', [], function() {return {version: 'v9999'};});
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['cleanup'], function(_cleanup) {
+      cleanup = _cleanup;
+    });
+  });
+
+  beforeEach(function(done) {
+
+    tests = [];
+    define('tests', function() {return tests;});
+
+    req(['ModernizrProto', 'tests'], function(_ModernizrProto, _tests) {
+      ModernizrProto = _ModernizrProto;
+      tests = _tests;
+      done();
+    });
+
+  });
+
+  afterEach(function() {
+    req.undef('tests');
+    req.undef('ModernizrProto');
+  });
+
+  it('should define a version', function() {
+    expect(ModernizrProto._version).to.be.a('string');
+  });
+
+  it('should set a default config', function() {
+    var config = ModernizrProto._config;
+
+    expect(config.classPrefix).to.be.a('string');
+    expect(config.enableClasses).to.be.a('boolean');
+    expect(config.enableJSClass).to.be.a('boolean');
+    expect(config.usePrefixes).to.be.a('boolean');
+  });
+
+  it('should define a working stub for `Modernizr.on`', function(done) {
+    ModernizrProto.on('fakeDetect', done);
+  });
+
+  it('should define `Modernizr.addTest` and have it pushed to the internal `tests` queue', function() {
+    var name = 'fakeDetect';
+    var fn = function fakeCallback() {};
+    var options = {opt: 'opt'};
+
+    ModernizrProto.addTest(name, fn, options);
+    expect(tests).to.have.length(1);
+    expect(tests[0].name).to.be(name);
+    expect(tests[0].fn).to.be(fn);
+    expect(tests[0].options).to.be(options);
+  });
+
+  it('should define `Modernizr.addAsyncTest` and have it pushed to the internal `tests` queue', function() {
+    var fn = function fakeCallback() {};
+
+    ModernizrProto.addAsyncTest(fn);
+    expect(tests).to.have.length(1);
+    expect(tests[0].fn).to.be(fn);
+  });
+
+  after(function() {
+    cleanup();
+  });
+
+});
diff --git a/js/modernizr/test/browser/src/addTest.js b/js/modernizr/test/browser/src/addTest.js
new file mode 100644 (file)
index 0000000..b32c67a
--- /dev/null
@@ -0,0 +1,258 @@
+describe('addTest', function() {
+  var ModernizrProto;
+  var setClasses;
+  var Modernizr;
+  var addTest;
+  var cleanup;
+  var sinon;
+  var req;
+
+  before(function(done) {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {
+        cleanup: '../test/cleanup',
+        sinon: '../test/js/lib/sinon'
+      }
+    });
+
+    req(['cleanup', 'sinon'], function(_cleanup, _sinon) {
+      cleanup = _cleanup;
+      sinon = _sinon;
+      done();
+    });
+
+  });
+
+  beforeEach(function(done) {
+
+    ModernizrProto = {};
+    Modernizr = {_q: [], _config:  {}};
+    setClasses = sinon.spy();
+
+    define('ModernizrProto', [], function() {return ModernizrProto;});
+    define('Modernizr', [], function() {return Modernizr;});
+    define('setClasses', [], function() {return setClasses;});
+    define('package', [], function() {return {};});
+
+    req(['addTest'], function(_addTest) {
+      addTest = _addTest;
+      done();
+    });
+  });
+
+  afterEach(function() {
+    req.undef('ModernizrProto');
+    req.undef('setClasses');
+    req.undef('Modernizr');
+    req.undef('package');
+    req.undef('addTest');
+  });
+
+  describe('setup', function() {
+
+    it('adds an object for test listeners', function() {
+      expect(ModernizrProto._l).to.be.an('object');
+    });
+
+    it('should define the `ModernizrProto._trigger` function', function() {
+      expect(ModernizrProto._trigger).to.be.an('function');
+    });
+
+    it('should push the Modernizr.addTest definition to the `_q`', function() {
+      expect(Modernizr._q).to.have.length(1);
+      expect(Modernizr._q[0]).to.be.a('function');
+    });
+
+    it('should define Modernizr.addTest at the end of the _q', function() {
+      Modernizr._q[0]();
+      expect(ModernizrProto.addTest).to.be(addTest);
+    });
+  });
+
+  describe('Modernizr.on', function() {
+    var fakeDetect = function() {};
+
+    it('keeps track of requests', function() {
+        ModernizrProto.on('fakeDetect', fakeDetect);
+        expect(ModernizrProto._l.fakeDetect).to.be.an('array');
+        expect(ModernizrProto._l.fakeDetect[0]).to.be(fakeDetect);
+    });
+
+    it('does not recreate the queue with duplicate requests', function() {
+        ModernizrProto.on('fakeDetect', fakeDetect);
+        ModernizrProto.on('fakeDetect', fakeDetect);
+        expect(ModernizrProto._l.fakeDetect.length).to.be(2);
+    });
+
+
+    it('triggers results if the detect already ran', function(done) {
+        Modernizr.fakeDetect = 'fake';
+        Modernizr._trigger = sinon.spy();
+        ModernizrProto.on('fakeDetect', fakeDetect);
+
+        setTimeout(function() {
+          expect(Modernizr._trigger.calledOnce).to.be(true);
+          expect(Modernizr._trigger.calledWith('fakeDetect', Modernizr.fakeDetect)).to.be(true);
+          done();
+        }, 0);
+    });
+
+  });
+
+  describe('Modernizr._trigger', function() {
+
+    it('skips the callback if it does not exist', function() {
+      expect(function() {ModernizrProto._trigger('fakeDetect');}).to.not.throwError();
+    });
+
+    it('runs the listener calledback if it does exist', function(done) {
+      var spy = sinon.spy();
+
+      ModernizrProto.on('fakeDetect', spy);
+      ModernizrProto._trigger('fakeDetect', 'fakeRes');
+
+      setTimeout(function() {
+        expect(spy.calledOnce).to.be(true);
+        done();
+      });
+    });
+
+    it('deletes the listener after it runs', function(done) {
+
+      ModernizrProto.on('fakeDetect', function() {});
+
+      expect(ModernizrProto._l.fakeDetect).to.be.an('array');
+
+      ModernizrProto._trigger('fakeDetect', 'fakeRes');
+
+      setTimeout(function() {
+        expect(ModernizrProto._l.fakeDetect).to.be(undefined);
+        done();
+      });
+    });
+  });
+
+  describe('Modernizr.addTest', function() {
+
+    beforeEach(function() {
+      Modernizr._trigger = sinon.spy();
+      Modernizr._trigger = sinon.spy();
+      expect(Modernizr.fakedetect).to.be(undefined);
+      expect(Modernizr.fake).to.be(undefined);
+      expect(Modernizr.detect).to.be(undefined);
+    });
+
+    it('sets the proper bool on the Modernizr object with a function', function() {
+      addTest('fakedetect', function() {return true;});
+      expect(Modernizr.fakedetect).to.be(true);
+    });
+
+    it('sets the proper bool on the Modernizr object with a bool', function() {
+      addTest('fakedetect', false);
+      expect(Modernizr.fakedetect).to.be(false);
+    });
+
+    it('does not cast to a bool on the Modernizr object with a truthy value', function() {
+      addTest('fakedetect', function() {return 100;});
+      expect(Modernizr.fakedetect).to.be(100);
+    });
+
+    it('sets a true class for a true value', function() {
+      addTest('fakedetect', function() {return 100;});
+      expect(setClasses.callCount).to.be(1);
+      expect(setClasses.calledWith(['fakedetect'])).to.be(true);
+    });
+
+    it('sets a truthy class for a truthy value', function() {
+      addTest('fakedetect', function() {return 100;});
+      expect(setClasses.callCount).to.be(1);
+      expect(setClasses.calledWith(['fakedetect'])).to.be(true);
+    });
+
+    it('sets a negative class for a false value', function() {
+      addTest('fakedetect', function() {return false;});
+      expect(setClasses.callCount).to.be(1);
+      expect(setClasses.calledWith(['no-fakedetect'])).to.be(true);
+    });
+
+    it('sets a negative class for a falsey value', function() {
+      addTest('fakedetect', function() {return undefined;});
+      expect(setClasses.callCount).to.be(1);
+      expect(setClasses.calledWith(['no-fakedetect'])).to.be(true);
+    });
+
+    it('does not cast to a bool on the Modernizr object with a falsy value', function() {
+      addTest('fakedetect', function() {return undefined;});
+      expect('fakedetect' in Modernizr).to.be(true);
+      expect(Modernizr.fakedetect).to.be(undefined);
+    });
+
+    it('forces detect names are lowercase', function() {
+      addTest('FaKeDeTeCt', true);
+      expect(Modernizr.fakedetect).to.be(true);
+    });
+
+    it('supports nested properties with a bool base', function() {
+      /* jshint -W053 */
+      addTest('fake', new Boolean(true));
+      /* jshint +W053 */
+      addTest('fake.detect', true);
+      expect(Modernizr.fake).to.be.an('object');
+      expect(Modernizr.fake.detect).to.be(true);
+    });
+
+    it('supports nested properties', function() {
+      addTest('fake', true);
+      addTest('fake.detect', true);
+      expect(Modernizr.fake).to.be.an('object');
+      expect(Modernizr.fake.detect).to.be(true);
+    });
+
+    it('does not overwrite values once they are set', function() {
+      addTest('fakeDetect', false);
+      expect(Modernizr.fakedetect).to.be(false);
+      expect(Modernizr._trigger.calledOnce).to.be(true);
+
+      addTest('fakeDetect', true);
+      expect(Modernizr.fakedetect).to.be(false);
+      expect(Modernizr._trigger.calledOnce).to.be(true);
+    });
+
+    it('allows feature to be an object of features', function() {
+      addTest({fake: true, detect: false});
+      expect(Modernizr.fake).to.be(true);
+      expect(Modernizr.detect).to.be(false);
+      expect(setClasses.callCount).to.be(2);
+      expect(setClasses.calledWith(['fake'])).to.be(true);
+      expect(setClasses.calledWith(['no-detect'])).to.be(true);
+    });
+
+    it('properly filters out monkey patched object properties', function() {
+      var noop = function() {};
+      Object.prototype.MOD_FAKE_VALUE = noop;
+      var config = {detect: false};
+
+      expect(config.MOD_FAKE_VALUE).to.be(noop);
+      addTest(config);
+
+      delete Object.prototype.MOD_FAKE_VALUE;
+
+      expect(Modernizr.MOD_FAKE_VALUE).to.be(undefined);
+      expect(Modernizr.mod_fake_value).to.be(undefined);
+      expect(Modernizr.detect).to.be(false);
+      expect(setClasses.callCount).to.be(1);
+    });
+
+    it('returns an instance of Modernizr for chaining', function() {
+      expect(addTest('fakeDetect', true)).to.be(Modernizr);
+    });
+
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/atRule.js b/js/modernizr/test/browser/src/atRule.js
new file mode 100644 (file)
index 0000000..392b1eb
--- /dev/null
@@ -0,0 +1,62 @@
+describe('atRule', function() {
+  var atRule;
+  var cleanup;
+
+  before(function(done) {
+
+    if (window.CSSRule) {
+      window.CSSRule.MODERNIZR_FAKE_RULE = 999;
+    }
+
+    var prefixes = ['Modernizr'];
+
+    define('cssomPrefixes', [], function() {return prefixes;});
+    define('package', [], function() {return {};});
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['atRule', 'cleanup'], function(_atRule, _cleanup) {
+      atRule = _atRule;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+    it('returns undefined when the browser does not support CSSRule', function() {
+      var ref = window.CSSRule;
+      window.CSSRule = undefined;
+
+      expect(atRule('charset')).to.be(undefined);
+
+      window.CSSRule = ref;
+    });
+
+    if (window.CSSRule) {
+      it('detects `@rule`s', function() {
+        expect(atRule('charset')).to.be('@charset');
+      });
+
+      it('returns false when a property is not given', function() {
+        expect(atRule()).to.be(false);
+      });
+
+      it('returns false when a property is not found', function() {
+        expect(atRule('fart')).to.be(false);
+      });
+
+      it('detects prefixed properties', function() {
+        expect(atRule('fake')).to.be('@-modernizr-fake');
+      });
+    }
+
+  after(function() {
+    if (window.CSSRule) {
+      delete window.CSSRule.MODERNIZR_FAKE_RULE;
+    }
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/classes.js b/js/modernizr/test/browser/src/classes.js
new file mode 100644 (file)
index 0000000..3904a7e
--- /dev/null
@@ -0,0 +1,28 @@
+describe('classes', function() {
+  var classes;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['classes', 'cleanup'], function(_classes, _cleanup) {
+      classes = _classes;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+
+  it('is an array', function() {
+    expect(classes).to.be.an('array');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/contains.js b/js/modernizr/test/browser/src/contains.js
new file mode 100644 (file)
index 0000000..be6867f
--- /dev/null
@@ -0,0 +1,27 @@
+describe('contains', function() {
+  var contains;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['contains', 'cleanup'], function(_contains, _cleanup) {
+      contains = _contains;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('finds substrings', function() {
+    expect(contains('fakeDetect', 'akeDet')).to.be(true);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/createElement.js b/js/modernizr/test/browser/src/createElement.js
new file mode 100644 (file)
index 0000000..9817a1f
--- /dev/null
@@ -0,0 +1,33 @@
+describe('createElement', function() {
+  var createElement;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['createElement', 'cleanup'], function(_createElement, _cleanup) {
+      createElement = _createElement;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+
+  it('is a function', function() {
+    expect(createElement).to.be.a('function');
+  });
+
+  it('creates an element', function() {
+    var element = createElement('modernizr');
+    expect(element.nodeName.toUpperCase()).to.be('MODERNIZR');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/cssToDOM.js b/js/modernizr/test/browser/src/cssToDOM.js
new file mode 100644 (file)
index 0000000..15eb74e
--- /dev/null
@@ -0,0 +1,27 @@
+describe('cssToDOM', function() {
+  var cssToDOM;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['cssToDOM', 'cleanup'], function(_cssToDOM, _cleanup) {
+      cssToDOM = _cssToDOM;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('converts kebab to camel', function() {
+    expect(cssToDOM('fake-detect')).to.equal('fakeDetect');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/cssomPrefixes.js b/js/modernizr/test/browser/src/cssomPrefixes.js
new file mode 100644 (file)
index 0000000..d6fced9
--- /dev/null
@@ -0,0 +1,71 @@
+describe('cssomPrefixes', function() {
+  var setup = function(done, bool) {
+    return (function() {
+      define('ModernizrProto', [], function() {return {_config: {usePrefixes: bool}};});
+
+      req(['cssomPrefixes'], function(_cssomPrefixes) {
+        cssomPrefixes = _cssomPrefixes;
+        done();
+      });
+    })();
+  };
+
+  var teardown = function() {
+    cssomPrefixes = undefined;
+    req.undef('cssomPrefixes');
+    req.undef('ModernizrProto');
+  };
+
+  var cssomPrefixes;
+  var cleanup;
+  var req;
+
+  before(function(done) {
+    define('package', [], function() {return {version: 'v9999'};});
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['cleanup'], function(_cleanup) {
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  describe('prefixes enabled', function() {
+    before(function(done) {
+      setup(done, true);
+    });
+
+    after(teardown);
+
+    it('returns prefixes', function(done) {
+      req(['cssomPrefixes'], function(cssomPrefixes) {
+        expect(cssomPrefixes).to.not.have.length(0);
+        done();
+      });
+    });
+  });
+
+  describe('prefixes disabled', function() {
+    before(function(done) {
+      setup(done, false);
+    });
+
+    after(teardown);
+
+    it('returns no prefixes', function(done) {
+      req(['cssomPrefixes'], function(cssomPrefixes) {
+        expect(cssomPrefixes).to.have.length(0);
+        done();
+      });
+    });
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/docElement.js b/js/modernizr/test/browser/src/docElement.js
new file mode 100644 (file)
index 0000000..a88158a
--- /dev/null
@@ -0,0 +1,31 @@
+describe('docElement', function() {
+  var docElement;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['docElement', 'cleanup'], function(_docElement, _cleanup) {
+      docElement = _docElement;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('is an alias to document.documentElement', function() {
+    expect(docElement).to.equal(document.documentElement);
+  });
+
+  it('is valid and correct', function() {
+    expect(docElement).to.equal(document.getElementsByTagName('html')[0]);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/domPrefixes.js b/js/modernizr/test/browser/src/domPrefixes.js
new file mode 100644 (file)
index 0000000..c11b307
--- /dev/null
@@ -0,0 +1,71 @@
+describe('domPrefixes', function() {
+  var req;
+
+  var setup = function(done, bool) {
+    return (function() {
+      define('ModernizrProto', [], function() {return {_config: {usePrefixes: bool}};});
+
+      req(['domPrefixes'], function(_domPrefixes) {
+        domPrefixes = _domPrefixes;
+        done();
+      });
+    })();
+  };
+
+  var teardown = function() {
+    domPrefixes = undefined;
+    req.undef('domPrefixes');
+    req.undef('ModernizrProto');
+  };
+  var domPrefixes;
+  var cleanup;
+
+  before(function(done) {
+    define('package', [], function() {return {version: 'v9999'};});
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['cleanup'], function(_cleanup) {
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  describe('prefixes enabled', function() {
+    before(function(done) {
+      setup(done, true);
+    });
+
+    after(teardown);
+
+    it('returns prefixes', function(done) {
+      req(['domPrefixes'], function(domPrefixes) {
+        expect(domPrefixes).to.not.have.length(0);
+        done();
+      });
+    });
+  });
+
+  describe('prefixes disabled', function() {
+    before(function(done) {
+      setup(done, false);
+    });
+
+    after(teardown);
+
+    it('returns no prefixes', function(done) {
+      req(['domPrefixes'], function(domPrefixes) {
+        expect(domPrefixes).to.have.length(0);
+        done();
+      });
+    });
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/domToCSS.js b/js/modernizr/test/browser/src/domToCSS.js
new file mode 100644 (file)
index 0000000..9444fbb
--- /dev/null
@@ -0,0 +1,27 @@
+describe('domToCSS', function() {
+  var domToCSS;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['domToCSS', 'cleanup'], function(_domToCSS, _cleanup) {
+      domToCSS = _domToCSS;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('converts kebab to camel', function() {
+    expect(domToCSS('fakeDetect')).to.equal('fake-detect');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/fnBind.js b/js/modernizr/test/browser/src/fnBind.js
new file mode 100644 (file)
index 0000000..cfe2eb5
--- /dev/null
@@ -0,0 +1,32 @@
+describe('fnBind', function() {
+  var fnBind;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['fnBind', 'cleanup'], function(_fnBind, _cleanup) {
+      fnBind = _fnBind;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('binds to `this`', function() {
+    var foo = {x: 1};
+    var bar = function() {
+      return this.x;
+    };
+
+    expect(fnBind(bar, foo)()).to.equal(1);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/generate.js b/js/modernizr/test/browser/src/generate.js
new file mode 100644 (file)
index 0000000..1c28534
--- /dev/null
@@ -0,0 +1,99 @@
+describe('generate', function() {
+  var generate;
+  var cleanup;
+
+  before(function(done) {
+
+    define('package', [], function() {return {};});
+    define('Modernizr', [], function() {return {};});
+    define('testRunner', [], function() {return {};});
+    define('lodash', [], function() {return window._;});
+    define('ModernizrProto', [], function() {return {};});
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['generate', 'cleanup'], function(_generate, _cleanup) {
+      generate = _generate;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('is a function', function() {
+    expect(generate).to.be.a('function');
+  });
+
+  it('does not blow up when no config is given', function() {
+    expect(function() {generate();}).to.not.throwError();
+  });
+
+  it('defines `feature-detects` if it is not on the config already', function() {
+    var config = {};
+    generate(config);
+    expect(config['feature-detects']).to.not.be(undefined);
+  });
+
+  it('does not overwrite `feature-detects` if it is defined already', function() {
+    var config = {'feature-detects': ['fake']};
+    generate(config);
+    expect(config['feature-detects'][0]).to.be('fake');
+  });
+
+  describe('outputs feature detects when they are requested', function() {
+
+    it('with amd prefix', function() {
+      var config = {'feature-detects': ['test/fake']};
+      var output = generate(config);
+      expect(output).to.contain('test/fake');
+    });
+
+    it('without amd prefix', function() {
+      var config = {'feature-detects': ['fake']};
+      var output = generate(config);
+      expect(output).to.contain('test/fake');
+    });
+  });
+
+  it('adds `setClasses` and `classes` when defined', function() {
+    var config = {'options': ['setClasses']};
+    var output = generate(config);
+    expect(output).to.contain('setClasses", "classes');
+  });
+
+  it('adds options when defined', function() {
+    var config = {'options': ['fakeOption']};
+    var output = generate(config);
+    expect(output).to.contain('fakeOption');
+  });
+
+  it('only adds one of the shivs if both are defined', function() {
+    var config = {'options': ['html5shiv', 'html5printshiv']};
+    var output = generate(config);
+    expect(output).to.contain('html5printshiv');
+    expect(output).to.not.contain('html5shiv');
+  });
+
+  it('outputs a valid function', function() {
+    var output = generate({});
+    var stashedRequire = window.require;
+    window.require = function() {};
+    expect(function() {eval(output);}).to.not.throwError();
+    window.require = stashedRequire;
+  });
+
+  it('outputs a valid function when minified', function() {
+    var output = generate({minify: true});
+    var stashedRequire = window.require;
+    window.require = function() {};
+    expect(function() {eval(output);}).to.not.throwError();
+    window.require = stashedRequire;
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/getBody.js b/js/modernizr/test/browser/src/getBody.js
new file mode 100644 (file)
index 0000000..ce2e17c
--- /dev/null
@@ -0,0 +1,40 @@
+describe('getBody', function() {
+  var getBody;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['getBody', 'cleanup'], function(_getBody, _cleanup) {
+      getBody = _getBody;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('returns document.body', function() {
+    var body = getBody();
+    expect(body).to.equal(document.body);
+    expect(body.fake).to.be(undefined);
+  });
+
+  it('returns a fake when document.body does not exist', function() {
+    var originalBody = document.body;
+    var parentNode = originalBody.parentNode;
+    parentNode.removeChild(originalBody);
+    var body = getBody();
+    parentNode.appendChild(originalBody);
+
+    expect(body).to.not.equal(document.body);
+    expect(body.fake).to.be(true);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/hasEvent.js b/js/modernizr/test/browser/src/hasEvent.js
new file mode 100644 (file)
index 0000000..1966c31
--- /dev/null
@@ -0,0 +1,106 @@
+describe('hasEvent', function() {
+  var hasEvent;
+  var cleanup;
+  var req;
+
+  before(function(done) {
+
+    define('package', [], function() {return {};});
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['hasEvent', 'cleanup'], function(_hasEvent, _cleanup) {
+      hasEvent = _hasEvent;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('allows you to pass an element to test against', function() {
+    expect(hasEvent('click'), document.createElement('a')).to.be(true);
+  });
+
+  it('allows you to pass an string name for an element to test against', function() {
+    expect(hasEvent('click', 'a')).to.be(true);
+  });
+
+  it('allows you to pass something other then a DOM element or string', function() {
+    expect(hasEvent('click', document)).to.be(true);
+  });
+
+
+  it('returns false when no event name is provided', function() {
+    expect(hasEvent()).to.be(false);
+  });
+
+
+  it('returns true when the event exists', function() {
+    expect(hasEvent('click')).to.be(true);
+  });
+
+  it('returns false when the event does not exists', function() {
+    expect(hasEvent('fart')).to.be(false);
+  });
+
+  describe('fallback', function() {
+    var onblur = document.documentElement.onblur;
+    var called;
+
+    before(function(done) {
+      try {
+        // IE 7 fails if we try to delete properties that don't exist
+        delete document.documentElement.onblur;
+      } catch (e) {}
+
+      req.undef('hasEvent');
+      req.undef('createElement');
+
+      define('createElement', [], function() {
+        return function() {
+
+          var elm = typeof document.createElement !== 'function' ?
+            document.createElement(arguments[0]) :
+            document.createElement.apply(document, arguments);
+
+          // logic added to get simulate old firefox's behavior
+          if (!called) {
+            try {
+              delete elm.onclick;
+            } catch (e) {}
+
+            elm.setAttribute = undefined;
+            called = true;
+          }
+          return elm;
+        };
+      });
+
+      req(['hasEvent'], function(_hasEvent) {
+        hasEvent = _hasEvent;
+        done();
+      });
+
+    });
+
+    it('fallsback properly with no element', function() {
+      expect(hasEvent('click')).to.be(true);
+    });
+
+    it('fallsback properly when testing with a global element', function() {
+      expect(hasEvent('click', document)).to.be(true);
+    });
+
+    after(function() {
+      document.documentElement.onblur = onblur;
+    });
+
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/hasOwnProp.js b/js/modernizr/test/browser/src/hasOwnProp.js
new file mode 100644 (file)
index 0000000..5fe4b8c
--- /dev/null
@@ -0,0 +1,33 @@
+describe('hasOwnProp', function() {
+  var hasOwnProp;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['hasOwnProp', 'cleanup'], function(_hasOwnProp, _cleanup) {
+      hasOwnProp = _hasOwnProp;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('is a function', function() {
+    expect(hasOwnProp).to.be.an('function');
+  });
+
+  it('works', function() {
+    var obj = {};
+    obj.prop = true;
+    expect(hasOwnProp(obj, 'prop')).to.be(true);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/html5printshiv.js b/js/modernizr/test/browser/src/html5printshiv.js
new file mode 100644 (file)
index 0000000..3b104b4
--- /dev/null
@@ -0,0 +1,50 @@
+describe('html5printshiv', function() {
+  this.timeout(10000);
+  var iframeWindow;
+  var $iframe;
+
+  before(function(done) {
+    var url = './iframe.html?id=printshiv';
+    $iframe = $('<iframe>');
+
+    $(document.body).append($iframe);
+
+    $iframe
+      .css({
+        'height':10,
+        'width':10,
+        'position':'absolute',
+        'top': 0,
+        'left': 0
+      })
+      .attr({
+        'src': url,
+        'id': 'printshiv'
+      })
+      .on('lockedAndLoaded', function() {
+        iframeWindow = $(this)[0].contentWindow;
+        iframeWindow.requirejs.config({
+          baseUrl: '../src'
+        });
+        done();
+      });
+
+  });
+
+  it('shivs the document', function(done) {
+    try {
+      iframeWindow.requirejs(['html5printshiv'], function() {
+        expect('html5' in iframeWindow).to.be(true);
+        expect(iframeWindow.html5.type).to.equal('default print');
+        done();
+      });
+    } catch (e) {
+      done(e);
+    }
+  });
+
+  after(function() {
+    $iframe.remove();
+    iframeWindow = $iframe = undefined;
+  });
+});
diff --git a/js/modernizr/test/browser/src/html5shiv.js b/js/modernizr/test/browser/src/html5shiv.js
new file mode 100644 (file)
index 0000000..def8978
--- /dev/null
@@ -0,0 +1,52 @@
+describe('html5shiv', function() {
+  this.timeout(30000);
+  var iframeWindow;
+  var $iframe;
+
+  before(function(done) {
+    var url = './iframe.html?id=shiv';
+    $iframe = $('<iframe>');
+
+    $(document.body).append($iframe);
+
+    $iframe
+      .css({
+        'height':10,
+        'width':10,
+        'position':'absolute',
+        'top': 0,
+        'left': 0
+      })
+      .attr({
+        'src': url,
+        'id': 'shiv'
+      })
+      .on('lockedAndLoaded', function() {
+        iframeWindow = $(this)[0].contentWindow;
+        iframeWindow.requirejs.config({
+          baseUrl: '../src'
+        });
+        done();
+      });
+
+  });
+
+  it('shivs the document', function(done) {
+    try {
+      iframeWindow.requirejs(['html5shiv'], function() {
+        expect('html5' in iframeWindow).to.be(true);
+        expect(iframeWindow.html5.type).to.equal('default');
+        done();
+      });
+    }
+    catch (e) {
+      done(e);
+    }
+  });
+
+  after(function() {
+    $iframe.remove();
+    iframeWindow = $iframe = undefined;
+  });
+
+});
diff --git a/js/modernizr/test/browser/src/injectElementWithStyles.js b/js/modernizr/test/browser/src/injectElementWithStyles.js
new file mode 100644 (file)
index 0000000..3be3c67
--- /dev/null
@@ -0,0 +1,133 @@
+describe('injectElementWithStyles', function() {
+  var injectElementWithStyles;
+  var originalBody;
+  var parentNode;
+  var cleanup;
+  var sinon;
+
+  before(function(done) {
+
+    define('package', [], function() {return {};});
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {
+        cleanup: '../test/cleanup',
+        sinon: '../test/js/lib/sinon'
+      }
+    });
+
+    req(['injectElementWithStyles', 'sinon', 'cleanup'], function(_injectElementWithStyles, _sinon, _cleanup) {
+      injectElementWithStyles = _injectElementWithStyles;
+      sinon = _sinon;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('is a function', function() {
+    expect(injectElementWithStyles).to.be.a('function');
+  });
+
+  it('styles an injected element', function() {
+    var callback = function() {
+      var modernizr = document.getElementById('modernizr');
+      return modernizr.clientWidth === 10;
+    };
+
+    var result = injectElementWithStyles('#modernizr{width: 10px}', callback);
+    expect(result).to.be(true);
+  });
+
+  it('passes back a rule matching what we gave it', function(done) {
+    var style = '#modernizr{width: 10px}';
+    var callback = function(elm, rule) {
+      expect(rule).to.be(style);
+      done();
+    };
+
+    injectElementWithStyles(style, callback);
+  });
+
+  it('passes the #modernizr element in the callback', function(done) {
+    var style = '#modernizr{width: 10px}';
+    var callback = function(elm) {
+      expect(elm.id).to.be('modernizr');
+      done();
+    };
+
+    injectElementWithStyles(style, callback);
+  });
+
+  it('deletes an element after the test', function() {
+    expect(document.getElementById('modernizr')).to.be(null);
+
+    var callback = function() {
+      expect(document.getElementById('modernizr')).to.not.be(null);
+    };
+
+    injectElementWithStyles('', callback);
+
+    expect(document.getElementById('modernizr')).to.be(null);
+  });
+
+  it('creates multiple nodes when requested', function(done) {
+
+    var callback = function(elm) {
+      expect(elm.childNodes.length).to.be(9);
+      done();
+    };
+
+    injectElementWithStyles('', callback, 8);
+  });
+
+  it('names multiple nodes based on `testname` when configured', function(done) {
+
+    var callback = function() {
+      var test = document.getElementById('test');
+      var element = document.getElementById('element');
+
+      expect(test).to.not.be(null);
+      expect(element).to.not.be(null);
+      done();
+    };
+
+    injectElementWithStyles('', callback, 2, ['test', 'element']);
+  });
+
+
+  it('copes with a fake body', function(done) {
+
+    originalBody = document.body;
+    parentNode = originalBody.parentNode;
+
+    var callback = function() {
+      var body = document.body;
+
+      expect(body.fake).to.be(true);
+
+      // injectElementWithStyles overrides the background value for fake body to
+      // an empty string, however old IE changes this to the following string.
+      if (body.style.background != 'none transparent scroll repeat 0% 0%') {
+        expect(body.style.background.length).to.be(0);
+      }
+
+      expect(body.style.overflow).to.be('hidden');
+      done();
+    };
+
+    expect(document.body.fake).to.not.be(true);
+    parentNode.removeChild(originalBody);
+    injectElementWithStyles('', callback);
+
+  });
+
+  after(function() {
+    if (!$.contains(parentNode, originalBody)) {
+      parentNode.appendChild(originalBody);
+    }
+    expect(document.body.fake).to.not.be(true);
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/inputElem.js b/js/modernizr/test/browser/src/inputElem.js
new file mode 100644 (file)
index 0000000..c412868
--- /dev/null
@@ -0,0 +1,27 @@
+describe('inputElem', function() {
+  var inputElem;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['inputElem', 'cleanup'], function(_inputElem, _cleanup) {
+      inputElem = _inputElem;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('returns an input element', function() {
+    expect(inputElem.nodeName).to.equal('INPUT');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/is.js b/js/modernizr/test/browser/src/is.js
new file mode 100644 (file)
index 0000000..9db0b0f
--- /dev/null
@@ -0,0 +1,42 @@
+describe('is', function() {
+  var cleanup;
+  var is;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['is', 'cleanup'], function(_is, _cleanup) {
+      is = _is;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+
+  it('is a function', function() {
+    expect(is).to.be.a('function');
+  });
+
+  it('recognizes all types', function() {
+    var _undefined = is(undefined, 'undefined');
+    var _func = is(function() {}, 'function');
+    var _bool = is(true, 'boolean');
+    var _null = is(null, 'object');
+    var _str = is('1', 'string');
+
+    expect(_undefined).to.be(true);
+    expect(_func).to.be(true);
+    expect(_bool).to.be(true);
+    expect(_null).to.be(true);
+    expect(_str).to.be(true);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/load.js b/js/modernizr/test/browser/src/load.js
new file mode 100644 (file)
index 0000000..70862c1
--- /dev/null
@@ -0,0 +1,136 @@
+describe('load', function() {
+  var ModernizrProto;
+  var cleanup;
+  var sinon;
+  var load;
+
+
+  before(function(done) {
+
+    define('ModernizrProto', [], function() {return {};});
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {
+        sinon: '../test/js/lib/sinon',
+        cleanup: '../test/cleanup'
+      }
+    });
+
+    req(['ModernizrProto', 'sinon', 'load', 'cleanup'], function(_ModernizrProto, _sinon, _load, _cleanup) {
+      ModernizrProto = _ModernizrProto;
+      cleanup = _cleanup;
+      sinon = _sinon;
+      load = _load;
+      done();
+    });
+  });
+
+  it('creates a reference on `ModernizrProto`', function() {
+    expect(ModernizrProto.load).to.be.a('function');
+  });
+
+
+  if (window.console && console.error) {
+    describe('errors', function() {
+
+      it('reports that `load` has been removed', function() {
+        var err = console.error;
+        console.error = sinon.spy();
+        ModernizrProto.load();
+        expect(console.error.calledOnce).to.be(true);
+        console.error = err;
+      });
+
+      it('fallsback to log when `console.error` is not defined', function() {
+        var err;
+        var log;
+        err = console.error;
+        log = console.log;
+        console.error = undefined;
+        console.log = sinon.spy();
+
+        ModernizrProto.load();
+
+        expect(console.log.calledOnce).to.be(true);
+
+        console.log = log;
+        console.error = err;
+      });
+
+    });
+  }
+
+  if (window.console && console.log) {
+
+    describe('warnings', function() {
+      var yepnope;
+
+      beforeEach(function() {
+        yepnope = sinon.spy();
+        window.yepnope = yepnope;
+      });
+
+      it('reports that `load` has been removed, but still calls if yepnope is on the page', function() {
+        var warn = console.warn;
+        console.warn = sinon.spy();
+        ModernizrProto.load();
+        expect(console.warn.calledOnce).to.be(true);
+        expect(yepnope.calledOnce).to.be(true);
+        console.warn = warn;
+      });
+
+      it('fallsback to log when `console.warn` is not defined', function() {
+        var warn;
+        var log;
+        warn = console.warn;
+        log = console.log;
+        console.warn = undefined;
+        console.log = sinon.spy();
+
+        ModernizrProto.load();
+
+        expect(console.log.calledOnce).to.be(true);
+        expect(yepnope.calledOnce).to.be(true);
+
+        console.log = log;
+        console.warn = warn;
+      });
+
+      afterEach(function() {
+        yepnope = undefined;
+        // ie <= 8 doesn't support deleting window properties,
+        //  so we fallback to setting it to undefiend
+        try {
+          delete window.yepnope;
+        } catch (e) {
+          window.yepnope = undefined;
+        }
+      });
+
+    });
+
+  }
+
+  if (!window.console) {
+    describe('browsers without a console', function() {
+
+      it('doesn\'t blow up when calling console.error', function() {
+        expect(ModernizrProto.load).to.not.throwError();
+      });
+
+      it('doesn\'t blow up when calling console.warn', function() {
+        var yepnope = sinon.spy();
+        window.yepnope = yepnope;
+        expect(ModernizrProto.load).to.not.throwError();
+        expect(yepnope.calledOnce).to.be(true);
+      });
+
+    });
+  }
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/mStyle.js b/js/modernizr/test/browser/src/mStyle.js
new file mode 100644 (file)
index 0000000..6efece7
--- /dev/null
@@ -0,0 +1,57 @@
+describe('mStyle', function() {
+  var Modernizr;
+  var mStyle;
+  var cleanup;
+  var req;
+
+  before(function() {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+  });
+
+  beforeEach(function(done) {
+    Modernizr = {_q: []};
+    define('Modernizr', [], function() {return Modernizr;});
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['mStyle', 'cleanup'], function(_mStyle, _cleanup) {
+      mStyle = _mStyle;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('returns an object with a style prop', function() {
+    expect(mStyle).to.be.an('object');
+    expect(mStyle.style).to.not.be(undefined);
+  });
+
+  it('pushes a function onto the Modernizr._q', function() {
+    expect(Modernizr._q[0]).to.be.a('function');
+  });
+
+  it('deletes mStyle.style after the `_q` runs', function() {
+    expect(mStyle.style).to.not.be(undefined);
+    Modernizr._q[0]();
+    expect(mStyle.style).to.be(undefined);
+  });
+
+  afterEach(function() {
+    req.undef('Modernizr');
+    req.undef('mStyle');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/modElem.js b/js/modernizr/test/browser/src/modElem.js
new file mode 100644 (file)
index 0000000..cf17f62
--- /dev/null
@@ -0,0 +1,48 @@
+describe('modElem', function() {
+  var Modernizr;
+  var modElem;
+  var cleanup;
+  var req;
+
+  beforeEach(function(done) {
+    Modernizr = {_q: []};
+    define('Modernizr', [], function() {return Modernizr;});
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['modElem', 'cleanup'], function(_modElem, _cleanup) {
+      modElem = _modElem;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('returns an object with an `elem` prop', function() {
+    expect(modElem).to.be.an('object');
+    expect(modElem.elem).to.not.be(undefined);
+    expect(modElem.elem.nodeName.toUpperCase()).to.be('MODERNIZR');
+  });
+
+  it('pushes a function onto the Modernizr._q', function() {
+    expect(Modernizr._q[0]).to.be.a('function');
+  });
+
+  it('deletes modElem.style after the `_q` runs', function() {
+    expect(modElem.elem).to.not.be(undefined);
+    Modernizr._q[0]();
+    expect(modElem.elem).to.be(undefined);
+  });
+
+  afterEach(function() {
+    req.undef('Modernizr');
+    req.undef('modElem');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/mq.js b/js/modernizr/test/browser/src/mq.js
new file mode 100644 (file)
index 0000000..cf1a4f0
--- /dev/null
@@ -0,0 +1,107 @@
+describe('mq', function() {
+  var injectElementWithStyles;
+  var mq;
+  var cleanup;
+  var sinon;
+  var req;
+
+  var media = window.matchMedia || (function() {
+    // adapted from jQuery Mobile
+    // http://git.io/NFWo
+
+    var bool;
+    var docElem = document.documentElement;
+    var refNode = docElem.firstElementChild || docElem.firstChild;
+    // fakeBody required for <FF4 when executed in <head>
+    var fakeBody = document.createElement('body');
+    var div = document.createElement('div');
+
+    div.id = 'mq-test-1';
+    div.style.cssText = 'position:absolute;top:-100em';
+    fakeBody.style.background = 'none';
+    fakeBody.appendChild(div);
+
+    return function(q) {
+
+      div.innerHTML = '&shy;<style media="' + q + '"> #mq-test-1 { width: 42px; }</style>';
+
+      docElem.insertBefore(fakeBody, refNode);
+      bool = div.offsetWidth === 42;
+      docElem.removeChild(fakeBody);
+
+      return {
+        matches: bool,
+        media: q
+      };
+    };
+  })();
+
+  before(function(done) {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {
+        sinon: '../test/js/lib/sinon',
+        cleanup: '../test/cleanup'
+      }
+    });
+
+    req(['injectElementWithStyles', 'cleanup', 'sinon'], function(_injectElementWithStyles, _cleanup, _sinon) {
+      injectElementWithStyles = _injectElementWithStyles;
+      cleanup = _cleanup;
+      sinon = _sinon;
+      done();
+    });
+
+  });
+
+  if (window.matchMedia || window.msMatchMedia) {
+    describe('matchMedia version', function() {
+      before(function(done) {
+        req(['mq'], function(_mq) {
+          mq = _mq;
+          done();
+        });
+      });
+
+      it('works', function() {
+        expect(mq('only screen')).to.equal(media('only screen').matches);
+        expect(mq('only fake rule')).to.equal(media('only fake rule').matches);
+      });
+    });
+  } else {
+    describe('fallback version', function() {
+
+      before(function(done) {
+        injectElementWithStyles = sinon.spy(injectElementWithStyles);
+        req.undef('injectElementWithStyles');
+        req.undef('mq');
+
+        define('injectElementWithStyles', [], function() {return injectElementWithStyles;});
+
+        req(['mq'], function(_mq) {
+          mq = _mq;
+          done();
+        });
+      });
+
+      it('works', function() {
+
+        expect(mq('only screen')).to.equal(media('only screen').matches);
+        expect(mq('only fake rule')).to.equal(media('only fake rule').matches);
+        expect(injectElementWithStyles.called).to.be(true);
+      });
+
+    });
+
+  }
+
+  afterEach(function() {
+    req.undef('mq');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/nativeTestProps.js b/js/modernizr/test/browser/src/nativeTestProps.js
new file mode 100644 (file)
index 0000000..1770e07
--- /dev/null
@@ -0,0 +1,44 @@
+describe('nativeTestProps', function() {
+  var nativeTestProps;
+  var cleanup;
+
+  before(function(done) {
+
+    define('package', [], function() {return {};});
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['nativeTestProps', 'cleanup'], function(_nativeTestProps, _cleanup) {
+      nativeTestProps = _nativeTestProps;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('is a function', function() {
+    expect(nativeTestProps).to.be.a('function');
+  });
+
+  if (window.CSS && window.CSS.supports) {
+    it('looks up if the value is supported', function() {
+      expect(nativeTestProps(['display'], 'block')).to.be(true);
+      expect(nativeTestProps(['display'], 'fart')).to.be(false);
+    });
+  } else if ('CSSSupportsRule' in window) {
+    it('supports the old version of the lookup', function() {
+      expect(nativeTestProps(['display'], 'block')).to.be(true);
+    });
+  } else {
+    it('returns undefined for browsers lacking support', function() {
+      expect(nativeTestProps(['display'], 'block')).to.be(undefined);
+    });
+  }
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/omPrefixes.js b/js/modernizr/test/browser/src/omPrefixes.js
new file mode 100644 (file)
index 0000000..95fad0d
--- /dev/null
@@ -0,0 +1,28 @@
+describe('omPrefixes', function() {
+  var omPrefixes;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['omPrefixes', 'cleanup'], function(_omPrefixes, _cleanup) {
+      omPrefixes = _omPrefixes;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('returns a string', function() {
+    expect(omPrefixes).to.be.a('string');
+    expect(omPrefixes.length).to.not.be(0);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/prefixed.js b/js/modernizr/test/browser/src/prefixed.js
new file mode 100644 (file)
index 0000000..5448cf5
--- /dev/null
@@ -0,0 +1,85 @@
+describe('prefixed', function() {
+  var ModernizrProto;
+  var testPropsAll;
+  var prefixed;
+  var cssToDOM;
+  var cleanup;
+  var atRule;
+  var sinon;
+  var req;
+
+  before(function(done) {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {
+        sinon: '../test/js/lib/sinon',
+        cleanup: '../test/cleanup'
+      }
+    });
+
+    req(['sinon', 'cleanup'], function(_sinon, _cleanup) {
+      sinon = _sinon;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  beforeEach(function(done) {
+
+    testPropsAll = sinon.spy(function() {return 'fakeRule';});
+    cssToDOM = sinon.spy(function() {return 'fakeRule';});
+    atRule = sinon.spy(function() {return '@fakeRule';});
+    ModernizrProto = {};
+
+    define('ModernizrProto', [], function() {return ModernizrProto;});
+    define('testPropsAll', [], function() {return testPropsAll;});
+    define('cssToDOM', [], function() {return cssToDOM;});
+    define('atRule', [], function() {return atRule;});
+
+
+    req(['prefixed'], function(_prefixed) {
+      prefixed = _prefixed;
+
+      done();
+    });
+  });
+
+  it('is a function', function() {
+    expect(prefixed).to.be.a('function');
+  });
+
+  it('creates a reference on `ModernizrProto`', function() {
+    expect(prefixed).to.equal(ModernizrProto.prefixed);
+  });
+
+  it('uses atRule to lookup rules starting with "@"', function() {
+    expect(prefixed('@fakeRule')).to.equal('@fakeRule');
+    expect(atRule.calledOnce).to.be(true);
+  });
+
+  it('uses cssToDOM to lookup rules with "-"', function() {
+    expect(prefixed('fake-rule')).to.equal('fakeRule');
+    expect(cssToDOM.calledOnce).to.be(true);
+    expect(testPropsAll.calledOnce).to.be(true);
+  });
+
+  it('looks up properties on an element, when one is provided', function() {
+    var elm = document.createElement('div');
+    expect(prefixed('children', elm)).to.equal('fakeRule');
+    expect(testPropsAll.calledOnce).to.be(true);
+  });
+
+  afterEach(function() {
+    req.undef('ModernizrProto');
+    req.undef('testPropsAll');
+    req.undef('cssToDOM');
+    req.undef('prefixed');
+    req.undef('atRule');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/prefixedCSS.js b/js/modernizr/test/browser/src/prefixedCSS.js
new file mode 100644 (file)
index 0000000..fc480fd
--- /dev/null
@@ -0,0 +1,39 @@
+describe('prefixedCSS', function() {
+  var ModernizrProto = {_config: {usePrefixes: true}, _q: []};
+  var prefixedCSS;
+  var cleanup;
+
+  before(function(done) {
+    define('ModernizrProto', [], function() {return ModernizrProto;});
+    define('package', [], function() {return {version: 'v9999'};});
+
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['cleanup', 'prefixedCSS'], function(_cleanup, _prefixedCSS) {
+      prefixedCSS = _prefixedCSS;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('creates a reference on `ModernizrProto`', function() {
+    expect(prefixedCSS).to.equal(ModernizrProto.prefixedCSS);
+  });
+
+  it('returns false on unknown properties', function() {
+    expect(prefixedCSS('fart')).to.equal(false);
+  });
+
+  it('returns known values without prefix', function() {
+    expect(prefixedCSS('display')).to.equal('display');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/prefixes.js b/js/modernizr/test/browser/src/prefixes.js
new file mode 100644 (file)
index 0000000..bd18a6c
--- /dev/null
@@ -0,0 +1,72 @@
+describe('prefixes', function() {
+  var setup = function(done, bool) {
+    return (function() {
+      define('ModernizrProto', [], function() {return {_config: {usePrefixes: bool}};});
+
+      req(['prefixes'], function(_prefixes) {
+        prefixes = _prefixes;
+        done();
+      });
+    })();
+  };
+  var teardown = function() {
+    prefixes = undefined;
+    req.undef('prefixes');
+    req.undef('ModernizrProto');
+  };
+  var prefixes;
+  var cleanup;
+  var req;
+
+
+  before(function(done) {
+    define('package', [], function() {return {};});
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['cleanup'], function(_cleanup) {
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  describe('prefixes enabled', function() {
+    before(function(done) {
+      setup(done, true);
+    });
+
+    after(teardown);
+
+    it('returns prefixes', function(done) {
+      req(['prefixes'], function(prefixes) {
+        expect(prefixes).to.be.an('array');
+        expect(prefixes).to.not.have.length(0);
+        done();
+      });
+    });
+  });
+
+  describe('prefixes disabled', function() {
+    before(function(done) {
+      setup(done, false);
+    });
+
+    after(teardown);
+
+    it('returns no prefixes', function(done) {
+      req(['prefixes'], function(prefixes) {
+        expect(prefixes).to.be.an('array');
+        expect(prefixes).to.have.length(0);
+        done();
+      });
+    });
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/roundedEquals.js b/js/modernizr/test/browser/src/roundedEquals.js
new file mode 100644 (file)
index 0000000..cb8c334
--- /dev/null
@@ -0,0 +1,29 @@
+describe('roundedEquals', function() {
+  var roundedEquals;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['roundedEquals', 'cleanup'], function(_roundedEquals, _cleanup) {
+      roundedEquals = _roundedEquals;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('works', function() {
+    expect(roundedEquals(1, 2)).to.be(true);
+    expect(roundedEquals(2, 2)).to.be(true);
+    expect(roundedEquals(3, 2)).to.be(true);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/setClasses.js b/js/modernizr/test/browser/src/setClasses.js
new file mode 100644 (file)
index 0000000..5e2eae0
--- /dev/null
@@ -0,0 +1,165 @@
+describe('setClasses', function() {
+  var setClasses;
+  var cleanup;
+  var elm;
+  var req;
+
+  var setup = function(done, config, defaultClassName) {
+    return (function() {
+      var modConfig = {_config: config};
+
+      elm = document.createElement('div');
+      if (defaultClassName) {
+        elm.className = defaultClassName;
+      }
+
+      define('Modernizr', [], function() {return modConfig;});
+      define('docElement', [], function() {return elm;});
+
+      req(['setClasses'], function(_setClasses) {
+        setClasses = _setClasses;
+        done();
+      });
+    })();
+  };
+  var teardown = function() {
+    setClasses = undefined;
+    req.undef('setClasses');
+    req.undef('docElement');
+    req.undef('Modernizr');
+  };
+
+
+  before(function(done) {
+    define('package', [], function() {return {};});
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['cleanup'], function(_cleanup) {
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  describe('cssClasses disabled', function() {
+    before(function(done) {
+      setup(done, {
+        'classPrefix': 'fake',
+        'enableClasses': false
+      });
+    });
+
+    it('should not add anything', function(done) {
+      req(['setClasses'], function(setClasses) {
+        setClasses(['detect']);
+        expect(elm.className).to.not.contain('fakedetect');
+        done();
+      });
+    });
+
+    after(teardown);
+  });
+
+  describe('cssClasses enabled, with prefix', function() {
+    before(function(done) {
+      setup(done, {
+        'classPrefix': 'fake',
+        'enableClasses': true
+      });
+    });
+
+    it('adds a class with a prefix', function(done) {
+      req(['setClasses'], function(setClasses) {
+        setClasses(['detect']);
+        expect(elm.className).to.contain('fakedetect');
+        done();
+      });
+    });
+
+    after(teardown);
+  });
+
+  describe('cssClasses enabled, without prefix', function() {
+    before(function(done) {
+      setup(done, {
+        'enableClasses': true
+      });
+    });
+
+    after(teardown);
+
+    it('adds a class without a prefix', function(done) {
+      req(['setClasses'], function(setClasses) {
+        setClasses(['detect']);
+        expect(elm.className).to.contain('detect');
+        done();
+      });
+    });
+  });
+
+
+  describe('enableJSClass enabled, with prefix', function() {
+    before(function(done) {
+      setup(done, {
+        'classPrefix': 'fake',
+        'enableClasses': true,
+        'enableJSClass': true
+      }, ' fakeno-js +fakeno-js fakeno-js- i-has-fakeno-js');
+    });
+
+    it('changes the `js` class, and adds a class with a prefix', function(done) {
+      req(['setClasses'], function(setClasses) {
+        var classNames = elm.className.split(' ');
+        expect(classNames).to.contain('fakeno-js');
+        setClasses(['detect']);
+
+        classNames = elm.className.split(' ');
+        expect(elm.className).to.contain('fakejs');
+        expect(elm.className).to.contain('+fakeno-js');
+        expect(elm.className).to.contain('fakeno-js-');
+        expect(elm.className).to.contain('i-has-fakeno-js');
+        expect(elm.className).to.contain('fakedetect');
+        done();
+      });
+    });
+
+    after(teardown);
+
+  });
+
+  describe('enableJSClass enabled, without prefix', function() {
+    before(function(done) {
+      setup(done, {
+        'enableJSClass': true,
+        'enableClasses': true
+      }, ' no-js +no-js no-js- i-has-no-js');
+    });
+
+    after(teardown);
+
+    it('changes the `js` class, and adds a class without a prefix', function(done) {
+      req(['setClasses'], function(setClasses) {
+        var classNames = elm.className.split(' ');
+        expect(classNames).to.contain('no-js');
+        setClasses(['detect']);
+
+        classNames = elm.className.split(' ');
+        expect(elm.className).to.contain('js');
+        expect(elm.className).to.contain('+no-js');
+        expect(elm.className).to.contain('no-js-');
+        expect(elm.className).to.contain('i-has-no-js');
+        expect(elm.className).to.contain('detect');
+        done();
+      });
+    });
+
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/slice.js b/js/modernizr/test/browser/src/slice.js
new file mode 100644 (file)
index 0000000..68ba25e
--- /dev/null
@@ -0,0 +1,27 @@
+describe('slice', function() {
+  var slice;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['slice', 'cleanup'], function(_slice, _cleanup) {
+      slice = _slice;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('returns an instance of `slice`', function() {
+    expect(slice).to.equal([].slice);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/testAllProps.js b/js/modernizr/test/browser/src/testAllProps.js
new file mode 100644 (file)
index 0000000..ad74ad4
--- /dev/null
@@ -0,0 +1,61 @@
+describe('testAllProps', function() {
+  var ModernizrProto = {};
+  var testAllProps;
+  var testPropsAll;
+  var cleanup;
+  var sinon;
+  var req;
+
+  before(function(done) {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {
+        sinon: '../test/js/lib/sinon',
+        cleanup: '../test/cleanup'
+      }
+    });
+
+    define('ModernizrProto', [], function() {return ModernizrProto;});
+    define('package', [], function() {return {};});
+
+    req(['cleanup', 'sinon'], function(_cleanup, _sinon) {
+      cleanup = _cleanup;
+      sinon = _sinon;
+      done();
+    });
+  });
+
+  beforeEach(function(done) {
+    testPropsAll = sinon.spy();
+
+    define('testPropsAll', function() {return testPropsAll;});
+
+    req(['testAllProps'], function(_testAllProps) {
+      testAllProps = _testAllProps;
+      done();
+    });
+  });
+
+  it('is a curried version of `testPropsAll`', function() {
+    testAllProps('flexAlign', 'end', true);
+    expect(testPropsAll.calledOnce).to.be(true);
+
+    expect(testPropsAll.calledWithExactly(
+      'flexAlign',
+      undefined,
+      undefined,
+      'end',
+      true
+    )).to.be(true);
+  });
+
+  it('is added to ModernizrProto', function() {
+    expect(testAllProps).to.equal(ModernizrProto.testAllProps);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/testDOMProps.js b/js/modernizr/test/browser/src/testDOMProps.js
new file mode 100644 (file)
index 0000000..375ad22
--- /dev/null
@@ -0,0 +1,55 @@
+describe('testDOMProps', function() {
+  var elm = document.createElement('div');
+  var testDOMProps;
+  var cleanup;
+  var req;
+
+  before(function(done) {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['cleanup'], function(_cleanup) {
+      cleanup = _cleanup;
+      done();
+    });
+
+  });
+
+  beforeEach(function(done) {
+    req(['testDOMProps'], function(_testDOMProps) {
+      testDOMProps = _testDOMProps;
+      done();
+    });
+  });
+
+  it('returns known values', function() {
+    expect(testDOMProps(['clientHeight'], elm)).to.equal(elm.clientHeight);
+  });
+
+  it('returns false for unknown values', function() {
+    expect(testDOMProps(['fart'], elm)).to.equal(false);
+  });
+
+  it('bind a value to to the object', function() {
+    elm.answer = function() {return 42;};
+    expect(testDOMProps(['answer'], elm)()).to.equal(elm.answer());
+  });
+
+  it('bind a value to the element, if it is provided', function() {
+    elm.answer = function() {return 42;};
+    expect(testDOMProps(['answer'], {}, elm)).to.equal(false);
+  });
+
+  it('return the property name as a string if elem is false', function() {
+    elm.answer = function() {return 42;};
+    expect(testDOMProps(['answer'], {'answer': 42}, false)).to.equal('answer');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/testProp.js b/js/modernizr/test/browser/src/testProp.js
new file mode 100644 (file)
index 0000000..597800d
--- /dev/null
@@ -0,0 +1,60 @@
+describe('testProp', function() {
+  var ModernizrProto = {};
+  var testProp;
+  var testProps;
+  var cleanup;
+  var sinon;
+  var req;
+
+  before(function(done) {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {
+        sinon: '../test/js/lib/sinon',
+        cleanup: '../test/cleanup'
+      }
+    });
+
+    define('ModernizrProto', [], function() {return ModernizrProto;});
+    define('package', [], function() {return {};});
+
+    req(['cleanup', 'sinon'], function(_cleanup, _sinon) {
+      cleanup = _cleanup;
+      sinon = _sinon;
+      done();
+    });
+  });
+
+  beforeEach(function(done) {
+    testProps = sinon.spy();
+
+    define('testProps', function() {return testProps;});
+
+    req(['testProp'], function(_testProp) {
+      testProp = _testProp;
+      done();
+    });
+  });
+
+  it('is a curried version of `testProps`', function() {
+    testProp('flexAlign', 'end', true);
+    expect(testProps.calledOnce).to.be(true);
+
+    expect(testProps.calledWithExactly(
+      ['flexAlign'],
+      undefined,
+      'end',
+      true
+    )).to.be(true);
+  });
+
+  it('is added to ModernizrProto', function() {
+    expect(testProp).to.equal(ModernizrProto.testProp);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/testProps.js b/js/modernizr/test/browser/src/testProps.js
new file mode 100644 (file)
index 0000000..42d8376
--- /dev/null
@@ -0,0 +1,151 @@
+describe('testProps', function() {
+  var ModernizrProto = {foo: 7};
+  var Modernizr = {_q: []};
+  var testProps;
+  var cleanup;
+  var sinon;
+  var req;
+
+  before(function(done) {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {
+        sinon: '../test/js/lib/sinon',
+        cleanup: '../test/cleanup'
+      }
+    });
+
+    define('ModernizrProto', [], function() {return ModernizrProto;});
+    define('Modernizr', function() {return Modernizr;});
+    define('package', [], function() {return {};});
+
+    req(['cleanup', 'sinon'], function(_cleanup, _sinon) {
+      cleanup = _cleanup;
+      sinon = _sinon;
+      done();
+    });
+  });
+
+  describe('native detect', function() {
+    var nativeTestProps = function(props, value) {
+      return !!value ? true : undefined;
+    };
+    var contains;
+
+    beforeEach(function(done) {
+      contains = sinon.spy();
+
+      nativeTestProps = sinon.spy(nativeTestProps);
+
+      define('contains', function() {return contains;});
+      define('nativeTestProps', sinon.spy(function() {return nativeTestProps;}));
+
+      req(['testProps'], function(_testProps) {
+        testProps = _testProps;
+        done();
+      });
+    });
+
+    it('returns the value from nativeTestProp if not undefined', function() {
+      expect(testProps(['fake'], undefined, true));
+      expect(nativeTestProps.callCount).to.be(1);
+      expect(contains.callCount).to.be(0);
+    });
+
+    it('does not return the value from nativeTestProp when undefined', function() {
+      expect(testProps(['fake'], undefined, false));
+      expect(nativeTestProps.callCount).to.be(1);
+      expect(contains.callCount).to.not.be(0);
+    });
+
+    afterEach(function() {
+      req.undef('mStyle');
+      req.undef('cssToDOM');
+      req.undef('contains');
+      req.undef('testProps');
+      req.undef('nativeTestProps');
+    });
+  });
+
+  describe('nonnative detect', function() {
+    var contains = function(a, b) {return a.indexOf(b) > -1;};
+    var nativeTestProps = function() { return; };
+    var cssToDOM;
+    var mStyle;
+
+    beforeEach(function(done) {
+      nativeTestProps = sinon.spy(nativeTestProps);
+      contains = sinon.spy(contains);
+      cssToDOM = sinon.spy();
+      mStyle = {};
+
+      define('nativeTestProps', sinon.spy(function() {return nativeTestProps;}));
+      define('cssToDOM', function() {return cssToDOM;});
+      define('contains', function() {return contains;});
+      define('mStyle', function() {return mStyle;});
+
+      req(['testProps'], function(_testProps) {
+        testProps = _testProps;
+        done();
+      });
+    });
+
+    it('cleans up mStyle changes', function() {
+      expect(testProps(['fake'], undefined, true));
+      expect(contains.callCount).to.be(1);
+      expect(mStyle.style).to.equal(undefined);
+      expect(mStyle.modElem).to.equal(undefined);
+    });
+
+    it('calls cssToDOM when props have a `-`', function() {
+      expect(testProps(['fake-detect'], undefined, true));
+      expect(cssToDOM.called).to.be(true);
+    });
+
+    it('returns true for valid prop, and skipValueTest', function() {
+      expect(testProps(['display'], undefined, true, true)).to.be(true);
+    });
+
+    it('returns true for valid prop, and good value', function() {
+      expect(testProps(['display'], undefined, 'block')).to.be(true);
+    });
+
+    it('returns false for valid prop and bad value', function() {
+      expect(testProps(['display'], undefined, 'penguin')).to.be(false);
+    });
+
+    it('returns the prop if a prefixed lookup', function() {
+      expect(testProps(['display'], 'pfx', 'block')).to.be('display');
+    });
+
+    it('returns the prop if a prefixed lookup with skipValueTest', function() {
+      expect(testProps(['display'], 'pfx', 'block', true)).to.be('display');
+    });
+
+    it('works properly', function() {
+      // Everyone supports margin
+      expect(testProps(['margin'])).to.equal(true);
+      // Nobody supports the happiness style. :(
+      expect(testProps(['happiness'])).to.equal(false);
+      // Everyone supports fontSize
+      expect(testProps(['fontSize'])).to.equal(true);
+      // kebab-case should work too
+    });
+
+
+    afterEach(function() {
+      req.undef('mStyle');
+      req.undef('cssToDOM');
+      req.undef('contains');
+      req.undef('testProps');
+      req.undef('ModernizrProto');
+      req.undef('nativeTestProps');
+    });
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/testPropsAll.js b/js/modernizr/test/browser/src/testPropsAll.js
new file mode 100644 (file)
index 0000000..d2df42d
--- /dev/null
@@ -0,0 +1,83 @@
+describe('testPropsAll', function() {
+  var ModernizrProto = {_config: {}};
+  var Modernizr = {_q: []};
+  var testPropsAll;
+  var testDOMProps;
+  var testProps;
+  var cleanup;
+  var req;
+
+  before(function(done) {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {
+        sinon: '../test/js/lib/sinon',
+        cleanup: '../test/cleanup'
+      }
+    });
+
+    define('ModernizrProto', [], function() {return ModernizrProto;});
+    define('Modernizr', [], function() {return Modernizr;});
+    define('package', [], function() {return {};});
+
+    req(['testDOMProps', 'testProps', 'cleanup', 'sinon'], function(_testDOMProps, _testProps, _cleanup, _sinon) {
+        testDOMProps = _sinon.spy(_testDOMProps);
+        testProps = _sinon.spy(_testProps);
+        cleanup = _cleanup;
+
+        done();
+      });
+
+  });
+
+  beforeEach(function(done) {
+    req.undef('testDOMProps');
+    req.undef('testProps');
+
+    testDOMProps.reset();
+    testProps.reset();
+
+    define('testDOMProps', function() {return testDOMProps;});
+    define('testProps', function() {return testProps;});
+
+    req(['testPropsAll'], function(_testPropsAll) {
+      testPropsAll = _testPropsAll;
+
+      expect(testDOMProps.callCount).to.be(0);
+      expect(testProps.callCount).to.be(0);
+      done();
+    });
+
+  });
+
+  it('`testProps` is called if `prefixed` is a string', function() {
+    testPropsAll('display', 'pfx', undefined, 'block');
+    expect(testProps.callCount).to.be(1);
+  });
+
+  it('`testProps` is called if `prefixed` is undefined', function() {
+    testPropsAll('display', undefined, undefined, 'block');
+    expect(testProps.callCount).to.be(1);
+  });
+
+  it('`testDOMProps` is called if `prefixed` is anything else', function() {
+    testPropsAll('display', [], undefined, 'block');
+    expect(testDOMProps.callCount).to.be(1);
+  });
+
+  it('is added to ModernizrProto as `testAllProps`', function() {
+    expect(testPropsAll).to.equal(ModernizrProto.testAllProps);
+  });
+
+  afterEach(function() {
+    req.undef('testPropsAll');
+    req.undef('testDOMProps');
+    req.undef('testProps');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/testRunner.js b/js/modernizr/test/browser/src/testRunner.js
new file mode 100644 (file)
index 0000000..fdd4344
--- /dev/null
@@ -0,0 +1,88 @@
+describe('testRunner', function() {
+  var Modernizr = {};
+  var cleanup;
+  var req;
+
+  before(function(done) {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    define('Modernizr', [], function() {return Modernizr;});
+    define('tests', [], function() {
+      return [
+        {
+          'name': 'fakeFn',
+          'fn': function() {return true;}
+        }, {
+          'name': 'fakeBool',
+          'fn': false
+        }, {
+          'name': 'newFakeDetect',
+          'fn': function() {return 10;},
+          'options': {
+            'aliases': ['fakeDetect']
+          }
+        }, {
+          'name': 'fake',
+          'fn': true
+        }, {
+          'name': 'fake.detect',
+          'fn': 99
+        }, {
+          'name': 'fakeBoolDeep',
+          /* jshint -W053 */
+          'fn': new Boolean(true)
+          /* jshint +W053 */
+        }, {
+          'name': 'fakeBoolDeep.detect',
+          'fn': false
+        }, {
+          'fn': function() {
+            return !!'async test';
+          }
+        }
+      ];
+    });
+
+    req(['testRunner', 'cleanup'], function(_testRunner, _cleanup) {
+      _testRunner();
+      cleanup = _cleanup;
+      done();
+    });
+
+  });
+
+  it('returns true if fn returns true', function() {
+    expect('fakefn' in Modernizr).to.be(true);
+  });
+
+  it('returns true if fn is a bool', function() {
+    expect(Modernizr.fakebool).to.be(false);
+  });
+
+  it('assigns aliased values', function() {
+    expect(Modernizr.newfakedetect).to.equal(Modernizr.fakedetect);
+  });
+
+  it('deep assignments are valid', function() {
+    expect(Modernizr.fake.detect).to.equal(99);
+  });
+
+  it('deep assignments are true with bool base', function() {
+    expect(Modernizr.fakebooldeep instanceof Boolean).to.be(true);
+    expect(Modernizr.fakebooldeep.detect).to.equal(false);
+  });
+
+  afterEach(function() {
+    req.undef('testRunner');
+    req.undef('Modernizr');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/testStyles.js b/js/modernizr/test/browser/src/testStyles.js
new file mode 100644 (file)
index 0000000..e4ce662
--- /dev/null
@@ -0,0 +1,38 @@
+describe('testStyles', function() {
+  var injectElementWithStyles;
+  var ModernizrProto;
+  var cleanup;
+  var testStyles;
+
+
+  before(function(done) {
+
+    define('ModernizrProto', [], function() {return {};});
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['ModernizrProto', 'testStyles', 'injectElementWithStyles', 'cleanup'], function(_ModernizrProto, _testStyles, _injectElementWithStyles, _cleanup) {
+      injectElementWithStyles = _injectElementWithStyles;
+      ModernizrProto = _ModernizrProto;
+      testStyles = _testStyles;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('creates a reference on `ModernizrProto`', function() {
+    expect(ModernizrProto.testStyles).to.be.a('function');
+  });
+
+  it('is just an alias to injectElementWithStyles', function() {
+    expect(ModernizrProto.testStyles).to.equal(injectElementWithStyles);
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/testXhrType.js b/js/modernizr/test/browser/src/testXhrType.js
new file mode 100644 (file)
index 0000000..6279e7f
--- /dev/null
@@ -0,0 +1,44 @@
+describe('testXhrType', function() {
+  var cleanup;
+  var req;
+
+  before(function(done) {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {
+        cleanup: '../test/cleanup'
+      }
+    });
+
+    req(['cleanup'], function(_cleanup) {
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  /*jshint -W020 */
+  it('returns false when XHR is undefined', function(done) {
+    var originalXhr = XMLHttpRequest;
+    XMLHttpRequest = undefined;
+
+    req(['testXhrType'], function(testXhrType) {
+      expect(testXhrType('json')).to.equal(false);
+      XMLHttpRequest = originalXhr;
+      done();
+    });
+  });
+  /*jshint +W020 */
+
+  // TODO add more tests once sinon's XHR2 features land
+  // http://git.io/AemZ
+
+  afterEach(function() {
+    req.undef('testXhrType');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/tests.js b/js/modernizr/test/browser/src/tests.js
new file mode 100644 (file)
index 0000000..f0e459c
--- /dev/null
@@ -0,0 +1,28 @@
+describe('tests', function() {
+  var tests;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['tests', 'cleanup'], function(_tests, _cleanup) {
+      tests = _tests;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+
+  it('is an array', function() {
+    expect(tests).to.be.an('array');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/src/toStringFn.js b/js/modernizr/test/browser/src/toStringFn.js
new file mode 100644 (file)
index 0000000..ec48d81
--- /dev/null
@@ -0,0 +1,35 @@
+describe('toStringFn', function() {
+  var toStringFn;
+  var cleanup;
+
+  before(function(done) {
+
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      baseUrl: '../src',
+      paths: {cleanup: '../test/cleanup'}
+    });
+
+    req(['toStringFn', 'cleanup'], function(_toStringFn, _cleanup) {
+      toStringFn = _toStringFn;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+
+  it('is an function', function() {
+    expect(toStringFn).to.be.an('function');
+  });
+
+  it('toStrings stuff', function() {
+    expect(toStringFn.call([])).to.equal('[object Array]');
+    expect(toStringFn.call({})).to.equal('[object Object]');
+    expect(toStringFn.call(true)).to.equal('[object Boolean]');
+    expect(toStringFn.call(new Date())).to.equal('[object Date]');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
diff --git a/js/modernizr/test/browser/svgUnit.js b/js/modernizr/test/browser/svgUnit.js
new file mode 100644 (file)
index 0000000..17ba136
--- /dev/null
@@ -0,0 +1,158 @@
+describe('svg context unit tests', function() {
+  var svgContext;
+  var cleanup;
+  var object;
+  var req;
+
+  if ('createElementNS' in document) {
+
+    var setup = function(settings) {
+      var stringified = settings.stringified;
+      var instrumented = !!stringified.match(/__cov_/);
+
+      if (instrumented) {
+        settings.coverageObjName = stringified.match(/(?:^[^{]*{)([^.]*)/)[1];
+        svgContext[settings.coverageObjName] = window[settings.coverageObjName];
+      }
+
+      _.extend(svgContext, settings.setup);
+
+      svgContext.eval(stringified);
+
+      settings.cleanup = function() {
+        if (instrumented) {
+          window[settings.coverageObjName] = svgContext[settings.coverageObjName] ;
+        }
+      };
+
+      return settings;
+    };
+
+    before(function(done) {
+
+      req = requirejs.config({
+        context: Math.random().toString().slice(2),
+        baseUrl: '../src',
+        paths: {cleanup: '../test/cleanup'}
+      });
+
+      req(['cleanup'], function(_cleanup) {
+        cleanup = _cleanup;
+        done();
+      });
+    });
+
+    beforeEach(function(done) {
+      object = document.createElement('object');
+
+      object.data = '../test/img/unit.svg';
+      object.type = 'image/svg+xml';
+      object.id = 'svgContext';
+
+      object.onerror = function() {
+        var arg = Array.prototype.slice.call(arguments).join(' ');
+        try {
+          expect(arg).to.be(undefined);
+        } catch (e) {
+          done(e);
+        }
+      };
+
+      object.runUnitTests = function(thisRef) {
+        svgContext = thisRef;
+
+        req = requirejs.config({
+          context: Math.random().toString().slice(2),
+          baseUrl: '../src'
+        });
+
+        done();
+      };
+
+      document.body.appendChild(object);
+    });
+
+    it('is still able to set classNames correctly', function(done) {
+      req(['setClasses'], function(setClasses) {
+        try {
+          var testInstance = setup({
+            stringified: setClasses.toString(),
+            setup: {
+              Modernizr: {_config: {enableClasses: true}},
+              docElement: svgContext.document.documentElement,
+              isSVG: true
+            }
+          });
+
+          svgContext.test(function() {
+            setClasses(['svgdetect']);
+          });
+
+          expect(svgContext.document.documentElement.className.baseVal).to.contain('svgdetect');
+
+          testInstance.cleanup();
+
+          done();
+        }
+        catch (e) { done(e); }
+      });
+    });
+
+    it('uses the correct namespace when creating elements', function(done) {
+      req(['createElement'], function(createElement) {
+        try {
+          var testInstance = setup({
+            stringified: createElement.toString(),
+            setup: {
+              isSVG: true
+            }
+          });
+
+          svgContext.test(function() {
+            window._testElem = createElement('a');
+          });
+
+          expect(svgContext._testElem.namespaceURI).to.equal('http://www.w3.org/2000/svg');
+
+          testInstance.cleanup();
+
+          done();
+        }
+        catch (e) { done(e); }
+      });
+    });
+
+    it('uses a SVG element for when making a fake body', function(done) {
+      req(['getBody'], function(getBody) {
+        try {
+          var testInstance = setup({
+            stringified: getBody.toString(),
+            setup: {
+              isSVG: true,
+              createElement: function() {
+                return svgContext.document.createElement.apply(svgContext.document, arguments);
+              }
+            }
+          });
+
+          svgContext.test(function() {
+            window._body = getBody();
+          });
+
+          expect(svgContext._body.nodeName.toLowerCase()).to.equal('svg');
+
+          testInstance.cleanup();
+
+          done();
+        }
+        catch (e) { done(e); }
+      });
+    });
+
+
+    afterEach(function() {
+      object.parentNode.removeChild(object);
+      cleanup();
+    });
+  }
+});
diff --git a/js/modernizr/test/cleanup.js b/js/modernizr/test/cleanup.js
new file mode 100644 (file)
index 0000000..abc5501
--- /dev/null
@@ -0,0 +1,21 @@
+/*jshint: globals __coverage__ */
+if (typeof define !== 'function') {
+  var requirejs = require('requirejs');
+}
+
+define([], function() {
+  return function() {
+    var contexts = requirejs.s.contexts;
+
+    for (var context in contexts) {
+      if (contexts.hasOwnProperty(context)) {
+        var defined = contexts[context].defined;
+        for (var module in defined) {
+          if (defined.hasOwnProperty(module) && !module.match(/cleanup|sinon/)) {
+            requirejs.undef(module);
+          }
+        }
+      }
+    }
+  };
+});
diff --git a/js/modernizr/test/js/lib/sinon.js b/js/modernizr/test/js/lib/sinon.js
new file mode 100644 (file)
index 0000000..f280bcc
--- /dev/null
@@ -0,0 +1,5782 @@
+/**
+ * Sinon.JS 1.12.2, 2015/02/15
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
+ *
+ * (The BSD License)
+ * 
+ * Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice,
+ *       this list of conditions and the following disclaimer in the documentation
+ *       and/or other materials provided with the distribution.
+ *     * Neither the name of Christian Johansen nor the names of his contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function (root, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define([], function () {
+      return (root.sinon = factory());
+    });
+  } else if (typeof exports === 'object') {
+    module.exports = factory();
+  } else {
+    root.sinon = factory();
+  }
+}(this, function () {
+  var samsam, formatio;
+  (function () {
+                function define(mod, deps, fn) {
+                  if (mod == "samsam") {
+                    samsam = deps();
+                  } else if (typeof deps === "function" && mod.length === 0) {
+                    lolex = deps();
+                  } else if (typeof fn === "function") {
+                    formatio = fn(samsam);
+                  }
+                }
+    define.amd = {};
+((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) ||
+ (typeof module === "object" &&
+      function (m) { module.exports = m(); }) || // Node
+ function (m) { this.samsam = m(); } // Browser globals
+)(function () {
+    var o = Object.prototype;
+    var div = typeof document !== "undefined" && document.createElement("div");
+
+    function isNaN(value) {
+        // Unlike global isNaN, this avoids type coercion
+        // typeof check avoids IE host object issues, hat tip to
+        // lodash
+        var val = value; // JsLint thinks value !== value is "weird"
+        return typeof value === "number" && value !== val;
+    }
+
+    function getClass(value) {
+        // Returns the internal [[Class]] by calling Object.prototype.toString
+        // with the provided value as this. Return value is a string, naming the
+        // internal class, e.g. "Array"
+        return o.toString.call(value).split(/[ \]]/)[1];
+    }
+
+    /**
+     * @name samsam.isArguments
+     * @param Object object
+     *
+     * Returns ``true`` if ``object`` is an ``arguments`` object,
+     * ``false`` otherwise.
+     */
+    function isArguments(object) {
+        if (getClass(object) === 'Arguments') { return true; }
+        if (typeof object !== "object" || typeof object.length !== "number" ||
+                getClass(object) === "Array") {
+            return false;
+        }
+        if (typeof object.callee == "function") { return true; }
+        try {
+            object[object.length] = 6;
+            delete object[object.length];
+        } catch (e) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @name samsam.isElement
+     * @param Object object
+     *
+     * Returns ``true`` if ``object`` is a DOM element node. Unlike
+     * Underscore.js/lodash, this function will return ``false`` if ``object``
+     * is an *element-like* object, i.e. a regular object with a ``nodeType``
+     * property that holds the value ``1``.
+     */
+    function isElement(object) {
+        if (!object || object.nodeType !== 1 || !div) { return false; }
+        try {
+            object.appendChild(div);
+            object.removeChild(div);
+        } catch (e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @name samsam.keys
+     * @param Object object
+     *
+     * Return an array of own property names.
+     */
+    function keys(object) {
+        var ks = [], prop;
+        for (prop in object) {
+            if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
+        }
+        return ks;
+    }
+
+    /**
+     * @name samsam.isDate
+     * @param Object value
+     *
+     * Returns true if the object is a ``Date``, or *date-like*. Duck typing
+     * of date objects work by checking that the object has a ``getTime``
+     * function whose return value equals the return value from the object's
+     * ``valueOf``.
+     */
+    function isDate(value) {
+        return typeof value.getTime == "function" &&
+            value.getTime() == value.valueOf();
+    }
+
+    /**
+     * @name samsam.isNegZero
+     * @param Object value
+     *
+     * Returns ``true`` if ``value`` is ``-0``.
+     */
+    function isNegZero(value) {
+        return value === 0 && 1 / value === -Infinity;
+    }
+
+    /**
+     * @name samsam.equal
+     * @param Object obj1
+     * @param Object obj2
+     *
+     * Returns ``true`` if two objects are strictly equal. Compared to
+     * ``===`` there are two exceptions:
+     *
+     *   - NaN is considered equal to NaN
+     *   - -0 and +0 are not considered equal
+     */
+    function identical(obj1, obj2) {
+        if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
+            return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
+        }
+    }
+
+
+    /**
+     * @name samsam.deepEqual
+     * @param Object obj1
+     * @param Object obj2
+     *
+     * Deep equal comparison. Two values are "deep equal" if:
+     *
+     *   - They are equal, according to samsam.identical
+     *   - They are both date objects representing the same time
+     *   - They are both arrays containing elements that are all deepEqual
+     *   - They are objects with the same set of properties, and each property
+     *     in ``obj1`` is deepEqual to the corresponding property in ``obj2``
+     *
+     * Supports cyclic objects.
+     */
+    function deepEqualCyclic(obj1, obj2) {
+
+        // used for cyclic comparison
+        // contain already visited objects
+        var objects1 = [],
+            objects2 = [],
+        // contain pathes (position in the object structure)
+        // of the already visited objects
+        // indexes same as in objects arrays
+            paths1 = [],
+            paths2 = [],
+        // contains combinations of already compared objects
+        // in the manner: { "$1['ref']$2['ref']": true }
+            compared = {};
+
+        /**
+         * used to check, if the value of a property is an object
+         * (cyclic logic is only needed for objects)
+         * only needed for cyclic logic
+         */
+        function isObject(value) {
+
+            if (typeof value === 'object' && value !== null &&
+                    !(value instanceof Boolean) &&
+                    !(value instanceof Date)    &&
+                    !(value instanceof Number)  &&
+                    !(value instanceof RegExp)  &&
+                    !(value instanceof String)) {
+
+                return true;
+            }
+
+            return false;
+        }
+
+        /**
+         * returns the index of the given object in the
+         * given objects array, -1 if not contained
+         * only needed for cyclic logic
+         */
+        function getIndex(objects, obj) {
+
+            var i;
+            for (i = 0; i < objects.length; i++) {
+                if (objects[i] === obj) {
+                    return i;
+                }
+            }
+
+            return -1;
+        }
+
+        // does the recursion for the deep equal check
+        return (function deepEqual(obj1, obj2, path1, path2) {
+            var type1 = typeof obj1;
+            var type2 = typeof obj2;
+
+            // == null also matches undefined
+            if (obj1 === obj2 ||
+                    isNaN(obj1) || isNaN(obj2) ||
+                    obj1 == null || obj2 == null ||
+                    type1 !== "object" || type2 !== "object") {
+
+                return identical(obj1, obj2);
+            }
+
+            // Elements are only equal if identical(expected, actual)
+            if (isElement(obj1) || isElement(obj2)) { return false; }
+
+            var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
+            if (isDate1 || isDate2) {
+                if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
+                    return false;
+                }
+            }
+
+            if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
+                if (obj1.toString() !== obj2.toString()) { return false; }
+            }
+
+            var class1 = getClass(obj1);
+            var class2 = getClass(obj2);
+            var keys1 = keys(obj1);
+            var keys2 = keys(obj2);
+
+            if (isArguments(obj1) || isArguments(obj2)) {
+                if (obj1.length !== obj2.length) { return false; }
+            } else {
+                if (type1 !== type2 || class1 !== class2 ||
+                        keys1.length !== keys2.length) {
+                    return false;
+                }
+            }
+
+            var key, i, l,
+                // following vars are used for the cyclic logic
+                value1, value2,
+                isObject1, isObject2,
+                index1, index2,
+                newPath1, newPath2;
+
+            for (i = 0, l = keys1.length; i < l; i++) {
+                key = keys1[i];
+                if (!o.hasOwnProperty.call(obj2, key)) {
+                    return false;
+                }
+
+                // Start of the cyclic logic
+
+                value1 = obj1[key];
+                value2 = obj2[key];
+
+                isObject1 = isObject(value1);
+                isObject2 = isObject(value2);
+
+                // determine, if the objects were already visited
+                // (it's faster to check for isObject first, than to
+                // get -1 from getIndex for non objects)
+                index1 = isObject1 ? getIndex(objects1, value1) : -1;
+                index2 = isObject2 ? getIndex(objects2, value2) : -1;
+
+                // determine the new pathes of the objects
+                // - for non cyclic objects the current path will be extended
+                //   by current property name
+                // - for cyclic objects the stored path is taken
+                newPath1 = index1 !== -1
+                    ? paths1[index1]
+                    : path1 + '[' + JSON.stringify(key) + ']';
+                newPath2 = index2 !== -1
+                    ? paths2[index2]
+                    : path2 + '[' + JSON.stringify(key) + ']';
+
+                // stop recursion if current objects are already compared
+                if (compared[newPath1 + newPath2]) {
+                    return true;
+                }
+
+                // remember the current objects and their pathes
+                if (index1 === -1 && isObject1) {
+                    objects1.push(value1);
+                    paths1.push(newPath1);
+                }
+                if (index2 === -1 && isObject2) {
+                    objects2.push(value2);
+                    paths2.push(newPath2);
+                }
+
+                // remember that the current objects are already compared
+                if (isObject1 && isObject2) {
+                    compared[newPath1 + newPath2] = true;
+                }
+
+                // End of cyclic logic
+
+                // neither value1 nor value2 is a cycle
+                // continue with next level
+                if (!deepEqual(value1, value2, newPath1, newPath2)) {
+                    return false;
+                }
+            }
+
+            return true;
+
+        }(obj1, obj2, '$1', '$2'));
+    }
+
+    var match;
+
+    function arrayContains(array, subset) {
+        if (subset.length === 0) { return true; }
+        var i, l, j, k;
+        for (i = 0, l = array.length; i < l; ++i) {
+            if (match(array[i], subset[0])) {
+                for (j = 0, k = subset.length; j < k; ++j) {
+                    if (!match(array[i + j], subset[j])) { return false; }
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @name samsam.match
+     * @param Object object
+     * @param Object matcher
+     *
+     * Compare arbitrary value ``object`` with matcher.
+     */
+    match = function match(object, matcher) {
+        if (matcher && typeof matcher.test === "function") {
+            return matcher.test(object);
+        }
+
+        if (typeof matcher === "function") {
+            return matcher(object) === true;
+        }
+
+        if (typeof matcher === "string") {
+            matcher = matcher.toLowerCase();
+            var notNull = typeof object === "string" || !!object;
+            return notNull &&
+                (String(object)).toLowerCase().indexOf(matcher) >= 0;
+        }
+
+        if (typeof matcher === "number") {
+            return matcher === object;
+        }
+
+        if (typeof matcher === "boolean") {
+            return matcher === object;
+        }
+
+        if (typeof(matcher) === "undefined") {
+            return typeof(object) === "undefined";
+        }
+
+        if (matcher === null) {
+            return object === null;
+        }
+
+        if (getClass(object) === "Array" && getClass(matcher) === "Array") {
+            return arrayContains(object, matcher);
+        }
+
+        if (matcher && typeof matcher === "object") {
+            if (matcher === object) {
+                return true;
+            }
+            var prop;
+            for (prop in matcher) {
+                var value = object[prop];
+                if (typeof value === "undefined" &&
+                        typeof object.getAttribute === "function") {
+                    value = object.getAttribute(prop);
+                }
+                if (matcher[prop] === null || typeof matcher[prop] === 'undefined') {
+                    if (value !== matcher[prop]) {
+                        return false;
+                    }
+                } else if (typeof  value === "undefined" || !match(value, matcher[prop])) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        throw new Error("Matcher was not a string, a number, a " +
+                        "function, a boolean or an object");
+    };
+
+    return {
+        isArguments: isArguments,
+        isElement: isElement,
+        isDate: isDate,
+        isNegZero: isNegZero,
+        identical: identical,
+        deepEqual: deepEqualCyclic,
+        match: match,
+        keys: keys
+    };
+});
+((typeof define === "function" && define.amd && function (m) {
+    define("formatio", ["samsam"], m);
+}) || (typeof module === "object" && function (m) {
+    module.exports = m(require("samsam"));
+}) || function (m) { this.formatio = m(this.samsam); }
+)(function (samsam) {
+    
+    var formatio = {
+        excludeConstructors: ["Object", /^.$/],
+        quoteStrings: true,
+        limitChildrenCount: 0
+    };
+
+    var hasOwn = Object.prototype.hasOwnProperty;
+
+    var specialObjects = [];
+    if (typeof global !== "undefined") {
+        specialObjects.push({ object: global, value: "[object global]" });
+    }
+    if (typeof document !== "undefined") {
+        specialObjects.push({
+            object: document,
+            value: "[object HTMLDocument]"
+        });
+    }
+    if (typeof window !== "undefined") {
+        specialObjects.push({ object: window, value: "[object Window]" });
+    }
+
+    function functionName(func) {
+        if (!func) { return ""; }
+        if (func.displayName) { return func.displayName; }
+        if (func.name) { return func.name; }
+        var matches = func.toString().match(/function\s+([^\(]+)/m);
+        return (matches && matches[1]) || "";
+    }
+
+    function constructorName(f, object) {
+        var name = functionName(object && object.constructor);
+        var excludes = f.excludeConstructors ||
+                formatio.excludeConstructors || [];
+
+        var i, l;
+        for (i = 0, l = excludes.length; i < l; ++i) {
+            if (typeof excludes[i] === "string" && excludes[i] === name) {
+                return "";
+            } else if (excludes[i].test && excludes[i].test(name)) {
+                return "";
+            }
+        }
+
+        return name;
+    }
+
+    function isCircular(object, objects) {
+        if (typeof object !== "object") { return false; }
+        var i, l;
+        for (i = 0, l = objects.length; i < l; ++i) {
+            if (objects[i] === object) { return true; }
+        }
+        return false;
+    }
+
+    function ascii(f, object, processed, indent) {
+        if (typeof object === "string") {
+            var qs = f.quoteStrings;
+            var quote = typeof qs !== "boolean" || qs;
+            return processed || quote ? '"' + object + '"' : object;
+        }
+
+        if (typeof object === "function" && !(object instanceof RegExp)) {
+            return ascii.func(object);
+        }
+
+        processed = processed || [];
+
+        if (isCircular(object, processed)) { return "[Circular]"; }
+
+        if (Object.prototype.toString.call(object) === "[object Array]") {
+            return ascii.array.call(f, object, processed);
+        }
+
+        if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
+        if (samsam.isElement(object)) { return ascii.element(object); }
+
+        if (typeof object.toString === "function" &&
+                object.toString !== Object.prototype.toString) {
+            return object.toString();
+        }
+
+        var i, l;
+        for (i = 0, l = specialObjects.length; i < l; i++) {
+            if (object === specialObjects[i].object) {
+                return specialObjects[i].value;
+            }
+        }
+
+        return ascii.object.call(f, object, processed, indent);
+    }
+
+    ascii.func = function (func) {
+        return "function " + functionName(func) + "() {}";
+    };
+
+    ascii.array = function (array, processed) {
+        processed = processed || [];
+        processed.push(array);
+        var pieces = [];
+        var i, l;
+        l = (this.limitChildrenCount > 0) ? 
+            Math.min(this.limitChildrenCount, array.length) : array.length;
+
+        for (i = 0; i < l; ++i) {
+            pieces.push(ascii(this, array[i], processed));
+        }
+
+        if(l < array.length)
+            pieces.push("[... " + (array.length - l) + " more elements]");
+
+        return "[" + pieces.join(", ") + "]";
+    };
+
+    ascii.object = function (object, processed, indent) {
+        processed = processed || [];
+        processed.push(object);
+        indent = indent || 0;
+        var pieces = [], properties = samsam.keys(object).sort();
+        var length = 3;
+        var prop, str, obj, i, k, l;
+        l = (this.limitChildrenCount > 0) ? 
+            Math.min(this.limitChildrenCount, properties.length) : properties.length;
+
+        for (i = 0; i < l; ++i) {
+            prop = properties[i];
+            obj = object[prop];
+
+            if (isCircular(obj, processed)) {
+                str = "[Circular]";
+            } else {
+                str = ascii(this, obj, processed, indent + 2);
+            }
+
+            str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
+            length += str.length;
+            pieces.push(str);
+        }
+
+        var cons = constructorName(this, object);
+        var prefix = cons ? "[" + cons + "] " : "";
+        var is = "";
+        for (i = 0, k = indent; i < k; ++i) { is += " "; }
+
+        if(l < properties.length)
+            pieces.push("[... " + (properties.length - l) + " more elements]");
+
+        if (length + indent > 80) {
+            return prefix + "{\n  " + is + pieces.join(",\n  " + is) + "\n" +
+                is + "}";
+        }
+        return prefix + "{ " + pieces.join(", ") + " }";
+    };
+
+    ascii.element = function (element) {
+        var tagName = element.tagName.toLowerCase();
+        var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
+
+        for (i = 0, l = attrs.length; i < l; ++i) {
+            attr = attrs.item(i);
+            attrName = attr.nodeName.toLowerCase().replace("html:", "");
+            val = attr.nodeValue;
+            if (attrName !== "contenteditable" || val !== "inherit") {
+                if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
+            }
+        }
+
+        var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
+        var content = element.innerHTML;
+
+        if (content.length > 20) {
+            content = content.substr(0, 20) + "[...]";
+        }
+
+        var res = formatted + pairs.join(" ") + ">" + content +
+                "</" + tagName + ">";
+
+        return res.replace(/ contentEditable="inherit"/, "");
+    };
+
+    function Formatio(options) {
+        for (var opt in options) {
+            this[opt] = options[opt];
+        }
+    }
+
+    Formatio.prototype = {
+        functionName: functionName,
+
+        configure: function (options) {
+            return new Formatio(options);
+        },
+
+        constructorName: function (object) {
+            return constructorName(this, object);
+        },
+
+        ascii: function (object, processed, indent) {
+            return ascii(this, object, processed, indent);
+        }
+    };
+
+    return Formatio.prototype;
+});
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.lolex=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+(function (global){
+/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
+/*global global*/
+/**
+ * @author Christian Johansen (christian@cjohansen.no) and contributors
+ * @license BSD
+ *
+ * Copyright (c) 2010-2014 Christian Johansen
+ */
+
+// node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref()
+// browsers, a number.
+// see https://github.com/cjohansen/Sinon.JS/pull/436
+var timeoutResult = setTimeout(function() {}, 0);
+var addTimerReturnsObject = typeof timeoutResult === "object";
+clearTimeout(timeoutResult);
+
+var NativeDate = Date;
+var id = 1;
+
+/**
+ * Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into
+ * number of milliseconds. This is used to support human-readable strings passed
+ * to clock.tick()
+ */
+function parseTime(str) {
+    if (!str) {
+        return 0;
+    }
+
+    var strings = str.split(":");
+    var l = strings.length, i = l;
+    var ms = 0, parsed;
+
+    if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
+        throw new Error("tick only understands numbers and 'h:m:s'");
+    }
+
+    while (i--) {
+        parsed = parseInt(strings[i], 10);
+
+        if (parsed >= 60) {
+            throw new Error("Invalid time " + str);
+        }
+
+        ms += parsed * Math.pow(60, (l - i - 1));
+    }
+
+    return ms * 1000;
+}
+
+/**
+ * Used to grok the `now` parameter to createClock.
+ */
+function getEpoch(epoch) {
+    if (!epoch) { return 0; }
+    if (typeof epoch.getTime === "function") { return epoch.getTime(); }
+    if (typeof epoch === "number") { return epoch; }
+    throw new TypeError("now should be milliseconds since UNIX epoch");
+}
+
+function inRange(from, to, timer) {
+    return timer && timer.callAt >= from && timer.callAt <= to;
+}
+
+function mirrorDateProperties(target, source) {
+    if (source.now) {
+        target.now = function now() {
+            return target.clock.now;
+        };
+    } else {
+        delete target.now;
+    }
+
+    if (source.toSource) {
+        target.toSource = function toSource() {
+            return source.toSource();
+        };
+    } else {
+        delete target.toSource;
+    }
+
+    target.toString = function toString() {
+        return source.toString();
+    };
+
+    target.prototype = source.prototype;
+    target.parse = source.parse;
+    target.UTC = source.UTC;
+    target.prototype.toUTCString = source.prototype.toUTCString;
+
+    for (var prop in source) {
+        if (source.hasOwnProperty(prop)) {
+            target[prop] = source[prop];
+        }
+    }
+
+    return target;
+}
+
+function createDate() {
+    function ClockDate(year, month, date, hour, minute, second, ms) {
+        // Defensive and verbose to avoid potential harm in passing
+        // explicit undefined when user does not pass argument
+        switch (arguments.length) {
+        case 0:
+            return new NativeDate(ClockDate.clock.now);
+        case 1:
+            return new NativeDate(year);
+        case 2:
+            return new NativeDate(year, month);
+        case 3:
+            return new NativeDate(year, month, date);
+        case 4:
+            return new NativeDate(year, month, date, hour);
+        case 5:
+            return new NativeDate(year, month, date, hour, minute);
+        case 6:
+            return new NativeDate(year, month, date, hour, minute, second);
+        default:
+            return new NativeDate(year, month, date, hour, minute, second, ms);
+        }
+    }
+
+    return mirrorDateProperties(ClockDate, NativeDate);
+}
+
+function addTimer(clock, timer) {
+    if (typeof timer.func === "undefined") {
+        throw new Error("Callback must be provided to timer calls");
+    }
+
+    if (!clock.timers) {
+        clock.timers = {};
+    }
+
+    timer.id = id++;
+    timer.createdAt = clock.now;
+    timer.callAt = clock.now + (timer.delay || 0);
+
+    clock.timers[timer.id] = timer;
+
+    if (addTimerReturnsObject) {
+        return {
+            id: timer.id,
+            ref: function() {},
+            unref: function() {}
+        };
+    }
+    else {
+        return timer.id;
+    }
+}
+
+function firstTimerInRange(clock, from, to) {
+    var timers = clock.timers, timer = null;
+
+    for (var id in timers) {
+        if (!inRange(from, to, timers[id])) {
+            continue;
+        }
+
+        if (!timer || ~compareTimers(timer, timers[id])) {
+            timer = timers[id];
+        }
+    }
+
+    return timer;
+}
+
+function compareTimers(a, b) {
+    // Sort first by absolute timing
+    if (a.callAt < b.callAt) {
+        return -1;
+    }
+    if (a.callAt > b.callAt) {
+        return 1;
+    }
+
+    // Sort next by immediate, immediate timers take precedence
+    if (a.immediate && !b.immediate) {
+        return -1;
+    }
+    if (!a.immediate && b.immediate) {
+        return 1;
+    }
+
+    // Sort next by creation time, earlier-created timers take precedence
+    if (a.createdAt < b.createdAt) {
+        return -1;
+    }
+    if (a.createdAt > b.createdAt) {
+        return 1;
+    }
+
+    // Sort next by id, lower-id timers take precedence
+    if (a.id < b.id) {
+        return -1;
+    }
+    if (a.id > b.id) {
+        return 1;
+    }
+
+    // As timer ids are unique, no fallback `0` is necessary
+}
+
+function callTimer(clock, timer) {
+    if (typeof timer.interval == "number") {
+        clock.timers[timer.id].callAt += timer.interval;
+    } else {
+        delete clock.timers[timer.id];
+    }
+
+    try {
+        if (typeof timer.func == "function") {
+            timer.func.apply(null, timer.args);
+        } else {
+            eval(timer.func);
+        }
+    } catch (e) {
+        var exception = e;
+    }
+
+    if (!clock.timers[timer.id]) {
+        if (exception) {
+            throw exception;
+        }
+        return;
+    }
+
+    if (exception) {
+        throw exception;
+    }
+}
+
+function uninstall(clock, target) {
+    var method;
+
+    for (var i = 0, l = clock.methods.length; i < l; i++) {
+        method = clock.methods[i];
+
+        if (target[method].hadOwnProperty) {
+            target[method] = clock["_" + method];
+        } else {
+            try {
+                delete target[method];
+            } catch (e) {}
+        }
+    }
+
+    // Prevent multiple executions which will completely remove these props
+    clock.methods = [];
+}
+
+function hijackMethod(target, method, clock) {
+    clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
+    clock["_" + method] = target[method];
+
+    if (method == "Date") {
+        var date = mirrorDateProperties(clock[method], target[method]);
+        target[method] = date;
+    } else {
+        target[method] = function () {
+            return clock[method].apply(clock, arguments);
+        };
+
+        for (var prop in clock[method]) {
+            if (clock[method].hasOwnProperty(prop)) {
+                target[method][prop] = clock[method][prop];
+            }
+        }
+    }
+
+    target[method].clock = clock;
+}
+
+var timers = {
+    setTimeout: setTimeout,
+    clearTimeout: clearTimeout,
+    setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
+    clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
+    setInterval: setInterval,
+    clearInterval: clearInterval,
+    Date: Date
+};
+
+var keys = Object.keys || function (obj) {
+    var ks = [];
+    for (var key in obj) {
+        ks.push(key);
+    }
+    return ks;
+};
+
+exports.timers = timers;
+
+var createClock = exports.createClock = function (now) {
+    var clock = {
+        now: getEpoch(now),
+        timeouts: {},
+        Date: createDate()
+    };
+
+    clock.Date.clock = clock;
+
+    clock.setTimeout = function setTimeout(func, timeout) {
+        return addTimer(clock, {
+            func: func,
+            args: Array.prototype.slice.call(arguments, 2),
+            delay: timeout
+        });
+    };
+
+    clock.clearTimeout = function clearTimeout(timerId) {
+        if (!timerId) {
+            // null appears to be allowed in most browsers, and appears to be
+            // relied upon by some libraries, like Bootstrap carousel
+            return;
+        }
+        if (!clock.timers) {
+            clock.timers = [];
+        }
+        // in Node, timerId is an object with .ref()/.unref(), and
+        // its .id field is the actual timer id.
+        if (typeof timerId === "object") {
+            timerId = timerId.id
+        }
+        if (timerId in clock.timers) {
+            delete clock.timers[timerId];
+        }
+    };
+
+    clock.setInterval = function setInterval(func, timeout) {
+        return addTimer(clock, {
+            func: func,
+            args: Array.prototype.slice.call(arguments, 2),
+            delay: timeout,
+            interval: timeout
+        });
+    };
+
+    clock.clearInterval = function clearInterval(timerId) {
+        clock.clearTimeout(timerId);
+    };
+
+    clock.setImmediate = function setImmediate(func) {
+        return addTimer(clock, {
+            func: func,
+            args: Array.prototype.slice.call(arguments, 1),
+            immediate: true
+        });
+    };
+
+    clock.clearImmediate = function clearImmediate(timerId) {
+        clock.clearTimeout(timerId);
+    };
+
+    clock.tick = function tick(ms) {
+        ms = typeof ms == "number" ? ms : parseTime(ms);
+        var tickFrom = clock.now, tickTo = clock.now + ms, previous = clock.now;
+        var timer = firstTimerInRange(clock, tickFrom, tickTo);
+
+        var firstException;
+        while (timer && tickFrom <= tickTo) {
+            if (clock.timers[timer.id]) {
+                tickFrom = clock.now = timer.callAt;
+                try {
+                    callTimer(clock, timer);
+                } catch (e) {
+                    firstException = firstException || e;
+                }
+            }
+
+            timer = firstTimerInRange(clock, previous, tickTo);
+            previous = tickFrom;
+        }
+
+        clock.now = tickTo;
+
+        if (firstException) {
+            throw firstException;
+        }
+
+        return clock.now;
+    };
+
+    clock.reset = function reset() {
+        clock.timers = {};
+    };
+
+    return clock;
+};
+
+exports.install = function install(target, now, toFake) {
+    if (typeof target === "number") {
+        toFake = now;
+        now = target;
+        target = null;
+    }
+
+    if (!target) {
+        target = global;
+    }
+
+    var clock = createClock(now);
+
+    clock.uninstall = function () {
+        uninstall(clock, target);
+    };
+
+    clock.methods = toFake || [];
+
+    if (clock.methods.length === 0) {
+        clock.methods = keys(timers);
+    }
+
+    for (var i = 0, l = clock.methods.length; i < l; i++) {
+        hijackMethod(target, clock.methods[i], clock);
+    }
+
+    return clock;
+};
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}]},{},[1])(1)
+});
+  })();
+  var define;
+/**
+ * Sinon core utilities. For internal use only.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+var sinon = (function () {
+"use strict";
+
+    var sinon;
+    var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        sinon = module.exports = require("./sinon/util/core");
+        require("./sinon/extend");
+        require("./sinon/typeOf");
+        require("./sinon/times_in_words");
+        require("./sinon/spy");
+        require("./sinon/call");
+        require("./sinon/behavior");
+        require("./sinon/stub");
+        require("./sinon/mock");
+        require("./sinon/collection");
+        require("./sinon/assert");
+        require("./sinon/sandbox");
+        require("./sinon/test");
+        require("./sinon/test_case");
+        require("./sinon/match");
+        require("./sinon/format");
+        require("./sinon/log_error");
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+        sinon = module.exports;
+    } else {
+        sinon = {};
+    }
+
+    return sinon;
+}());
+
+/**
+ * @depend ../../sinon.js
+ */
+/**
+ * Sinon core utilities. For internal use only.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var div = typeof document != "undefined" && document.createElement("div");
+    var hasOwn = Object.prototype.hasOwnProperty;
+
+    function isDOMNode(obj) {
+        var success = false;
+
+        try {
+            obj.appendChild(div);
+            success = div.parentNode == obj;
+        } catch (e) {
+            return false;
+        } finally {
+            try {
+                obj.removeChild(div);
+            } catch (e) {
+                // Remove failed, not much we can do about that
+            }
+        }
+
+        return success;
+    }
+
+    function isElement(obj) {
+        return div && obj && obj.nodeType === 1 && isDOMNode(obj);
+    }
+
+    function isFunction(obj) {
+        return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply);
+    }
+
+    function isReallyNaN(val) {
+        return typeof val === "number" && isNaN(val);
+    }
+
+    function mirrorProperties(target, source) {
+        for (var prop in source) {
+            if (!hasOwn.call(target, prop)) {
+                target[prop] = source[prop];
+            }
+        }
+    }
+
+    function isRestorable(obj) {
+        return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
+    }
+
+    function makeApi(sinon) {
+        sinon.wrapMethod = function wrapMethod(object, property, method) {
+            if (!object) {
+                throw new TypeError("Should wrap property of object");
+            }
+
+            if (typeof method != "function") {
+                throw new TypeError("Method wrapper should be function");
+            }
+
+            var wrappedMethod = object[property],
+                error;
+
+            if (!isFunction(wrappedMethod)) {
+                error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
+                                    property + " as function");
+            } else if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
+                error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
+            } else if (wrappedMethod.calledBefore) {
+                var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
+                error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
+            }
+
+            if (error) {
+                if (wrappedMethod && wrappedMethod.stackTrace) {
+                    error.stack += "\n--------------\n" + wrappedMethod.stackTrace;
+                }
+                throw error;
+            }
+
+            // IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
+            // when using hasOwn.call on objects from other frames.
+            var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
+            object[property] = method;
+            method.displayName = property;
+            // Set up a stack trace which can be used later to find what line of
+            // code the original method was created on.
+            method.stackTrace = (new Error("Stack Trace for original")).stack;
+
+            method.restore = function () {
+                // For prototype properties try to reset by delete first.
+                // If this fails (ex: localStorage on mobile safari) then force a reset
+                // via direct assignment.
+                if (!owned) {
+                    delete object[property];
+                }
+                if (object[property] === method) {
+                    object[property] = wrappedMethod;
+                }
+            };
+
+            method.restore.sinon = true;
+            mirrorProperties(method, wrappedMethod);
+
+            return method;
+        };
+
+        sinon.create = function create(proto) {
+            var F = function () {};
+            F.prototype = proto;
+            return new F();
+        };
+
+        sinon.deepEqual = function deepEqual(a, b) {
+            if (sinon.match && sinon.match.isMatcher(a)) {
+                return a.test(b);
+            }
+
+            if (typeof a != "object" || typeof b != "object") {
+                if (isReallyNaN(a) && isReallyNaN(b)) {
+                    return true;
+                } else {
+                    return a === b;
+                }
+            }
+
+            if (isElement(a) || isElement(b)) {
+                return a === b;
+            }
+
+            if (a === b) {
+                return true;
+            }
+
+            if ((a === null && b !== null) || (a !== null && b === null)) {
+                return false;
+            }
+
+            if (a instanceof RegExp && b instanceof RegExp) {
+                return (a.source === b.source) && (a.global === b.global) &&
+                    (a.ignoreCase === b.ignoreCase) && (a.multiline === b.multiline);
+            }
+
+            var aString = Object.prototype.toString.call(a);
+            if (aString != Object.prototype.toString.call(b)) {
+                return false;
+            }
+
+            if (aString == "[object Date]") {
+                return a.valueOf() === b.valueOf();
+            }
+
+            var prop, aLength = 0, bLength = 0;
+
+            if (aString == "[object Array]" && a.length !== b.length) {
+                return false;
+            }
+
+            for (prop in a) {
+                aLength += 1;
+
+                if (!(prop in b)) {
+                    return false;
+                }
+
+                if (!deepEqual(a[prop], b[prop])) {
+                    return false;
+                }
+            }
+
+            for (prop in b) {
+                bLength += 1;
+            }
+
+            return aLength == bLength;
+        };
+
+        sinon.functionName = function functionName(func) {
+            var name = func.displayName || func.name;
+
+            // Use function decomposition as a last resort to get function
+            // name. Does not rely on function decomposition to work - if it
+            // doesn't debugging will be slightly less informative
+            // (i.e. toString will say 'spy' rather than 'myFunc').
+            if (!name) {
+                var matches = func.toString().match(/function ([^\s\(]+)/);
+                name = matches && matches[1];
+            }
+
+            return name;
+        };
+
+        sinon.functionToString = function toString() {
+            if (this.getCall && this.callCount) {
+                var thisValue, prop, i = this.callCount;
+
+                while (i--) {
+                    thisValue = this.getCall(i).thisValue;
+
+                    for (prop in thisValue) {
+                        if (thisValue[prop] === this) {
+                            return prop;
+                        }
+                    }
+                }
+            }
+
+            return this.displayName || "sinon fake";
+        };
+
+        sinon.getConfig = function (custom) {
+            var config = {};
+            custom = custom || {};
+            var defaults = sinon.defaultConfig;
+
+            for (var prop in defaults) {
+                if (defaults.hasOwnProperty(prop)) {
+                    config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
+                }
+            }
+
+            return config;
+        };
+
+        sinon.defaultConfig = {
+            injectIntoThis: true,
+            injectInto: null,
+            properties: ["spy", "stub", "mock", "clock", "server", "requests"],
+            useFakeTimers: true,
+            useFakeServer: true
+        };
+
+        sinon.timesInWords = function timesInWords(count) {
+            return count == 1 && "once" ||
+                count == 2 && "twice" ||
+                count == 3 && "thrice" ||
+                (count || 0) + " times";
+        };
+
+        sinon.calledInOrder = function (spies) {
+            for (var i = 1, l = spies.length; i < l; i++) {
+                if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
+                    return false;
+                }
+            }
+
+            return true;
+        };
+
+        sinon.orderByFirstCall = function (spies) {
+            return spies.sort(function (a, b) {
+                // uuid, won't ever be equal
+                var aCall = a.getCall(0);
+                var bCall = b.getCall(0);
+                var aId = aCall && aCall.callId || -1;
+                var bId = bCall && bCall.callId || -1;
+
+                return aId < bId ? -1 : 1;
+            });
+        };
+
+        sinon.createStubInstance = function (constructor) {
+            if (typeof constructor !== "function") {
+                throw new TypeError("The constructor should be a function.");
+            }
+            return sinon.stub(sinon.create(constructor.prototype));
+        };
+
+        sinon.restore = function (object) {
+            if (object !== null && typeof object === "object") {
+                for (var prop in object) {
+                    if (isRestorable(object[prop])) {
+                        object[prop].restore();
+                    }
+                }
+            } else if (isRestorable(object)) {
+                object.restore();
+            }
+        };
+
+        return sinon;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports) {
+        makeApi(exports);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ */
+
+(function (sinon) {
+    function makeApi(sinon) {
+
+        // Adapted from https://developer.mozilla.org/en/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
+        var hasDontEnumBug = (function () {
+            var obj = {
+                constructor: function () {
+                    return "0";
+                },
+                toString: function () {
+                    return "1";
+                },
+                valueOf: function () {
+                    return "2";
+                },
+                toLocaleString: function () {
+                    return "3";
+                },
+                prototype: function () {
+                    return "4";
+                },
+                isPrototypeOf: function () {
+                    return "5";
+                },
+                propertyIsEnumerable: function () {
+                    return "6";
+                },
+                hasOwnProperty: function () {
+                    return "7";
+                },
+                length: function () {
+                    return "8";
+                },
+                unique: function () {
+                    return "9"
+                }
+            };
+
+            var result = [];
+            for (var prop in obj) {
+                result.push(obj[prop]());
+            }
+            return result.join("") !== "0123456789";
+        })();
+
+        /* Public: Extend target in place with all (own) properties from sources in-order. Thus, last source will
+         *         override properties in previous sources.
+         *
+         * target - The Object to extend
+         * sources - Objects to copy properties from.
+         *
+         * Returns the extended target
+         */
+        function extend(target /*, sources */) {
+            var sources = Array.prototype.slice.call(arguments, 1),
+                source, i, prop;
+
+            for (i = 0; i < sources.length; i++) {
+                source = sources[i];
+
+                for (prop in source) {
+                    if (source.hasOwnProperty(prop)) {
+                        target[prop] = source[prop];
+                    }
+                }
+
+                // Make sure we copy (own) toString method even when in JScript with DontEnum bug
+                // See https://developer.mozilla.org/en/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
+                if (hasDontEnumBug && source.hasOwnProperty("toString") && source.toString !== target.toString) {
+                    target.toString = source.toString;
+                }
+            }
+
+            return target;
+        };
+
+        sinon.extend = extend;
+        return sinon.extend;
+    }
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        module.exports = makeApi(sinon);
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ */
+
+(function (sinon) {
+    function makeApi(sinon) {
+
+        function timesInWords(count) {
+            switch (count) {
+                case 1:
+                    return "once";
+                case 2:
+                    return "twice";
+                case 3:
+                    return "thrice";
+                default:
+                    return (count || 0) + " times";
+            }
+        }
+
+        sinon.timesInWords = timesInWords;
+        return sinon.timesInWords;
+    }
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        module.exports = makeApi(sinon);
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ */
+/**
+ * Format functions
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2014 Christian Johansen
+ */
+
+(function (sinon, formatio) {
+    function makeApi(sinon) {
+        function typeOf(value) {
+            if (value === null) {
+                return "null";
+            } else if (value === undefined) {
+                return "undefined";
+            }
+            var string = Object.prototype.toString.call(value);
+            return string.substring(8, string.length - 1).toLowerCase();
+        };
+
+        sinon.typeOf = typeOf;
+        return sinon.typeOf;
+    }
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        module.exports = makeApi(sinon);
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(
+    (typeof sinon == "object" && sinon || null),
+    (typeof formatio == "object" && formatio)
+));
+
+/**
+ * @depend util/core.js
+ * @depend typeOf.js
+ */
+/*jslint eqeqeq: false, onevar: false, plusplus: false*/
+/*global module, require, sinon*/
+/**
+ * Match functions
+ *
+ * @author Maximilian Antoni (mail@maxantoni.de)
+ * @license BSD
+ *
+ * Copyright (c) 2012 Maximilian Antoni
+ */
+
+(function (sinon) {
+    function makeApi(sinon) {
+        function assertType(value, type, name) {
+            var actual = sinon.typeOf(value);
+            if (actual !== type) {
+                throw new TypeError("Expected type of " + name + " to be " +
+                    type + ", but was " + actual);
+            }
+        }
+
+        var matcher = {
+            toString: function () {
+                return this.message;
+            }
+        };
+
+        function isMatcher(object) {
+            return matcher.isPrototypeOf(object);
+        }
+
+        function matchObject(expectation, actual) {
+            if (actual === null || actual === undefined) {
+                return false;
+            }
+            for (var key in expectation) {
+                if (expectation.hasOwnProperty(key)) {
+                    var exp = expectation[key];
+                    var act = actual[key];
+                    if (match.isMatcher(exp)) {
+                        if (!exp.test(act)) {
+                            return false;
+                        }
+                    } else if (sinon.typeOf(exp) === "object") {
+                        if (!matchObject(exp, act)) {
+                            return false;
+                        }
+                    } else if (!sinon.deepEqual(exp, act)) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+
+        matcher.or = function (m2) {
+            if (!arguments.length) {
+                throw new TypeError("Matcher expected");
+            } else if (!isMatcher(m2)) {
+                m2 = match(m2);
+            }
+            var m1 = this;
+            var or = sinon.create(matcher);
+            or.test = function (actual) {
+                return m1.test(actual) || m2.test(actual);
+            };
+            or.message = m1.message + ".or(" + m2.message + ")";
+            return or;
+        };
+
+        matcher.and = function (m2) {
+            if (!arguments.length) {
+                throw new TypeError("Matcher expected");
+            } else if (!isMatcher(m2)) {
+                m2 = match(m2);
+            }
+            var m1 = this;
+            var and = sinon.create(matcher);
+            and.test = function (actual) {
+                return m1.test(actual) && m2.test(actual);
+            };
+            and.message = m1.message + ".and(" + m2.message + ")";
+            return and;
+        };
+
+        var match = function (expectation, message) {
+            var m = sinon.create(matcher);
+            var type = sinon.typeOf(expectation);
+            switch (type) {
+            case "object":
+                if (typeof expectation.test === "function") {
+                    m.test = function (actual) {
+                        return expectation.test(actual) === true;
+                    };
+                    m.message = "match(" + sinon.functionName(expectation.test) + ")";
+                    return m;
+                }
+                var str = [];
+                for (var key in expectation) {
+                    if (expectation.hasOwnProperty(key)) {
+                        str.push(key + ": " + expectation[key]);
+                    }
+                }
+                m.test = function (actual) {
+                    return matchObject(expectation, actual);
+                };
+                m.message = "match(" + str.join(", ") + ")";
+                break;
+            case "number":
+                m.test = function (actual) {
+                    return expectation == actual;
+                };
+                break;
+            case "string":
+                m.test = function (actual) {
+                    if (typeof actual !== "string") {
+                        return false;
+                    }
+                    return actual.indexOf(expectation) !== -1;
+                };
+                m.message = "match(\"" + expectation + "\")";
+                break;
+            case "regexp":
+                m.test = function (actual) {
+                    if (typeof actual !== "string") {
+                        return false;
+                    }
+                    return expectation.test(actual);
+                };
+                break;
+            case "function":
+                m.test = expectation;
+                if (message) {
+                    m.message = message;
+                } else {
+                    m.message = "match(" + sinon.functionName(expectation) + ")";
+                }
+                break;
+            default:
+                m.test = function (actual) {
+                    return sinon.deepEqual(expectation, actual);
+                };
+            }
+            if (!m.message) {
+                m.message = "match(" + expectation + ")";
+            }
+            return m;
+        };
+
+        match.isMatcher = isMatcher;
+
+        match.any = match(function () {
+            return true;
+        }, "any");
+
+        match.defined = match(function (actual) {
+            return actual !== null && actual !== undefined;
+        }, "defined");
+
+        match.truthy = match(function (actual) {
+            return !!actual;
+        }, "truthy");
+
+        match.falsy = match(function (actual) {
+            return !actual;
+        }, "falsy");
+
+        match.same = function (expectation) {
+            return match(function (actual) {
+                return expectation === actual;
+            }, "same(" + expectation + ")");
+        };
+
+        match.typeOf = function (type) {
+            assertType(type, "string", "type");
+            return match(function (actual) {
+                return sinon.typeOf(actual) === type;
+            }, "typeOf(\"" + type + "\")");
+        };
+
+        match.instanceOf = function (type) {
+            assertType(type, "function", "type");
+            return match(function (actual) {
+                return actual instanceof type;
+            }, "instanceOf(" + sinon.functionName(type) + ")");
+        };
+
+        function createPropertyMatcher(propertyTest, messagePrefix) {
+            return function (property, value) {
+                assertType(property, "string", "property");
+                var onlyProperty = arguments.length === 1;
+                var message = messagePrefix + "(\"" + property + "\"";
+                if (!onlyProperty) {
+                    message += ", " + value;
+                }
+                message += ")";
+                return match(function (actual) {
+                    if (actual === undefined || actual === null ||
+                            !propertyTest(actual, property)) {
+                        return false;
+                    }
+                    return onlyProperty || sinon.deepEqual(value, actual[property]);
+                }, message);
+            };
+        }
+
+        match.has = createPropertyMatcher(function (actual, property) {
+            if (typeof actual === "object") {
+                return property in actual;
+            }
+            return actual[property] !== undefined;
+        }, "has");
+
+        match.hasOwn = createPropertyMatcher(function (actual, property) {
+            return actual.hasOwnProperty(property);
+        }, "hasOwn");
+
+        match.bool = match.typeOf("boolean");
+        match.number = match.typeOf("number");
+        match.string = match.typeOf("string");
+        match.object = match.typeOf("object");
+        match.func = match.typeOf("function");
+        match.array = match.typeOf("array");
+        match.regexp = match.typeOf("regexp");
+        match.date = match.typeOf("date");
+
+        sinon.match = match;
+        return match;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        module.exports = makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ */
+/**
+ * Format functions
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2014 Christian Johansen
+ */
+
+(function (sinon, formatio) {
+    function makeApi(sinon) {
+        function valueFormatter(value) {
+            return "" + value;
+        }
+
+        function getFormatioFormatter() {
+            var formatter = formatio.configure({
+                    quoteStrings: false,
+                    limitChildrenCount: 250
+                });
+
+            function format() {
+                return formatter.ascii.apply(formatter, arguments);
+            };
+
+            return format;
+        }
+
+        function getNodeFormatter(value) {
+            function format(value) {
+                return typeof value == "object" && value.toString === Object.prototype.toString ? util.inspect(value) : value;
+            };
+
+            try {
+                var util = require("util");
+            } catch (e) {
+                /* Node, but no util module - would be very old, but better safe than sorry */
+            }
+
+            return util ? format : valueFormatter;
+        }
+
+        var isNode = typeof module !== "undefined" && module.exports && typeof require == "function",
+            formatter;
+
+        if (isNode) {
+            try {
+                formatio = require("formatio");
+            } catch (e) {}
+        }
+
+        if (formatio) {
+            formatter = getFormatioFormatter()
+        } else if (isNode) {
+            formatter = getNodeFormatter();
+        } else {
+            formatter = valueFormatter;
+        }
+
+        sinon.format = formatter;
+        return sinon.format;
+    }
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        module.exports = makeApi(sinon);
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(
+    (typeof sinon == "object" && sinon || null),
+    (typeof formatio == "object" && formatio)
+));
+
+/**
+  * @depend util/core.js
+  * @depend match.js
+  * @depend format.js
+  */
+/**
+  * Spy calls
+  *
+  * @author Christian Johansen (christian@cjohansen.no)
+  * @author Maximilian Antoni (mail@maxantoni.de)
+  * @license BSD
+  *
+  * Copyright (c) 2010-2013 Christian Johansen
+  * Copyright (c) 2013 Maximilian Antoni
+  */
+
+(function (sinon) {
+    function makeApi(sinon) {
+        function throwYieldError(proxy, text, args) {
+            var msg = sinon.functionName(proxy) + text;
+            if (args.length) {
+                msg += " Received [" + slice.call(args).join(", ") + "]";
+            }
+            throw new Error(msg);
+        }
+
+        var slice = Array.prototype.slice;
+
+        var callProto = {
+            calledOn: function calledOn(thisValue) {
+                if (sinon.match && sinon.match.isMatcher(thisValue)) {
+                    return thisValue.test(this.thisValue);
+                }
+                return this.thisValue === thisValue;
+            },
+
+            calledWith: function calledWith() {
+                for (var i = 0, l = arguments.length; i < l; i += 1) {
+                    if (!sinon.deepEqual(arguments[i], this.args[i])) {
+                        return false;
+                    }
+                }
+
+                return true;
+            },
+
+            calledWithMatch: function calledWithMatch() {
+                for (var i = 0, l = arguments.length; i < l; i += 1) {
+                    var actual = this.args[i];
+                    var expectation = arguments[i];
+                    if (!sinon.match || !sinon.match(expectation).test(actual)) {
+                        return false;
+                    }
+                }
+                return true;
+            },
+
+            calledWithExactly: function calledWithExactly() {
+                return arguments.length == this.args.length &&
+                    this.calledWith.apply(this, arguments);
+            },
+
+            notCalledWith: function notCalledWith() {
+                return !this.calledWith.apply(this, arguments);
+            },
+
+            notCalledWithMatch: function notCalledWithMatch() {
+                return !this.calledWithMatch.apply(this, arguments);
+            },
+
+            returned: function returned(value) {
+                return sinon.deepEqual(value, this.returnValue);
+            },
+
+            threw: function threw(error) {
+                if (typeof error === "undefined" || !this.exception) {
+                    return !!this.exception;
+                }
+
+                return this.exception === error || this.exception.name === error;
+            },
+
+            calledWithNew: function calledWithNew() {
+                return this.proxy.prototype && this.thisValue instanceof this.proxy;
+            },
+
+            calledBefore: function (other) {
+                return this.callId < other.callId;
+            },
+
+            calledAfter: function (other) {
+                return this.callId > other.callId;
+            },
+
+            callArg: function (pos) {
+                this.args[pos]();
+            },
+
+            callArgOn: function (pos, thisValue) {
+                this.args[pos].apply(thisValue);
+            },
+
+            callArgWith: function (pos) {
+                this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
+            },
+
+            callArgOnWith: function (pos, thisValue) {
+                var args = slice.call(arguments, 2);
+                this.args[pos].apply(thisValue, args);
+            },
+
+            yield: function () {
+                this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
+            },
+
+            yieldOn: function (thisValue) {
+                var args = this.args;
+                for (var i = 0, l = args.length; i < l; ++i) {
+                    if (typeof args[i] === "function") {
+                        args[i].apply(thisValue, slice.call(arguments, 1));
+                        return;
+                    }
+                }
+                throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
+            },
+
+            yieldTo: function (prop) {
+                this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
+            },
+
+            yieldToOn: function (prop, thisValue) {
+                var args = this.args;
+                for (var i = 0, l = args.length; i < l; ++i) {
+                    if (args[i] && typeof args[i][prop] === "function") {
+                        args[i][prop].apply(thisValue, slice.call(arguments, 2));
+                        return;
+                    }
+                }
+                throwYieldError(this.proxy, " cannot yield to '" + prop +
+                    "' since no callback was passed.", args);
+            },
+
+            toString: function () {
+                var callStr = this.proxy.toString() + "(";
+                var args = [];
+
+                for (var i = 0, l = this.args.length; i < l; ++i) {
+                    args.push(sinon.format(this.args[i]));
+                }
+
+                callStr = callStr + args.join(", ") + ")";
+
+                if (typeof this.returnValue != "undefined") {
+                    callStr += " => " + sinon.format(this.returnValue);
+                }
+
+                if (this.exception) {
+                    callStr += " !" + this.exception.name;
+
+                    if (this.exception.message) {
+                        callStr += "(" + this.exception.message + ")";
+                    }
+                }
+
+                return callStr;
+            }
+        };
+
+        callProto.invokeCallback = callProto.yield;
+
+        function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
+            if (typeof id !== "number") {
+                throw new TypeError("Call id is not a number");
+            }
+            var proxyCall = sinon.create(callProto);
+            proxyCall.proxy = spy;
+            proxyCall.thisValue = thisValue;
+            proxyCall.args = args;
+            proxyCall.returnValue = returnValue;
+            proxyCall.exception = exception;
+            proxyCall.callId = id;
+
+            return proxyCall;
+        }
+        createSpyCall.toString = callProto.toString; // used by mocks
+
+        sinon.spyCall = createSpyCall;
+        return createSpyCall;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        require("./match");
+        module.exports = makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+  * @depend times_in_words.js
+  * @depend util/core.js
+  * @depend extend.js
+  * @depend call.js
+  * @depend format.js
+  */
+/**
+  * Spy functions
+  *
+  * @author Christian Johansen (christian@cjohansen.no)
+  * @license BSD
+  *
+  * Copyright (c) 2010-2013 Christian Johansen
+  */
+
+(function (sinon) {
+    function makeApi(sinon) {
+        var push = Array.prototype.push;
+        var slice = Array.prototype.slice;
+        var callId = 0;
+
+        function spy(object, property) {
+            if (!property && typeof object == "function") {
+                return spy.create(object);
+            }
+
+            if (!object && !property) {
+                return spy.create(function () { });
+            }
+
+            var method = object[property];
+            return sinon.wrapMethod(object, property, spy.create(method));
+        }
+
+        function matchingFake(fakes, args, strict) {
+            if (!fakes) {
+                return;
+            }
+
+            for (var i = 0, l = fakes.length; i < l; i++) {
+                if (fakes[i].matches(args, strict)) {
+                    return fakes[i];
+                }
+            }
+        }
+
+        function incrementCallCount() {
+            this.called = true;
+            this.callCount += 1;
+            this.notCalled = false;
+            this.calledOnce = this.callCount == 1;
+            this.calledTwice = this.callCount == 2;
+            this.calledThrice = this.callCount == 3;
+        }
+
+        function createCallProperties() {
+            this.firstCall = this.getCall(0);
+            this.secondCall = this.getCall(1);
+            this.thirdCall = this.getCall(2);
+            this.lastCall = this.getCall(this.callCount - 1);
+        }
+
+        var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
+        function createProxy(func, proxyLength) {
+            // Retain the function length:
+            var p;
+            if (proxyLength) {
+                eval("p = (function proxy(" + vars.substring(0, proxyLength * 2 - 1) +
+                    ") { return p.invoke(func, this, slice.call(arguments)); });");
+            } else {
+                p = function proxy() {
+                    return p.invoke(func, this, slice.call(arguments));
+                };
+            }
+            return p;
+        }
+
+        var uuid = 0;
+
+        // Public API
+        var spyApi = {
+            reset: function () {
+                if (this.invoking) {
+                    var err = new Error("Cannot reset Sinon function while invoking it. " +
+                                        "Move the call to .reset outside of the callback.");
+                    err.name = "InvalidResetException";
+                    throw err;
+                }
+
+                this.called = false;
+                this.notCalled = true;
+                this.calledOnce = false;
+                this.calledTwice = false;
+                this.calledThrice = false;
+                this.callCount = 0;
+                this.firstCall = null;
+                this.secondCall = null;
+                this.thirdCall = null;
+                this.lastCall = null;
+                this.args = [];
+                this.returnValues = [];
+                this.thisValues = [];
+                this.exceptions = [];
+                this.callIds = [];
+                if (this.fakes) {
+                    for (var i = 0; i < this.fakes.length; i++) {
+                        this.fakes[i].reset();
+                    }
+                }
+
+                return this;
+            },
+
+            create: function create(func, spyLength) {
+                var name;
+
+                if (typeof func != "function") {
+                    func = function () { };
+                } else {
+                    name = sinon.functionName(func);
+                }
+
+                if (!spyLength) {
+                    spyLength = func.length;
+                }
+
+                var proxy = createProxy(func, spyLength);
+
+                sinon.extend(proxy, spy);
+                delete proxy.create;
+                sinon.extend(proxy, func);
+
+                proxy.reset();
+                proxy.prototype = func.prototype;
+                proxy.displayName = name || "spy";
+                proxy.toString = sinon.functionToString;
+                proxy.instantiateFake = sinon.spy.create;
+                proxy.id = "spy#" + uuid++;
+
+                return proxy;
+            },
+
+            invoke: function invoke(func, thisValue, args) {
+                var matching = matchingFake(this.fakes, args);
+                var exception, returnValue;
+
+                incrementCallCount.call(this);
+                push.call(this.thisValues, thisValue);
+                push.call(this.args, args);
+                push.call(this.callIds, callId++);
+
+                // Make call properties available from within the spied function:
+                createCallProperties.call(this);
+
+                try {
+                    this.invoking = true;
+
+                    if (matching) {
+                        returnValue = matching.invoke(func, thisValue, args);
+                    } else {
+                        returnValue = (this.func || func).apply(thisValue, args);
+                    }
+
+                    var thisCall = this.getCall(this.callCount - 1);
+                    if (thisCall.calledWithNew() && typeof returnValue !== "object") {
+                        returnValue = thisValue;
+                    }
+                } catch (e) {
+                    exception = e;
+                } finally {
+                    delete this.invoking;
+                }
+
+                push.call(this.exceptions, exception);
+                push.call(this.returnValues, returnValue);
+
+                // Make return value and exception available in the calls:
+                createCallProperties.call(this);
+
+                if (exception !== undefined) {
+                    throw exception;
+                }
+
+                return returnValue;
+            },
+
+            named: function named(name) {
+                this.displayName = name;
+                return this;
+            },
+
+            getCall: function getCall(i) {
+                if (i < 0 || i >= this.callCount) {
+                    return null;
+                }
+
+                return sinon.spyCall(this, this.thisValues[i], this.args[i],
+                                        this.returnValues[i], this.exceptions[i],
+                                        this.callIds[i]);
+            },
+
+            getCalls: function () {
+                var calls = [];
+                var i;
+
+                for (i = 0; i < this.callCount; i++) {
+                    calls.push(this.getCall(i));
+                }
+
+                return calls;
+            },
+
+            calledBefore: function calledBefore(spyFn) {
+                if (!this.called) {
+                    return false;
+                }
+
+                if (!spyFn.called) {
+                    return true;
+                }
+
+                return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
+            },
+
+            calledAfter: function calledAfter(spyFn) {
+                if (!this.called || !spyFn.called) {
+                    return false;
+                }
+
+                return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
+            },
+
+            withArgs: function () {
+                var args = slice.call(arguments);
+
+                if (this.fakes) {
+                    var match = matchingFake(this.fakes, args, true);
+
+                    if (match) {
+                        return match;
+                    }
+                } else {
+                    this.fakes = [];
+                }
+
+                var original = this;
+                var fake = this.instantiateFake();
+                fake.matchingAguments = args;
+                fake.parent = this;
+                push.call(this.fakes, fake);
+
+                fake.withArgs = function () {
+                    return original.withArgs.apply(original, arguments);
+                };
+
+                for (var i = 0; i < this.args.length; i++) {
+                    if (fake.matches(this.args[i])) {
+                        incrementCallCount.call(fake);
+                        push.call(fake.thisValues, this.thisValues[i]);
+                        push.call(fake.args, this.args[i]);
+                        push.call(fake.returnValues, this.returnValues[i]);
+                        push.call(fake.exceptions, this.exceptions[i]);
+                        push.call(fake.callIds, this.callIds[i]);
+                    }
+                }
+                createCallProperties.call(fake);
+
+                return fake;
+            },
+
+            matches: function (args, strict) {
+                var margs = this.matchingAguments;
+
+                if (margs.length <= args.length &&
+                    sinon.deepEqual(margs, args.slice(0, margs.length))) {
+                    return !strict || margs.length == args.length;
+                }
+            },
+
+            printf: function (format) {
+                var spy = this;
+                var args = slice.call(arguments, 1);
+                var formatter;
+
+                return (format || "").replace(/%(.)/g, function (match, specifyer) {
+                    formatter = spyApi.formatters[specifyer];
+
+                    if (typeof formatter == "function") {
+                        return formatter.call(null, spy, args);
+                    } else if (!isNaN(parseInt(specifyer, 10))) {
+                        return sinon.format(args[specifyer - 1]);
+                    }
+
+                    return "%" + specifyer;
+                });
+            }
+        };
+
+        function delegateToCalls(method, matchAny, actual, notCalled) {
+            spyApi[method] = function () {
+                if (!this.called) {
+                    if (notCalled) {
+                        return notCalled.apply(this, arguments);
+                    }
+                    return false;
+                }
+
+                var currentCall;
+                var matches = 0;
+
+                for (var i = 0, l = this.callCount; i < l; i += 1) {
+                    currentCall = this.getCall(i);
+
+                    if (currentCall[actual || method].apply(currentCall, arguments)) {
+                        matches += 1;
+
+                        if (matchAny) {
+                            return true;
+                        }
+                    }
+                }
+
+                return matches === this.callCount;
+            };
+        }
+
+        delegateToCalls("calledOn", true);
+        delegateToCalls("alwaysCalledOn", false, "calledOn");
+        delegateToCalls("calledWith", true);
+        delegateToCalls("calledWithMatch", true);
+        delegateToCalls("alwaysCalledWith", false, "calledWith");
+        delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
+        delegateToCalls("calledWithExactly", true);
+        delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
+        delegateToCalls("neverCalledWith", false, "notCalledWith",
+            function () { return true; });
+        delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
+            function () { return true; });
+        delegateToCalls("threw", true);
+        delegateToCalls("alwaysThrew", false, "threw");
+        delegateToCalls("returned", true);
+        delegateToCalls("alwaysReturned", false, "returned");
+        delegateToCalls("calledWithNew", true);
+        delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
+        delegateToCalls("callArg", false, "callArgWith", function () {
+            throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
+        });
+        spyApi.callArgWith = spyApi.callArg;
+        delegateToCalls("callArgOn", false, "callArgOnWith", function () {
+            throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
+        });
+        spyApi.callArgOnWith = spyApi.callArgOn;
+        delegateToCalls("yield", false, "yield", function () {
+            throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
+        });
+        // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
+        spyApi.invokeCallback = spyApi.yield;
+        delegateToCalls("yieldOn", false, "yieldOn", function () {
+            throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
+        });
+        delegateToCalls("yieldTo", false, "yieldTo", function (property) {
+            throw new Error(this.toString() + " cannot yield to '" + property +
+                "' since it was not yet invoked.");
+        });
+        delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
+            throw new Error(this.toString() + " cannot yield to '" + property +
+                "' since it was not yet invoked.");
+        });
+
+        spyApi.formatters = {
+            c: function (spy) {
+                return sinon.timesInWords(spy.callCount);
+            },
+
+            n: function (spy) {
+                return spy.toString();
+            },
+
+            C: function (spy) {
+                var calls = [];
+
+                for (var i = 0, l = spy.callCount; i < l; ++i) {
+                    var stringifiedCall = "    " + spy.getCall(i).toString();
+                    if (/\n/.test(calls[i - 1])) {
+                        stringifiedCall = "\n" + stringifiedCall;
+                    }
+                    push.call(calls, stringifiedCall);
+                }
+
+                return calls.length > 0 ? "\n" + calls.join("\n") : "";
+            },
+
+            t: function (spy) {
+                var objects = [];
+
+                for (var i = 0, l = spy.callCount; i < l; ++i) {
+                    push.call(objects, sinon.format(spy.thisValues[i]));
+                }
+
+                return objects.join(", ");
+            },
+
+            "*": function (spy, args) {
+                var formatted = [];
+
+                for (var i = 0, l = args.length; i < l; ++i) {
+                    push.call(formatted, sinon.format(args[i]));
+                }
+
+                return formatted.join(", ");
+            }
+        };
+
+        sinon.extend(spy, spyApi);
+
+        spy.spyCall = sinon.spyCall;
+        sinon.spy = spy;
+
+        return spy;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        require("./call");
+        module.exports = makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend util/core.js
+ * @depend extend.js
+ */
+/**
+ * Stub behavior
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @author Tim Fischbach (mail@timfischbach.de)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var slice = Array.prototype.slice;
+    var join = Array.prototype.join;
+
+    var nextTick = (function () {
+        if (typeof process === "object" && typeof process.nextTick === "function") {
+            return process.nextTick;
+        } else if (typeof setImmediate === "function") {
+            return setImmediate;
+        } else {
+            return function (callback) {
+                setTimeout(callback, 0);
+            };
+        }
+    })();
+
+    function throwsException(error, message) {
+        if (typeof error == "string") {
+            this.exception = new Error(message || "");
+            this.exception.name = error;
+        } else if (!error) {
+            this.exception = new Error("Error");
+        } else {
+            this.exception = error;
+        }
+
+        return this;
+    }
+
+    function getCallback(behavior, args) {
+        var callArgAt = behavior.callArgAt;
+
+        if (callArgAt < 0) {
+            var callArgProp = behavior.callArgProp;
+
+            for (var i = 0, l = args.length; i < l; ++i) {
+                if (!callArgProp && typeof args[i] == "function") {
+                    return args[i];
+                }
+
+                if (callArgProp && args[i] &&
+                    typeof args[i][callArgProp] == "function") {
+                    return args[i][callArgProp];
+                }
+            }
+
+            return null;
+        }
+
+        return args[callArgAt];
+    }
+
+    function makeApi(sinon) {
+        function getCallbackError(behavior, func, args) {
+            if (behavior.callArgAt < 0) {
+                var msg;
+
+                if (behavior.callArgProp) {
+                    msg = sinon.functionName(behavior.stub) +
+                        " expected to yield to '" + behavior.callArgProp +
+                        "', but no object with such a property was passed.";
+                } else {
+                    msg = sinon.functionName(behavior.stub) +
+                        " expected to yield, but no callback was passed.";
+                }
+
+                if (args.length > 0) {
+                    msg += " Received [" + join.call(args, ", ") + "]";
+                }
+
+                return msg;
+            }
+
+            return "argument at index " + behavior.callArgAt + " is not a function: " + func;
+        }
+
+        function callCallback(behavior, args) {
+            if (typeof behavior.callArgAt == "number") {
+                var func = getCallback(behavior, args);
+
+                if (typeof func != "function") {
+                    throw new TypeError(getCallbackError(behavior, func, args));
+                }
+
+                if (behavior.callbackAsync) {
+                    nextTick(function () {
+                        func.apply(behavior.callbackContext, behavior.callbackArguments);
+                    });
+                } else {
+                    func.apply(behavior.callbackContext, behavior.callbackArguments);
+                }
+            }
+        }
+
+        var proto = {
+            create: function create(stub) {
+                var behavior = sinon.extend({}, sinon.behavior);
+                delete behavior.create;
+                behavior.stub = stub;
+
+                return behavior;
+            },
+
+            isPresent: function isPresent() {
+                return (typeof this.callArgAt == "number" ||
+                        this.exception ||
+                        typeof this.returnArgAt == "number" ||
+                        this.returnThis ||
+                        this.returnValueDefined);
+            },
+
+            invoke: function invoke(context, args) {
+                callCallback(this, args);
+
+                if (this.exception) {
+                    throw this.exception;
+                } else if (typeof this.returnArgAt == "number") {
+                    return args[this.returnArgAt];
+                } else if (this.returnThis) {
+                    return context;
+                }
+
+                return this.returnValue;
+            },
+
+            onCall: function onCall(index) {
+                return this.stub.onCall(index);
+            },
+
+            onFirstCall: function onFirstCall() {
+                return this.stub.onFirstCall();
+            },
+
+            onSecondCall: function onSecondCall() {
+                return this.stub.onSecondCall();
+            },
+
+            onThirdCall: function onThirdCall() {
+                return this.stub.onThirdCall();
+            },
+
+            withArgs: function withArgs(/* arguments */) {
+                throw new Error("Defining a stub by invoking \"stub.onCall(...).withArgs(...)\" is not supported. " +
+                                "Use \"stub.withArgs(...).onCall(...)\" to define sequential behavior for calls with certain arguments.");
+            },
+
+            callsArg: function callsArg(pos) {
+                if (typeof pos != "number") {
+                    throw new TypeError("argument index is not number");
+                }
+
+                this.callArgAt = pos;
+                this.callbackArguments = [];
+                this.callbackContext = undefined;
+                this.callArgProp = undefined;
+                this.callbackAsync = false;
+
+                return this;
+            },
+
+            callsArgOn: function callsArgOn(pos, context) {
+                if (typeof pos != "number") {
+                    throw new TypeError("argument index is not number");
+                }
+                if (typeof context != "object") {
+                    throw new TypeError("argument context is not an object");
+                }
+
+                this.callArgAt = pos;
+                this.callbackArguments = [];
+                this.callbackContext = context;
+                this.callArgProp = undefined;
+                this.callbackAsync = false;
+
+                return this;
+            },
+
+            callsArgWith: function callsArgWith(pos) {
+                if (typeof pos != "number") {
+                    throw new TypeError("argument index is not number");
+                }
+
+                this.callArgAt = pos;
+                this.callbackArguments = slice.call(arguments, 1);
+                this.callbackContext = undefined;
+                this.callArgProp = undefined;
+                this.callbackAsync = false;
+
+                return this;
+            },
+
+            callsArgOnWith: function callsArgWith(pos, context) {
+                if (typeof pos != "number") {
+                    throw new TypeError("argument index is not number");
+                }
+                if (typeof context != "object") {
+                    throw new TypeError("argument context is not an object");
+                }
+
+                this.callArgAt = pos;
+                this.callbackArguments = slice.call(arguments, 2);
+                this.callbackContext = context;
+                this.callArgProp = undefined;
+                this.callbackAsync = false;
+
+                return this;
+            },
+
+            yields: function () {
+                this.callArgAt = -1;
+                this.callbackArguments = slice.call(arguments, 0);
+                this.callbackContext = undefined;
+                this.callArgProp = undefined;
+                this.callbackAsync = false;
+
+                return this;
+            },
+
+            yieldsOn: function (context) {
+                if (typeof context != "object") {
+                    throw new TypeError("argument context is not an object");
+                }
+
+                this.callArgAt = -1;
+                this.callbackArguments = slice.call(arguments, 1);
+                this.callbackContext = context;
+                this.callArgProp = undefined;
+                this.callbackAsync = false;
+
+                return this;
+            },
+
+            yieldsTo: function (prop) {
+                this.callArgAt = -1;
+                this.callbackArguments = slice.call(arguments, 1);
+                this.callbackContext = undefined;
+                this.callArgProp = prop;
+                this.callbackAsync = false;
+
+                return this;
+            },
+
+            yieldsToOn: function (prop, context) {
+                if (typeof context != "object") {
+                    throw new TypeError("argument context is not an object");
+                }
+
+                this.callArgAt = -1;
+                this.callbackArguments = slice.call(arguments, 2);
+                this.callbackContext = context;
+                this.callArgProp = prop;
+                this.callbackAsync = false;
+
+                return this;
+            },
+
+            throws: throwsException,
+            throwsException: throwsException,
+
+            returns: function returns(value) {
+                this.returnValue = value;
+                this.returnValueDefined = true;
+
+                return this;
+            },
+
+            returnsArg: function returnsArg(pos) {
+                if (typeof pos != "number") {
+                    throw new TypeError("argument index is not number");
+                }
+
+                this.returnArgAt = pos;
+
+                return this;
+            },
+
+            returnsThis: function returnsThis() {
+                this.returnThis = true;
+
+                return this;
+            }
+        };
+
+        // create asynchronous versions of callsArg* and yields* methods
+        for (var method in proto) {
+            // need to avoid creating anotherasync versions of the newly added async methods
+            if (proto.hasOwnProperty(method) &&
+                method.match(/^(callsArg|yields)/) &&
+                !method.match(/Async/)) {
+                proto[method + "Async"] = (function (syncFnName) {
+                    return function () {
+                        var result = this[syncFnName].apply(this, arguments);
+                        this.callbackAsync = true;
+                        return result;
+                    };
+                })(method);
+            }
+        }
+
+        sinon.behavior = proto;
+        return proto;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        module.exports = makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend util/core.js
+ * @depend extend.js
+ * @depend spy.js
+ * @depend behavior.js
+ */
+/**
+ * Stub functions
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    function makeApi(sinon) {
+        function stub(object, property, func) {
+            if (!!func && typeof func != "function") {
+                throw new TypeError("Custom stub should be function");
+            }
+
+            var wrapper;
+
+            if (func) {
+                wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
+            } else {
+                var stubLength = 0;
+                if (typeof object == "object" && typeof object[property] == "function") {
+                    stubLength = object[property].length;
+                }
+                wrapper = stub.create(stubLength);
+            }
+
+            if (!object && typeof property === "undefined") {
+                return sinon.stub.create();
+            }
+
+            if (typeof property === "undefined" && typeof object == "object") {
+                for (var prop in object) {
+                    if (typeof object[prop] === "function") {
+                        stub(object, prop);
+                    }
+                }
+
+                return object;
+            }
+
+            return sinon.wrapMethod(object, property, wrapper);
+        }
+
+        function getDefaultBehavior(stub) {
+            return stub.defaultBehavior || getParentBehaviour(stub) || sinon.behavior.create(stub);
+        }
+
+        function getParentBehaviour(stub) {
+            return (stub.parent && getCurrentBehavior(stub.parent));
+        }
+
+        function getCurrentBehavior(stub) {
+            var behavior = stub.behaviors[stub.callCount - 1];
+            return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stub);
+        }
+
+        var uuid = 0;
+
+        var proto = {
+            create: function create(stubLength) {
+                var functionStub = function () {
+                    return getCurrentBehavior(functionStub).invoke(this, arguments);
+                };
+
+                functionStub.id = "stub#" + uuid++;
+                var orig = functionStub;
+                functionStub = sinon.spy.create(functionStub, stubLength);
+                functionStub.func = orig;
+
+                sinon.extend(functionStub, stub);
+                functionStub.instantiateFake = sinon.stub.create;
+                functionStub.displayName = "stub";
+                functionStub.toString = sinon.functionToString;
+
+                functionStub.defaultBehavior = null;
+                functionStub.behaviors = [];
+
+                return functionStub;
+            },
+
+            resetBehavior: function () {
+                var i;
+
+                this.defaultBehavior = null;
+                this.behaviors = [];
+
+                delete this.returnValue;
+                delete this.returnArgAt;
+                this.returnThis = false;
+
+                if (this.fakes) {
+                    for (i = 0; i < this.fakes.length; i++) {
+                        this.fakes[i].resetBehavior();
+                    }
+                }
+            },
+
+            onCall: function onCall(index) {
+                if (!this.behaviors[index]) {
+                    this.behaviors[index] = sinon.behavior.create(this);
+                }
+
+                return this.behaviors[index];
+            },
+
+            onFirstCall: function onFirstCall() {
+                return this.onCall(0);
+            },
+
+            onSecondCall: function onSecondCall() {
+                return this.onCall(1);
+            },
+
+            onThirdCall: function onThirdCall() {
+                return this.onCall(2);
+            }
+        };
+
+        for (var method in sinon.behavior) {
+            if (sinon.behavior.hasOwnProperty(method) &&
+                !proto.hasOwnProperty(method) &&
+                method != "create" &&
+                method != "withArgs" &&
+                method != "invoke") {
+                proto[method] = (function (behaviorMethod) {
+                    return function () {
+                        this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
+                        this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
+                        return this;
+                    };
+                }(method));
+            }
+        }
+
+        sinon.extend(stub, proto);
+        sinon.stub = stub;
+
+        return stub;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        require("./behavior");
+        require("./spy");
+        module.exports = makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend times_in_words.js
+ * @depend util/core.js
+ * @depend extend.js
+ * @depend stub.js
+ * @depend format.js
+ */
+/**
+ * Mock functions.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    function makeApi(sinon) {
+        var push = [].push;
+        var match = sinon.match;
+
+        function mock(object) {
+            if (!object) {
+                return sinon.expectation.create("Anonymous mock");
+            }
+
+            return mock.create(object);
+        }
+
+        function each(collection, callback) {
+            if (!collection) {
+                return;
+            }
+
+            for (var i = 0, l = collection.length; i < l; i += 1) {
+                callback(collection[i]);
+            }
+        }
+
+        sinon.extend(mock, {
+            create: function create(object) {
+                if (!object) {
+                    throw new TypeError("object is null");
+                }
+
+                var mockObject = sinon.extend({}, mock);
+                mockObject.object = object;
+                delete mockObject.create;
+
+                return mockObject;
+            },
+
+            expects: function expects(method) {
+                if (!method) {
+                    throw new TypeError("method is falsy");
+                }
+
+                if (!this.expectations) {
+                    this.expectations = {};
+                    this.proxies = [];
+                }
+
+                if (!this.expectations[method]) {
+                    this.expectations[method] = [];
+                    var mockObject = this;
+
+                    sinon.wrapMethod(this.object, method, function () {
+                        return mockObject.invokeMethod(method, this, arguments);
+                    });
+
+                    push.call(this.proxies, method);
+                }
+
+                var expectation = sinon.expectation.create(method);
+                push.call(this.expectations[method], expectation);
+
+                return expectation;
+            },
+
+            restore: function restore() {
+                var object = this.object;
+
+                each(this.proxies, function (proxy) {
+                    if (typeof object[proxy].restore == "function") {
+                        object[proxy].restore();
+                    }
+                });
+            },
+
+            verify: function verify() {
+                var expectations = this.expectations || {};
+                var messages = [], met = [];
+
+                each(this.proxies, function (proxy) {
+                    each(expectations[proxy], function (expectation) {
+                        if (!expectation.met()) {
+                            push.call(messages, expectation.toString());
+                        } else {
+                            push.call(met, expectation.toString());
+                        }
+                    });
+                });
+
+                this.restore();
+
+                if (messages.length > 0) {
+                    sinon.expectation.fail(messages.concat(met).join("\n"));
+                } else if (met.length > 0) {
+                    sinon.expectation.pass(messages.concat(met).join("\n"));
+                }
+
+                return true;
+            },
+
+            invokeMethod: function invokeMethod(method, thisValue, args) {
+                var expectations = this.expectations && this.expectations[method];
+                var length = expectations && expectations.length || 0, i;
+
+                for (i = 0; i < length; i += 1) {
+                    if (!expectations[i].met() &&
+                        expectations[i].allowsCall(thisValue, args)) {
+                        return expectations[i].apply(thisValue, args);
+                    }
+                }
+
+                var messages = [], available, exhausted = 0;
+
+                for (i = 0; i < length; i += 1) {
+                    if (expectations[i].allowsCall(thisValue, args)) {
+                        available = available || expectations[i];
+                    } else {
+                        exhausted += 1;
+                    }
+                    push.call(messages, "    " + expectations[i].toString());
+                }
+
+                if (exhausted === 0) {
+                    return available.apply(thisValue, args);
+                }
+
+                messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
+                    proxy: method,
+                    args: args
+                }));
+
+                sinon.expectation.fail(messages.join("\n"));
+            }
+        });
+
+        var times = sinon.timesInWords;
+        var slice = Array.prototype.slice;
+
+        function callCountInWords(callCount) {
+            if (callCount == 0) {
+                return "never called";
+            } else {
+                return "called " + times(callCount);
+            }
+        }
+
+        function expectedCallCountInWords(expectation) {
+            var min = expectation.minCalls;
+            var max = expectation.maxCalls;
+
+            if (typeof min == "number" && typeof max == "number") {
+                var str = times(min);
+
+                if (min != max) {
+                    str = "at least " + str + " and at most " + times(max);
+                }
+
+                return str;
+            }
+
+            if (typeof min == "number") {
+                return "at least " + times(min);
+            }
+
+            return "at most " + times(max);
+        }
+
+        function receivedMinCalls(expectation) {
+            var hasMinLimit = typeof expectation.minCalls == "number";
+            return !hasMinLimit || expectation.callCount >= expectation.minCalls;
+        }
+
+        function receivedMaxCalls(expectation) {
+            if (typeof expectation.maxCalls != "number") {
+                return false;
+            }
+
+            return expectation.callCount == expectation.maxCalls;
+        }
+
+        function verifyMatcher(possibleMatcher, arg) {
+            if (match && match.isMatcher(possibleMatcher)) {
+                return possibleMatcher.test(arg);
+            } else {
+                return true;
+            }
+        }
+
+        sinon.expectation = {
+            minCalls: 1,
+            maxCalls: 1,
+
+            create: function create(methodName) {
+                var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
+                delete expectation.create;
+                expectation.method = methodName;
+
+                return expectation;
+            },
+
+            invoke: function invoke(func, thisValue, args) {
+                this.verifyCallAllowed(thisValue, args);
+
+                return sinon.spy.invoke.apply(this, arguments);
+            },
+
+            atLeast: function atLeast(num) {
+                if (typeof num != "number") {
+                    throw new TypeError("'" + num + "' is not number");
+                }
+
+                if (!this.limitsSet) {
+                    this.maxCalls = null;
+                    this.limitsSet = true;
+                }
+
+                this.minCalls = num;
+
+                return this;
+            },
+
+            atMost: function atMost(num) {
+                if (typeof num != "number") {
+                    throw new TypeError("'" + num + "' is not number");
+                }
+
+                if (!this.limitsSet) {
+                    this.minCalls = null;
+                    this.limitsSet = true;
+                }
+
+                this.maxCalls = num;
+
+                return this;
+            },
+
+            never: function never() {
+                return this.exactly(0);
+            },
+
+            once: function once() {
+                return this.exactly(1);
+            },
+
+            twice: function twice() {
+                return this.exactly(2);
+            },
+
+            thrice: function thrice() {
+                return this.exactly(3);
+            },
+
+            exactly: function exactly(num) {
+                if (typeof num != "number") {
+                    throw new TypeError("'" + num + "' is not a number");
+                }
+
+                this.atLeast(num);
+                return this.atMost(num);
+            },
+
+            met: function met() {
+                return !this.failed && receivedMinCalls(this);
+            },
+
+            verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
+                if (receivedMaxCalls(this)) {
+                    this.failed = true;
+                    sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
+                }
+
+                if ("expectedThis" in this && this.expectedThis !== thisValue) {
+                    sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
+                        this.expectedThis);
+                }
+
+                if (!("expectedArguments" in this)) {
+                    return;
+                }
+
+                if (!args) {
+                    sinon.expectation.fail(this.method + " received no arguments, expected " +
+                        sinon.format(this.expectedArguments));
+                }
+
+                if (args.length < this.expectedArguments.length) {
+                    sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
+                        "), expected " + sinon.format(this.expectedArguments));
+                }
+
+                if (this.expectsExactArgCount &&
+                    args.length != this.expectedArguments.length) {
+                    sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
+                        "), expected " + sinon.format(this.expectedArguments));
+                }
+
+                for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
+
+                    if (!verifyMatcher(this.expectedArguments[i], args[i])) {
+                        sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
+                            ", didn't match " + this.expectedArguments.toString());
+                    }
+
+                    if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
+                        sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
+                            ", expected " + sinon.format(this.expectedArguments));
+                    }
+                }
+            },
+
+            allowsCall: function allowsCall(thisValue, args) {
+                if (this.met() && receivedMaxCalls(this)) {
+                    return false;
+                }
+
+                if ("expectedThis" in this && this.expectedThis !== thisValue) {
+                    return false;
+                }
+
+                if (!("expectedArguments" in this)) {
+                    return true;
+                }
+
+                args = args || [];
+
+                if (args.length < this.expectedArguments.length) {
+                    return false;
+                }
+
+                if (this.expectsExactArgCount &&
+                    args.length != this.expectedArguments.length) {
+                    return false;
+                }
+
+                for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
+                    if (!verifyMatcher(this.expectedArguments[i], args[i])) {
+                        return false;
+                    }
+
+                    if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
+                        return false;
+                    }
+                }
+
+                return true;
+            },
+
+            withArgs: function withArgs() {
+                this.expectedArguments = slice.call(arguments);
+                return this;
+            },
+
+            withExactArgs: function withExactArgs() {
+                this.withArgs.apply(this, arguments);
+                this.expectsExactArgCount = true;
+                return this;
+            },
+
+            on: function on(thisValue) {
+                this.expectedThis = thisValue;
+                return this;
+            },
+
+            toString: function () {
+                var args = (this.expectedArguments || []).slice();
+
+                if (!this.expectsExactArgCount) {
+                    push.call(args, "[...]");
+                }
+
+                var callStr = sinon.spyCall.toString.call({
+                    proxy: this.method || "anonymous mock expectation",
+                    args: args
+                });
+
+                var message = callStr.replace(", [...", "[, ...") + " " +
+                    expectedCallCountInWords(this);
+
+                if (this.met()) {
+                    return "Expectation met: " + message;
+                }
+
+                return "Expected " + message + " (" +
+                    callCountInWords(this.callCount) + ")";
+            },
+
+            verify: function verify() {
+                if (!this.met()) {
+                    sinon.expectation.fail(this.toString());
+                } else {
+                    sinon.expectation.pass(this.toString());
+                }
+
+                return true;
+            },
+
+            pass: function pass(message) {
+                sinon.assert.pass(message);
+            },
+
+            fail: function fail(message) {
+                var exception = new Error(message);
+                exception.name = "ExpectationError";
+
+                throw exception;
+            }
+        };
+
+        sinon.mock = mock;
+        return mock;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        require("./call");
+        require("./match");
+        require("./spy");
+        module.exports = makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend util/core.js
+ * @depend stub.js
+ * @depend mock.js
+ */
+/**
+ * Collections of stubs, spies and mocks.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var push = [].push;
+    var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+    function getFakes(fakeCollection) {
+        if (!fakeCollection.fakes) {
+            fakeCollection.fakes = [];
+        }
+
+        return fakeCollection.fakes;
+    }
+
+    function each(fakeCollection, method) {
+        var fakes = getFakes(fakeCollection);
+
+        for (var i = 0, l = fakes.length; i < l; i += 1) {
+            if (typeof fakes[i][method] == "function") {
+                fakes[i][method]();
+            }
+        }
+    }
+
+    function compact(fakeCollection) {
+        var fakes = getFakes(fakeCollection);
+        var i = 0;
+        while (i < fakes.length) {
+            fakes.splice(i, 1);
+        }
+    }
+
+    function makeApi(sinon) {
+        var collection = {
+            verify: function resolve() {
+                each(this, "verify");
+            },
+
+            restore: function restore() {
+                each(this, "restore");
+                compact(this);
+            },
+
+            reset: function restore() {
+                each(this, "reset");
+            },
+
+            verifyAndRestore: function verifyAndRestore() {
+                var exception;
+
+                try {
+                    this.verify();
+                } catch (e) {
+                    exception = e;
+                }
+
+                this.restore();
+
+                if (exception) {
+                    throw exception;
+                }
+            },
+
+            add: function add(fake) {
+                push.call(getFakes(this), fake);
+                return fake;
+            },
+
+            spy: function spy() {
+                return this.add(sinon.spy.apply(sinon, arguments));
+            },
+
+            stub: function stub(object, property, value) {
+                if (property) {
+                    var original = object[property];
+
+                    if (typeof original != "function") {
+                        if (!hasOwnProperty.call(object, property)) {
+                            throw new TypeError("Cannot stub non-existent own property " + property);
+                        }
+
+                        object[property] = value;
+
+                        return this.add({
+                            restore: function () {
+                                object[property] = original;
+                            }
+                        });
+                    }
+                }
+                if (!property && !!object && typeof object == "object") {
+                    var stubbedObj = sinon.stub.apply(sinon, arguments);
+
+                    for (var prop in stubbedObj) {
+                        if (typeof stubbedObj[prop] === "function") {
+                            this.add(stubbedObj[prop]);
+                        }
+                    }
+
+                    return stubbedObj;
+                }
+
+                return this.add(sinon.stub.apply(sinon, arguments));
+            },
+
+            mock: function mock() {
+                return this.add(sinon.mock.apply(sinon, arguments));
+            },
+
+            inject: function inject(obj) {
+                var col = this;
+
+                obj.spy = function () {
+                    return col.spy.apply(col, arguments);
+                };
+
+                obj.stub = function () {
+                    return col.stub.apply(col, arguments);
+                };
+
+                obj.mock = function () {
+                    return col.mock.apply(col, arguments);
+                };
+
+                return obj;
+            }
+        };
+
+        sinon.collection = collection;
+        return collection;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        require("./mock");
+        require("./spy");
+        require("./stub");
+        module.exports = makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/*global lolex */
+
+/**
+ * Fake timer API
+ * setTimeout
+ * setInterval
+ * clearTimeout
+ * clearInterval
+ * tick
+ * reset
+ * Date
+ *
+ * Inspired by jsUnitMockTimeOut from JsUnit
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+if (typeof sinon == "undefined") {
+    var sinon = {};
+}
+
+(function (global) {
+    function makeApi(sinon, lol) {
+        var llx = typeof lolex !== "undefined" ? lolex : lol;
+
+        sinon.useFakeTimers = function () {
+            var now, methods = Array.prototype.slice.call(arguments);
+
+            if (typeof methods[0] === "string") {
+                now = 0;
+            } else {
+                now = methods.shift();
+            }
+
+            var clock = llx.install(now || 0, methods);
+            clock.restore = clock.uninstall;
+            return clock;
+        };
+
+        sinon.clock = {
+            create: function (now) {
+                return llx.createClock(now);
+            }
+        };
+
+        sinon.timers = {
+            setTimeout: setTimeout,
+            clearTimeout: clearTimeout,
+            setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
+            clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate : undefined),
+            setInterval: setInterval,
+            clearInterval: clearInterval,
+            Date: Date
+        };
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, epxorts, module) {
+        var sinon = require("./core");
+        makeApi(sinon, require("lolex"));
+        module.exports = sinon;
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else {
+        makeApi(sinon);
+    }
+}(typeof global != "undefined" && typeof global !== "function" ? global : this));
+
+/**
+ * Minimal Event interface implementation
+ *
+ * Original implementation by Sven Fuchs: https://gist.github.com/995028
+ * Modifications and tests by Christian Johansen.
+ *
+ * @author Sven Fuchs (svenfuchs@artweb-design.de)
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2011 Sven Fuchs, Christian Johansen
+ */
+
+if (typeof sinon == "undefined") {
+    this.sinon = {};
+}
+
+(function () {
+    var push = [].push;
+
+    function makeApi(sinon) {
+        sinon.Event = function Event(type, bubbles, cancelable, target) {
+            this.initEvent(type, bubbles, cancelable, target);
+        };
+
+        sinon.Event.prototype = {
+            initEvent: function (type, bubbles, cancelable, target) {
+                this.type = type;
+                this.bubbles = bubbles;
+                this.cancelable = cancelable;
+                this.target = target;
+            },
+
+            stopPropagation: function () {},
+
+            preventDefault: function () {
+                this.defaultPrevented = true;
+            }
+        };
+
+        sinon.ProgressEvent = function ProgressEvent(type, progressEventRaw, target) {
+            this.initEvent(type, false, false, target);
+            this.loaded = progressEventRaw.loaded || null;
+            this.total = progressEventRaw.total || null;
+            this.lengthComputable = !!progressEventRaw.total;
+        };
+
+        sinon.ProgressEvent.prototype = new sinon.Event();
+
+        sinon.ProgressEvent.prototype.constructor =  sinon.ProgressEvent;
+
+        sinon.CustomEvent = function CustomEvent(type, customData, target) {
+            this.initEvent(type, false, false, target);
+            this.detail = customData.detail || null;
+        };
+
+        sinon.CustomEvent.prototype = new sinon.Event();
+
+        sinon.CustomEvent.prototype.constructor =  sinon.CustomEvent;
+
+        sinon.EventTarget = {
+            addEventListener: function addEventListener(event, listener) {
+                this.eventListeners = this.eventListeners || {};
+                this.eventListeners[event] = this.eventListeners[event] || [];
+                push.call(this.eventListeners[event], listener);
+            },
+
+            removeEventListener: function removeEventListener(event, listener) {
+                var listeners = this.eventListeners && this.eventListeners[event] || [];
+
+                for (var i = 0, l = listeners.length; i < l; ++i) {
+                    if (listeners[i] == listener) {
+                        return listeners.splice(i, 1);
+                    }
+                }
+            },
+
+            dispatchEvent: function dispatchEvent(event) {
+                var type = event.type;
+                var listeners = this.eventListeners && this.eventListeners[type] || [];
+
+                for (var i = 0; i < listeners.length; i++) {
+                    if (typeof listeners[i] == "function") {
+                        listeners[i].call(this, event);
+                    } else {
+                        listeners[i].handleEvent(event);
+                    }
+                }
+
+                return !!event.defaultPrevented;
+            }
+        };
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require) {
+        var sinon = require("./core");
+        makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require);
+    } else {
+        makeApi(sinon);
+    }
+}());
+
+/**
+ * @depend ../sinon.js
+ */
+/**
+ * Logs errors
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2014 Christian Johansen
+ */
+
+(function (sinon) {
+    // cache a reference to setTimeout, so that our reference won't be stubbed out
+    // when using fake timers and errors will still get logged
+    // https://github.com/cjohansen/Sinon.JS/issues/381
+    var realSetTimeout = setTimeout;
+
+    function makeApi(sinon) {
+
+        function log() {}
+
+        function logError(label, err) {
+            var msg = label + " threw exception: ";
+
+            sinon.log(msg + "[" + err.name + "] " + err.message);
+
+            if (err.stack) {
+                sinon.log(err.stack);
+            }
+
+            logError.setTimeout(function () {
+                err.message = msg + err.message;
+                throw err;
+            }, 0);
+        };
+
+        // wrap realSetTimeout with something we can stub in tests
+        logError.setTimeout = function (func, timeout) {
+            realSetTimeout(func, timeout);
+        }
+
+        var exports = {};
+        exports.log = sinon.log = log;
+        exports.logError = sinon.logError = logError;
+
+        return exports;
+    }
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        module.exports = makeApi(sinon);
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend core.js
+ * @depend ../extend.js
+ * @depend event.js
+ * @depend ../log_error.js
+ */
+/**
+ * Fake XDomainRequest object
+ */
+
+if (typeof sinon == "undefined") {
+    this.sinon = {};
+}
+
+// wrapper for global
+(function (global) {
+    var xdr = { XDomainRequest: global.XDomainRequest };
+    xdr.GlobalXDomainRequest = global.XDomainRequest;
+    xdr.supportsXDR = typeof xdr.GlobalXDomainRequest != "undefined";
+    xdr.workingXDR = xdr.supportsXDR ? xdr.GlobalXDomainRequest :  false;
+
+    function makeApi(sinon) {
+        sinon.xdr = xdr;
+
+        function FakeXDomainRequest() {
+            this.readyState = FakeXDomainRequest.UNSENT;
+            this.requestBody = null;
+            this.requestHeaders = {};
+            this.status = 0;
+            this.timeout = null;
+
+            if (typeof FakeXDomainRequest.onCreate == "function") {
+                FakeXDomainRequest.onCreate(this);
+            }
+        }
+
+        function verifyState(xdr) {
+            if (xdr.readyState !== FakeXDomainRequest.OPENED) {
+                throw new Error("INVALID_STATE_ERR");
+            }
+
+            if (xdr.sendFlag) {
+                throw new Error("INVALID_STATE_ERR");
+            }
+        }
+
+        function verifyRequestSent(xdr) {
+            if (xdr.readyState == FakeXDomainRequest.UNSENT) {
+                throw new Error("Request not sent");
+            }
+            if (xdr.readyState == FakeXDomainRequest.DONE) {
+                throw new Error("Request done");
+            }
+        }
+
+        function verifyResponseBodyType(body) {
+            if (typeof body != "string") {
+                var error = new Error("Attempted to respond to fake XDomainRequest with " +
+                                    body + ", which is not a string.");
+                error.name = "InvalidBodyException";
+                throw error;
+            }
+        }
+
+        sinon.extend(FakeXDomainRequest.prototype, sinon.EventTarget, {
+            open: function open(method, url) {
+                this.method = method;
+                this.url = url;
+
+                this.responseText = null;
+                this.sendFlag = false;
+
+                this.readyStateChange(FakeXDomainRequest.OPENED);
+            },
+
+            readyStateChange: function readyStateChange(state) {
+                this.readyState = state;
+                var eventName = "";
+                switch (this.readyState) {
+                case FakeXDomainRequest.UNSENT:
+                    break;
+                case FakeXDomainRequest.OPENED:
+                    break;
+                case FakeXDomainRequest.LOADING:
+                    if (this.sendFlag) {
+                        //raise the progress event
+                        eventName = "onprogress";
+                    }
+                    break;
+                case FakeXDomainRequest.DONE:
+                    if (this.isTimeout) {
+                        eventName = "ontimeout"
+                    } else if (this.errorFlag || (this.status < 200 || this.status > 299)) {
+                        eventName = "onerror";
+                    } else {
+                        eventName = "onload"
+                    }
+                    break;
+                }
+
+                // raising event (if defined)
+                if (eventName) {
+                    if (typeof this[eventName] == "function") {
+                        try {
+                            this[eventName]();
+                        } catch (e) {
+                            sinon.logError("Fake XHR " + eventName + " handler", e);
+                        }
+                    }
+                }
+            },
+
+            send: function send(data) {
+                verifyState(this);
+
+                if (!/^(get|head)$/i.test(this.method)) {
+                    this.requestBody = data;
+                }
+                this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
+
+                this.errorFlag = false;
+                this.sendFlag = true;
+                this.readyStateChange(FakeXDomainRequest.OPENED);
+
+                if (typeof this.onSend == "function") {
+                    this.onSend(this);
+                }
+            },
+
+            abort: function abort() {
+                this.aborted = true;
+                this.responseText = null;
+                this.errorFlag = true;
+
+                if (this.readyState > sinon.FakeXDomainRequest.UNSENT && this.sendFlag) {
+                    this.readyStateChange(sinon.FakeXDomainRequest.DONE);
+                    this.sendFlag = false;
+                }
+            },
+
+            setResponseBody: function setResponseBody(body) {
+                verifyRequestSent(this);
+                verifyResponseBodyType(body);
+
+                var chunkSize = this.chunkSize || 10;
+                var index = 0;
+                this.responseText = "";
+
+                do {
+                    this.readyStateChange(FakeXDomainRequest.LOADING);
+                    this.responseText += body.substring(index, index + chunkSize);
+                    index += chunkSize;
+                } while (index < body.length);
+
+                this.readyStateChange(FakeXDomainRequest.DONE);
+            },
+
+            respond: function respond(status, contentType, body) {
+                // content-type ignored, since XDomainRequest does not carry this
+                // we keep the same syntax for respond(...) as for FakeXMLHttpRequest to ease
+                // test integration across browsers
+                this.status = typeof status == "number" ? status : 200;
+                this.setResponseBody(body || "");
+            },
+
+            simulatetimeout: function simulatetimeout() {
+                this.status = 0;
+                this.isTimeout = true;
+                // Access to this should actually throw an error
+                this.responseText = undefined;
+                this.readyStateChange(FakeXDomainRequest.DONE);
+            }
+        });
+
+        sinon.extend(FakeXDomainRequest, {
+            UNSENT: 0,
+            OPENED: 1,
+            LOADING: 3,
+            DONE: 4
+        });
+
+        sinon.useFakeXDomainRequest = function useFakeXDomainRequest() {
+            sinon.FakeXDomainRequest.restore = function restore(keepOnCreate) {
+                if (xdr.supportsXDR) {
+                    global.XDomainRequest = xdr.GlobalXDomainRequest;
+                }
+
+                delete sinon.FakeXDomainRequest.restore;
+
+                if (keepOnCreate !== true) {
+                    delete sinon.FakeXDomainRequest.onCreate;
+                }
+            };
+            if (xdr.supportsXDR) {
+                global.XDomainRequest = sinon.FakeXDomainRequest;
+            }
+            return sinon.FakeXDomainRequest;
+        };
+
+        sinon.FakeXDomainRequest = FakeXDomainRequest;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./core");
+        require("./event");
+        makeApi(sinon);
+        module.exports = sinon;
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else {
+        makeApi(sinon);
+    }
+})(this);
+
+/**
+ * @depend core.js
+ * @depend ../extend.js
+ * @depend event.js
+ * @depend ../log_error.js
+ */
+/**
+ * Fake XMLHttpRequest object
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (global) {
+
+    var supportsProgress = typeof ProgressEvent !== "undefined";
+    var supportsCustomEvent = typeof CustomEvent !== "undefined";
+    var sinonXhr = { XMLHttpRequest: global.XMLHttpRequest };
+    sinonXhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
+    sinonXhr.GlobalActiveXObject = global.ActiveXObject;
+    sinonXhr.supportsActiveX = typeof sinonXhr.GlobalActiveXObject != "undefined";
+    sinonXhr.supportsXHR = typeof sinonXhr.GlobalXMLHttpRequest != "undefined";
+    sinonXhr.workingXHR = sinonXhr.supportsXHR ? sinonXhr.GlobalXMLHttpRequest : sinonXhr.supportsActiveX
+                                     ? function () { return new sinonXhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
+    sinonXhr.supportsCORS = sinonXhr.supportsXHR && "withCredentials" in (new sinonXhr.GlobalXMLHttpRequest());
+
+    /*jsl:ignore*/
+    var unsafeHeaders = {
+        "Accept-Charset": true,
+        "Accept-Encoding": true,
+        Connection: true,
+        "Content-Length": true,
+        Cookie: true,
+        Cookie2: true,
+        "Content-Transfer-Encoding": true,
+        Date: true,
+        Expect: true,
+        Host: true,
+        "Keep-Alive": true,
+        Referer: true,
+        TE: true,
+        Trailer: true,
+        "Transfer-Encoding": true,
+        Upgrade: true,
+        "User-Agent": true,
+        Via: true
+    };
+    /*jsl:end*/
+
+    function FakeXMLHttpRequest() {
+        this.readyState = FakeXMLHttpRequest.UNSENT;
+        this.requestHeaders = {};
+        this.requestBody = null;
+        this.status = 0;
+        this.statusText = "";
+        this.upload = new UploadProgress();
+        if (sinonXhr.supportsCORS) {
+            this.withCredentials = false;
+        }
+
+        var xhr = this;
+        var events = ["loadstart", "load", "abort", "loadend"];
+
+        function addEventListener(eventName) {
+            xhr.addEventListener(eventName, function (event) {
+                var listener = xhr["on" + eventName];
+
+                if (listener && typeof listener == "function") {
+                    listener.call(this, event);
+                }
+            });
+        }
+
+        for (var i = events.length - 1; i >= 0; i--) {
+            addEventListener(events[i]);
+        }
+
+        if (typeof FakeXMLHttpRequest.onCreate == "function") {
+            FakeXMLHttpRequest.onCreate(this);
+        }
+    }
+
+    // An upload object is created for each
+    // FakeXMLHttpRequest and allows upload
+    // events to be simulated using uploadProgress
+    // and uploadError.
+    function UploadProgress() {
+        this.eventListeners = {
+            progress: [],
+            load: [],
+            abort: [],
+            error: []
+        }
+    }
+
+    UploadProgress.prototype.addEventListener = function addEventListener(event, listener) {
+        this.eventListeners[event].push(listener);
+    };
+
+    UploadProgress.prototype.removeEventListener = function removeEventListener(event, listener) {
+        var listeners = this.eventListeners[event] || [];
+
+        for (var i = 0, l = listeners.length; i < l; ++i) {
+            if (listeners[i] == listener) {
+                return listeners.splice(i, 1);
+            }
+        }
+    };
+
+    UploadProgress.prototype.dispatchEvent = function dispatchEvent(event) {
+        var listeners = this.eventListeners[event.type] || [];
+
+        for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
+            listener(event);
+        }
+    };
+
+    function verifyState(xhr) {
+        if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
+            throw new Error("INVALID_STATE_ERR");
+        }
+
+        if (xhr.sendFlag) {
+            throw new Error("INVALID_STATE_ERR");
+        }
+    }
+
+    function getHeader(headers, header) {
+        header = header.toLowerCase();
+
+        for (var h in headers) {
+            if (h.toLowerCase() == header) {
+                return h;
+            }
+        }
+
+        return null;
+    }
+
+    // filtering to enable a white-list version of Sinon FakeXhr,
+    // where whitelisted requests are passed through to real XHR
+    function each(collection, callback) {
+        if (!collection) {
+            return;
+        }
+
+        for (var i = 0, l = collection.length; i < l; i += 1) {
+            callback(collection[i]);
+        }
+    }
+    function some(collection, callback) {
+        for (var index = 0; index < collection.length; index++) {
+            if (callback(collection[index]) === true) {
+                return true;
+            }
+        }
+        return false;
+    }
+    // largest arity in XHR is 5 - XHR#open
+    var apply = function (obj, method, args) {
+        switch (args.length) {
+        case 0: return obj[method]();
+        case 1: return obj[method](args[0]);
+        case 2: return obj[method](args[0], args[1]);
+        case 3: return obj[method](args[0], args[1], args[2]);
+        case 4: return obj[method](args[0], args[1], args[2], args[3]);
+        case 5: return obj[method](args[0], args[1], args[2], args[3], args[4]);
+        }
+    };
+
+    FakeXMLHttpRequest.filters = [];
+    FakeXMLHttpRequest.addFilter = function addFilter(fn) {
+        this.filters.push(fn)
+    };
+    var IE6Re = /MSIE 6/;
+    FakeXMLHttpRequest.defake = function defake(fakeXhr, xhrArgs) {
+        var xhr = new sinonXhr.workingXHR();
+        each([
+            "open",
+            "setRequestHeader",
+            "send",
+            "abort",
+            "getResponseHeader",
+            "getAllResponseHeaders",
+            "addEventListener",
+            "overrideMimeType",
+            "removeEventListener"
+        ], function (method) {
+            fakeXhr[method] = function () {
+                return apply(xhr, method, arguments);
+            };
+        });
+
+        var copyAttrs = function (args) {
+            each(args, function (attr) {
+                try {
+                    fakeXhr[attr] = xhr[attr]
+                } catch (e) {
+                    if (!IE6Re.test(navigator.userAgent)) {
+                        throw e;
+                    }
+                }
+            });
+        };
+
+        var stateChange = function stateChange() {
+            fakeXhr.readyState = xhr.readyState;
+            if (xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
+                copyAttrs(["status", "statusText"]);
+            }
+            if (xhr.readyState >= FakeXMLHttpRequest.LOADING) {
+                copyAttrs(["responseText", "response"]);
+            }
+            if (xhr.readyState === FakeXMLHttpRequest.DONE) {
+                copyAttrs(["responseXML"]);
+            }
+            if (fakeXhr.onreadystatechange) {
+                fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
+            }
+        };
+
+        if (xhr.addEventListener) {
+            for (var event in fakeXhr.eventListeners) {
+                if (fakeXhr.eventListeners.hasOwnProperty(event)) {
+                    each(fakeXhr.eventListeners[event], function (handler) {
+                        xhr.addEventListener(event, handler);
+                    });
+                }
+            }
+            xhr.addEventListener("readystatechange", stateChange);
+        } else {
+            xhr.onreadystatechange = stateChange;
+        }
+        apply(xhr, "open", xhrArgs);
+    };
+    FakeXMLHttpRequest.useFilters = false;
+
+    function verifyRequestOpened(xhr) {
+        if (xhr.readyState != FakeXMLHttpRequest.OPENED) {
+            throw new Error("INVALID_STATE_ERR - " + xhr.readyState);
+        }
+    }
+
+    function verifyRequestSent(xhr) {
+        if (xhr.readyState == FakeXMLHttpRequest.DONE) {
+            throw new Error("Request done");
+        }
+    }
+
+    function verifyHeadersReceived(xhr) {
+        if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
+            throw new Error("No headers received");
+        }
+    }
+
+    function verifyResponseBodyType(body) {
+        if (typeof body != "string") {
+            var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
+                                 body + ", which is not a string.");
+            error.name = "InvalidBodyException";
+            throw error;
+        }
+    }
+
+    FakeXMLHttpRequest.parseXML = function parseXML(text) {
+        var xmlDoc;
+
+        if (typeof DOMParser != "undefined") {
+            var parser = new DOMParser();
+            xmlDoc = parser.parseFromString(text, "text/xml");
+        } else {
+            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
+            xmlDoc.async = "false";
+            xmlDoc.loadXML(text);
+        }
+
+        return xmlDoc;
+    };
+
+    FakeXMLHttpRequest.statusCodes = {
+        100: "Continue",
+        101: "Switching Protocols",
+        200: "OK",
+        201: "Created",
+        202: "Accepted",
+        203: "Non-Authoritative Information",
+        204: "No Content",
+        205: "Reset Content",
+        206: "Partial Content",
+        207: "Multi-Status",
+        300: "Multiple Choice",
+        301: "Moved Permanently",
+        302: "Found",
+        303: "See Other",
+        304: "Not Modified",
+        305: "Use Proxy",
+        307: "Temporary Redirect",
+        400: "Bad Request",
+        401: "Unauthorized",
+        402: "Payment Required",
+        403: "Forbidden",
+        404: "Not Found",
+        405: "Method Not Allowed",
+        406: "Not Acceptable",
+        407: "Proxy Authentication Required",
+        408: "Request Timeout",
+        409: "Conflict",
+        410: "Gone",
+        411: "Length Required",
+        412: "Precondition Failed",
+        413: "Request Entity Too Large",
+        414: "Request-URI Too Long",
+        415: "Unsupported Media Type",
+        416: "Requested Range Not Satisfiable",
+        417: "Expectation Failed",
+        422: "Unprocessable Entity",
+        500: "Internal Server Error",
+        501: "Not Implemented",
+        502: "Bad Gateway",
+        503: "Service Unavailable",
+        504: "Gateway Timeout",
+        505: "HTTP Version Not Supported"
+    };
+
+    function makeApi(sinon) {
+        sinon.xhr = sinonXhr;
+
+        sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
+            async: true,
+
+            open: function open(method, url, async, username, password) {
+                this.method = method;
+                this.url = url;
+                this.async = typeof async == "boolean" ? async : true;
+                this.username = username;
+                this.password = password;
+                this.responseText = null;
+                this.responseXML = null;
+                this.requestHeaders = {};
+                this.sendFlag = false;
+
+                if (FakeXMLHttpRequest.useFilters === true) {
+                    var xhrArgs = arguments;
+                    var defake = some(FakeXMLHttpRequest.filters, function (filter) {
+                        return filter.apply(this, xhrArgs)
+                    });
+                    if (defake) {
+                        return FakeXMLHttpRequest.defake(this, arguments);
+                    }
+                }
+                this.readyStateChange(FakeXMLHttpRequest.OPENED);
+            },
+
+            readyStateChange: function readyStateChange(state) {
+                this.readyState = state;
+
+                if (typeof this.onreadystatechange == "function") {
+                    try {
+                        this.onreadystatechange();
+                    } catch (e) {
+                        sinon.logError("Fake XHR onreadystatechange handler", e);
+                    }
+                }
+
+                this.dispatchEvent(new sinon.Event("readystatechange"));
+
+                switch (this.readyState) {
+                    case FakeXMLHttpRequest.DONE:
+                        this.dispatchEvent(new sinon.Event("load", false, false, this));
+                        this.dispatchEvent(new sinon.Event("loadend", false, false, this));
+                        this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
+                        if (supportsProgress) {
+                            this.upload.dispatchEvent(new sinon.ProgressEvent("progress", {loaded: 100, total: 100}));
+                            this.dispatchEvent(new sinon.ProgressEvent("progress", {loaded: 100, total: 100}));
+                        }
+                        break;
+                }
+            },
+
+            setRequestHeader: function setRequestHeader(header, value) {
+                verifyState(this);
+
+                if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
+                    throw new Error("Refused to set unsafe header \"" + header + "\"");
+                }
+
+                if (this.requestHeaders[header]) {
+                    this.requestHeaders[header] += "," + value;
+                } else {
+                    this.requestHeaders[header] = value;
+                }
+            },
+
+            // Helps testing
+            setResponseHeaders: function setResponseHeaders(headers) {
+                verifyRequestOpened(this);
+                this.responseHeaders = {};
+
+                for (var header in headers) {
+                    if (headers.hasOwnProperty(header)) {
+                        this.responseHeaders[header] = headers[header];
+                    }
+                }
+
+                if (this.async) {
+                    this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
+                } else {
+                    this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
+                }
+            },
+
+            // Currently treats ALL data as a DOMString (i.e. no Document)
+            send: function send(data) {
+                verifyState(this);
+
+                if (!/^(get|head)$/i.test(this.method)) {
+                    var contentType = getHeader(this.requestHeaders, "Content-Type");
+                    if (this.requestHeaders[contentType]) {
+                        var value = this.requestHeaders[contentType].split(";");
+                        this.requestHeaders[contentType] = value[0] + ";charset=utf-8";
+                    } else if (!(data instanceof FormData)) {
+                        this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
+                    }
+
+                    this.requestBody = data;
+                }
+
+                this.errorFlag = false;
+                this.sendFlag = this.async;
+                this.readyStateChange(FakeXMLHttpRequest.OPENED);
+
+                if (typeof this.onSend == "function") {
+                    this.onSend(this);
+                }
+
+                this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
+            },
+
+            abort: function abort() {
+                this.aborted = true;
+                this.responseText = null;
+                this.errorFlag = true;
+                this.requestHeaders = {};
+
+                if (this.readyState > FakeXMLHttpRequest.UNSENT && this.sendFlag) {
+                    this.readyStateChange(FakeXMLHttpRequest.DONE);
+                    this.sendFlag = false;
+                }
+
+                this.readyState = FakeXMLHttpRequest.UNSENT;
+
+                this.dispatchEvent(new sinon.Event("abort", false, false, this));
+
+                this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
+
+                if (typeof this.onerror === "function") {
+                    this.onerror();
+                }
+            },
+
+            getResponseHeader: function getResponseHeader(header) {
+                if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
+                    return null;
+                }
+
+                if (/^Set-Cookie2?$/i.test(header)) {
+                    return null;
+                }
+
+                header = getHeader(this.responseHeaders, header);
+
+                return this.responseHeaders[header] || null;
+            },
+
+            getAllResponseHeaders: function getAllResponseHeaders() {
+                if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
+                    return "";
+                }
+
+                var headers = "";
+
+                for (var header in this.responseHeaders) {
+                    if (this.responseHeaders.hasOwnProperty(header) &&
+                        !/^Set-Cookie2?$/i.test(header)) {
+                        headers += header + ": " + this.responseHeaders[header] + "\r\n";
+                    }
+                }
+
+                return headers;
+            },
+
+            setResponseBody: function setResponseBody(body) {
+                verifyRequestSent(this);
+                verifyHeadersReceived(this);
+                verifyResponseBodyType(body);
+
+                var chunkSize = this.chunkSize || 10;
+                var index = 0;
+                this.responseText = "";
+
+                do {
+                    if (this.async) {
+                        this.readyStateChange(FakeXMLHttpRequest.LOADING);
+                    }
+
+                    this.responseText += body.substring(index, index + chunkSize);
+                    index += chunkSize;
+                } while (index < body.length);
+
+                var type = this.getResponseHeader("Content-Type");
+
+                if (this.responseText &&
+                    (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
+                    try {
+                        this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
+                    } catch (e) {
+                        // Unable to parse XML - no biggie
+                    }
+                }
+
+                this.readyStateChange(FakeXMLHttpRequest.DONE);
+            },
+
+            respond: function respond(status, headers, body) {
+                this.status = typeof status == "number" ? status : 200;
+                this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
+                this.setResponseHeaders(headers || {});
+                this.setResponseBody(body || "");
+            },
+
+            uploadProgress: function uploadProgress(progressEventRaw) {
+                if (supportsProgress) {
+                    this.upload.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
+                }
+            },
+
+            downloadProgress: function downloadProgress(progressEventRaw) {
+                if (supportsProgress) {
+                    this.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
+                }
+            },
+
+            uploadError: function uploadError(error) {
+                if (supportsCustomEvent) {
+                    this.upload.dispatchEvent(new sinon.CustomEvent("error", {detail: error}));
+                }
+            }
+        });
+
+        sinon.extend(FakeXMLHttpRequest, {
+            UNSENT: 0,
+            OPENED: 1,
+            HEADERS_RECEIVED: 2,
+            LOADING: 3,
+            DONE: 4
+        });
+
+        sinon.useFakeXMLHttpRequest = function () {
+            FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
+                if (sinonXhr.supportsXHR) {
+                    global.XMLHttpRequest = sinonXhr.GlobalXMLHttpRequest;
+                }
+
+                if (sinonXhr.supportsActiveX) {
+                    global.ActiveXObject = sinonXhr.GlobalActiveXObject;
+                }
+
+                delete FakeXMLHttpRequest.restore;
+
+                if (keepOnCreate !== true) {
+                    delete FakeXMLHttpRequest.onCreate;
+                }
+            };
+            if (sinonXhr.supportsXHR) {
+                global.XMLHttpRequest = FakeXMLHttpRequest;
+            }
+
+            if (sinonXhr.supportsActiveX) {
+                global.ActiveXObject = function ActiveXObject(objId) {
+                    if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
+
+                        return new FakeXMLHttpRequest();
+                    }
+
+                    return new sinonXhr.GlobalActiveXObject(objId);
+                };
+            }
+
+            return FakeXMLHttpRequest;
+        };
+
+        sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./core");
+        require("./event");
+        makeApi(sinon);
+        module.exports = sinon;
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (typeof sinon === "undefined") {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+
+})(typeof global !== "undefined" ? global : this);
+
+/**
+ * @depend fake_xdomain_request.js
+ * @depend fake_xml_http_request.js
+ * @depend ../format.js
+ * @depend ../log_error.js
+ */
+/**
+ * The Sinon "server" mimics a web server that receives requests from
+ * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
+ * both synchronously and asynchronously. To respond synchronuously, canned
+ * answers have to be provided upfront.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+if (typeof sinon == "undefined") {
+    var sinon = {};
+}
+
+(function () {
+    var push = [].push;
+    function F() {}
+
+    function create(proto) {
+        F.prototype = proto;
+        return new F();
+    }
+
+    function responseArray(handler) {
+        var response = handler;
+
+        if (Object.prototype.toString.call(handler) != "[object Array]") {
+            response = [200, {}, handler];
+        }
+
+        if (typeof response[2] != "string") {
+            throw new TypeError("Fake server response body should be string, but was " +
+                                typeof response[2]);
+        }
+
+        return response;
+    }
+
+    var wloc = typeof window !== "undefined" ? window.location : {};
+    var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
+
+    function matchOne(response, reqMethod, reqUrl) {
+        var rmeth = response.method;
+        var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
+        var url = response.url;
+        var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
+
+        return matchMethod && matchUrl;
+    }
+
+    function match(response, request) {
+        var requestUrl = request.url;
+
+        if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
+            requestUrl = requestUrl.replace(rCurrLoc, "");
+        }
+
+        if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
+            if (typeof response.response == "function") {
+                var ru = response.url;
+                var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []);
+                return response.response.apply(response, args);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    function makeApi(sinon) {
+        sinon.fakeServer = {
+            create: function () {
+                var server = create(this);
+                if (!sinon.xhr.supportsCORS) {
+                    this.xhr = sinon.useFakeXDomainRequest();
+                } else {
+                    this.xhr = sinon.useFakeXMLHttpRequest();
+                }
+                server.requests = [];
+
+                this.xhr.onCreate = function (xhrObj) {
+                    server.addRequest(xhrObj);
+                };
+
+                return server;
+            },
+
+            addRequest: function addRequest(xhrObj) {
+                var server = this;
+                push.call(this.requests, xhrObj);
+
+                xhrObj.onSend = function () {
+                    server.handleRequest(this);
+
+                    if (server.autoRespond && !server.responding) {
+                        setTimeout(function () {
+                            server.responding = false;
+                            server.respond();
+                        }, server.autoRespondAfter || 10);
+
+                        server.responding = true;
+                    }
+                };
+            },
+
+            getHTTPMethod: function getHTTPMethod(request) {
+                if (this.fakeHTTPMethods && /post/i.test(request.method)) {
+                    var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
+                    return !!matches ? matches[1] : request.method;
+                }
+
+                return request.method;
+            },
+
+            handleRequest: function handleRequest(xhr) {
+                if (xhr.async) {
+                    if (!this.queue) {
+                        this.queue = [];
+                    }
+
+                    push.call(this.queue, xhr);
+                } else {
+                    this.processRequest(xhr);
+                }
+            },
+
+            log: function log(response, request) {
+                var str;
+
+                str =  "Request:\n"  + sinon.format(request)  + "\n\n";
+                str += "Response:\n" + sinon.format(response) + "\n\n";
+
+                sinon.log(str);
+            },
+
+            respondWith: function respondWith(method, url, body) {
+                if (arguments.length == 1 && typeof method != "function") {
+                    this.response = responseArray(method);
+                    return;
+                }
+
+                if (!this.responses) { this.responses = []; }
+
+                if (arguments.length == 1) {
+                    body = method;
+                    url = method = null;
+                }
+
+                if (arguments.length == 2) {
+                    body = url;
+                    url = method;
+                    method = null;
+                }
+
+                push.call(this.responses, {
+                    method: method,
+                    url: url,
+                    response: typeof body == "function" ? body : responseArray(body)
+                });
+            },
+
+            respond: function respond() {
+                if (arguments.length > 0) {
+                    this.respondWith.apply(this, arguments);
+                }
+
+                var queue = this.queue || [];
+                var requests = queue.splice(0, queue.length);
+                var request;
+
+                while (request = requests.shift()) {
+                    this.processRequest(request);
+                }
+            },
+
+            processRequest: function processRequest(request) {
+                try {
+                    if (request.aborted) {
+                        return;
+                    }
+
+                    var response = this.response || [404, {}, ""];
+
+                    if (this.responses) {
+                        for (var l = this.responses.length, i = l - 1; i >= 0; i--) {
+                            if (match.call(this, this.responses[i], request)) {
+                                response = this.responses[i].response;
+                                break;
+                            }
+                        }
+                    }
+
+                    if (request.readyState != 4) {
+                        this.log(response, request);
+
+                        request.respond(response[0], response[1], response[2]);
+                    }
+                } catch (e) {
+                    sinon.logError("Fake server request processing", e);
+                }
+            },
+
+            restore: function restore() {
+                return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
+            }
+        };
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./core");
+        require("./fake_xdomain_request");
+        require("./fake_xml_http_request");
+        makeApi(sinon);
+        module.exports = sinon;
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else {
+        makeApi(sinon);
+    }
+}());
+
+/**
+ * @depend fake_server.js
+ * @depend fake_timers.js
+ */
+/**
+ * Add-on for sinon.fakeServer that automatically handles a fake timer along with
+ * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
+ * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
+ * it polls the object for completion with setInterval. Dispite the direct
+ * motivation, there is nothing jQuery-specific in this file, so it can be used
+ * in any environment where the ajax implementation depends on setInterval or
+ * setTimeout.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function () {
+    function makeApi(sinon) {
+        function Server() {}
+        Server.prototype = sinon.fakeServer;
+
+        sinon.fakeServerWithClock = new Server();
+
+        sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
+            if (xhr.async) {
+                if (typeof setTimeout.clock == "object") {
+                    this.clock = setTimeout.clock;
+                } else {
+                    this.clock = sinon.useFakeTimers();
+                    this.resetClock = true;
+                }
+
+                if (!this.longestTimeout) {
+                    var clockSetTimeout = this.clock.setTimeout;
+                    var clockSetInterval = this.clock.setInterval;
+                    var server = this;
+
+                    this.clock.setTimeout = function (fn, timeout) {
+                        server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
+
+                        return clockSetTimeout.apply(this, arguments);
+                    };
+
+                    this.clock.setInterval = function (fn, timeout) {
+                        server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
+
+                        return clockSetInterval.apply(this, arguments);
+                    };
+                }
+            }
+
+            return sinon.fakeServer.addRequest.call(this, xhr);
+        };
+
+        sinon.fakeServerWithClock.respond = function respond() {
+            var returnVal = sinon.fakeServer.respond.apply(this, arguments);
+
+            if (this.clock) {
+                this.clock.tick(this.longestTimeout || 0);
+                this.longestTimeout = 0;
+
+                if (this.resetClock) {
+                    this.clock.restore();
+                    this.resetClock = false;
+                }
+            }
+
+            return returnVal;
+        };
+
+        sinon.fakeServerWithClock.restore = function restore() {
+            if (this.clock) {
+                this.clock.restore();
+            }
+
+            return sinon.fakeServer.restore.apply(this, arguments);
+        };
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require) {
+        var sinon = require("./core");
+        require("./fake_server");
+        require("./fake_timers");
+        makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require);
+    } else {
+        makeApi(sinon);
+    }
+}());
+
+/**
+ * @depend util/core.js
+ * @depend extend.js
+ * @depend collection.js
+ * @depend util/fake_timers.js
+ * @depend util/fake_server_with_clock.js
+ */
+/**
+ * Manages fake collections as well as fake utilities such as Sinon's
+ * timers and fake XHR implementation in one convenient object.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function () {
+    function makeApi(sinon) {
+        var push = [].push;
+
+        function exposeValue(sandbox, config, key, value) {
+            if (!value) {
+                return;
+            }
+
+            if (config.injectInto && !(key in config.injectInto)) {
+                config.injectInto[key] = value;
+                sandbox.injectedKeys.push(key);
+            } else {
+                push.call(sandbox.args, value);
+            }
+        }
+
+        function prepareSandboxFromConfig(config) {
+            var sandbox = sinon.create(sinon.sandbox);
+
+            if (config.useFakeServer) {
+                if (typeof config.useFakeServer == "object") {
+                    sandbox.serverPrototype = config.useFakeServer;
+                }
+
+                sandbox.useFakeServer();
+            }
+
+            if (config.useFakeTimers) {
+                if (typeof config.useFakeTimers == "object") {
+                    sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
+                } else {
+                    sandbox.useFakeTimers();
+                }
+            }
+
+            return sandbox;
+        }
+
+        sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
+            useFakeTimers: function useFakeTimers() {
+                this.clock = sinon.useFakeTimers.apply(sinon, arguments);
+
+                return this.add(this.clock);
+            },
+
+            serverPrototype: sinon.fakeServer,
+
+            useFakeServer: function useFakeServer() {
+                var proto = this.serverPrototype || sinon.fakeServer;
+
+                if (!proto || !proto.create) {
+                    return null;
+                }
+
+                this.server = proto.create();
+                return this.add(this.server);
+            },
+
+            inject: function (obj) {
+                sinon.collection.inject.call(this, obj);
+
+                if (this.clock) {
+                    obj.clock = this.clock;
+                }
+
+                if (this.server) {
+                    obj.server = this.server;
+                    obj.requests = this.server.requests;
+                }
+
+                obj.match = sinon.match;
+
+                return obj;
+            },
+
+            restore: function () {
+                sinon.collection.restore.apply(this, arguments);
+                this.restoreContext();
+            },
+
+            restoreContext: function () {
+                if (this.injectedKeys) {
+                    for (var i = 0, j = this.injectedKeys.length; i < j; i++) {
+                        delete this.injectInto[this.injectedKeys[i]];
+                    }
+                    this.injectedKeys = [];
+                }
+            },
+
+            create: function (config) {
+                if (!config) {
+                    return sinon.create(sinon.sandbox);
+                }
+
+                var sandbox = prepareSandboxFromConfig(config);
+                sandbox.args = sandbox.args || [];
+                sandbox.injectedKeys = [];
+                sandbox.injectInto = config.injectInto;
+                var prop, value, exposed = sandbox.inject({});
+
+                if (config.properties) {
+                    for (var i = 0, l = config.properties.length; i < l; i++) {
+                        prop = config.properties[i];
+                        value = exposed[prop] || prop == "sandbox" && sandbox;
+                        exposeValue(sandbox, config, prop, value);
+                    }
+                } else {
+                    exposeValue(sandbox, config, "sandbox", value);
+                }
+
+                return sandbox;
+            },
+
+            match: sinon.match
+        });
+
+        sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
+
+        return sinon.sandbox;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        require("./util/fake_server");
+        require("./util/fake_timers");
+        require("./collection");
+        module.exports = makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}());
+
+/**
+ * @depend util/core.js
+ * @depend stub.js
+ * @depend mock.js
+ * @depend sandbox.js
+ */
+/**
+ * Test function, sandboxes fakes
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    function makeApi(sinon) {
+        function test(callback) {
+            var type = typeof callback;
+
+            if (type != "function") {
+                throw new TypeError("sinon.test needs to wrap a test function, got " + type);
+            }
+
+            function sinonSandboxedTest() {
+                var config = sinon.getConfig(sinon.config);
+                config.injectInto = config.injectIntoThis && this || config.injectInto;
+                var sandbox = sinon.sandbox.create(config);
+                var exception, result;
+                var doneIsWrapped = false;
+                var argumentsCopy = Array.prototype.slice.call(arguments);
+                if (argumentsCopy.length > 0 && typeof argumentsCopy[arguments.length - 1] == "function") {
+                    var oldDone = argumentsCopy[arguments.length - 1];
+                    argumentsCopy[arguments.length - 1] = function done(result) {
+                        if (result) {
+                            sandbox.restore();
+                            throw exception;
+                        } else {
+                            sandbox.verifyAndRestore();
+                        }
+                        oldDone(result);
+                    }
+                    doneIsWrapped = true;
+                }
+
+                var args = argumentsCopy.concat(sandbox.args);
+
+                try {
+                    result = callback.apply(this, args);
+                } catch (e) {
+                    exception = e;
+                }
+
+                if (!doneIsWrapped) {
+                    if (typeof exception !== "undefined") {
+                        sandbox.restore();
+                        throw exception;
+                    } else {
+                        sandbox.verifyAndRestore();
+                    }
+                }
+
+                return result;
+            };
+
+            if (callback.length) {
+                return function sinonAsyncSandboxedTest(callback) {
+                    return sinonSandboxedTest.apply(this, arguments);
+                };
+            }
+
+            return sinonSandboxedTest;
+        }
+
+        test.config = {
+            injectIntoThis: true,
+            injectInto: null,
+            properties: ["spy", "stub", "mock", "clock", "server", "requests"],
+            useFakeTimers: true,
+            useFakeServer: true
+        };
+
+        sinon.test = test;
+        return test;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        require("./sandbox");
+        module.exports = makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend util/core.js
+ * @depend test.js
+ */
+/**
+ * Test case, sandboxes all test functions
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    function createTest(property, setUp, tearDown) {
+        return function () {
+            if (setUp) {
+                setUp.apply(this, arguments);
+            }
+
+            var exception, result;
+
+            try {
+                result = property.apply(this, arguments);
+            } catch (e) {
+                exception = e;
+            }
+
+            if (tearDown) {
+                tearDown.apply(this, arguments);
+            }
+
+            if (exception) {
+                throw exception;
+            }
+
+            return result;
+        };
+    }
+
+    function makeApi(sinon) {
+        function testCase(tests, prefix) {
+            /*jsl:ignore*/
+            if (!tests || typeof tests != "object") {
+                throw new TypeError("sinon.testCase needs an object with test functions");
+            }
+            /*jsl:end*/
+
+            prefix = prefix || "test";
+            var rPrefix = new RegExp("^" + prefix);
+            var methods = {}, testName, property, method;
+            var setUp = tests.setUp;
+            var tearDown = tests.tearDown;
+
+            for (testName in tests) {
+                if (tests.hasOwnProperty(testName)) {
+                    property = tests[testName];
+
+                    if (/^(setUp|tearDown)$/.test(testName)) {
+                        continue;
+                    }
+
+                    if (typeof property == "function" && rPrefix.test(testName)) {
+                        method = property;
+
+                        if (setUp || tearDown) {
+                            method = createTest(property, setUp, tearDown);
+                        }
+
+                        methods[testName] = sinon.test(method);
+                    } else {
+                        methods[testName] = tests[testName];
+                    }
+                }
+            }
+
+            return methods;
+        }
+
+        sinon.testCase = testCase;
+        return testCase;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        require("./test");
+        module.exports = makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend times_in_words.js
+ * @depend util/core.js
+ * @depend stub.js
+ * @depend format.js
+ */
+/**
+ * Assertions matching the test spy retrieval interface.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon, global) {
+    var slice = Array.prototype.slice;
+
+    function makeApi(sinon) {
+        var assert;
+
+        function verifyIsStub() {
+            var method;
+
+            for (var i = 0, l = arguments.length; i < l; ++i) {
+                method = arguments[i];
+
+                if (!method) {
+                    assert.fail("fake is not a spy");
+                }
+
+                if (method.proxy) {
+                    verifyIsStub(method.proxy);
+                } else {
+                    if (typeof method != "function") {
+                        assert.fail(method + " is not a function");
+                    }
+
+                    if (typeof method.getCall != "function") {
+                        assert.fail(method + " is not stubbed");
+                    }
+                }
+
+            }
+        }
+
+        function failAssertion(object, msg) {
+            object = object || global;
+            var failMethod = object.fail || assert.fail;
+            failMethod.call(object, msg);
+        }
+
+        function mirrorPropAsAssertion(name, method, message) {
+            if (arguments.length == 2) {
+                message = method;
+                method = name;
+            }
+
+            assert[name] = function (fake) {
+                verifyIsStub(fake);
+
+                var args = slice.call(arguments, 1);
+                var failed = false;
+
+                if (typeof method == "function") {
+                    failed = !method(fake);
+                } else {
+                    failed = typeof fake[method] == "function" ?
+                        !fake[method].apply(fake, args) : !fake[method];
+                }
+
+                if (failed) {
+                    failAssertion(this, (fake.printf || fake.proxy.printf).apply(fake, [message].concat(args)));
+                } else {
+                    assert.pass(name);
+                }
+            };
+        }
+
+        function exposedName(prefix, prop) {
+            return !prefix || /^fail/.test(prop) ? prop :
+                prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
+        }
+
+        assert = {
+            failException: "AssertError",
+
+            fail: function fail(message) {
+                var error = new Error(message);
+                error.name = this.failException || assert.failException;
+
+                throw error;
+            },
+
+            pass: function pass(assertion) {},
+
+            callOrder: function assertCallOrder() {
+                verifyIsStub.apply(null, arguments);
+                var expected = "", actual = "";
+
+                if (!sinon.calledInOrder(arguments)) {
+                    try {
+                        expected = [].join.call(arguments, ", ");
+                        var calls = slice.call(arguments);
+                        var i = calls.length;
+                        while (i) {
+                            if (!calls[--i].called) {
+                                calls.splice(i, 1);
+                            }
+                        }
+                        actual = sinon.orderByFirstCall(calls).join(", ");
+                    } catch (e) {
+                        // If this fails, we'll just fall back to the blank string
+                    }
+
+                    failAssertion(this, "expected " + expected + " to be " +
+                                "called in order but were called as " + actual);
+                } else {
+                    assert.pass("callOrder");
+                }
+            },
+
+            callCount: function assertCallCount(method, count) {
+                verifyIsStub(method);
+
+                if (method.callCount != count) {
+                    var msg = "expected %n to be called " + sinon.timesInWords(count) +
+                        " but was called %c%C";
+                    failAssertion(this, method.printf(msg));
+                } else {
+                    assert.pass("callCount");
+                }
+            },
+
+            expose: function expose(target, options) {
+                if (!target) {
+                    throw new TypeError("target is null or undefined");
+                }
+
+                var o = options || {};
+                var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
+                var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
+
+                for (var method in this) {
+                    if (method != "expose" && (includeFail || !/^(fail)/.test(method))) {
+                        target[exposedName(prefix, method)] = this[method];
+                    }
+                }
+
+                return target;
+            },
+
+            match: function match(actual, expectation) {
+                var matcher = sinon.match(expectation);
+                if (matcher.test(actual)) {
+                    assert.pass("match");
+                } else {
+                    var formatted = [
+                        "expected value to match",
+                        "    expected = " + sinon.format(expectation),
+                        "    actual = " + sinon.format(actual)
+                    ]
+                    failAssertion(this, formatted.join("\n"));
+                }
+            }
+        };
+
+        mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
+        mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
+                            "expected %n to not have been called but was called %c%C");
+        mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
+        mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
+        mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
+        mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
+        mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
+        mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
+        mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
+        mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
+        mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
+        mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
+        mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
+        mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
+        mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
+        mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
+        mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
+        mirrorPropAsAssertion("threw", "%n did not throw exception%C");
+        mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
+
+        sinon.assert = assert;
+        return assert;
+    }
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
+
+    function loadDependencies(require, exports, module) {
+        var sinon = require("./util/core");
+        require("./match");
+        module.exports = makeApi(sinon);
+    }
+
+    if (isAMD) {
+        define(loadDependencies);
+    } else if (isNode) {
+        loadDependencies(require, module.exports, module);
+    } else if (!sinon) {
+        return;
+    } else {
+        makeApi(sinon);
+    }
+
+}(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
+
+  return sinon;
+}));
index eb70eb9..19f132d 100644 (file)
@@ -7,7 +7,7 @@
 (function(exports){
 
   exports.uaparse = parse;
-  
+
   function parse(ua) {
     for (var i=0; i < parsers.length; i++) {
       var result = parsers[i](ua);
@@ -39,8 +39,8 @@
     if (suffix) { suffix = ' ' + suffix; }
     return this.family + suffix;
   };
-  
-  
+
+
   var regexes = [
       {"pattern":"^(Opera)/(\\d+)\\.(\\d+) \\(Nintendo Wii",
        "v1_replacement":null,
@@ -87,6 +87,9 @@
       {"pattern":"(konqueror)/(\\d+)\\.(\\d+)\\.(\\d+)",
        "v1_replacement":null,
        "family_replacement":"Konqueror"},
+      {"pattern":"(Edge)/(\\d+)\.(\\d+)",
+       "v1_replacement":null,
+       "family_replacement":"IE"},
       {"pattern":"(Jasmine|ANTGalio|Midori|Fresco|Lobo|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Shiira|Sunrise|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Vodafone|NetFront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|Iron|Iris)/(\\d+)\\.(\\d+)\\.(\\d+)",
        "v1_replacement":null,
        "family_replacement":null},
       {"pattern":"(Teleca Q7)",
        "v1_replacement":null,
        "family_replacement":null},
+      {"pattern":"Trident(.*)rv.(\\d+)\.(\\d+)",
+       "v1_replacement":null,
+       "family_replacement":"IE"},
       {"pattern":"(MSIE) (\\d+)\\.(\\d+)",
        "v1_replacement":null,
        "family_replacement":"IE"}
 
   ];
-  
-  var parsers = regexes.map(function(obj) {
+
+  var parsers = _.map(regexes, function(obj) {
     var regexp = new RegExp(obj.pattern),
         famRep = obj.family_replacement,
         v1Rep = obj.v1_replacement;
 
     return parser;
   });
-  
-  
+
+
 })(window);
 
 
diff --git a/js/modernizr/test/mocks/lib/build-query.js b/js/modernizr/test/mocks/lib/build-query.js
new file mode 100644 (file)
index 0000000..ba2d25d
--- /dev/null
@@ -0,0 +1,5 @@
+define([], function() {
+  return function() {
+    return '?--dontmin';
+  }
+});
diff --git a/js/modernizr/test/mocks/lib/metadata.js b/js/modernizr/test/mocks/lib/metadata.js
new file mode 100644 (file)
index 0000000..6f2a733
--- /dev/null
@@ -0,0 +1,61 @@
+define([], [
+  {
+    'name': 'Box Sizing',
+    'property': 'boxsizing',
+    'caniuse': 'css3-boxsizing',
+    'polyfills': [],
+    'tags': [],
+    'builderAliases': [ ],
+    'notes': [{
+      'name': 'MDN Docs',
+      'href': 'http://developer.mozilla.org/en/CSS/box-sizing'
+    }],
+    'doc': '<p>Detects support for the ability to control the css box model</p>\n',
+    'deps': [
+      'testAllProps'
+    ],
+    'path': './feature-detects/css/boxsizing.js',
+    'amdPath': 'test/css/boxsizing',
+    'async': false,
+    'warnings': [],
+    'cssclass': 'boxsizing',
+    'authors': [],
+    'knownBugs': []
+  }, {
+    'name': 'createElement with Attributes',
+    'property': [
+      'createelementattrs',
+      'createelement-attrs'
+    ],
+    'tags': [
+      'dom'
+    ],
+    'builderAliases': [
+      'dom_createElement_attrs'
+    ],
+    'authors': [
+      'James A. Rosen'
+    ],
+    'notes': [
+      {
+        'name': 'Related Github Issue',
+        'href': 'https://github.com/Modernizr/Modernizr/issues/258'
+      }
+    ],
+    'doc': null,
+    'deps': [
+      'createElement'
+    ],
+    'path': './feature-detects/dom/createElement-attrs.js',
+    'amdPath': 'test/dom/createElement-attrs',
+    'polyfills': [],
+    'async': false,
+    'warnings': [],
+    'caniuse': null,
+    'cssclass': [
+      'createelementattrs',
+      'createelement-attrs'
+    ],
+    'knownBugs': []
+  }
+])
diff --git a/js/modernizr/test/node/lib/build.js b/js/modernizr/test/node/lib/build.js
new file mode 100644 (file)
index 0000000..e50ddd8
--- /dev/null
@@ -0,0 +1,153 @@
+var root = require('find-parent-dir').sync(__dirname, 'package.json');
+var build = require(root + 'lib/build');
+var expect = require('expect.js');
+
+describe('cli/build', function() {
+
+  it('should build without error', function() {
+    expect(function() {build();}).to.not.throwError();
+  });
+
+  describe('custom builds', function(done) {
+
+    it('should build without errors when using a custom build', function() {
+      expect(function() {
+        build({'feature-detects': ['css/boxsizing']}, done);
+      }).to.not.throwError();
+    });
+
+    it('should include the requested options', function(done) {
+      build({'feature-detects': ['css/boxsizing']}, function(file) {
+        expect(file).to.contain('boxsizing');
+        done();
+      });
+    });
+
+    it('should exclude options that are not requested', function(done) {
+      build({'feature-detects': ['dom/classlist']}, function(file) {
+        expect(file).to.contain('classlist');
+        expect(file).to.not.contain('boxsizing');
+        done();
+      });
+    });
+
+    it('should strip out DOC comments when `uglify`ing', function(done) {
+      var config = {
+        minify: true,
+        'feature-detects': ['css/boxsizing']
+      };
+
+      build(config, function(file) {
+        expect(file).to.not.contain('Box Sizing');
+        done();
+      });
+    });
+
+    it('should inject the proper classPath when configured', function(done) {
+      var prefix = 'TEST_PREFIX';
+      var config = {
+        classPrefix: prefix,
+        setClasses: true
+      };
+      var configRE = /_config:\s*?({[^}]*})/m;
+
+      build(config, function(file) {
+        var parsedConfig = file.match(configRE);
+        parsedConfig = JSON.parse(parsedConfig[1].replace(/'/g, '"'));
+        expect(parsedConfig.classPrefix).to.be(prefix);
+        done();
+      });
+    });
+
+    it('should inject the proper classPath when configured and minified', function(done) {
+      var prefix = 'TEST_PREFIX';
+      var config = {
+        classPrefix: prefix,
+        setClasses: true,
+        minify: true
+      };
+      var configRE = /_config:\s*?({[^}]*})/m;
+
+      build(config, function(file) {
+        var parsedConfig = file.match(configRE);
+        //use eval becuase the minified code creates non valid JSON.
+        parsedConfig = eval('(' + parsedConfig[1].replace(/'/g, '"') + ')');
+        expect(parsedConfig.classPrefix).to.be(prefix);
+        done();
+      });
+    });
+
+    describe('unminified', function() {
+      var output;
+
+      before(function(done) {
+        var config = {
+          'feature-detects': ['css/boxsizing']
+        };
+
+        build(config, function(file) {
+          output = file;
+          done();
+        });
+      });
+
+      it('strips out the modernizr-init/build `define` section', function() {
+        var defineRe = /define\("modernizr-(init|build)"\)/m;
+        expect(defineRe.test(output)).to.be(false);
+      });
+
+      it('strips out the `define` section', function() {
+        var docRe = /define\(.*?\{/;
+        expect(docRe.test(output)).to.be(false);
+      });
+
+      it('strips out the `require` section', function() {
+        var requireRe = /require[^\{\r\n]+\{/;
+        expect(requireRe.test(output)).to.be(false);
+      });
+
+      it('replaces __VERSION__ ', function() {
+        expect(output).to.not.contain('__VERSION__');
+      });
+
+    });
+
+    describe('minified', function() {
+      var output;
+
+      before(function(done) {
+        var config = {
+          'feature-detects': ['css/boxsizing'],
+          minify: true
+        };
+
+        build(config, function(file) {
+          output = file;
+          done();
+        });
+      });
+
+      it('strips out the modernizr-init/build `define` section', function() {
+        var defineRe = /define\("modernizr-(init|build)"\)/m;
+        expect(defineRe.test(output)).to.be(false);
+      });
+
+      it('strips out the `define` section', function() {
+        var docRe = /define\(.*?\{/;
+        expect(docRe.test(output)).to.be(false);
+      });
+
+      it('strips out the `require` section', function() {
+        var requireRe = /require[^\{\r\n]+\{/;
+        expect(requireRe.test(output)).to.be(false);
+      });
+
+      it('replaces __VERSION__ ', function() {
+        expect(output).to.not.contain('__VERSION__');
+      });
+
+    });
+
+  });
+
+});
diff --git a/js/modernizr/test/node/lib/cli.js b/js/modernizr/test/node/lib/cli.js
new file mode 100644 (file)
index 0000000..902ad47
--- /dev/null
@@ -0,0 +1,16 @@
+var root = require('find-parent-dir').sync(__dirname, 'package.json');
+var expect = require('expect.js');
+var Modernizr = require(root + 'lib/cli');
+
+
+describe('cli', function() {
+
+  it('exposes a build function', function() {
+    expect(Modernizr.build).to.be.a('function');
+  });
+
+  it('exposes a metadata function', function() {
+    expect(Modernizr.metadata).to.be.a('function');
+  });
+
+});
diff --git a/js/modernizr/test/node/lib/metadata.js b/js/modernizr/test/node/lib/metadata.js
new file mode 100644 (file)
index 0000000..e0b1e74
--- /dev/null
@@ -0,0 +1,212 @@
+var root = require('find-parent-dir').sync(__dirname, 'package.json');
+var proxyquire = require('proxyquire').noPreserveCache();
+var metadata = require(root + 'lib/metadata');
+var expect = require('expect.js');
+var Joi = require('joi');
+
+describe('cli/metadata', function() {
+
+  it('should ignore .DS_STORE files', function(done) {
+
+    var metadata = proxyquire(root + 'lib/metadata', {
+      'file': {
+        'walkSync': function(dir, cb) {
+          cb('/', [], ['.DS_Store']);
+        }
+      }
+    });
+
+    metadata(function(data) {
+      expect(data).to.be.an('array');
+      expect(data).to.have.length(0);
+      done();
+    });
+  });
+
+  it('should throw on malformed metadata', function() {
+
+    var metadata = proxyquire(root + 'lib/metadata', {
+      'fs': {
+        'readFileSync': function() {
+          return '/*! { !*/';
+        }
+      }
+    });
+
+    expect(metadata).to.throwException(/Error Parsing Metadata/);
+  });
+
+  it('should not throw when metadata is missing', function() {
+
+    var metadata = proxyquire(root + 'lib/metadata', {
+      'fs': {
+        'readFileSync': function() {
+          return 'sup dude';
+        }
+      }
+    });
+
+    expect(metadata).to.not.throwException(/Error Parsing Metadata/);
+  });
+
+  it('should throw on malformed deps', function() {
+
+    var metadata = proxyquire(root + 'lib/metadata', {
+      'fs': {
+        'readFileSync': function() {
+          return 'define([[],';
+        }
+      }
+    });
+
+    expect(metadata).to.throwException(/Couldn't parse dependencies/);
+  });
+
+  it('should throw if we can\'t find the define', function() {
+
+    var metadata = proxyquire(root + 'lib/metadata', {
+      'fs': {
+        'readFileSync': function() {
+          return 'defin([]),';
+        }
+      }
+    });
+
+    expect(metadata).to.throwException(/Couldn't find the define/);
+  });
+
+  it('should use amdPath as a fallback for name', function() {
+
+    var metadata = proxyquire(root + 'lib/metadata', {
+      'file': {
+        'walkSync': function(dir, cb) {
+          cb('/', [], ['fakeDetect.js']);
+        }
+      },
+      'fs': {
+        'readFileSync': function() {
+          return '/*! { "property": "fake"}!*/ define([],';
+        }
+      }
+    });
+    var result = metadata();
+
+    expect(result.name).to.equal(result.amdPath);
+  });
+
+  it('should throw if we can\'t find the define', function() {
+
+    var metadata = proxyquire(root + 'lib/metadata', {
+      'fs': {
+        'readFileSync': function() {
+          return '/*! { "polyfills": ["fake"]}!*/ define([],';
+        }
+      }
+    });
+
+    expect(metadata).to.throwException(/Polyfill not found/);
+  });
+
+  it('should throw if we can\'t find the define', function() {
+
+    var metadata = proxyquire(root + 'lib/metadata', {
+      'fs': {
+        'readFileSync': function() {
+          return '/*! { "property": "fake", "cssclass": "realFake"}!*/ define([],';
+        }
+      }
+    });
+
+    var firstResult = metadata()[0];
+
+    expect(firstResult.cssclass).to.be(null);
+  });
+
+  it('should rename `docs` to `doc` when found', function() {
+
+    var metadata = proxyquire(root + 'lib/metadata', {
+      'fs': {
+        'readFileSync': function() {
+          return '/*! { "docs": "originally docs" }!*/ define([],';
+        }
+      }
+    });
+
+    var firstResult = metadata()[0];
+
+    expect(firstResult.docs).to.be(undefined);
+    expect(firstResult.doc).to.match(/originally docs/);
+  });
+
+  it('returns a json blob when invoked without callback', function() {
+    expect(metadata()).to.be.an('array');
+  });
+
+  it('return nothing when given a callback', function() {
+    expect(metadata(function noop() {})).to.be(undefined);
+  });
+
+  it('pass the json blob when given a callback', function(done) {
+    metadata(function(data) {
+      expect(data).to.be.an('array');
+      done();
+    });
+  });
+
+  describe('returns an array of valid objects', function() {
+    var schema = Joi.object().keys({
+                  amdPath        : Joi.string().required(),
+                  name           : Joi.string().required(),
+                  path           : Joi.string().required(),
+                  doc            : Joi.alternatives().try(Joi.string(), null),
+
+                  caniuse        : Joi.alternatives().try(Joi.string(), null),
+
+                  async          : Joi.boolean(),
+
+                  aliases        : Joi.array().items(Joi.string()),
+                  builderAliases : Joi.array().items(Joi.string()),
+                  knownBugs      : Joi.array().items(Joi.string()),
+                  warnings       : Joi.array().items(Joi.string()),
+                  authors        : Joi.array().items(Joi.string()),
+                  tags           : Joi.array().items(Joi.string()),
+                  deps           : Joi.array().items(Joi.string()),
+
+                  notes          : Joi.array().items(
+                    Joi.object().keys({
+                      name: Joi.string().required(),
+                      href: Joi.string().required()
+                    })
+                  ).unique(),
+
+                  cssclass       : Joi.alternatives().try(
+                                    Joi.string().lowercase(),
+                                    Joi.array().items(Joi.string().lowercase())
+                                  ).required(),
+
+                  property       : Joi.alternatives().try(
+                                    Joi.string().lowercase(),
+                                    Joi.array().items(Joi.string().lowercase())
+                                  ).required(),
+
+                  polyfills : Joi.array().items(
+                                Joi.object().keys({
+                                  name     : Joi.string().required(),
+                                  authors  : Joi.array().items(Joi.string()),
+                                  notes    : Joi.array().items(Joi.string()),
+                                  href     : Joi.string().required(),
+                                  licenses : Joi.array().items(Joi.string()).required()
+                                })
+                              ).unique()
+                });
+
+    metadata(function(data) {
+      data.forEach(function(obj) {
+        var err = schema.validate(obj).error;
+        it('for ' + obj.name, function() {
+          expect(err).to.be(null);
+        });
+      });
+    });
+  });
+});
diff --git a/js/modernizr/test/node/lib/options.js b/js/modernizr/test/node/lib/options.js
new file mode 100644 (file)
index 0000000..ecfe0f0
--- /dev/null
@@ -0,0 +1,34 @@
+var root = require('find-parent-dir').sync(__dirname, 'package.json');
+var options = require(root + 'lib/options');
+var expect = require('expect.js');
+var Joi = require('joi');
+
+var schema = Joi.array().items(
+  Joi.object().keys({
+    name: Joi.string(),
+    property: Joi.string()
+  })
+);
+
+
+describe('cli/options', function() {
+  this.timeout(20000);
+
+  it('should return an array of objects in a callback', function(done) {
+    options(function(opts) {
+      var err = schema.validate(opts).error;
+      expect(err).to.be(null);
+      done(err);
+    });
+  });
+
+  it('should return the array of objects immediately after the first run', function() {
+    var err = schema.validate(options()).error;
+    expect(err).to.be(null);
+  });
+
+  it('should return all jsdoc info when the second arg is true', function() {
+    expect(options(null, true) !== options(null)).to.be(true);
+    expect(options(null, true)[0].description).to.not.be(undefined);
+  });
+});
diff --git a/js/modernizr/test/universal/lib/build-hash.js b/js/modernizr/test/universal/lib/build-hash.js
new file mode 100644 (file)
index 0000000..a4f8a0e
--- /dev/null
@@ -0,0 +1,86 @@
+if (typeof define !== 'function') {
+  var projectRoot = require('find-parent-dir').sync(__dirname, 'package.json');
+  var filesRoot = projectRoot;
+  if (process.env.APP_DIR_FOR_CODE_COVERAGE) {
+    filesRoot = filesRoot + process.env.APP_DIR_FOR_CODE_COVERAGE;
+  }
+  var requirejs = require('requirejs');
+  var expect = require('expect.js');
+} else {
+  var projectRoot = '..';
+  var filesRoot = '..';
+}
+var cleanup;
+var req;
+
+
+describe('build-query', function() {
+  var buildQuery;
+
+  before(function(done) {
+
+    req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      paths: {
+        lib: filesRoot + '/lib',
+        lodash: projectRoot + '/node_modules/lodash/index',
+        metadata: projectRoot + '/test/mocks/lib/metadata',
+        cleanup: projectRoot + '/test/cleanup'
+      }
+    });
+
+    req(['lib/build-query', 'cleanup'], function(_buildQuery, _cleanup) {
+      buildQuery = _buildQuery;
+      cleanup = _cleanup;
+      done();
+    });
+  });
+
+  it('builds a query from a feature-detect', function() {
+    var query = buildQuery({
+      'feature-detects': ['css/boxsizing']
+    });
+    expect(query).to.be('?-boxsizing-dontmin');
+  });
+
+  it('properly formats detects with multiple properties', function() {
+    var query = buildQuery({
+      'feature-detects': ['dom/createElement-attrs']
+    });
+    expect(query).to.be('?-createelementattrs_createelement_attrs-dontmin');
+  });
+
+  it('adds options to the query', function() {
+    var query = buildQuery({
+      options: ['mq']
+    });
+    expect(query).to.be('?-mq-dontmin');
+  });
+
+  it('adds classPrefix when setClasses is true as well', function() {
+    var query = buildQuery({
+      classPrefix: 'TEST_PREFIX',
+      options: ['setClasses']
+    });
+    expect(query).to.be('?-cssclasses-dontmin-cssclassprefix:TEST_PREFIX');
+  });
+
+  it('strips `html5` from the shiv options', function() {
+    var query = buildQuery({
+      options: ['html5shiv']
+    });
+    expect(query).to.be('?-shiv-dontmin');
+  });
+
+  it('removes the dontmin option when minify is true', function() {
+    var query = buildQuery({
+      minify: true
+    });
+    expect(query).to.be('?-');
+  });
+
+  after(function() {
+    cleanup();
+  });
+
+});
diff --git a/js/modernizr/test/universal/lib/generate-banner.js b/js/modernizr/test/universal/lib/generate-banner.js
new file mode 100644 (file)
index 0000000..8e2a29a
--- /dev/null
@@ -0,0 +1,76 @@
+if (typeof define !== 'function') {
+  var projectRoot = require('find-parent-dir').sync(__dirname, 'package.json');
+  var filesRoot = projectRoot;
+  if (process.env.APP_DIR_FOR_CODE_COVERAGE) {
+    filesRoot = filesRoot + process.env.APP_DIR_FOR_CODE_COVERAGE;
+  }
+  var requirejs = require('requirejs');
+  var pkg = require(projectRoot + '/package');
+  var expect = require('expect.js');
+  var domain = 'modernizr.com';
+  var _ = require('lodash');
+  var def = function() {
+    return requirejs.define.apply(this, arguments);
+  };
+} else {
+  var domain = location.host;
+  var projectRoot = '..';
+  var filesRoot = '..';
+  var pkg = {};
+  var _ = window.lodash;
+  var def = function() {
+    return define.apply(this, arguments);
+  };
+}
+var generateBanner;
+var cleanup;
+
+describe('generate-banner', function() {
+
+  before(function(done) {
+    var req = requirejs.config({
+      context: Math.random().toString().slice(2),
+      paths: {
+        lib: projectRoot + '/test/mocks/lib',
+        generateBanner: filesRoot + '/lib/generate-banner',
+        cleanup: projectRoot + '/test/cleanup'
+      }
+    });
+
+    def('package', [], function() {return pkg;});
+    def('lodash', [], function() {return _;});
+
+    req(['generateBanner', 'package', 'cleanup'], function(_generateBanner, _pkg, _cleanup) {
+      generateBanner = _generateBanner;
+      cleanup = _cleanup;
+      pkg = _pkg;
+      done();
+    });
+  });
+
+  it('should produce a compact banner when requested', function() {
+    var banner = generateBanner('compact');
+    var test = '/*! ' + pkg.name + ' ' + pkg.version + ' (Custom Build) | ' + pkg.license  + ' *';
+    expect(banner).to.contain(test);
+  });
+
+  it('should produce a full banner when requested', function() {
+    var banner = generateBanner('full');
+    var test = 'Modernizr tests which native CSS3 and HTML5 features are available';
+    expect(banner).to.contain(test);
+  });
+
+  it('should include a build url', function() {
+    var banner = generateBanner();
+    var test = ' * http://' + domain + '/download/?--dontmin';
+    expect(banner).to.contain(test);
+  });
+
+  it('should only accept "full" and "compact" as type arguments', function() {
+    expect(function() {generateBanner('sup');}).to.throwError('banners() must be passed "compact" or "full" as an argument.');
+  });
+
+  after(function() {
+    cleanup();
+  });
+});
index 57ca7a6..88f31f6 100644 (file)
@@ -175,6 +175,7 @@ input[type="submit"].blogbutton {
         }
         .meta.date {
             font-family: "Josefin Sans";
+            color: grey;
         }
     }
 }
index 86eb310..a0e8a72 100644 (file)
@@ -8,38 +8,37 @@
                         <div class="row">
                             <div class="small-12 columns">
                                 <article id="<?php the_ID()?>" <?php post_class()?>>
-                                    <h2><?php the_title();?></h2>
                                     <header class="entry-header">
                                         <h1 class="entry-title"><a href="<?php the_permalink(); ?>"><?php the_title();?></a></h1>
                                         <span class="meta date">Posted on <?php the_time('F jS, Y') ?></span>
                                     </header>
                                     <?php echo the_content(); ?>
-                                    <footer class="entry-meta small-12 medium-6 medium-push-3 center">
-                                        <?php $post_categories = wp_get_post_categories( get_the_ID() );
-                                        $cats = array();
-                                        echo 'This entry was posted ';
-                                        if (has_category()) {
-                                            echo 'in ';
-                                            foreach($post_categories as $c){
-                                                $cat = get_category( $c );
-                                                $cats[] = array( 'name' => $cat->name, 'slug' => $cat->slug );
-                                                echo '<a rel="category" title="View all posts in '. $cat->name . ' " href="'. $cat->slug .'">'. $cat->name .'</a>, ';
-                                            }
-                                        }
-                                        $post_tags = wp_get_post_tags( get_the_ID() );
-                                        $tags = array();
-                                        if (has_tag( )) {
-                                            echo ' and tagged ';
-                                            foreach($post_tags as $t){
-                                                $tag = get_tag( $t );
-                                                $tags[] = array( 'name' => $tag->name, 'slug' => $tag->slug );
-                                                echo '<a rel="category" title="View all posts in '. $tag->name . ' " href="'. $tag->slug .'">'. $tag->name .'</a>, ';
-                                            }
-                                        }
-                                        echo ' on ';
-                                        echo ' <span class="meta date"> ' . the_time('F jS, Y') . '</span>';
-                                        ?>
-                                    </footer>
+<!--                                    <footer class="entry-meta small-12 medium-6 medium-push-3 center">-->
+                                        <?php // $post_categories = wp_get_post_categories( get_the_ID() );
+//                                        $cats = array();
+//                                        echo 'This entry was posted ';
+//                                        if (has_category()) {
+//                                            echo 'in ';
+//                                            foreach($post_categories as $c){
+//                                                $cat = get_category( $c );
+//                                                $cats[] = array( 'name' => $cat->name, 'slug' => $cat->slug );
+//                                                echo '<a rel="category" title="View all posts in '. $cat->name . ' " href="'. $cat->slug .'">'. $cat->name .'</a>, ';
+//                                            }
+//                                        }
+//                                        $post_tags = wp_get_post_tags( get_the_ID() );
+//                                        $tags = array();
+//                                        if (has_tag( )) {
+//                                            echo ' and tagged ';
+//                                            foreach($post_tags as $t){
+//                                                $tag = get_tag( $t );
+//                                                $tags[] = array( 'name' => $tag->name, 'slug' => $tag->slug );
+//                                                echo '<a rel="category" title="View all posts in '. $tag->name . ' " href="'. $tag->slug .'">'. $tag->name .'</a>, ';
+//                                            }
+//                                        }
+//                                        echo ' on ';
+//                                        echo ' <span class="meta date"> ' . the_time('F jS, Y') . '</span>';
+//                                        ?>
+<!--                                    </footer>-->
                                 </article>
                             </div>
                         </div>