├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── bower.json ├── gruntfile.js ├── package-lock.json ├── package.json ├── src ├── lazyad-loader.js └── libs │ ├── boxsizing.htc │ ├── indexof-polyfill.js │ ├── media.match.js │ └── ready.js └── tests ├── index.html ├── index2.html ├── styles.css └── utils.js /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | npm-debug.log 15 | node_modules 16 | dist 17 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiley/madgex-lazy-ads/d35aadf6b8f70a22060141e6cf3d71342ff6a384/.npmignore -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Madgex 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Lazy Ads 2 | ======== 3 | 4 | Deliver synchronous ads asynchronously, without modifying the ad code. Also, conditionally load ads for responsive websites using a media query or the ad container's dimensions. 5 | 6 | #### Demo 7 | Here's a little demo. It lazily loads and unloads each ad depending on the environment, a green background and the ad should load (a timestamped image instead of real ad in the demo), red and it will unload (if loaded): [Demo](http://htmlpreview.github.io/?https://github.com/madgex/lazy-ads/blob/develop/tests/index2.html) 8 | 9 | ## The problem 10 | Ads have long been the elephant in the room in regards to Responsive Web Design, with few providers supporting the fluid, flexible layouts that define responsive websites. Here at [Madgex](http://madgex.com/) we deal with over 30 ad providers and many show no signs of supporting responsive layouts. 11 | 12 | ##### Approach 1 - Hide the ad container using CSS 13 | It's trivially simple to hide the ad using CSS if a media query condition is met. However, this doesn't prevent the ad code from executing. An ad impression is still recorded, even if the ad isn't actually visible. Furthermore, potentially pointless network round-trips to load the ad content would still take place. This is detrimental to the site's speed and performance, especially on a mobile device. 14 | 15 | ##### Approach 2 - Force the ads to be flexible 16 | Forcing images or flash objects to be flexible quickly creates illegible ads on small screened devices. Furthermore, some ad providers wrap ads in multiple layers of unsemantic, inline pixel width defined elements. These can be difficult (or highly brittle, or outright impossible) to make flexible. 17 | 18 | ##### Approach 3 - Wait for ad providers 19 | Seeing as most ad providers are still using the 90's-web `document.write` as a delivery technique, we're not holding our breath. 20 | 21 | ## Our proposed approach 22 | Leave ads scripts intact, but wrap them to prevent inline execution. Place load criteria on the element wrapping the ad, either using dimensions, or a media query. On DOMready, [lazily](http://en.wikipedia.org/wiki/Lazy_loading) inject the ads if the criteria is met. 23 | 24 | #### Putting it all together 25 | The lazy ads loader sits on top of a couple of polyfills & tried and tested open source projects: 26 | * [PostScribe](https://github.com/krux/postscribe/) by Krux Digital, Inc. overrides document.write to provide async support. 27 | * [indexof polyfill](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) for indexOf support on older browsers (via MDN) 28 | * [Media.match](https://github.com/weblinc/media-match) media queries polyfill for older browsers. 29 | * [domReady](https://github.com/ded/domready) a tiny, sturdy DOMReady implementation for older browsers. 30 | 31 | Once minified & gzipped the script weighs in at ~6.5KB. 32 | 33 | ## An additional benefit - performance 34 | This asynchronous approach to loading ads also provides a fair performance boost for the page content as `document.write` is no longer blocking rendering. This performance bottleneck has been [widely documented](http://www.stevesouders.com/blog/2012/04/10/dont-docwrite-scripts/), yet ad providers continue to use the technique. 35 | 36 | ## Installation 37 | Install via `npm`: 38 | 39 | ``` console 40 | npm install --save lazy-ads 41 | ``` 42 | 43 | ## Basic usage 44 | Load the script. 45 | ``` html 46 | 47 | ``` 48 | 49 | Wrap the ad script to prevent it from running inline. The `data-lazyad` attribute is a required hook. 50 | 51 | ``` html 52 | 53 |
54 | 59 |
60 | ``` 61 | 62 | **Important:** The HTML comments wrapping the ad script **are required**. They prevent the ads closing `` tag from closing our `text/lazyad` script tag prematurely. 63 | 64 | ## Adding conditions 65 | 66 | #### Media query 67 | This ad will only load if the viewport is a screen & at least 800px wide on load. 68 | ``` html 69 | 70 |
71 | 76 |
77 | ``` 78 | 79 | #### Container dimensions 80 | This ad will only load if the ad container is at least 728px x 90px on load. 81 | ``` html 82 | 83 |
84 | 89 |
90 | ``` 91 | 92 | ## Support 93 | IE7 and up, and modern browsers (Chrome, FF, Opera etc). 94 | 95 | ## How to build 96 | You need to have [Node.js](http://nodejs.org/download/) & NPM installed before you start. 97 | 98 | If you don't have the Grunt command line interface, install it as a global package 99 | ```bash 100 | npm install -g grunt-cli 101 | ``` 102 | Clone the lazy-ads repo 103 | ```bash 104 | git clone https://github.com/madgex/lazy-ads.git 105 | ``` 106 | CD into the directory 107 | ```bash 108 | cd lazy-ads 109 | ``` 110 | Run `grunt` to create the distribution packages in the `dist/` directory 111 | ```bash 112 | grunt 113 | ``` 114 | 115 | 116 | ## Feedback 117 | Although we've had initial success in this approach we're keen to hear your [feedback](https://github.com/madgex/lazy-ads/issues/new). 118 | 119 | ## MIT license 120 | Lazy Ads is released under the [MIT license](https://github.com/madgex/lazy-ads/blob/master/LICENSE). 121 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lazy-ads", 3 | "version": "1.1.11", 4 | "homepage": "https://github.com/madgex/lazy-ads", 5 | "authors": [ 6 | "James Wragg " 7 | ], 8 | "description": "Deliver synchronous ads asynchronously with RWD support without modifying the ad code.", 9 | "main": "dist/lazyads-loader.js", 10 | "keywords": [ 11 | "ads", 12 | "lazy-load", 13 | "async", 14 | "responsive", 15 | "rwd" 16 | ], 17 | "license": "MIT", 18 | "ignore": [ 19 | "**/.*", 20 | "node_modules", 21 | "bower_components", 22 | "test", 23 | "tests", 24 | "src", 25 | "gruntfile.js", 26 | "package.json" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.initConfig({ 4 | pkg: grunt.file.readJSON('package.json'), 5 | clean: ['dist/*'], 6 | concat: { 7 | options: { 8 | separator: ';', 9 | banner: '/**\n' + 10 | '* <%= pkg.name %> v<%= pkg.version %>\n' + 11 | '* <%= pkg.description %>\n' + 12 | '* Madgex. Build date: <%= grunt.template.today("dd-mm-yyyy") %>\n' + 13 | '*/\n\n' 14 | }, 15 | target: { 16 | src: ['node_modules/postscribe/dist/postscribe.js','src/libs/*.js', 'src/lazyad-loader.js'], 17 | dest: 'dist/lazyad-loader.js' 18 | } 19 | }, 20 | uglify: { 21 | options: { 22 | banner: '<%= concat.options.banner %>' 23 | }, 24 | target: { 25 | options: { 26 | banner: '<%= uglify.options.banner %>', 27 | }, 28 | files: { 29 | 'dist/lazyad-loader.min.js': ['<%= concat.target.dest %>'] 30 | } 31 | } 32 | }, 33 | watch: { 34 | files: ['Gruntfile.js', 'src/**/*.js', 'tests/**/*'], 35 | tasks: ['concat'], 36 | options: { 37 | livereload: true 38 | } 39 | }, 40 | connect: { 41 | server: { 42 | options: { 43 | open: true, 44 | port: 9000, 45 | hostname: '*', 46 | livereload: true, 47 | } 48 | } 49 | }, 50 | release: { 51 | options: { 52 | additionalFiles: ['bower.json'] 53 | } 54 | } 55 | 56 | }); 57 | 58 | grunt.loadNpmTasks('grunt-contrib-uglify'); 59 | grunt.loadNpmTasks('grunt-contrib-watch'); 60 | grunt.loadNpmTasks('grunt-contrib-concat'); 61 | grunt.loadNpmTasks('grunt-contrib-clean'); 62 | grunt.loadNpmTasks('grunt-contrib-connect'); 63 | grunt.loadNpmTasks('grunt-release'); 64 | 65 | grunt.registerTask('test', ['connect', 'watch']); 66 | 67 | grunt.registerTask('default', ['clean', 'concat', 'uglify']); 68 | 69 | }; -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lazy-ads", 3 | "version": "1.1.12", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abbrev": { 8 | "version": "1.1.1", 9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 10 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", 11 | "dev": true 12 | }, 13 | "accepts": { 14 | "version": "1.3.5", 15 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", 16 | "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", 17 | "dev": true, 18 | "requires": { 19 | "mime-types": "~2.1.18", 20 | "negotiator": "0.6.1" 21 | } 22 | }, 23 | "align-text": { 24 | "version": "0.1.4", 25 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", 26 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", 27 | "dev": true, 28 | "requires": { 29 | "kind-of": "^3.0.2", 30 | "longest": "^1.0.1", 31 | "repeat-string": "^1.5.2" 32 | } 33 | }, 34 | "amdefine": { 35 | "version": "1.0.1", 36 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", 37 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", 38 | "dev": true 39 | }, 40 | "ansi-regex": { 41 | "version": "0.2.1", 42 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", 43 | "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", 44 | "dev": true 45 | }, 46 | "ansi-styles": { 47 | "version": "1.1.0", 48 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", 49 | "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", 50 | "dev": true 51 | }, 52 | "argparse": { 53 | "version": "0.1.16", 54 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", 55 | "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=", 56 | "dev": true, 57 | "requires": { 58 | "underscore": "~1.7.0", 59 | "underscore.string": "~2.4.0" 60 | }, 61 | "dependencies": { 62 | "underscore.string": { 63 | "version": "2.4.0", 64 | "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz", 65 | "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=", 66 | "dev": true 67 | } 68 | } 69 | }, 70 | "array-find-index": { 71 | "version": "1.0.2", 72 | "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", 73 | "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", 74 | "dev": true 75 | }, 76 | "async": { 77 | "version": "0.1.22", 78 | "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", 79 | "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=", 80 | "dev": true 81 | }, 82 | "balanced-match": { 83 | "version": "1.0.0", 84 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 85 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 86 | "dev": true 87 | }, 88 | "basic-auth": { 89 | "version": "2.0.0", 90 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz", 91 | "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=", 92 | "dev": true, 93 | "requires": { 94 | "safe-buffer": "5.1.1" 95 | }, 96 | "dependencies": { 97 | "safe-buffer": { 98 | "version": "5.1.1", 99 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 100 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", 101 | "dev": true 102 | } 103 | } 104 | }, 105 | "batch": { 106 | "version": "0.6.1", 107 | "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", 108 | "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", 109 | "dev": true 110 | }, 111 | "brace-expansion": { 112 | "version": "1.1.11", 113 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 114 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 115 | "dev": true, 116 | "requires": { 117 | "balanced-match": "^1.0.0", 118 | "concat-map": "0.0.1" 119 | } 120 | }, 121 | "browserify-zlib": { 122 | "version": "0.1.4", 123 | "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", 124 | "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", 125 | "dev": true, 126 | "requires": { 127 | "pako": "~0.2.0" 128 | } 129 | }, 130 | "buffer-from": { 131 | "version": "1.0.0", 132 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", 133 | "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", 134 | "dev": true 135 | }, 136 | "builtin-modules": { 137 | "version": "1.1.1", 138 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 139 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", 140 | "dev": true 141 | }, 142 | "camelcase": { 143 | "version": "2.1.1", 144 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", 145 | "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", 146 | "dev": true 147 | }, 148 | "camelcase-keys": { 149 | "version": "2.1.0", 150 | "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", 151 | "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", 152 | "dev": true, 153 | "requires": { 154 | "camelcase": "^2.0.0", 155 | "map-obj": "^1.0.0" 156 | } 157 | }, 158 | "center-align": { 159 | "version": "0.1.3", 160 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", 161 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", 162 | "dev": true, 163 | "requires": { 164 | "align-text": "^0.1.3", 165 | "lazy-cache": "^1.0.3" 166 | } 167 | }, 168 | "chalk": { 169 | "version": "0.5.1", 170 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", 171 | "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", 172 | "dev": true, 173 | "requires": { 174 | "ansi-styles": "^1.1.0", 175 | "escape-string-regexp": "^1.0.0", 176 | "has-ansi": "^0.1.0", 177 | "strip-ansi": "^0.3.0", 178 | "supports-color": "^0.2.0" 179 | } 180 | }, 181 | "cliui": { 182 | "version": "2.1.0", 183 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", 184 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", 185 | "dev": true, 186 | "requires": { 187 | "center-align": "^0.1.1", 188 | "right-align": "^0.1.1", 189 | "wordwrap": "0.0.2" 190 | } 191 | }, 192 | "coffee-script": { 193 | "version": "1.3.3", 194 | "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz", 195 | "integrity": "sha1-FQ1rTLUiiUNp7+1qIQHCC8f0pPQ=", 196 | "dev": true 197 | }, 198 | "colors": { 199 | "version": "0.6.2", 200 | "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", 201 | "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", 202 | "dev": true 203 | }, 204 | "combined-stream": { 205 | "version": "1.0.6", 206 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", 207 | "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", 208 | "dev": true, 209 | "requires": { 210 | "delayed-stream": "~1.0.0" 211 | } 212 | }, 213 | "component-emitter": { 214 | "version": "1.2.1", 215 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", 216 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", 217 | "dev": true 218 | }, 219 | "concat-map": { 220 | "version": "0.0.1", 221 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 222 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 223 | "dev": true 224 | }, 225 | "concat-stream": { 226 | "version": "1.6.2", 227 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 228 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 229 | "dev": true, 230 | "requires": { 231 | "buffer-from": "^1.0.0", 232 | "inherits": "^2.0.3", 233 | "readable-stream": "^2.2.2", 234 | "typedarray": "^0.0.6" 235 | }, 236 | "dependencies": { 237 | "isarray": { 238 | "version": "1.0.0", 239 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 240 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 241 | "dev": true 242 | }, 243 | "readable-stream": { 244 | "version": "2.3.6", 245 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 246 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 247 | "dev": true, 248 | "requires": { 249 | "core-util-is": "~1.0.0", 250 | "inherits": "~2.0.3", 251 | "isarray": "~1.0.0", 252 | "process-nextick-args": "~2.0.0", 253 | "safe-buffer": "~5.1.1", 254 | "string_decoder": "~1.1.1", 255 | "util-deprecate": "~1.0.1" 256 | } 257 | }, 258 | "string_decoder": { 259 | "version": "1.1.1", 260 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 261 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 262 | "dev": true, 263 | "requires": { 264 | "safe-buffer": "~5.1.0" 265 | } 266 | } 267 | } 268 | }, 269 | "connect": { 270 | "version": "3.6.6", 271 | "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", 272 | "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", 273 | "dev": true, 274 | "requires": { 275 | "debug": "2.6.9", 276 | "finalhandler": "1.1.0", 277 | "parseurl": "~1.3.2", 278 | "utils-merge": "1.0.1" 279 | }, 280 | "dependencies": { 281 | "debug": { 282 | "version": "2.6.9", 283 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 284 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 285 | "dev": true, 286 | "requires": { 287 | "ms": "2.0.0" 288 | } 289 | }, 290 | "ms": { 291 | "version": "2.0.0", 292 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 293 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 294 | "dev": true 295 | } 296 | } 297 | }, 298 | "connect-livereload": { 299 | "version": "0.5.4", 300 | "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.5.4.tgz", 301 | "integrity": "sha1-gBV9E3HJ83zBQDmrGJWXDRGdw7w=", 302 | "dev": true 303 | }, 304 | "cookiejar": { 305 | "version": "2.0.6", 306 | "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.0.6.tgz", 307 | "integrity": "sha1-Cr81atANHFohnYjURRgEbdAmrP4=", 308 | "dev": true 309 | }, 310 | "core-util-is": { 311 | "version": "1.0.2", 312 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 313 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 314 | "dev": true 315 | }, 316 | "currently-unhandled": { 317 | "version": "0.4.1", 318 | "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", 319 | "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", 320 | "dev": true, 321 | "requires": { 322 | "array-find-index": "^1.0.1" 323 | } 324 | }, 325 | "dateformat": { 326 | "version": "1.0.2-1.2.3", 327 | "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz", 328 | "integrity": "sha1-sCIMAt6YYXQztyhRz0fePfLNvuk=", 329 | "dev": true 330 | }, 331 | "debug": { 332 | "version": "2.2.0", 333 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", 334 | "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", 335 | "dev": true, 336 | "requires": { 337 | "ms": "0.7.1" 338 | } 339 | }, 340 | "decamelize": { 341 | "version": "1.2.0", 342 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 343 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 344 | "dev": true 345 | }, 346 | "delayed-stream": { 347 | "version": "1.0.0", 348 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 349 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", 350 | "dev": true 351 | }, 352 | "depd": { 353 | "version": "1.1.2", 354 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 355 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 356 | "dev": true 357 | }, 358 | "destroy": { 359 | "version": "1.0.4", 360 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 361 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", 362 | "dev": true 363 | }, 364 | "ee-first": { 365 | "version": "1.1.1", 366 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 367 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", 368 | "dev": true 369 | }, 370 | "encodeurl": { 371 | "version": "1.0.2", 372 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 373 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 374 | "dev": true 375 | }, 376 | "error-ex": { 377 | "version": "1.3.1", 378 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", 379 | "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", 380 | "dev": true, 381 | "requires": { 382 | "is-arrayish": "^0.2.1" 383 | } 384 | }, 385 | "escape-html": { 386 | "version": "1.0.3", 387 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 388 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", 389 | "dev": true 390 | }, 391 | "escape-string-regexp": { 392 | "version": "1.0.5", 393 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 394 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 395 | "dev": true 396 | }, 397 | "esprima": { 398 | "version": "1.0.4", 399 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", 400 | "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=", 401 | "dev": true 402 | }, 403 | "etag": { 404 | "version": "1.8.1", 405 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 406 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", 407 | "dev": true 408 | }, 409 | "eventemitter2": { 410 | "version": "0.4.14", 411 | "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", 412 | "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", 413 | "dev": true 414 | }, 415 | "exit": { 416 | "version": "0.1.2", 417 | "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", 418 | "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", 419 | "dev": true 420 | }, 421 | "extend": { 422 | "version": "3.0.0", 423 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", 424 | "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=", 425 | "dev": true 426 | }, 427 | "faye-websocket": { 428 | "version": "0.4.4", 429 | "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.4.4.tgz", 430 | "integrity": "sha1-wUxbO/FNdBf/v9mQwKdJXNnzN7w=", 431 | "dev": true 432 | }, 433 | "figures": { 434 | "version": "1.7.0", 435 | "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", 436 | "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", 437 | "dev": true, 438 | "requires": { 439 | "escape-string-regexp": "^1.0.5", 440 | "object-assign": "^4.1.0" 441 | } 442 | }, 443 | "finalhandler": { 444 | "version": "1.1.0", 445 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", 446 | "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", 447 | "dev": true, 448 | "requires": { 449 | "debug": "2.6.9", 450 | "encodeurl": "~1.0.1", 451 | "escape-html": "~1.0.3", 452 | "on-finished": "~2.3.0", 453 | "parseurl": "~1.3.2", 454 | "statuses": "~1.3.1", 455 | "unpipe": "~1.0.0" 456 | }, 457 | "dependencies": { 458 | "debug": { 459 | "version": "2.6.9", 460 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 461 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 462 | "dev": true, 463 | "requires": { 464 | "ms": "2.0.0" 465 | } 466 | }, 467 | "ms": { 468 | "version": "2.0.0", 469 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 470 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 471 | "dev": true 472 | } 473 | } 474 | }, 475 | "find-up": { 476 | "version": "1.1.2", 477 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", 478 | "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", 479 | "dev": true, 480 | "requires": { 481 | "path-exists": "^2.0.0", 482 | "pinkie-promise": "^2.0.0" 483 | } 484 | }, 485 | "findup-sync": { 486 | "version": "0.1.3", 487 | "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz", 488 | "integrity": "sha1-fz56l7gjksZTvwZYm9hRkOk8NoM=", 489 | "dev": true, 490 | "requires": { 491 | "glob": "~3.2.9", 492 | "lodash": "~2.4.1" 493 | }, 494 | "dependencies": { 495 | "glob": { 496 | "version": "3.2.11", 497 | "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", 498 | "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", 499 | "dev": true, 500 | "requires": { 501 | "inherits": "2", 502 | "minimatch": "0.3" 503 | } 504 | }, 505 | "lodash": { 506 | "version": "2.4.2", 507 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", 508 | "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", 509 | "dev": true 510 | }, 511 | "minimatch": { 512 | "version": "0.3.0", 513 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", 514 | "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", 515 | "dev": true, 516 | "requires": { 517 | "lru-cache": "2", 518 | "sigmund": "~1.0.0" 519 | } 520 | } 521 | } 522 | }, 523 | "form-data": { 524 | "version": "1.0.0-rc3", 525 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc3.tgz", 526 | "integrity": "sha1-01vGLn+8KTeuePlIqqDTjZBgdXc=", 527 | "dev": true, 528 | "requires": { 529 | "async": "^1.4.0", 530 | "combined-stream": "^1.0.5", 531 | "mime-types": "^2.1.3" 532 | }, 533 | "dependencies": { 534 | "async": { 535 | "version": "1.5.2", 536 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 537 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", 538 | "dev": true 539 | } 540 | } 541 | }, 542 | "formidable": { 543 | "version": "1.0.16", 544 | "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.16.tgz", 545 | "integrity": "sha1-SRbP38TL7QILJXpqlQWpqzjCzQ4=", 546 | "dev": true 547 | }, 548 | "fresh": { 549 | "version": "0.5.2", 550 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 551 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", 552 | "dev": true 553 | }, 554 | "fs.realpath": { 555 | "version": "1.0.0", 556 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 557 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 558 | "dev": true 559 | }, 560 | "gaze": { 561 | "version": "0.5.2", 562 | "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", 563 | "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", 564 | "dev": true, 565 | "requires": { 566 | "globule": "~0.1.0" 567 | } 568 | }, 569 | "get-stdin": { 570 | "version": "4.0.1", 571 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", 572 | "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", 573 | "dev": true 574 | }, 575 | "getobject": { 576 | "version": "0.1.0", 577 | "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", 578 | "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", 579 | "dev": true 580 | }, 581 | "glob": { 582 | "version": "7.1.2", 583 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 584 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 585 | "dev": true, 586 | "requires": { 587 | "fs.realpath": "^1.0.0", 588 | "inflight": "^1.0.4", 589 | "inherits": "2", 590 | "minimatch": "^3.0.4", 591 | "once": "^1.3.0", 592 | "path-is-absolute": "^1.0.0" 593 | } 594 | }, 595 | "globule": { 596 | "version": "0.1.0", 597 | "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", 598 | "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", 599 | "dev": true, 600 | "requires": { 601 | "glob": "~3.1.21", 602 | "lodash": "~1.0.1", 603 | "minimatch": "~0.2.11" 604 | }, 605 | "dependencies": { 606 | "glob": { 607 | "version": "3.1.21", 608 | "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", 609 | "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", 610 | "dev": true, 611 | "requires": { 612 | "graceful-fs": "~1.2.0", 613 | "inherits": "1", 614 | "minimatch": "~0.2.11" 615 | } 616 | }, 617 | "inherits": { 618 | "version": "1.0.2", 619 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", 620 | "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", 621 | "dev": true 622 | }, 623 | "lodash": { 624 | "version": "1.0.2", 625 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", 626 | "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", 627 | "dev": true 628 | }, 629 | "minimatch": { 630 | "version": "0.2.14", 631 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", 632 | "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", 633 | "dev": true, 634 | "requires": { 635 | "lru-cache": "2", 636 | "sigmund": "~1.0.0" 637 | } 638 | } 639 | } 640 | }, 641 | "graceful-fs": { 642 | "version": "1.2.3", 643 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", 644 | "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", 645 | "dev": true 646 | }, 647 | "grunt": { 648 | "version": "0.4.5", 649 | "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz", 650 | "integrity": "sha1-VpN81RlDJK3/bSB2MYMqnWuk5/A=", 651 | "dev": true, 652 | "requires": { 653 | "async": "~0.1.22", 654 | "coffee-script": "~1.3.3", 655 | "colors": "~0.6.2", 656 | "dateformat": "1.0.2-1.2.3", 657 | "eventemitter2": "~0.4.13", 658 | "exit": "~0.1.1", 659 | "findup-sync": "~0.1.2", 660 | "getobject": "~0.1.0", 661 | "glob": "~3.1.21", 662 | "grunt-legacy-log": "~0.1.0", 663 | "grunt-legacy-util": "~0.2.0", 664 | "hooker": "~0.2.3", 665 | "iconv-lite": "~0.2.11", 666 | "js-yaml": "~2.0.5", 667 | "lodash": "~0.9.2", 668 | "minimatch": "~0.2.12", 669 | "nopt": "~1.0.10", 670 | "rimraf": "~2.2.8", 671 | "underscore.string": "~2.2.1", 672 | "which": "~1.0.5" 673 | }, 674 | "dependencies": { 675 | "glob": { 676 | "version": "3.1.21", 677 | "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", 678 | "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", 679 | "dev": true, 680 | "requires": { 681 | "graceful-fs": "~1.2.0", 682 | "inherits": "1", 683 | "minimatch": "~0.2.11" 684 | } 685 | }, 686 | "inherits": { 687 | "version": "1.0.2", 688 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", 689 | "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", 690 | "dev": true 691 | }, 692 | "minimatch": { 693 | "version": "0.2.14", 694 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", 695 | "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", 696 | "dev": true, 697 | "requires": { 698 | "lru-cache": "2", 699 | "sigmund": "~1.0.0" 700 | } 701 | }, 702 | "rimraf": { 703 | "version": "2.2.8", 704 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", 705 | "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", 706 | "dev": true 707 | } 708 | } 709 | }, 710 | "grunt-cli": { 711 | "version": "1.2.0", 712 | "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", 713 | "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", 714 | "dev": true, 715 | "requires": { 716 | "findup-sync": "~0.3.0", 717 | "grunt-known-options": "~1.1.0", 718 | "nopt": "~3.0.6", 719 | "resolve": "~1.1.0" 720 | }, 721 | "dependencies": { 722 | "findup-sync": { 723 | "version": "0.3.0", 724 | "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", 725 | "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", 726 | "dev": true, 727 | "requires": { 728 | "glob": "~5.0.0" 729 | } 730 | }, 731 | "glob": { 732 | "version": "5.0.15", 733 | "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", 734 | "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", 735 | "dev": true, 736 | "requires": { 737 | "inflight": "^1.0.4", 738 | "inherits": "2", 739 | "minimatch": "2 || 3", 740 | "once": "^1.3.0", 741 | "path-is-absolute": "^1.0.0" 742 | } 743 | }, 744 | "nopt": { 745 | "version": "3.0.6", 746 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", 747 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", 748 | "dev": true, 749 | "requires": { 750 | "abbrev": "1" 751 | } 752 | } 753 | } 754 | }, 755 | "grunt-contrib-clean": { 756 | "version": "0.6.0", 757 | "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-0.6.0.tgz", 758 | "integrity": "sha1-9TLbpLghJnTHwBPhRr2mY4uQSPY=", 759 | "dev": true, 760 | "requires": { 761 | "rimraf": "~2.2.1" 762 | }, 763 | "dependencies": { 764 | "rimraf": { 765 | "version": "2.2.8", 766 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", 767 | "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", 768 | "dev": true 769 | } 770 | } 771 | }, 772 | "grunt-contrib-concat": { 773 | "version": "0.5.1", 774 | "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-0.5.1.tgz", 775 | "integrity": "sha1-lTxu/f39LBB6uchQd/LUsk0xzUk=", 776 | "dev": true, 777 | "requires": { 778 | "chalk": "^0.5.1", 779 | "source-map": "^0.3.0" 780 | } 781 | }, 782 | "grunt-contrib-connect": { 783 | "version": "1.0.2", 784 | "resolved": "https://registry.npmjs.org/grunt-contrib-connect/-/grunt-contrib-connect-1.0.2.tgz", 785 | "integrity": "sha1-XPkzuRpnOGBEJzwLJERgPNmIebo=", 786 | "dev": true, 787 | "requires": { 788 | "async": "^1.5.2", 789 | "connect": "^3.4.0", 790 | "connect-livereload": "^0.5.0", 791 | "http2": "^3.3.4", 792 | "morgan": "^1.6.1", 793 | "opn": "^4.0.0", 794 | "portscanner": "^1.0.0", 795 | "serve-index": "^1.7.1", 796 | "serve-static": "^1.10.0" 797 | }, 798 | "dependencies": { 799 | "async": { 800 | "version": "1.5.2", 801 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 802 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", 803 | "dev": true 804 | } 805 | } 806 | }, 807 | "grunt-contrib-uglify": { 808 | "version": "0.9.2", 809 | "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-0.9.2.tgz", 810 | "integrity": "sha1-GmHG8hJBDkq7T3yJFTcXsQFWAmA=", 811 | "dev": true, 812 | "requires": { 813 | "chalk": "^1.0.0", 814 | "lodash": "^3.2.0", 815 | "maxmin": "^1.0.0", 816 | "uglify-js": "^2.4.24", 817 | "uri-path": "0.0.2" 818 | }, 819 | "dependencies": { 820 | "ansi-regex": { 821 | "version": "2.1.1", 822 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 823 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 824 | "dev": true 825 | }, 826 | "ansi-styles": { 827 | "version": "2.2.1", 828 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 829 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", 830 | "dev": true 831 | }, 832 | "chalk": { 833 | "version": "1.1.3", 834 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 835 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 836 | "dev": true, 837 | "requires": { 838 | "ansi-styles": "^2.2.1", 839 | "escape-string-regexp": "^1.0.2", 840 | "has-ansi": "^2.0.0", 841 | "strip-ansi": "^3.0.0", 842 | "supports-color": "^2.0.0" 843 | } 844 | }, 845 | "has-ansi": { 846 | "version": "2.0.0", 847 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 848 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 849 | "dev": true, 850 | "requires": { 851 | "ansi-regex": "^2.0.0" 852 | } 853 | }, 854 | "lodash": { 855 | "version": "3.10.1", 856 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", 857 | "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", 858 | "dev": true 859 | }, 860 | "strip-ansi": { 861 | "version": "3.0.1", 862 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 863 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 864 | "dev": true, 865 | "requires": { 866 | "ansi-regex": "^2.0.0" 867 | } 868 | }, 869 | "supports-color": { 870 | "version": "2.0.0", 871 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 872 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", 873 | "dev": true 874 | } 875 | } 876 | }, 877 | "grunt-contrib-watch": { 878 | "version": "0.6.1", 879 | "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-0.6.1.tgz", 880 | "integrity": "sha1-ZP3LolpjX1tNobbOb5DaCutuPxU=", 881 | "dev": true, 882 | "requires": { 883 | "async": "~0.2.9", 884 | "gaze": "~0.5.1", 885 | "lodash": "~2.4.1", 886 | "tiny-lr-fork": "0.0.5" 887 | }, 888 | "dependencies": { 889 | "async": { 890 | "version": "0.2.10", 891 | "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", 892 | "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", 893 | "dev": true 894 | }, 895 | "lodash": { 896 | "version": "2.4.2", 897 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", 898 | "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", 899 | "dev": true 900 | } 901 | } 902 | }, 903 | "grunt-known-options": { 904 | "version": "1.1.0", 905 | "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.0.tgz", 906 | "integrity": "sha1-pCdO6zL6dl2lp6OxcSYXzjsUQUk=", 907 | "dev": true 908 | }, 909 | "grunt-legacy-log": { 910 | "version": "0.1.3", 911 | "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz", 912 | "integrity": "sha1-7ClCboAwIa9ZAp+H0vnNczWgVTE=", 913 | "dev": true, 914 | "requires": { 915 | "colors": "~0.6.2", 916 | "grunt-legacy-log-utils": "~0.1.1", 917 | "hooker": "~0.2.3", 918 | "lodash": "~2.4.1", 919 | "underscore.string": "~2.3.3" 920 | }, 921 | "dependencies": { 922 | "lodash": { 923 | "version": "2.4.2", 924 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", 925 | "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", 926 | "dev": true 927 | }, 928 | "underscore.string": { 929 | "version": "2.3.3", 930 | "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", 931 | "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", 932 | "dev": true 933 | } 934 | } 935 | }, 936 | "grunt-legacy-log-utils": { 937 | "version": "0.1.1", 938 | "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz", 939 | "integrity": "sha1-wHBrndkGThFvNvI/5OawSGcsD34=", 940 | "dev": true, 941 | "requires": { 942 | "colors": "~0.6.2", 943 | "lodash": "~2.4.1", 944 | "underscore.string": "~2.3.3" 945 | }, 946 | "dependencies": { 947 | "lodash": { 948 | "version": "2.4.2", 949 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", 950 | "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", 951 | "dev": true 952 | }, 953 | "underscore.string": { 954 | "version": "2.3.3", 955 | "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", 956 | "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", 957 | "dev": true 958 | } 959 | } 960 | }, 961 | "grunt-legacy-util": { 962 | "version": "0.2.0", 963 | "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz", 964 | "integrity": "sha1-kzJIhNv343qf98Am3/RR2UqeVUs=", 965 | "dev": true, 966 | "requires": { 967 | "async": "~0.1.22", 968 | "exit": "~0.1.1", 969 | "getobject": "~0.1.0", 970 | "hooker": "~0.2.3", 971 | "lodash": "~0.9.2", 972 | "underscore.string": "~2.2.1", 973 | "which": "~1.0.5" 974 | } 975 | }, 976 | "grunt-release": { 977 | "version": "0.14.0", 978 | "resolved": "https://registry.npmjs.org/grunt-release/-/grunt-release-0.14.0.tgz", 979 | "integrity": "sha1-uNYAiJVhlm1g/9zAYGfrAVWX940=", 980 | "dev": true, 981 | "requires": { 982 | "q": "^1.4.1", 983 | "semver": "^5.1.0", 984 | "shelljs": "^0.7.0", 985 | "superagent": "^1.8.3" 986 | } 987 | }, 988 | "gzip-size": { 989 | "version": "1.0.0", 990 | "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz", 991 | "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=", 992 | "dev": true, 993 | "requires": { 994 | "browserify-zlib": "^0.1.4", 995 | "concat-stream": "^1.4.1" 996 | } 997 | }, 998 | "has-ansi": { 999 | "version": "0.1.0", 1000 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", 1001 | "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", 1002 | "dev": true, 1003 | "requires": { 1004 | "ansi-regex": "^0.2.0" 1005 | } 1006 | }, 1007 | "hooker": { 1008 | "version": "0.2.3", 1009 | "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", 1010 | "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", 1011 | "dev": true 1012 | }, 1013 | "hosted-git-info": { 1014 | "version": "2.6.0", 1015 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", 1016 | "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", 1017 | "dev": true 1018 | }, 1019 | "http-errors": { 1020 | "version": "1.6.3", 1021 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", 1022 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", 1023 | "dev": true, 1024 | "requires": { 1025 | "depd": "~1.1.2", 1026 | "inherits": "2.0.3", 1027 | "setprototypeof": "1.1.0", 1028 | "statuses": ">= 1.4.0 < 2" 1029 | }, 1030 | "dependencies": { 1031 | "statuses": { 1032 | "version": "1.5.0", 1033 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1034 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", 1035 | "dev": true 1036 | } 1037 | } 1038 | }, 1039 | "http2": { 1040 | "version": "3.3.7", 1041 | "resolved": "https://registry.npmjs.org/http2/-/http2-3.3.7.tgz", 1042 | "integrity": "sha512-puSi8M8WNlFJm9Pk4c/Mbz9Gwparuj3gO9/RRO5zv6piQ0FY+9Qywp0PdWshYgsMJSalixFY7eC6oPu0zRxLAQ==", 1043 | "dev": true 1044 | }, 1045 | "iconv-lite": { 1046 | "version": "0.2.11", 1047 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz", 1048 | "integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=", 1049 | "dev": true 1050 | }, 1051 | "indent-string": { 1052 | "version": "2.1.0", 1053 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", 1054 | "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", 1055 | "dev": true, 1056 | "requires": { 1057 | "repeating": "^2.0.0" 1058 | } 1059 | }, 1060 | "inflight": { 1061 | "version": "1.0.6", 1062 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1063 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1064 | "dev": true, 1065 | "requires": { 1066 | "once": "^1.3.0", 1067 | "wrappy": "1" 1068 | } 1069 | }, 1070 | "inherits": { 1071 | "version": "2.0.3", 1072 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1073 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 1074 | "dev": true 1075 | }, 1076 | "interpret": { 1077 | "version": "1.1.0", 1078 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", 1079 | "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", 1080 | "dev": true 1081 | }, 1082 | "is-arrayish": { 1083 | "version": "0.2.1", 1084 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 1085 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", 1086 | "dev": true 1087 | }, 1088 | "is-buffer": { 1089 | "version": "1.1.6", 1090 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 1091 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", 1092 | "dev": true 1093 | }, 1094 | "is-builtin-module": { 1095 | "version": "1.0.0", 1096 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 1097 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 1098 | "dev": true, 1099 | "requires": { 1100 | "builtin-modules": "^1.0.0" 1101 | } 1102 | }, 1103 | "is-finite": { 1104 | "version": "1.0.2", 1105 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", 1106 | "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", 1107 | "dev": true, 1108 | "requires": { 1109 | "number-is-nan": "^1.0.0" 1110 | } 1111 | }, 1112 | "is-utf8": { 1113 | "version": "0.2.1", 1114 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", 1115 | "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", 1116 | "dev": true 1117 | }, 1118 | "isarray": { 1119 | "version": "0.0.1", 1120 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 1121 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", 1122 | "dev": true 1123 | }, 1124 | "js-yaml": { 1125 | "version": "2.0.5", 1126 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz", 1127 | "integrity": "sha1-olrmUJmZ6X3yeMZxnaEb0Gh3Q6g=", 1128 | "dev": true, 1129 | "requires": { 1130 | "argparse": "~ 0.1.11", 1131 | "esprima": "~ 1.0.2" 1132 | } 1133 | }, 1134 | "kind-of": { 1135 | "version": "3.2.2", 1136 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 1137 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 1138 | "dev": true, 1139 | "requires": { 1140 | "is-buffer": "^1.1.5" 1141 | } 1142 | }, 1143 | "lazy-cache": { 1144 | "version": "1.0.4", 1145 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", 1146 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", 1147 | "dev": true 1148 | }, 1149 | "load-json-file": { 1150 | "version": "1.1.0", 1151 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", 1152 | "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", 1153 | "dev": true, 1154 | "requires": { 1155 | "graceful-fs": "^4.1.2", 1156 | "parse-json": "^2.2.0", 1157 | "pify": "^2.0.0", 1158 | "pinkie-promise": "^2.0.0", 1159 | "strip-bom": "^2.0.0" 1160 | }, 1161 | "dependencies": { 1162 | "graceful-fs": { 1163 | "version": "4.1.11", 1164 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 1165 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", 1166 | "dev": true 1167 | } 1168 | } 1169 | }, 1170 | "lodash": { 1171 | "version": "0.9.2", 1172 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz", 1173 | "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=", 1174 | "dev": true 1175 | }, 1176 | "longest": { 1177 | "version": "1.0.1", 1178 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 1179 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", 1180 | "dev": true 1181 | }, 1182 | "loud-rejection": { 1183 | "version": "1.6.0", 1184 | "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", 1185 | "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", 1186 | "dev": true, 1187 | "requires": { 1188 | "currently-unhandled": "^0.4.1", 1189 | "signal-exit": "^3.0.0" 1190 | } 1191 | }, 1192 | "lru-cache": { 1193 | "version": "2.7.3", 1194 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", 1195 | "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", 1196 | "dev": true 1197 | }, 1198 | "map-obj": { 1199 | "version": "1.0.1", 1200 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", 1201 | "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", 1202 | "dev": true 1203 | }, 1204 | "maxmin": { 1205 | "version": "1.1.0", 1206 | "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-1.1.0.tgz", 1207 | "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=", 1208 | "dev": true, 1209 | "requires": { 1210 | "chalk": "^1.0.0", 1211 | "figures": "^1.0.1", 1212 | "gzip-size": "^1.0.0", 1213 | "pretty-bytes": "^1.0.0" 1214 | }, 1215 | "dependencies": { 1216 | "ansi-regex": { 1217 | "version": "2.1.1", 1218 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 1219 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 1220 | "dev": true 1221 | }, 1222 | "ansi-styles": { 1223 | "version": "2.2.1", 1224 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 1225 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", 1226 | "dev": true 1227 | }, 1228 | "chalk": { 1229 | "version": "1.1.3", 1230 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 1231 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 1232 | "dev": true, 1233 | "requires": { 1234 | "ansi-styles": "^2.2.1", 1235 | "escape-string-regexp": "^1.0.2", 1236 | "has-ansi": "^2.0.0", 1237 | "strip-ansi": "^3.0.0", 1238 | "supports-color": "^2.0.0" 1239 | } 1240 | }, 1241 | "has-ansi": { 1242 | "version": "2.0.0", 1243 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 1244 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 1245 | "dev": true, 1246 | "requires": { 1247 | "ansi-regex": "^2.0.0" 1248 | } 1249 | }, 1250 | "strip-ansi": { 1251 | "version": "3.0.1", 1252 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 1253 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 1254 | "dev": true, 1255 | "requires": { 1256 | "ansi-regex": "^2.0.0" 1257 | } 1258 | }, 1259 | "supports-color": { 1260 | "version": "2.0.0", 1261 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 1262 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", 1263 | "dev": true 1264 | } 1265 | } 1266 | }, 1267 | "meow": { 1268 | "version": "3.7.0", 1269 | "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", 1270 | "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", 1271 | "dev": true, 1272 | "requires": { 1273 | "camelcase-keys": "^2.0.0", 1274 | "decamelize": "^1.1.2", 1275 | "loud-rejection": "^1.0.0", 1276 | "map-obj": "^1.0.1", 1277 | "minimist": "^1.1.3", 1278 | "normalize-package-data": "^2.3.4", 1279 | "object-assign": "^4.0.1", 1280 | "read-pkg-up": "^1.0.1", 1281 | "redent": "^1.0.0", 1282 | "trim-newlines": "^1.0.0" 1283 | } 1284 | }, 1285 | "methods": { 1286 | "version": "1.1.2", 1287 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1288 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", 1289 | "dev": true 1290 | }, 1291 | "mime": { 1292 | "version": "1.3.4", 1293 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", 1294 | "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", 1295 | "dev": true 1296 | }, 1297 | "mime-db": { 1298 | "version": "1.33.0", 1299 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", 1300 | "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", 1301 | "dev": true 1302 | }, 1303 | "mime-types": { 1304 | "version": "2.1.18", 1305 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", 1306 | "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", 1307 | "dev": true, 1308 | "requires": { 1309 | "mime-db": "~1.33.0" 1310 | } 1311 | }, 1312 | "minimatch": { 1313 | "version": "3.0.4", 1314 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1315 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1316 | "dev": true, 1317 | "requires": { 1318 | "brace-expansion": "^1.1.7" 1319 | } 1320 | }, 1321 | "minimist": { 1322 | "version": "1.2.0", 1323 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 1324 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", 1325 | "dev": true 1326 | }, 1327 | "morgan": { 1328 | "version": "1.9.0", 1329 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz", 1330 | "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=", 1331 | "dev": true, 1332 | "requires": { 1333 | "basic-auth": "~2.0.0", 1334 | "debug": "2.6.9", 1335 | "depd": "~1.1.1", 1336 | "on-finished": "~2.3.0", 1337 | "on-headers": "~1.0.1" 1338 | }, 1339 | "dependencies": { 1340 | "debug": { 1341 | "version": "2.6.9", 1342 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1343 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1344 | "dev": true, 1345 | "requires": { 1346 | "ms": "2.0.0" 1347 | } 1348 | }, 1349 | "ms": { 1350 | "version": "2.0.0", 1351 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1352 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 1353 | "dev": true 1354 | } 1355 | } 1356 | }, 1357 | "ms": { 1358 | "version": "0.7.1", 1359 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", 1360 | "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", 1361 | "dev": true 1362 | }, 1363 | "negotiator": { 1364 | "version": "0.6.1", 1365 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 1366 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", 1367 | "dev": true 1368 | }, 1369 | "nopt": { 1370 | "version": "1.0.10", 1371 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", 1372 | "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", 1373 | "dev": true, 1374 | "requires": { 1375 | "abbrev": "1" 1376 | } 1377 | }, 1378 | "noptify": { 1379 | "version": "0.0.3", 1380 | "resolved": "https://registry.npmjs.org/noptify/-/noptify-0.0.3.tgz", 1381 | "integrity": "sha1-WPZUpz2XU98MUdlobckhBKZ/S7s=", 1382 | "dev": true, 1383 | "requires": { 1384 | "nopt": "~2.0.0" 1385 | }, 1386 | "dependencies": { 1387 | "nopt": { 1388 | "version": "2.0.0", 1389 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.0.0.tgz", 1390 | "integrity": "sha1-ynQW8gpeP5w7hhgPlilfo9C1Lg0=", 1391 | "dev": true, 1392 | "requires": { 1393 | "abbrev": "1" 1394 | } 1395 | } 1396 | } 1397 | }, 1398 | "normalize-package-data": { 1399 | "version": "2.4.0", 1400 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", 1401 | "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", 1402 | "dev": true, 1403 | "requires": { 1404 | "hosted-git-info": "^2.1.4", 1405 | "is-builtin-module": "^1.0.0", 1406 | "semver": "2 || 3 || 4 || 5", 1407 | "validate-npm-package-license": "^3.0.1" 1408 | } 1409 | }, 1410 | "number-is-nan": { 1411 | "version": "1.0.1", 1412 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 1413 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", 1414 | "dev": true 1415 | }, 1416 | "object-assign": { 1417 | "version": "4.1.1", 1418 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1419 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 1420 | "dev": true 1421 | }, 1422 | "on-finished": { 1423 | "version": "2.3.0", 1424 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1425 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1426 | "dev": true, 1427 | "requires": { 1428 | "ee-first": "1.1.1" 1429 | } 1430 | }, 1431 | "on-headers": { 1432 | "version": "1.0.1", 1433 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", 1434 | "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", 1435 | "dev": true 1436 | }, 1437 | "once": { 1438 | "version": "1.4.0", 1439 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1440 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1441 | "dev": true, 1442 | "requires": { 1443 | "wrappy": "1" 1444 | } 1445 | }, 1446 | "opn": { 1447 | "version": "4.0.2", 1448 | "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", 1449 | "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=", 1450 | "dev": true, 1451 | "requires": { 1452 | "object-assign": "^4.0.1", 1453 | "pinkie-promise": "^2.0.0" 1454 | } 1455 | }, 1456 | "pako": { 1457 | "version": "0.2.9", 1458 | "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", 1459 | "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", 1460 | "dev": true 1461 | }, 1462 | "parse-json": { 1463 | "version": "2.2.0", 1464 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 1465 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", 1466 | "dev": true, 1467 | "requires": { 1468 | "error-ex": "^1.2.0" 1469 | } 1470 | }, 1471 | "parseurl": { 1472 | "version": "1.3.2", 1473 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 1474 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", 1475 | "dev": true 1476 | }, 1477 | "path-exists": { 1478 | "version": "2.1.0", 1479 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", 1480 | "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", 1481 | "dev": true, 1482 | "requires": { 1483 | "pinkie-promise": "^2.0.0" 1484 | } 1485 | }, 1486 | "path-is-absolute": { 1487 | "version": "1.0.1", 1488 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1489 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1490 | "dev": true 1491 | }, 1492 | "path-type": { 1493 | "version": "1.1.0", 1494 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", 1495 | "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", 1496 | "dev": true, 1497 | "requires": { 1498 | "graceful-fs": "^4.1.2", 1499 | "pify": "^2.0.0", 1500 | "pinkie-promise": "^2.0.0" 1501 | }, 1502 | "dependencies": { 1503 | "graceful-fs": { 1504 | "version": "4.1.11", 1505 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 1506 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", 1507 | "dev": true 1508 | } 1509 | } 1510 | }, 1511 | "pify": { 1512 | "version": "2.3.0", 1513 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1514 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", 1515 | "dev": true 1516 | }, 1517 | "pinkie": { 1518 | "version": "2.0.4", 1519 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1520 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", 1521 | "dev": true 1522 | }, 1523 | "pinkie-promise": { 1524 | "version": "2.0.1", 1525 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1526 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 1527 | "dev": true, 1528 | "requires": { 1529 | "pinkie": "^2.0.0" 1530 | } 1531 | }, 1532 | "portscanner": { 1533 | "version": "1.2.0", 1534 | "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-1.2.0.tgz", 1535 | "integrity": "sha1-sUu9olfRTDEPqcwJaCrwLUCWGAI=", 1536 | "dev": true, 1537 | "requires": { 1538 | "async": "1.5.2" 1539 | }, 1540 | "dependencies": { 1541 | "async": { 1542 | "version": "1.5.2", 1543 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 1544 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", 1545 | "dev": true 1546 | } 1547 | } 1548 | }, 1549 | "postscribe": { 1550 | "version": "1.4.0", 1551 | "resolved": "https://registry.npmjs.org/postscribe/-/postscribe-1.4.0.tgz", 1552 | "integrity": "sha1-7DS1kmgk6Y8iJeWOR6I+tcN2tnI=" 1553 | }, 1554 | "pretty-bytes": { 1555 | "version": "1.0.4", 1556 | "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", 1557 | "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", 1558 | "dev": true, 1559 | "requires": { 1560 | "get-stdin": "^4.0.1", 1561 | "meow": "^3.1.0" 1562 | } 1563 | }, 1564 | "process-nextick-args": { 1565 | "version": "2.0.0", 1566 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 1567 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", 1568 | "dev": true 1569 | }, 1570 | "q": { 1571 | "version": "1.5.1", 1572 | "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", 1573 | "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", 1574 | "dev": true 1575 | }, 1576 | "range-parser": { 1577 | "version": "1.2.0", 1578 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 1579 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", 1580 | "dev": true 1581 | }, 1582 | "read-pkg": { 1583 | "version": "1.1.0", 1584 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", 1585 | "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", 1586 | "dev": true, 1587 | "requires": { 1588 | "load-json-file": "^1.0.0", 1589 | "normalize-package-data": "^2.3.2", 1590 | "path-type": "^1.0.0" 1591 | } 1592 | }, 1593 | "read-pkg-up": { 1594 | "version": "1.0.1", 1595 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", 1596 | "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", 1597 | "dev": true, 1598 | "requires": { 1599 | "find-up": "^1.0.0", 1600 | "read-pkg": "^1.0.0" 1601 | } 1602 | }, 1603 | "rechoir": { 1604 | "version": "0.6.2", 1605 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 1606 | "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", 1607 | "dev": true, 1608 | "requires": { 1609 | "resolve": "^1.1.6" 1610 | } 1611 | }, 1612 | "redent": { 1613 | "version": "1.0.0", 1614 | "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", 1615 | "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", 1616 | "dev": true, 1617 | "requires": { 1618 | "indent-string": "^2.1.0", 1619 | "strip-indent": "^1.0.1" 1620 | } 1621 | }, 1622 | "reduce-component": { 1623 | "version": "1.0.1", 1624 | "resolved": "https://registry.npmjs.org/reduce-component/-/reduce-component-1.0.1.tgz", 1625 | "integrity": "sha1-4Mk1QsV0UhvqE98PlIjtgqt3xdo=", 1626 | "dev": true 1627 | }, 1628 | "repeat-string": { 1629 | "version": "1.6.1", 1630 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", 1631 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", 1632 | "dev": true 1633 | }, 1634 | "repeating": { 1635 | "version": "2.0.1", 1636 | "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", 1637 | "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", 1638 | "dev": true, 1639 | "requires": { 1640 | "is-finite": "^1.0.0" 1641 | } 1642 | }, 1643 | "resolve": { 1644 | "version": "1.1.7", 1645 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", 1646 | "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", 1647 | "dev": true 1648 | }, 1649 | "right-align": { 1650 | "version": "0.1.3", 1651 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", 1652 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", 1653 | "dev": true, 1654 | "requires": { 1655 | "align-text": "^0.1.1" 1656 | } 1657 | }, 1658 | "rimraf": { 1659 | "version": "2.6.2", 1660 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 1661 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 1662 | "dev": true, 1663 | "requires": { 1664 | "glob": "^7.0.5" 1665 | } 1666 | }, 1667 | "safe-buffer": { 1668 | "version": "5.1.2", 1669 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1670 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1671 | "dev": true 1672 | }, 1673 | "semver": { 1674 | "version": "5.5.0", 1675 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", 1676 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", 1677 | "dev": true 1678 | }, 1679 | "send": { 1680 | "version": "0.16.2", 1681 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", 1682 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", 1683 | "dev": true, 1684 | "requires": { 1685 | "debug": "2.6.9", 1686 | "depd": "~1.1.2", 1687 | "destroy": "~1.0.4", 1688 | "encodeurl": "~1.0.2", 1689 | "escape-html": "~1.0.3", 1690 | "etag": "~1.8.1", 1691 | "fresh": "0.5.2", 1692 | "http-errors": "~1.6.2", 1693 | "mime": "1.4.1", 1694 | "ms": "2.0.0", 1695 | "on-finished": "~2.3.0", 1696 | "range-parser": "~1.2.0", 1697 | "statuses": "~1.4.0" 1698 | }, 1699 | "dependencies": { 1700 | "debug": { 1701 | "version": "2.6.9", 1702 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1703 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1704 | "dev": true, 1705 | "requires": { 1706 | "ms": "2.0.0" 1707 | } 1708 | }, 1709 | "mime": { 1710 | "version": "1.4.1", 1711 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 1712 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", 1713 | "dev": true 1714 | }, 1715 | "ms": { 1716 | "version": "2.0.0", 1717 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1718 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 1719 | "dev": true 1720 | }, 1721 | "statuses": { 1722 | "version": "1.4.0", 1723 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 1724 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", 1725 | "dev": true 1726 | } 1727 | } 1728 | }, 1729 | "serve-index": { 1730 | "version": "1.9.1", 1731 | "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", 1732 | "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", 1733 | "dev": true, 1734 | "requires": { 1735 | "accepts": "~1.3.4", 1736 | "batch": "0.6.1", 1737 | "debug": "2.6.9", 1738 | "escape-html": "~1.0.3", 1739 | "http-errors": "~1.6.2", 1740 | "mime-types": "~2.1.17", 1741 | "parseurl": "~1.3.2" 1742 | }, 1743 | "dependencies": { 1744 | "debug": { 1745 | "version": "2.6.9", 1746 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1747 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1748 | "dev": true, 1749 | "requires": { 1750 | "ms": "2.0.0" 1751 | } 1752 | }, 1753 | "ms": { 1754 | "version": "2.0.0", 1755 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1756 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 1757 | "dev": true 1758 | } 1759 | } 1760 | }, 1761 | "serve-static": { 1762 | "version": "1.13.2", 1763 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", 1764 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", 1765 | "dev": true, 1766 | "requires": { 1767 | "encodeurl": "~1.0.2", 1768 | "escape-html": "~1.0.3", 1769 | "parseurl": "~1.3.2", 1770 | "send": "0.16.2" 1771 | } 1772 | }, 1773 | "setprototypeof": { 1774 | "version": "1.1.0", 1775 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 1776 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", 1777 | "dev": true 1778 | }, 1779 | "shelljs": { 1780 | "version": "0.7.8", 1781 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", 1782 | "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", 1783 | "dev": true, 1784 | "requires": { 1785 | "glob": "^7.0.0", 1786 | "interpret": "^1.0.0", 1787 | "rechoir": "^0.6.2" 1788 | } 1789 | }, 1790 | "sigmund": { 1791 | "version": "1.0.1", 1792 | "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", 1793 | "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", 1794 | "dev": true 1795 | }, 1796 | "signal-exit": { 1797 | "version": "3.0.2", 1798 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 1799 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 1800 | "dev": true 1801 | }, 1802 | "source-map": { 1803 | "version": "0.3.0", 1804 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.3.0.tgz", 1805 | "integrity": "sha1-hYb7mloAXltQHiHNGLbyG0V60fk=", 1806 | "dev": true, 1807 | "requires": { 1808 | "amdefine": ">=0.0.4" 1809 | } 1810 | }, 1811 | "spdx-correct": { 1812 | "version": "3.0.0", 1813 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", 1814 | "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", 1815 | "dev": true, 1816 | "requires": { 1817 | "spdx-expression-parse": "^3.0.0", 1818 | "spdx-license-ids": "^3.0.0" 1819 | } 1820 | }, 1821 | "spdx-exceptions": { 1822 | "version": "2.1.0", 1823 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", 1824 | "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", 1825 | "dev": true 1826 | }, 1827 | "spdx-expression-parse": { 1828 | "version": "3.0.0", 1829 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 1830 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 1831 | "dev": true, 1832 | "requires": { 1833 | "spdx-exceptions": "^2.1.0", 1834 | "spdx-license-ids": "^3.0.0" 1835 | } 1836 | }, 1837 | "spdx-license-ids": { 1838 | "version": "3.0.0", 1839 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", 1840 | "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", 1841 | "dev": true 1842 | }, 1843 | "statuses": { 1844 | "version": "1.3.1", 1845 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", 1846 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", 1847 | "dev": true 1848 | }, 1849 | "string_decoder": { 1850 | "version": "0.10.31", 1851 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 1852 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", 1853 | "dev": true 1854 | }, 1855 | "strip-ansi": { 1856 | "version": "0.3.0", 1857 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", 1858 | "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", 1859 | "dev": true, 1860 | "requires": { 1861 | "ansi-regex": "^0.2.1" 1862 | } 1863 | }, 1864 | "strip-bom": { 1865 | "version": "2.0.0", 1866 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", 1867 | "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", 1868 | "dev": true, 1869 | "requires": { 1870 | "is-utf8": "^0.2.0" 1871 | } 1872 | }, 1873 | "strip-indent": { 1874 | "version": "1.0.1", 1875 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", 1876 | "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", 1877 | "dev": true, 1878 | "requires": { 1879 | "get-stdin": "^4.0.1" 1880 | } 1881 | }, 1882 | "superagent": { 1883 | "version": "1.8.5", 1884 | "resolved": "https://registry.npmjs.org/superagent/-/superagent-1.8.5.tgz", 1885 | "integrity": "sha1-HA3cOvMOgOuE68BcshItqP6UC1U=", 1886 | "dev": true, 1887 | "requires": { 1888 | "component-emitter": "~1.2.0", 1889 | "cookiejar": "2.0.6", 1890 | "debug": "2", 1891 | "extend": "3.0.0", 1892 | "form-data": "1.0.0-rc3", 1893 | "formidable": "~1.0.14", 1894 | "methods": "~1.1.1", 1895 | "mime": "1.3.4", 1896 | "qs": "2.3.3", 1897 | "readable-stream": "1.0.27-1", 1898 | "reduce-component": "1.0.1" 1899 | }, 1900 | "dependencies": { 1901 | "qs": { 1902 | "version": "2.3.3", 1903 | "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", 1904 | "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", 1905 | "dev": true 1906 | }, 1907 | "readable-stream": { 1908 | "version": "1.0.27-1", 1909 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz", 1910 | "integrity": "sha1-a2eYPCA1fO/QfwFlABoW1xDZEHg=", 1911 | "dev": true, 1912 | "requires": { 1913 | "core-util-is": "~1.0.0", 1914 | "inherits": "~2.0.1", 1915 | "isarray": "0.0.1", 1916 | "string_decoder": "~0.10.x" 1917 | } 1918 | } 1919 | } 1920 | }, 1921 | "supports-color": { 1922 | "version": "0.2.0", 1923 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", 1924 | "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", 1925 | "dev": true 1926 | }, 1927 | "tiny-lr-fork": { 1928 | "version": "0.0.5", 1929 | "resolved": "https://registry.npmjs.org/tiny-lr-fork/-/tiny-lr-fork-0.0.5.tgz", 1930 | "integrity": "sha1-Hpnh4qhGm3NquX2X7vqYxx927Qo=", 1931 | "dev": true, 1932 | "requires": { 1933 | "debug": "~0.7.0", 1934 | "faye-websocket": "~0.4.3", 1935 | "noptify": "~0.0.3", 1936 | "qs": "~0.5.2" 1937 | }, 1938 | "dependencies": { 1939 | "debug": { 1940 | "version": "0.7.4", 1941 | "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", 1942 | "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", 1943 | "dev": true 1944 | }, 1945 | "qs": { 1946 | "version": "0.5.6", 1947 | "resolved": "https://registry.npmjs.org/qs/-/qs-0.5.6.tgz", 1948 | "integrity": "sha1-MbGtBYVnZRxSaSFQa5qHk5EaA4Q=", 1949 | "dev": true 1950 | } 1951 | } 1952 | }, 1953 | "trim-newlines": { 1954 | "version": "1.0.0", 1955 | "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", 1956 | "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", 1957 | "dev": true 1958 | }, 1959 | "typedarray": { 1960 | "version": "0.0.6", 1961 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 1962 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", 1963 | "dev": true 1964 | }, 1965 | "uglify-js": { 1966 | "version": "2.8.29", 1967 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", 1968 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", 1969 | "dev": true, 1970 | "requires": { 1971 | "source-map": "~0.5.1", 1972 | "uglify-to-browserify": "~1.0.0", 1973 | "yargs": "~3.10.0" 1974 | }, 1975 | "dependencies": { 1976 | "source-map": { 1977 | "version": "0.5.7", 1978 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 1979 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 1980 | "dev": true 1981 | } 1982 | } 1983 | }, 1984 | "uglify-to-browserify": { 1985 | "version": "1.0.2", 1986 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", 1987 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", 1988 | "dev": true, 1989 | "optional": true 1990 | }, 1991 | "underscore": { 1992 | "version": "1.7.0", 1993 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", 1994 | "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", 1995 | "dev": true 1996 | }, 1997 | "underscore.string": { 1998 | "version": "2.2.1", 1999 | "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz", 2000 | "integrity": "sha1-18D6KvXVoaZ/QlPa7pgTLnM/Dxk=", 2001 | "dev": true 2002 | }, 2003 | "unpipe": { 2004 | "version": "1.0.0", 2005 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 2006 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", 2007 | "dev": true 2008 | }, 2009 | "uri-path": { 2010 | "version": "0.0.2", 2011 | "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-0.0.2.tgz", 2012 | "integrity": "sha1-gD6wHy/rF5J9zOD2GH5yt19T9VQ=", 2013 | "dev": true 2014 | }, 2015 | "util-deprecate": { 2016 | "version": "1.0.2", 2017 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2018 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 2019 | "dev": true 2020 | }, 2021 | "utils-merge": { 2022 | "version": "1.0.1", 2023 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 2024 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", 2025 | "dev": true 2026 | }, 2027 | "validate-npm-package-license": { 2028 | "version": "3.0.3", 2029 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", 2030 | "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", 2031 | "dev": true, 2032 | "requires": { 2033 | "spdx-correct": "^3.0.0", 2034 | "spdx-expression-parse": "^3.0.0" 2035 | } 2036 | }, 2037 | "which": { 2038 | "version": "1.0.9", 2039 | "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", 2040 | "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=", 2041 | "dev": true 2042 | }, 2043 | "window-size": { 2044 | "version": "0.1.0", 2045 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", 2046 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", 2047 | "dev": true 2048 | }, 2049 | "wordwrap": { 2050 | "version": "0.0.2", 2051 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", 2052 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", 2053 | "dev": true 2054 | }, 2055 | "wrappy": { 2056 | "version": "1.0.2", 2057 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2058 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 2059 | "dev": true 2060 | }, 2061 | "yargs": { 2062 | "version": "3.10.0", 2063 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", 2064 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", 2065 | "dev": true, 2066 | "requires": { 2067 | "camelcase": "^1.0.2", 2068 | "cliui": "^2.1.0", 2069 | "decamelize": "^1.0.0", 2070 | "window-size": "0.1.0" 2071 | }, 2072 | "dependencies": { 2073 | "camelcase": { 2074 | "version": "1.2.1", 2075 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", 2076 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", 2077 | "dev": true 2078 | } 2079 | } 2080 | } 2081 | } 2082 | } 2083 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lazy-ads", 3 | "version": "1.1.12", 4 | "description": "Deliver synchronous ads asynchronously with RWD support without modifying the ad code.", 5 | "homepage": "https://github.com/madgex/lazy-ads", 6 | "author": "James Wragg ", 7 | "repository": { 8 | "type": "git", 9 | "url": "http://github.com/madgex/lazy-ads.git" 10 | }, 11 | "bugs": { 12 | "url": "http://github.com/madgex/lazy-ads/issues" 13 | }, 14 | "main": "dist/lazyad-loader.js", 15 | "scripts": { 16 | "prepublishOnly": "npm run build", 17 | "build": "rimraf dist && grunt" 18 | }, 19 | "keywords": [ 20 | "ads", 21 | "lazy-load", 22 | "async", 23 | "responsive" 24 | ], 25 | "devDependencies": { 26 | "grunt": "~0.4.5", 27 | "grunt-cli": "^1.2.0", 28 | "grunt-contrib-clean": "~0.6.0", 29 | "grunt-contrib-concat": "~0.5.1", 30 | "grunt-contrib-connect": "^1.0.2", 31 | "grunt-contrib-uglify": "~0.9.1", 32 | "grunt-contrib-watch": "~0.6.1", 33 | "grunt-release": "^0.14.0", 34 | "rimraf": "^2.6.2" 35 | }, 36 | "dependencies": { 37 | "postscribe": "^1.4.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/lazyad-loader.js: -------------------------------------------------------------------------------- 1 | LazyAds = (function() { 2 | 3 | 'use strict'; 4 | 5 | var debug = false; 6 | 7 | var config = { 8 | containerElement: 'div', 9 | containerClass: 'ad' 10 | }; 11 | var startTime; 12 | 13 | 14 | 15 | /** 16 | * Utility functions 17 | */ 18 | ''.trim || (String.prototype.trim = function() { 19 | return this.replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, ''); 20 | }); 21 | 22 | function log() { 23 | if (debug === true && window.console) { 24 | // Only run on the first time through - reset this function to the appropriate console.log helper 25 | if (Function.prototype.bind) { 26 | log = Function.prototype.bind.call(console.log, console); 27 | } else { 28 | log = function() { 29 | Function.prototype.apply.call(console.log, console, arguments); 30 | }; 31 | } 32 | 33 | log.apply(this, arguments); 34 | } 35 | } 36 | 37 | // Debounce source: https://github.com/rhysbrettbowen/debounce 38 | function debounce(func, wait) { 39 | // we need to save these in the closure 40 | var timeout, args, context, timestamp; 41 | 42 | return function() { 43 | 44 | // save details of latest call 45 | context = this; 46 | args = [].slice.call(arguments, 0); 47 | timestamp = new Date(); 48 | 49 | // this is where the magic happens 50 | var later = function() { 51 | 52 | // how long ago was the last call 53 | var last = (new Date()) - timestamp; 54 | 55 | // if the latest call was less that the wait period ago 56 | // then we reset the timeout to wait for the difference 57 | if (last < wait) { 58 | timeout = setTimeout(later, wait - last); 59 | 60 | // or if not we can null out the timer and run the latest 61 | } else { 62 | timeout = null; 63 | func.apply(context, args); 64 | } 65 | }; 66 | 67 | // we only need to set the timer now if one isn't already running 68 | if (!timeout) { 69 | timeout = setTimeout(later, wait); 70 | } 71 | }; 72 | } 73 | 74 | function addEvent(evnt, elem, func) { 75 | if (elem.addEventListener) // W3C DOM 76 | elem.addEventListener(evnt, func, false); 77 | else if (elem.attachEvent) { // IE DOM 78 | elem.attachEvent("on" + evnt, func); 79 | } else { // No much to do 80 | elem["on" + evnt] = func; 81 | } 82 | } 83 | 84 | 85 | // Internals 86 | function find(tagName, className, context) { 87 | var results = [], 88 | selector, node, i, isLazyAd, classListSupported, querySelectorSupported, 89 | context = context || document; 90 | 91 | classListSupported = 'classList' in document.createElement("_"), 92 | querySelectorSupported = 'querySelectorAll' in document; 93 | 94 | if (querySelectorSupported) { 95 | selector = tagName; 96 | selector += className ? '.' + className : ''; 97 | results = context.querySelectorAll(selector); 98 | 99 | } else { 100 | q = context.getElementsByTagName(tagName); 101 | 102 | for (i = 0; i < q.length; i++) { 103 | node = q[i]; 104 | if (className === false) { 105 | results.push(node); 106 | } else { 107 | if (classListSupported) { 108 | if (node.classList.contains(className)) { 109 | results.push(node); 110 | } 111 | } else { 112 | if (node.className && node.className.split(/\s/).indexOf(className) !== -1) { 113 | results.push(node); 114 | } 115 | } 116 | } 117 | } 118 | } 119 | 120 | return results; 121 | }; 122 | 123 | function findAdContainers(root) { 124 | var containers = find(config.containerElement, config.containerClass), 125 | node, 126 | isLazyAd = false, 127 | results = []; 128 | 129 | for (var i = 0; i < containers.length; i++) { 130 | node = containers[i]; 131 | isLazyAd = (node.getAttribute('data-lazyad') !== null); 132 | 133 | if (isLazyAd === true) { 134 | results.push(node); 135 | } 136 | } 137 | 138 | return results; 139 | }; 140 | 141 | function findAdScripts(root) { 142 | var ads = find('script', false, root), 143 | node, 144 | type, 145 | results = []; 146 | 147 | for (var i = 0; i < ads.length; i++) { 148 | node = ads[i]; 149 | type = node.getAttribute('type'); 150 | if (type && type === 'text/lazyad') { 151 | results.push(node); 152 | } 153 | } 154 | 155 | return results; 156 | }; 157 | 158 | function stripCommentBlock(str) { 159 | // trim whitespace 160 | str = str.replace(/^\s+|\s+$/g, ''); 161 | return str.replace('', '').trim(); 162 | }; 163 | 164 | function adReplace(el, text) { 165 | var node, target; 166 | 167 | log('Injecting lazy-loaded Ad', el); 168 | 169 | text = stripCommentBlock(text); 170 | setTimeout(function() { 171 | postscribe(el, text); 172 | }, 0); 173 | 174 | // set the loaded flag 175 | el.setAttribute('data-lazyad-loaded', true); 176 | }; 177 | 178 | function processAll(adContainers) { 179 | 180 | var counter = 0, 181 | el, 182 | adScripts, 183 | lazyAdEl, 184 | lazyAdElType, 185 | elWidth, 186 | elHeight, 187 | reqAdWidth, 188 | reqAdHeight, 189 | mq, 190 | sizeReqFulfilled, 191 | isLoaded; 192 | 193 | for (var x = 0; x < adContainers.length; x++) { 194 | 195 | el = adContainers[x]; 196 | mq = el.getAttribute('data-matchmedia') || false; 197 | reqAdWidth = parseInt(el.getAttribute('data-adwidth'), 0) || false; 198 | reqAdHeight = parseInt(el.getAttribute('data-adheight'), 0) || false; 199 | adScripts = findAdScripts(el); 200 | 201 | for (var i = 0; i < adScripts.length; i++) { 202 | lazyAdEl = adScripts[i]; 203 | 204 | isLoaded = (el.getAttribute('data-lazyad-loaded') === "true"); 205 | 206 | 207 | if (reqAdWidth || reqAdHeight) { 208 | elWidth = el.offsetWidth; 209 | elHeight = el.offsetHeight; 210 | sizeReqFulfilled = true; 211 | 212 | if (reqAdWidth && (reqAdWidth > elWidth)) sizeReqFulfilled = false; 213 | if (reqAdHeight && (reqAdHeight > elHeight)) sizeReqFulfilled = false; 214 | 215 | if (sizeReqFulfilled === false) { 216 | // log('Lazy-loaded container dimensions fulfilment not met.', reqAdWidth, reqAdHeight, elWidth, elHeight, el, lazyAdEl); 217 | if (isLoaded) { 218 | unloadAds(el); 219 | } 220 | break; 221 | } 222 | } 223 | 224 | if (mq !== false && matchMedia(mq).matches === false) { 225 | // log('Lazy-loaded Ad media-query fulfilment not met.', el, lazyAdEl); 226 | if (isLoaded) { 227 | unloadAds(el); 228 | } 229 | break; 230 | } 231 | 232 | if (!isLoaded) { 233 | adReplace(el, lazyAdEl.innerHTML); 234 | counter++; 235 | } 236 | 237 | } 238 | 239 | } 240 | 241 | return counter; 242 | }; 243 | 244 | function unloadAds(el) { 245 | log('Unloading Ad:', el); 246 | var childNodes = el.getElementsByTagName('*'); 247 | 248 | while (childNodes) { 249 | var child = childNodes[childNodes.length - 1]; 250 | if (child.nodeName.toLowerCase() === 'script' && child.type === 'text/lazyad') { 251 | // dont want to remove the lazy-loaded script 252 | break; 253 | } else { 254 | child.parentNode.removeChild(child); 255 | } 256 | } 257 | 258 | el.setAttribute('data-lazyad-loaded', "false"); 259 | } 260 | 261 | function init() { 262 | var adContainers, 263 | timeToComplete, 264 | counter = 0; 265 | 266 | // reset timer 267 | startTime = new Date().getTime(); 268 | 269 | // find all lazyads 270 | adContainers = findAdContainers(); 271 | 272 | // process/replace/unload 273 | if (adContainers && adContainers.length > 0) { 274 | counter = processAll(adContainers); 275 | } 276 | 277 | // stop the clock… 278 | timeToComplete = (new Date().getTime() - startTime); 279 | timeToComplete = '~' + timeToComplete + 'ms'; 280 | 281 | // finished 282 | log('Lazy-loaded count: ', counter, timeToComplete); 283 | }; 284 | 285 | // dependency on ready.js 286 | domready(function() { 287 | 288 | // watch the windows resize event 289 | addEvent('resize', window, debounce(function(e) { 290 | init(); 291 | }, 250)); 292 | 293 | init(); 294 | }); 295 | 296 | return { 297 | init: init 298 | } 299 | 300 | })(); -------------------------------------------------------------------------------- /src/libs/boxsizing.htc: -------------------------------------------------------------------------------- 1 | /** 2 | * box-sizing Polyfill 3 | * 4 | * A polyfill for box-sizing: border-box for IE6 & IE7. 5 | * 6 | * JScript 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU Lesser General Public License as published 10 | * by the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU Lesser General Public License for more details. 17 | * 18 | * See 19 | * 20 | * @category JScript 21 | * @package box-sizing-polyfill 22 | * @author Christian Schepp Schaefer 23 | * @copyright 2012 Christian Schepp Schaefer 24 | * @license http://www.gnu.org/copyleft/lesser.html The GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0 25 | * @link http://github.com/Schepp/box-sizing-polyfill 26 | * 27 | * PREFACE: 28 | * 29 | * This box-sizing polyfill is based on previous work done by Erik Arvidsson, 30 | * which he published in 2002 on http://webfx.eae.net/dhtml/boxsizing/boxsizing.html. 31 | * 32 | * USAGE: 33 | * 34 | * Add the behavior/HTC after every `box-sizing: border-box;` that you assign: 35 | * 36 | * box-sizing: border-box; 37 | * *behavior: url(/scripts/boxsizing.htc);` 38 | * 39 | * Prefix the `behavior` property with a star, like seen above, so it will only be seen by 40 | * IE6 & IE7, not by IE8+ who already implement box-sizing. 41 | * 42 | * The URL to the HTC file must be relative to your HTML(!) document, not relative to your CSS. 43 | * That's why I'd advise you to use absolute paths like in the example. 44 | * 45 | */ 46 | 47 | 48 | 49 | 50 | 504 | -------------------------------------------------------------------------------- /src/libs/indexof-polyfill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * lifted from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf 3 | * polyfill needed for IE <= 7 4 | */ 5 | if (!Array.prototype.indexOf) { 6 | Array.prototype.indexOf = function(searchElement, fromIndex) { 7 | if (this === undefined || this === null) { 8 | throw new TypeError('"this" is null or not defined'); 9 | } 10 | 11 | var length = this.length >>> 0; // Hack to convert object.length to a UInt32 12 | 13 | fromIndex = +fromIndex || 0; 14 | 15 | if (Math.abs(fromIndex) === Infinity) { 16 | fromIndex = 0; 17 | } 18 | 19 | if (fromIndex < 0) { 20 | fromIndex += length; 21 | if (fromIndex < 0) { 22 | fromIndex = 0; 23 | } 24 | } 25 | 26 | for (; fromIndex < length; fromIndex++) { 27 | if (this[fromIndex] === searchElement) { 28 | return fromIndex; 29 | } 30 | } 31 | 32 | return -1; 33 | }; 34 | } -------------------------------------------------------------------------------- /src/libs/media.match.js: -------------------------------------------------------------------------------- 1 | /* MediaMatch v.2.0.2 - Testing css media queries in Javascript. Authors & copyright (c) 2013: WebLinc, David Knight. */ 2 | 3 | window.matchMedia || (window.matchMedia = function (win) { 4 | 'use strict'; 5 | 6 | // Internal globals 7 | var _doc = win.document, 8 | _viewport = _doc.documentElement, 9 | _queries = [], 10 | _queryID = 0, 11 | _type = '', 12 | _features = {}, 13 | // only screen 14 | // only screen and 15 | // not screen 16 | // not screen and 17 | // screen 18 | // screen and 19 | _typeExpr = /\s*(only|not)?\s*(screen|print|[a-z\-]+)\s*(and)?\s*/i, 20 | // (-vendor-min-width: 300px) 21 | // (min-width: 300px) 22 | // (width: 300px) 23 | // (width) 24 | // (orientation: portrait|landscape) 25 | _mediaExpr = /^\s*\(\s*(-[a-z]+-)?(min-|max-)?([a-z\-]+)\s*(:?\s*([0-9]+(\.[0-9]+)?|portrait|landscape)(px|em|dppx|dpcm|rem|%|in|cm|mm|ex|pt|pc|\/([0-9]+(\.[0-9]+)?))?)?\s*\)\s*$/, 26 | _timer = 0, 27 | 28 | // Helper methods 29 | 30 | /* 31 | _matches 32 | */ 33 | _matches = function (media) { 34 | // screen and (min-width: 400px), screen and (max-width: 500px) 35 | var mql = (media.indexOf(',') !== -1 && media.split(',')) || [media], 36 | mqIndex = mql.length - 1, 37 | mqLength = mqIndex, 38 | mq = null, 39 | 40 | // not screen, screen 41 | negateType = null, 42 | negateTypeFound = '', 43 | negateTypeIndex = 0, 44 | negate = false, 45 | type = '', 46 | 47 | // (min-width: 400px), (min-width) 48 | exprListStr = '', 49 | exprList = null, 50 | exprIndex = 0, 51 | exprLength = 0, 52 | expr = null, 53 | 54 | prefix = '', 55 | length = '', 56 | unit = '', 57 | value = '', 58 | feature = '', 59 | 60 | match = false; 61 | 62 | if (media === '') { 63 | return true; 64 | } 65 | 66 | do { 67 | mq = mql[mqLength - mqIndex]; 68 | negate = false; 69 | negateType = mq.match(_typeExpr); 70 | 71 | if (negateType) { 72 | negateTypeFound = negateType[0]; 73 | negateTypeIndex = negateType.index; 74 | } 75 | 76 | if (!negateType || ((mq.substring(0, negateTypeIndex).indexOf('(') === -1) && (negateTypeIndex || (!negateType[3] && negateTypeFound !== negateType.input)))) { 77 | match = false; 78 | continue; 79 | } 80 | 81 | exprListStr = mq; 82 | 83 | negate = negateType[1] === 'not'; 84 | 85 | if (!negateTypeIndex) { 86 | type = negateType[2]; 87 | exprListStr = mq.substring(negateTypeFound.length); 88 | } 89 | 90 | // Test media type 91 | // Test type against this device or if 'all' or empty '' 92 | match = type === _type || type === 'all' || type === ''; 93 | 94 | exprList = (exprListStr.indexOf(' and ') !== -1 && exprListStr.split(' and ')) || [exprListStr]; 95 | exprIndex = exprList.length - 1; 96 | exprLength = exprIndex; 97 | 98 | if (match && exprIndex >= 0 && exprListStr !== '') { 99 | do { 100 | expr = exprList[exprIndex].match(_mediaExpr); 101 | 102 | if (!expr || !_features[expr[3]]) { 103 | match = false; 104 | break; 105 | } 106 | 107 | prefix = expr[2]; 108 | length = expr[5]; 109 | value = length; 110 | unit = expr[7]; 111 | feature = _features[expr[3]]; 112 | 113 | // Convert unit types 114 | if (unit) { 115 | if (unit === 'px') { 116 | // If unit is px 117 | value = Number(length); 118 | } else if (unit === 'em' || unit === 'rem') { 119 | // Convert relative length unit to pixels 120 | // Assumed base font size is 16px 121 | value = 16 * length; 122 | } else if (expr[8]) { 123 | // Convert aspect ratio to decimal 124 | value = (length / expr[8]).toFixed(2); 125 | } else if (unit === 'dppx') { 126 | // Convert resolution dppx unit to pixels 127 | value = length * 96; 128 | } else if (unit === 'dpcm') { 129 | // Convert resolution dpcm unit to pixels 130 | value = length * 0.3937; 131 | } else { 132 | // default 133 | value = Number(length); 134 | } 135 | } 136 | 137 | // Test for prefix min or max 138 | // Test value against feature 139 | if (prefix === 'min-' && value) { 140 | match = feature >= value; 141 | } else if (prefix === 'max-' && value) { 142 | match = feature <= value; 143 | } else if (value) { 144 | match = feature === value; 145 | } else { 146 | match = !!feature; 147 | } 148 | 149 | // If 'match' is false, break loop 150 | // Continue main loop through query list 151 | if (!match) { 152 | break; 153 | } 154 | } while (exprIndex--); 155 | } 156 | 157 | // If match is true, break loop 158 | // Once matched, no need to check other queries 159 | if (match) { 160 | break; 161 | } 162 | } while (mqIndex--); 163 | 164 | return negate ? !match : match; 165 | }, 166 | 167 | /* 168 | _setFeature 169 | */ 170 | _setFeature = function () { 171 | // Sets properties of '_features' that change on resize and/or orientation. 172 | var w = win.innerWidth || _viewport.clientWidth, 173 | h = win.innerHeight || _viewport.clientHeight, 174 | dw = win.screen.width, 175 | dh = win.screen.height, 176 | c = win.screen.colorDepth, 177 | x = win.devicePixelRatio; 178 | 179 | _features.width = w; 180 | _features.height = h; 181 | _features['aspect-ratio'] = (w / h).toFixed(2); 182 | _features['device-width'] = dw; 183 | _features['device-height'] = dh; 184 | _features['device-aspect-ratio'] = (dw / dh).toFixed(2); 185 | _features.color = c; 186 | _features['color-index'] = Math.pow(2, c); 187 | _features.orientation = (h >= w ? 'portrait' : 'landscape'); 188 | _features.resolution = (x && x * 96) || win.screen.deviceXDPI || 96; 189 | _features['device-pixel-ratio'] = x || 1; 190 | }, 191 | 192 | /* 193 | _watch 194 | */ 195 | _watch = function () { 196 | clearTimeout(_timer); 197 | 198 | _timer = setTimeout(function () { 199 | var query = null, 200 | qIndex = _queryID - 1, 201 | qLength = qIndex, 202 | match = false; 203 | 204 | if (qIndex >= 0) { 205 | _setFeature(); 206 | 207 | do { 208 | query = _queries[qLength - qIndex]; 209 | 210 | if (query) { 211 | match = _matches(query.mql.media); 212 | 213 | if ((match && !query.mql.matches) || (!match && query.mql.matches)) { 214 | query.mql.matches = match; 215 | 216 | if (query.listeners) { 217 | for (var i = 0, il = query.listeners.length; i < il; i++) { 218 | if (query.listeners[i]) { 219 | query.listeners[i].call(win, query.mql); 220 | } 221 | } 222 | } 223 | } 224 | } 225 | } while(qIndex--); 226 | } 227 | 228 | 229 | }, 10); 230 | }, 231 | 232 | /* 233 | _init 234 | */ 235 | _init = function () { 236 | var head = _doc.getElementsByTagName('head')[0], 237 | style = _doc.createElement('style'), 238 | info = null, 239 | typeList = ['screen', 'print', 'speech', 'projection', 'handheld', 'tv', 'braille', 'embossed', 'tty'], 240 | typeIndex = 0, 241 | typeLength = typeList.length, 242 | cssText = '#mediamatchjs { position: relative; z-index: 0; }', 243 | eventPrefix = '', 244 | addEvent = win.addEventListener || (eventPrefix = 'on') && win.attachEvent; 245 | 246 | style.type = 'text/css'; 247 | style.id = 'mediamatchjs'; 248 | 249 | head.appendChild(style); 250 | 251 | // Must be placed after style is inserted into the DOM for IE 252 | info = (win.getComputedStyle && win.getComputedStyle(style)) || style.currentStyle; 253 | 254 | // Create media blocks to test for media type 255 | for ( ; typeIndex < typeLength; typeIndex++) { 256 | cssText += '@media ' + typeList[typeIndex] + ' { #mediamatchjs { position: relative; z-index: ' + typeIndex + ' } }'; 257 | } 258 | 259 | // Add rules to style element 260 | if (style.styleSheet) { 261 | style.styleSheet.cssText = cssText; 262 | } else { 263 | style.textContent = cssText; 264 | } 265 | 266 | // Get media type 267 | _type = typeList[(info.zIndex * 1) || 0]; 268 | 269 | head.removeChild(style); 270 | 271 | _setFeature(); 272 | 273 | // Set up listeners 274 | addEvent(eventPrefix + 'resize', _watch); 275 | addEvent(eventPrefix + 'orientationchange', _watch); 276 | }; 277 | 278 | _init(); 279 | 280 | /* 281 | A list of parsed media queries, ex. screen and (max-width: 400px), screen and (max-width: 800px) 282 | */ 283 | return function (media) { 284 | var id = _queryID, 285 | mql = { 286 | matches : false, 287 | media : media, 288 | addListener : function addListener(listener) { 289 | _queries[id].listeners || (_queries[id].listeners = []); 290 | listener && _queries[id].listeners.push(listener); 291 | }, 292 | removeListener : function removeListener(listener) { 293 | var query = _queries[id], 294 | i = 0, 295 | il = 0; 296 | 297 | if (!query) { 298 | return; 299 | } 300 | 301 | il = query.listeners.length; 302 | 303 | for ( ; i < il; i++) { 304 | if (query.listeners[i] === listener) { 305 | query.listeners.splice(i, 1); 306 | } 307 | } 308 | } 309 | }; 310 | 311 | if (media === '') { 312 | mql.matches = true; 313 | return mql; 314 | } 315 | 316 | mql.matches = _matches(media); 317 | 318 | _queryID = _queries.push({ 319 | mql : mql, 320 | listeners : null 321 | }); 322 | 323 | return mql; 324 | }; 325 | }(window)); -------------------------------------------------------------------------------- /src/libs/ready.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * domready (c) Dustin Diaz 2012 - License MIT 3 | */ 4 | !function (name, definition) { 5 | if (typeof module != 'undefined') module.exports = definition() 6 | else if (typeof define == 'function' && typeof define.amd == 'object') define(definition) 7 | else this[name] = definition() 8 | }('domready', function (ready) { 9 | 10 | var fns = [], fn, f = false 11 | , doc = document 12 | , testEl = doc.documentElement 13 | , hack = testEl.doScroll 14 | , domContentLoaded = 'DOMContentLoaded' 15 | , addEventListener = 'addEventListener' 16 | , onreadystatechange = 'onreadystatechange' 17 | , readyState = 'readyState' 18 | , loadedRgx = hack ? /^loaded|^c/ : /^loaded|c/ 19 | , loaded = loadedRgx.test(doc[readyState]) 20 | 21 | function flush(f) { 22 | loaded = 1 23 | while (f = fns.shift()) f() 24 | } 25 | 26 | doc[addEventListener] && doc[addEventListener](domContentLoaded, fn = function () { 27 | doc.removeEventListener(domContentLoaded, fn, f) 28 | flush() 29 | }, f) 30 | 31 | 32 | hack && doc.attachEvent(onreadystatechange, fn = function () { 33 | if (/^c/.test(doc[readyState])) { 34 | doc.detachEvent(onreadystatechange, fn) 35 | flush() 36 | } 37 | }) 38 | 39 | return (ready = hack ? 40 | function (fn) { 41 | self != top ? 42 | loaded ? fn() : fns.push(fn) : 43 | function () { 44 | try { 45 | testEl.doScroll('left') 46 | } catch (e) { 47 | return setTimeout(function() { ready(fn) }, 50) 48 | } 49 | fn() 50 | }() 51 | } : 52 | function (fn) { 53 | loaded ? fn() : fns.push(fn) 54 | }) 55 | }) 56 | -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | Lazy-ads tests 13 | 14 | 21 | 22 | 23 | 24 |

Visual tests for lazy-ads

25 |

All ad container min-heights are 90px

26 | 27 |
28 |
29 | 30 |
31 | 32 |
33 |

No data-lazyad property

34 |
35 | 44 |
45 | 46 |
47 |

LazyAd requirement data-adwidth="320"

48 |

Mobile leaderboard

49 |
50 |
51 | 60 |
61 | 62 |
63 |

LazyAd requirement data-adwidth="728"

64 |

Leaderboard

65 |
66 |
67 | 76 |
77 | 78 |

LazyAd requirement data-adheight="90"

79 |
80 | 89 |
90 | 91 |

LazyAd requirement data-adheight="100"

92 |
93 | 102 |
103 | 104 |

LazyAd requirement data-adwidth="728" data-adheight="90"

105 |
106 | 115 |
116 | 117 |

LazyAd requirement data-matchmedia="only screen and (min-width: 320px)"

118 |
119 | 128 |
129 | 130 |

LazyAd requirement data-matchmedia="only screen and (max-width: 320px)"

131 |
132 | 141 |
142 | 143 |

LazyAd requirement data-matchmedia="only screen and (min-width: 725px)"

144 |
145 | 154 |
155 | 156 |

LazyAd requirement data-adwidth="728" data-adheight="90" data-matchmedia="only screen and (min-width: 800px)"

157 |
158 | 167 |
168 | 169 | 170 |
171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /tests/index2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Lazy-ads tests 10 | 11 | 12 | 13 | 14 |

Visual tests for loading/unloading lazy-ads

15 | 16 |
17 |
18 | 19 |
20 | 21 |
22 | 23 |

LazyAd requirement data-matchmedia="only screen and (max-width: 320px)"

24 | 25 |
26 | 35 |
36 | 37 |

LazyAd requirement data-matchmedia="only screen and (min-width: 321px) and (max-width: 850px)"

38 | 39 |
40 | 49 |
50 | 51 | 52 |
53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /tests/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 100%; 3 | font-family: sans-serif; 4 | margin: 0; 5 | } 6 | .withgutter { 7 | margin: 10px 20px; 8 | } 9 | .ads{ 10 | margin: 1em 0; 11 | padding: 0; 12 | list-style: none; 13 | } 14 | .ads__item { 15 | margin: 1em 0 2em; 16 | border-color: lightgrey; 17 | border-width: 2px 0; 18 | border-style: solid; 19 | min-height: 90px; 20 | border-left: none; 21 | border-right: none; 22 | background: lightgrey; 23 | text-align: center; 24 | } 25 | code { 26 | background: hsl(43, 100%, 90.8%); 27 | } 28 | .dimensionsContainer { 29 | display: block; 30 | text-align: center; 31 | margin: 2em 0; 32 | line-height: 1em; 33 | } 34 | .dimensionsContainer hr { 35 | border: none; 36 | border-top: 1px solid red; 37 | margin: 0; 38 | position: relative; 39 | color: red; 40 | } 41 | .dimensionsContainer hr:before { 42 | content: "◀"; 43 | position: absolute; 44 | display: block; 45 | left: 0; 46 | top: -0.5em; 47 | text-align: left; 48 | } 49 | .dimensionsContainer hr:after { 50 | content: "▶"; 51 | position: absolute; 52 | display: block; 53 | right: 0; 54 | top: -0.5em; 55 | text-align: right; 56 | } 57 | #windowDimensions { 58 | background: white; 59 | padding: 2px 10px; 60 | position: relative; 61 | top: -0.5em; 62 | margin: 0; 63 | } 64 | 65 | 66 | .ads__item--mobile-leaderboard, .ads__item--leaderboard { 67 | background: red; 68 | border-color: red; 69 | } 70 | 71 | @media only screen and (max-width: 320px) { 72 | .ads__item--mobile-leaderboard { 73 | background: green; 74 | border-color: green; 75 | } 76 | } 77 | @media only screen and (min-width: 321px) and (max-width: 850px) { 78 | .ads__item--leaderboard { 79 | background: green; 80 | border-color: green; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /tests/utils.js: -------------------------------------------------------------------------------- 1 | // simple time helper 2 | function currTime() { 3 | var d = new Date(); 4 | return d.toLocaleTimeString(); 5 | } 6 | 7 | // simple indicator of viewport width 8 | function updatePlaceHolder() { 9 | var placeholder = document.getElementById('windowDimensions'), 10 | width = window.document.documentElement.clientWidth, 11 | height = window.document.documentElement.clientHeight; 12 | 13 | placeholder.innerHTML = width + ' px'; 14 | } 15 | 16 | window.addEventListener('resize', updatePlaceHolder); 17 | 18 | window.addEventListener('load', updatePlaceHolder); --------------------------------------------------------------------------------