From 5902528bae21b560b6be4879e5e87ed36ce099b6 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 23 Jan 2018 16:42:24 -0800 Subject: [PATCH] undo and redo adding new cropper library as it had a .git config from the original project --- library/cropperjs/.babelrc | 10 + library/cropperjs/.editorconfig | 9 + library/cropperjs/.eslintrc | 13 + library/cropperjs/.travis.yml | 7 + library/cropperjs/CHANGELOG.md | 218 + library/cropperjs/CONTRIBUTING.md | 35 + library/cropperjs/ISSUE_TEMPLATE.md | 21 + library/cropperjs/LICENSE | 21 + library/cropperjs/README.md | 1028 ++ library/cropperjs/dist/cropper.common.js | 3760 +++++++ library/cropperjs/dist/cropper.css | 306 + library/cropperjs/dist/cropper.esm.js | 3758 +++++++ library/cropperjs/dist/cropper.js | 3766 +++++++ library/cropperjs/dist/cropper.min.css | 9 + library/cropperjs/dist/cropper.min.js | 10 + library/cropperjs/docs/css/cropper.css | 306 + library/cropperjs/docs/css/main.css | 252 + library/cropperjs/docs/images/data.jpg | Bin 0 -> 16534 bytes library/cropperjs/docs/images/layers.jpg | Bin 0 -> 26921 bytes library/cropperjs/docs/images/picture-2.jpg | Bin 0 -> 182998 bytes library/cropperjs/docs/images/picture-3.jpg | Bin 0 -> 224777 bytes library/cropperjs/docs/images/picture.jpg | Bin 0 -> 157356 bytes library/cropperjs/docs/index.html | 578 ++ library/cropperjs/docs/js/cropper.js | 3766 +++++++ library/cropperjs/docs/js/main.js | 298 + .../examples/a-range-of-aspect-ratio.html | 71 + .../examples/crop-a-round-image.html | 103 + .../examples/crop-cross-origin-image.html | 49 + .../cropperjs/examples/crop-on-canvas.html | 64 + .../cropperjs/examples/cropper-in-modal.html | 76 + .../cropperjs/examples/customize-preview.html | 123 + .../cropperjs/examples/fixed-crop-box.html | 48 + library/cropperjs/examples/full-crop-box.html | 48 + library/cropperjs/examples/mask-an-image.html | 123 + .../cropperjs/examples/multiple-croppers.html | 48 + .../examples/responsive-container.html | 49 + library/cropperjs/package-lock.json | 9111 +++++++++++++++++ library/cropperjs/package.json | 76 + library/cropperjs/postcss.config.js | 14 + library/cropperjs/rollup.config.js | 50 + library/cropperjs/src/css/cropper.css | 290 + library/cropperjs/src/images/bg.png | Bin 0 -> 168 bytes library/cropperjs/src/js/change.js | 471 + library/cropperjs/src/js/constants.js | 56 + library/cropperjs/src/js/cropper.js | 421 + library/cropperjs/src/js/defaults.js | 99 + library/cropperjs/src/js/events.js | 111 + library/cropperjs/src/js/handlers.js | 212 + library/cropperjs/src/js/methods.js | 842 ++ library/cropperjs/src/js/preview.js | 142 + library/cropperjs/src/js/render.js | 495 + library/cropperjs/src/js/template.js | 27 + library/cropperjs/src/js/utilities.js | 985 ++ library/cropperjs/test/css/main.css | 9 + library/cropperjs/test/events/crop.js | 21 + library/cropperjs/test/events/cropend.js | 24 + library/cropperjs/test/events/cropmove.js | 24 + library/cropperjs/test/events/cropstart.js | 56 + library/cropperjs/test/events/ready.js | 15 + library/cropperjs/test/events/zoom.js | 46 + library/cropperjs/test/index.html | 90 + library/cropperjs/test/js/main.js | 74 + library/cropperjs/test/methods/clear.js | 29 + library/cropperjs/test/methods/crop.js | 24 + library/cropperjs/test/methods/destroy.js | 22 + library/cropperjs/test/methods/disable.js | 60 + library/cropperjs/test/methods/enable.js | 23 + .../cropperjs/test/methods/getCanvasData.js | 23 + .../test/methods/getContainerData.js | 19 + .../cropperjs/test/methods/getCropBoxData.js | 21 + .../test/methods/getCroppedCanvas.js | 33 + library/cropperjs/test/methods/getData.js | 46 + .../cropperjs/test/methods/getImageData.js | 31 + library/cropperjs/test/methods/move.js | 20 + library/cropperjs/test/methods/moveTo.js | 19 + library/cropperjs/test/methods/replace.js | 23 + library/cropperjs/test/methods/reset.js | 35 + library/cropperjs/test/methods/rotate.js | 19 + library/cropperjs/test/methods/rotateTo.js | 20 + library/cropperjs/test/methods/scale.js | 19 + library/cropperjs/test/methods/scaleX.js | 18 + library/cropperjs/test/methods/scaleY.js | 18 + .../cropperjs/test/methods/setAspectRatio.js | 20 + .../cropperjs/test/methods/setCanvasData.js | 34 + .../cropperjs/test/methods/setCropBoxData.js | 36 + library/cropperjs/test/methods/setData.js | 36 + library/cropperjs/test/methods/setDragMode.js | 27 + library/cropperjs/test/methods/zoom.js | 20 + library/cropperjs/test/methods/zoomTo.js | 21 + library/cropperjs/test/options/aspectRatio.js | 39 + library/cropperjs/test/options/autoCrop.js | 39 + library/cropperjs/test/options/background.js | 40 + library/cropperjs/test/options/center.js | 41 + .../test/options/checkCrossOrigin.js | 67 + .../test/options/checkOrientation.js | 43 + library/cropperjs/test/options/crop.js | 21 + .../cropperjs/test/options/cropBoxMovable.js | 41 + .../test/options/cropBoxResizable.js | 65 + library/cropperjs/test/options/cropend.js | 24 + library/cropperjs/test/options/cropmove.js | 24 + library/cropperjs/test/options/cropstart.js | 56 + library/cropperjs/test/options/data.js | 35 + library/cropperjs/test/options/dragMode.js | 60 + library/cropperjs/test/options/guides.js | 43 + library/cropperjs/test/options/highlight.js | 41 + .../cropperjs/test/options/minCanvasHeight.js | 23 + .../cropperjs/test/options/minCanvasWidth.js | 23 + .../test/options/minContainerHeight.js | 21 + .../test/options/minContainerWidth.js | 21 + .../test/options/minCropBoxHeight.js | 23 + .../cropperjs/test/options/minCropBoxWidth.js | 23 + library/cropperjs/test/options/modal.js | 39 + library/cropperjs/test/options/movable.js | 45 + library/cropperjs/test/options/ready.js | 15 + library/cropperjs/test/options/rotatable.js | 39 + library/cropperjs/test/options/scalable.js | 43 + .../test/options/toggleDragModeOnDblclick.js | 45 + library/cropperjs/test/options/viewMode.js | 100 + library/cropperjs/test/options/zoom.js | 46 + library/cropperjs/test/options/zoomOnWheel.js | 47 + library/cropperjs/test/options/zoomable.js | 51 + 121 files changed, 34733 insertions(+) create mode 100644 library/cropperjs/.babelrc create mode 100644 library/cropperjs/.editorconfig create mode 100644 library/cropperjs/.eslintrc create mode 100644 library/cropperjs/.travis.yml create mode 100644 library/cropperjs/CHANGELOG.md create mode 100644 library/cropperjs/CONTRIBUTING.md create mode 100644 library/cropperjs/ISSUE_TEMPLATE.md create mode 100644 library/cropperjs/LICENSE create mode 100644 library/cropperjs/README.md create mode 100644 library/cropperjs/dist/cropper.common.js create mode 100644 library/cropperjs/dist/cropper.css create mode 100644 library/cropperjs/dist/cropper.esm.js create mode 100644 library/cropperjs/dist/cropper.js create mode 100644 library/cropperjs/dist/cropper.min.css create mode 100644 library/cropperjs/dist/cropper.min.js create mode 100644 library/cropperjs/docs/css/cropper.css create mode 100644 library/cropperjs/docs/css/main.css create mode 100644 library/cropperjs/docs/images/data.jpg create mode 100644 library/cropperjs/docs/images/layers.jpg create mode 100644 library/cropperjs/docs/images/picture-2.jpg create mode 100644 library/cropperjs/docs/images/picture-3.jpg create mode 100644 library/cropperjs/docs/images/picture.jpg create mode 100644 library/cropperjs/docs/index.html create mode 100644 library/cropperjs/docs/js/cropper.js create mode 100644 library/cropperjs/docs/js/main.js create mode 100644 library/cropperjs/examples/a-range-of-aspect-ratio.html create mode 100644 library/cropperjs/examples/crop-a-round-image.html create mode 100644 library/cropperjs/examples/crop-cross-origin-image.html create mode 100644 library/cropperjs/examples/crop-on-canvas.html create mode 100644 library/cropperjs/examples/cropper-in-modal.html create mode 100644 library/cropperjs/examples/customize-preview.html create mode 100644 library/cropperjs/examples/fixed-crop-box.html create mode 100644 library/cropperjs/examples/full-crop-box.html create mode 100644 library/cropperjs/examples/mask-an-image.html create mode 100644 library/cropperjs/examples/multiple-croppers.html create mode 100644 library/cropperjs/examples/responsive-container.html create mode 100644 library/cropperjs/package-lock.json create mode 100644 library/cropperjs/package.json create mode 100644 library/cropperjs/postcss.config.js create mode 100644 library/cropperjs/rollup.config.js create mode 100644 library/cropperjs/src/css/cropper.css create mode 100644 library/cropperjs/src/images/bg.png create mode 100644 library/cropperjs/src/js/change.js create mode 100644 library/cropperjs/src/js/constants.js create mode 100644 library/cropperjs/src/js/cropper.js create mode 100644 library/cropperjs/src/js/defaults.js create mode 100644 library/cropperjs/src/js/events.js create mode 100644 library/cropperjs/src/js/handlers.js create mode 100644 library/cropperjs/src/js/methods.js create mode 100644 library/cropperjs/src/js/preview.js create mode 100644 library/cropperjs/src/js/render.js create mode 100644 library/cropperjs/src/js/template.js create mode 100644 library/cropperjs/src/js/utilities.js create mode 100644 library/cropperjs/test/css/main.css create mode 100644 library/cropperjs/test/events/crop.js create mode 100644 library/cropperjs/test/events/cropend.js create mode 100644 library/cropperjs/test/events/cropmove.js create mode 100644 library/cropperjs/test/events/cropstart.js create mode 100644 library/cropperjs/test/events/ready.js create mode 100644 library/cropperjs/test/events/zoom.js create mode 100644 library/cropperjs/test/index.html create mode 100644 library/cropperjs/test/js/main.js create mode 100644 library/cropperjs/test/methods/clear.js create mode 100644 library/cropperjs/test/methods/crop.js create mode 100644 library/cropperjs/test/methods/destroy.js create mode 100644 library/cropperjs/test/methods/disable.js create mode 100644 library/cropperjs/test/methods/enable.js create mode 100644 library/cropperjs/test/methods/getCanvasData.js create mode 100644 library/cropperjs/test/methods/getContainerData.js create mode 100644 library/cropperjs/test/methods/getCropBoxData.js create mode 100644 library/cropperjs/test/methods/getCroppedCanvas.js create mode 100644 library/cropperjs/test/methods/getData.js create mode 100644 library/cropperjs/test/methods/getImageData.js create mode 100644 library/cropperjs/test/methods/move.js create mode 100644 library/cropperjs/test/methods/moveTo.js create mode 100644 library/cropperjs/test/methods/replace.js create mode 100644 library/cropperjs/test/methods/reset.js create mode 100644 library/cropperjs/test/methods/rotate.js create mode 100644 library/cropperjs/test/methods/rotateTo.js create mode 100644 library/cropperjs/test/methods/scale.js create mode 100644 library/cropperjs/test/methods/scaleX.js create mode 100644 library/cropperjs/test/methods/scaleY.js create mode 100644 library/cropperjs/test/methods/setAspectRatio.js create mode 100644 library/cropperjs/test/methods/setCanvasData.js create mode 100644 library/cropperjs/test/methods/setCropBoxData.js create mode 100644 library/cropperjs/test/methods/setData.js create mode 100644 library/cropperjs/test/methods/setDragMode.js create mode 100644 library/cropperjs/test/methods/zoom.js create mode 100644 library/cropperjs/test/methods/zoomTo.js create mode 100644 library/cropperjs/test/options/aspectRatio.js create mode 100644 library/cropperjs/test/options/autoCrop.js create mode 100644 library/cropperjs/test/options/background.js create mode 100644 library/cropperjs/test/options/center.js create mode 100644 library/cropperjs/test/options/checkCrossOrigin.js create mode 100644 library/cropperjs/test/options/checkOrientation.js create mode 100644 library/cropperjs/test/options/crop.js create mode 100644 library/cropperjs/test/options/cropBoxMovable.js create mode 100644 library/cropperjs/test/options/cropBoxResizable.js create mode 100644 library/cropperjs/test/options/cropend.js create mode 100644 library/cropperjs/test/options/cropmove.js create mode 100644 library/cropperjs/test/options/cropstart.js create mode 100644 library/cropperjs/test/options/data.js create mode 100644 library/cropperjs/test/options/dragMode.js create mode 100644 library/cropperjs/test/options/guides.js create mode 100644 library/cropperjs/test/options/highlight.js create mode 100644 library/cropperjs/test/options/minCanvasHeight.js create mode 100644 library/cropperjs/test/options/minCanvasWidth.js create mode 100644 library/cropperjs/test/options/minContainerHeight.js create mode 100644 library/cropperjs/test/options/minContainerWidth.js create mode 100644 library/cropperjs/test/options/minCropBoxHeight.js create mode 100644 library/cropperjs/test/options/minCropBoxWidth.js create mode 100644 library/cropperjs/test/options/modal.js create mode 100644 library/cropperjs/test/options/movable.js create mode 100644 library/cropperjs/test/options/ready.js create mode 100644 library/cropperjs/test/options/rotatable.js create mode 100644 library/cropperjs/test/options/scalable.js create mode 100644 library/cropperjs/test/options/toggleDragModeOnDblclick.js create mode 100644 library/cropperjs/test/options/viewMode.js create mode 100644 library/cropperjs/test/options/zoom.js create mode 100644 library/cropperjs/test/options/zoomOnWheel.js create mode 100644 library/cropperjs/test/options/zoomable.js diff --git a/library/cropperjs/.babelrc b/library/cropperjs/.babelrc new file mode 100644 index 000000000..6909c9dc9 --- /dev/null +++ b/library/cropperjs/.babelrc @@ -0,0 +1,10 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["last 2 versions", "ie >= 9"] + } + }] + ] +} diff --git a/library/cropperjs/.editorconfig b/library/cropperjs/.editorconfig new file mode 100644 index 000000000..0f1786729 --- /dev/null +++ b/library/cropperjs/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/library/cropperjs/.eslintrc b/library/cropperjs/.eslintrc new file mode 100644 index 000000000..8757045b6 --- /dev/null +++ b/library/cropperjs/.eslintrc @@ -0,0 +1,13 @@ +{ + "extends": "airbnb-base", + "env": { + "browser": true + }, + "rules": { + "no-param-reassign": "off", + "no-restricted-properties": "off", + "valid-jsdoc": ["error", { + "requireReturn": false + }] + } +} diff --git a/library/cropperjs/.travis.yml b/library/cropperjs/.travis.yml new file mode 100644 index 000000000..de9b4ae30 --- /dev/null +++ b/library/cropperjs/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +node_js: + - "node" +script: + - npm run lint + - npm run build + - npm test diff --git a/library/cropperjs/CHANGELOG.md b/library/cropperjs/CHANGELOG.md new file mode 100644 index 000000000..f0d54cd92 --- /dev/null +++ b/library/cropperjs/CHANGELOG.md @@ -0,0 +1,218 @@ +# Changelog + +## 1.2.2 (Jan 3, 2018) + +- Fix incorrect image natural sizes in iOS Safari (#279). + +## 1.2.1 (Dec 17, 2017) + +- Add `style` field to `package.json`. +- Fix size error when load SVG image (#256). + +## 1.2.0 (Dec 17, 2017) + +- Allow to set the pivot of zoom (#144). +- Fixed a bug of rotation (#260). + +## 1.1.3 (Oct 21, 2017) + +- Fixed a bug of render when disable one of `rotatable` and `scalable` options (#241). + +## 1.1.2 (Oct 18, 2017) + +- Normalize related decimal numbers when crop an image with canvas. + +## 1.1.1 (Oct 11, 2017) + +- Supports to load in node environment (#237). +- Fixed a bug of event binding (#238). + +## 1.1.0 (Oct 8, 2017) + +- Added 4 new options to `getCroppedCanvas` method: `minWidth`, `minHeight`, `maxWidth` and `maxHeight`. +- Enhanced image scaling: the `scaleX` and `scaleY` values should only be `1` or `-1` before, but now they can be any numbers. +- Improved crop box resizing behaviour in the northeast, northwest, southeast and southwest directions. (#222). + +## 1.0.0 (Sep 3, 2017) + +- Fixed a bug of zoom out after cleared the crop box in view mode 1, 2 and 3 (#209). +- Improve crop box resizing behaviour in the east, west, south and north directions (#222). + +## 1.0.0-rc.3 (Jul 7, 2017) + +- Added two new options (`imageSmoothingEnabled` and `imageSmoothingQuality`) to `getCroppedCanvas` method. +- Fixed a bug of RegExp using (#195 by @arusakov). + +## 1.0.0-rc.2 (May 30, 2017) + +- Fixed the issue of canvas box initialization (#179). + +## 1.0.0-rc.1 (Apr 30, 2017) + +- Change the `main` field value from `dist/cropper.js` (UMD) to `dist/cropper.common.js` (CommonJS). +- Added `module` and `browser` fields to `package.json`. + +## 1.0.0-rc (Mar 25, 2017) + +- Fixed the bug of touch zoom (#161). +- Fixed the bug of window resize (#162). +- Improve the `toggleDragModeOnDblclick` option (only available when the `dragMode` option is set to `crop` or `move`) + +## 1.0.0-beta.2 (Feb 25, 2017) + +- Fixed the bug of rotate square image lead image shrink (#155). +- Improved RegExps for DataURL processing (#156). + +## 1.0.0-beta.1 (Jan 21, 2017) + +- Use CSS3 2D Transforms instead of `left` and `top` for better performance (#138). +- Set `withCredentials` attribute when read the image data by XMLHttpRequest (#141). + +## 1.0.0-beta (Jan 1, 2017) + +- Supports to set an element for preview (#113). +- Improved event handler for Pointer Events (#127). + +## 1.0.0-alpha (Dec 4, 2016) + +- Built JavaScript with Rollup. +- Build CSS with PostCSS. +- Fixed a bug of auto crop when replace the image (#83). + +## 0.8.1 (Sep 3, 2016) + +- Fixed the bug of cropping (#80). +- Fixed the bug of calling `ready` event twice when call `replace` method (#81). +- Fixed the bug of `getCroppedCanvas` when set `scalable` or `rotatable` to `false` (#82). + +## 0.8.0 (Aug 18, 2016) + +- Removed `build` event. +- Renamed `built` event to `ready`. +- Fixed the error of orientation transform. +- Ported code to ECMAScript 6. + +## 0.7.2 (Jun 8, 2016) + +- Fixed a bug of `data-*` attributes setting and getting. +- Fixed the calling order of `scale` and `rotate`. + +## 0.7.1 (May 28, 2016) + +- Improved the rotate and scale transform behaviour. +- Improved the `getCroppedCanvas` method (returns the whole canvas if it is not cropped). +- Check cross origin setting when load image by XMLHTTPRequest. + +## 0.7.0 (Mar 20, 2016) + +- Supports 7 custom events: `build`, `built`, `cropstart`, `cropmove`, `cropend`, `crop` and `zoom`. +- The original callback options become shortcuts of these events now. +- IE8 is no longer supported after added these custom events. + +## 0.6.0 (Feb 22, 2016) + +- Added a new parameter to the `replace` method for applying filters. +- Improved the image initializing for Safari. +- Fixed incorrect size limitation of the crop box (#30). +- Fixed incorrect cropped canvas when scaleX or scaleY great than 1. + +## 0.5.6 (Jan 18, 2016) + +- Fixed crossOriginUrl undefined error when exists the `crossOrigin` property. +- Fixed the issue in the "destroy" method (#24). +- Optimized tests. + +## 0.5.5 (Jan 1, 2016) + +- Fixed a dimension bug in the "getCroppedCanvas" method. +- Added an example for cropping round image. + +## 0.5.4 (Dec 28, 2015) + +- Supports to zoom from event triggering point. + +## 0.5.3 (Dec 24, 2015) + +- Limit wheel speed to prevent zoom too fast (#21) +- Improve the `setCropBoxData` method (#22) + +## 0.5.2 (Dec 15, 2015) + +- Fix event handlers + +## 0.5.1 (Dec 12, 2015) + +- Handle Data URL (avoid to use XMLHttpRequest to open a Data URL) +- Handle ajax error when load ArrayBuffer +- Not to transform the image to base64 when Orientation equals to `1` +- Fix some typos + +## 0.5.0 (Dec 5, 2015) + +- Added a new option: `checkOrientation` +- Added a timestamp to the url of preview image + +## 0.4.0 (Dec 2, 2015) + +- Added a new option: `restore` +- Fixed #12: Added vendor prefixes to CSS `transform` + +## 0.3.3 (Nov 30, 2015) + +- Floor the numerical parameters for `CanvasRenderingContext2D.drawImage` + +## 0.3.2 (Nov 18, 2015) + +- Fixed #10: improve new crop box creating + +## 0.3.1 (Nov 11, 2015) + +- Fixed #7: reset the `crossOrigin` when call the `replace` method + +## 0.3.0 (Oct 28, 2015) + +- Supports four view modes +- Supports three drag modes +- Makes the crop box's borders and handlers visible when overflow +- Added some examples +- Fixed some issues + +### Options + +- Added `viewMode` +- Added `dragMode` +- Renamed `touchDragZoom` to `zoomOnTouch` +- Renamed `mouseWheelZoom` to `zoomOnWheel` +- Renamed `doubleClickToggle` to `toggleDragModeOnDblclick` +- Renamed `checkImageOrigin` to `checkCrossOrigin` +- Removed `strict` (supported by `viewMode: 1`) +- Removed `dragCrop` (supported by `dragMode: 'crop'`) + +## 0.2.1 (Oct 28, 2015) + +- Fix the error jQuery reference on the `setCanvasData` method +- Fix typo on the `destroy` method + +## 0.2.0 (Oct 25, 2015) + +- Added 5 new methods: `moveTo`, `zoomTo`, `rotateTo`, `scaleX` and `scaleY` +- Improved 4 methods: `move`, `zoom`, `rotate` and `getCanvasData` +- Improved cropping + +## 0.1.1 (Oct 10, 2015) + +- Improved canvas limitation +- Improved crop box limitation +- Improved preview for cross origin image + +## 0.1.0 (Sep 25, 2015) + +- Supports touch (mobile) +- Supports zoom +- Supports rotation +- Supports scale (flip) +- Supports canvas +- Supports multiple croppers +- Cross-browser support +- Supports 37 options: `aspectRatio`, `data`, `preview`, `strict`, `responsive`, `checkImageOrigin`, `modal`, `guides`, `center`, `highlight`, `background`, `autoCrop`, `autoCropArea`, `dragCrop`, `movable`, `rotatable`, `scalable`, `zoomable`, `mouseWheelZoom`, `wheelZoomRatio`, `touchDragZoom`, `cropBoxMovable`, `cropBoxResizable`, `doubleClickToggle`, `minCanvasWidth`, `minCanvasHeight`, `minCropBoxWidth`, `minCropBoxHeight`, `minContainerWidth`, `minContainerHeight`, `build`, `built`, `cropstart`, `cropmove`, `cropend`, `crop`, `zoom`. +- Support 22 methods: `crop`, `reset`, `clear`, `replace`, `enable`, `disable`, `destroy`, `move`, `zoom`, `rotate`, `scale`, `getData`, `setData`, `getContainerData`, `getImageData`, `getCanvasData`, `setCanvasData`, `getCropBoxData`, `setCropBoxData`, `getCroppedCanvas`, `setAspectRatio`, `setDragMode`. diff --git a/library/cropperjs/CONTRIBUTING.md b/library/cropperjs/CONTRIBUTING.md new file mode 100644 index 000000000..7c31d7ab0 --- /dev/null +++ b/library/cropperjs/CONTRIBUTING.md @@ -0,0 +1,35 @@ +# Contributing to Cropper + +## How to report bugs + +### Make sure it is a Cropper bug + +Most bugs reported to our bug tracker are actually bugs in user code, not in Cropper code. Keep in mind that just because your code throws an error inside of Cropper, this does *not* mean the bug is a Cropper bug. + +Ask for help first in a discussion forum like [Stack Overflow](http://stackoverflow.com/). You will get much quicker support, and you will help avoid tying up the Cropper team with invalid bug reports. + +### Disable browser extensions + +Make sure you have reproduced the bug with all browser extensions and add-ons disabled, as these can sometimes cause things to break in interesting and unpredictable ways. Try using incognito, stealth or anonymous browsing modes. + +### Try the latest version of Cropper + +Bugs in old versions of Cropper may have already been fixed. In order to avoid reporting known issues, make sure you are always testing against the [latest release](https://github.com/fengyuanchen/cropperjs/releases/latest). We cannot fix bugs in older released files, if a bug has been fixed in a subsequent version of Cropper the site should upgrade. + +### Simplify the test case + +When experiencing a problem, [reduce your code](http://webkit.org/quality/reduction.html) to the bare minimum required to reproduce the issue. This makes it *much* easier to isolate and fix the offending code. Bugs reported without reduced test cases take on average 9001% longer to fix than bugs that are submitted with them, so you really should try to do this if at all possible. + +### Search for related or duplicate issues + +Go to the [Cropper issue tracker](https://github.com/fengyuanchen/cropperjs/issues) and make sure the problem hasn't already been reported. If not, create a new issue there and include your test case. + +### Browser support + +Remember that Cropper supports multiple browsers and their versions; any contributed code must work in all of them. You can refer to the [browser support page](https://github.com/fengyuanchen/cropperjs/blob/master/README.md#browser-support) for the current list of supported browsers. + +## Notes for pull request + +- Run the test suites in the `test` directory first. +- Don't modify any files in the `dist` directory. +- Follow the same code style as the library. diff --git a/library/cropperjs/ISSUE_TEMPLATE.md b/library/cropperjs/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..0ed98b61d --- /dev/null +++ b/library/cropperjs/ISSUE_TEMPLATE.md @@ -0,0 +1,21 @@ +Before opening an issue: + +- [Search for duplicate or closed issues](https://github.com/fengyuanchen/cropperjs/issues?utf8=%E2%9C%93&q=is%3Aissue) +- Prepare a [reduced test case](https://css-tricks.com/reduced-test-cases/) for any bugs +- Read the [contributing guidelines](https://github.com/fengyuanchen/cropperjs/blob/master/CONTRIBUTING.md) + +When asking general "how to" questions: + +- Please do not open an issue here +- Instead, ask for help on [StackOverflow](http://stackoverflow.com/) + +When reporting a bug, include: + +- Operating system and version (Windows, Mac OS X, Android, iOS, Win10 Mobile) +- Browser and version (Chrome, Firefox, Safari, IE, MS Edge, Opera 15+, Android Browser) +- Reduced test cases and potential fixes using [JS Bin](https://jsbin.com), [JSFiddle](https://jsfiddle.net/) or [CodePen](https://codepen.io/) + +When suggesting a feature, include: + +- As much detail as possible for what we should add and why it's important to Cropper.js +- Relevant links to prior art, screenshots, or live demos whenever possible diff --git a/library/cropperjs/LICENSE b/library/cropperjs/LICENSE new file mode 100644 index 000000000..e9b8a22b3 --- /dev/null +++ b/library/cropperjs/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-present Chen Fengyuan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/library/cropperjs/README.md b/library/cropperjs/README.md new file mode 100644 index 000000000..73e8dda30 --- /dev/null +++ b/library/cropperjs/README.md @@ -0,0 +1,1028 @@ +# Cropper.js + +[![Build Status](https://travis-ci.org/fengyuanchen/cropperjs.svg)](https://travis-ci.org/fengyuanchen/cropperjs) [![Downloads](https://img.shields.io/npm/dm/cropperjs.svg)](https://www.npmjs.com/package/cropperjs) [![Version](https://img.shields.io/npm/v/cropperjs.svg)](https://www.npmjs.com/package/cropperjs) + +> JavaScript image cropper. + +- [Website](https://fengyuanchen.github.io/cropperjs) +- [Photo Editor](https://fengyuanchen.github.io/photo-editor) - An advanced example of Cropper.js. + +## Table of contents + +- [Features](#features) +- [Main](#main) +- [Getting started](#getting-started) +- [Options](#options) +- [Methods](#methods) +- [Events](#events) +- [No conflict](#no-conflict) +- [Browser support](#browser-support) +- [Contributing](#contributing) +- [Versioning](#versioning) +- [License](#license) + +## Features + +- Supports 38 [options](#options) +- Supports 27 [methods](#methods) +- Supports 6 [events](#events) +- Supports touch (mobile) +- Supports zooming +- Supports rotating +- Supports scaling (flipping) +- Supports multiple croppers +- Supports to crop on a canvas +- Supports to crop image in the browser-side by canvas +- Supports to translate Exif Orientation information +- Cross-browser support + +## Main + +```text +dist/ +├── cropper.css +├── cropper.min.css (compressed) +├── cropper.js (UMD) +├── cropper.min.js (UMD, compressed) +├── cropper.common.js (CommonJS, default) +└── cropper.esm.js (ES Module) +``` + +## Getting started + +### Installation + +```shell +npm install cropperjs +``` + +Include files: + +```html + + +``` + +The [cdnjs](https://github.com/cdnjs/cdnjs) provides CDN support for Cropper.js's CSS and JavaScript. You can find the links [here](https://cdnjs.com/libraries/cropperjs). + +### Usage + +Initialize with `Cropper` constructor: + +- Browser: `window.Cropper` +- CommonJS: `var Cropper = require('cropperjs')` +- ES2015: `import Cropper from 'cropperjs'` + +```html + +
+ +
+``` + +```css +/* Limit image width to avoid overflow the container */ +img { + max-width: 100%; /* This rule is very important, please do not ignore this! */ +} +``` + +```js +var image = document.getElementById('image'); +var cropper = new Cropper(image, { + aspectRatio: 16 / 9, + crop: function(e) { + console.log(e.detail.x); + console.log(e.detail.y); + console.log(e.detail.width); + console.log(e.detail.height); + console.log(e.detail.rotate); + console.log(e.detail.scaleX); + console.log(e.detail.scaleY); + } +}); +``` + +#### FAQ + +How to crop a new area after zoom in or zoom out? + +> Just double click your mouse to enter crop mode. + +How to move the image after crop an area? + +> Just double click your mouse to enter move mode. + +How to fix aspect ratio in free ratio mode? + +> Just hold the `shift` key when you resize the crop box. + +How to crop a square area in free ratio mode? + +> Just hold the `shift` key when you crop on the image. + +#### Notes + +- The size of the cropper inherits from the size of the image's parent element (wrapper), so be sure to wrap the image with a **visible block element**. + > If you are using cropper in a modal, you should initialize the cropper after the modal shown completely. Otherwise, you will not get a correct cropper. + +- The outputted cropped data bases on the original image size, so you can use them to crop the image directly. + +- If you try to start cropper on a cross-origin image, please make sure that your browser supports HTML5 [CORS settings attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes), and your image server supports the `Access-Control-Allow-Origin` option (see the [HTTP access control (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)). + +#### Known issues + +- [Known iOS resource limits](https://developer.apple.com/library/mac/documentation/AppleApplications/Reference/SafariWebContent/CreatingContentforSafarioniPhone/CreatingContentforSafarioniPhone.html): As iOS devices limit memory, the browser may crash when you are cropping a large image (iPhone camera resolution). To avoid this, you may resize the image first (preferably below 1024 pixels) before start a cropper. + +- Known image size increase: When export the cropped image on browser-side with the `HTMLCanvasElement.toDataURL` method, the size of the exported image may be greater than the original image's. This is because the type of the exported image is not the same as the original image's. So just pass the type the original image's as the first parameter to `toDataURL` to fix this. For example, if the original type is JPEG, then use `cropper.getCroppedCanvas().toDataURL('image/jpeg')` to export image. + +[⬆ back to top](#table-of-contents) + +## Options + +You may set cropper options with `new Cropper(image, options)`. +If you want to change the global default options, You may use `Cropper.setDefaults(options)`. + +### viewMode + +- Type: `Number` +- Default: `0` +- Options: + - `0`: no restrictions + - `1`: restrict the crop box to not exceed the size of the canvas. + - `2`: restrict the minimum canvas size to fit within the container. If the proportions of the the canvas and the container differ, the minimum canvas will be surrounded by extra space in one of the dimensions. + - `3`: restrict the minimum canvas size to fill fit the container. If the proportions of the canvas and the container are different, the container will not be able to fit the whole canvas in one of the dimensions. + +Define the view mode of the cropper. If you set `viewMode` to `0`, the crop box can extend outside the canvas, while a value of `1`, `2` or `3` will restrict the crop box to the size of the canvas. A `viewMode` of `2` or `3` will additionally restrict the canvas to the container. Note that if the proportions of the canvas and the container are the same, there is no difference between `2` and `3`. + +### dragMode + +- Type: `String` +- Default: `'crop'` +- Options: + - `'crop'`: create a new crop box + - `'move'`: move the canvas + - `'none'`: do nothing + +Define the dragging mode of the cropper. + +### aspectRatio + +- Type: `Number` +- Default: `NaN` + +Set the aspect ratio of the crop box. By default, the crop box is free ratio. + +### data + +- Type: `Object` +- Default: `null` + +The previous cropped data if you had stored, will be passed to `setData` method automatically when built. + +### preview + +- Type: `Element` or `String` +- Default: `''` +- An element or A valid selector for [Document.querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) + +Add extra elements (containers) for previewing. + +**Notes:** + +- The maximum width is the initial width of preview container. +- The maximum height is the initial height of preview container. +- If you set an `aspectRatio` option, be sure to set the same aspect ratio to the preview container. +- If preview is not getting properly displayed, set `overflow: hidden` style to the preview container. + +### responsive + +- Type: `Boolean` +- Default: `true` + +Re-render the cropper when resize the window. + +### restore + +- Type: `Boolean` +- Default: `true` + +Restore the cropped area after resize the window. + +### checkCrossOrigin + +- Type: `Boolean` +- Default: `true` + +Check if the current image is a cross-origin image. + +If it is, when clone the image, a `crossOrigin` attribute will be added to the cloned image element and a timestamp will be added to the `src` attribute to reload the source image to avoid browser cache error. + +By adding `crossOrigin` attribute to image will stop adding timestamp to image url and stop reload of image, but the request (XMLHttpRequest) to read the image data for orientation checking will require a timestamp now. + +If the value of the image's `crossOrigin` attribute is `"use-credentials"`, then the `withCredentials` attribute will set to `true` when read the image data by XMLHttpRequest. + +### checkOrientation + +- Type: `Boolean` +- Default: `true` + +Check the current image's Exif Orientation information. + +More exactly, read the Orientation value for rotating or flipping the image, and then override the Orientation value with `1` (the default value) to avoid some issues ([1](https://github.com/fengyuanchen/cropper/issues/120), [2](https://github.com/fengyuanchen/cropper/issues/509)) on iOS devices. + +Requires to set both the `rotatable` and `scalable` options to `true` at the same time. + +**Note:** Don't trust this all the time as some JPG images have incorrect (not standard) Orientation values. + +> Requires [Typed Arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) support ([IE 10+](http://caniuse.com/typedarrays)). + +### modal + +- Type: `Boolean` +- Default: `true` + +Show the black modal above the image and under the crop box. + +### guides + +- Type: `Boolean` +- Default: `true` + +Show the dashed lines above the crop box. + +### center + +- Type: `Boolean` +- Default: `true` + +Show the center indicator above the crop box. + +### highlight + +- Type: `Boolean` +- Default: `true` + +Show the white modal above the crop box (highlight the crop box). + +### background + +- Type: `Boolean` +- Default: `true` + +Show the grid background of the container. + +### autoCrop + +- Type: `Boolean` +- Default: `true` + +Enable to crop the image automatically when initialize. + +### autoCropArea + +- Type: `Number` +- Default: `0.8` (80% of the image) + +A number between 0 and 1. Define the automatic cropping area size (percentage). + +### movable + +- Type: `Boolean` +- Default: `true` + +Enable to move the image. + +### rotatable + +- Type: `Boolean` +- Default: `true` + +Enable to rotate the image. + +### scalable + +- Type: `Boolean` +- Default: `true` + +Enable to scale the image. + +### zoomable + +- Type: `Boolean` +- Default: `true` + +Enable to zoom the image. + +### zoomOnTouch + +- Type: `Boolean` +- Default: `true` + +Enable to zoom the image by dragging touch. + +### zoomOnWheel + +- Type: `Boolean` +- Default: `true` + +Enable to zoom the image by wheeling mouse. + +### wheelZoomRatio + +- Type: `Number` +- Default: `0.1` + +Define zoom ratio when zoom the image by wheeling mouse. + +### cropBoxMovable + +- Type: `Boolean` +- Default: `true` + +Enable to move the crop box by dragging. + +### cropBoxResizable + +- Type: `Boolean` +- Default: `true` + +Enable to resize the crop box by dragging. + +### toggleDragModeOnDblclick + +- Type: `Boolean` +- Default: `true` + +Enable to toggle drag mode between "crop" and "move" when click twice on the cropper. + +### minContainerWidth + +- Type: `Number` +- Default: `200` + +The minimum width of the container. + +### minContainerHeight + +- Type: `Number` +- Default: `100` + +The minimum height of the container. + +### minCanvasWidth + +- Type: `Number` +- Default: `0` + +The minimum width of the canvas (image wrapper). + +### minCanvasHeight + +- Type: `Number` +- Default: `0` + +The minimum height of the canvas (image wrapper). + +### minCropBoxWidth + +- Type: `Number` +- Default: `0` + +The minimum width of the crop box. + +**Note:** This size is relative to the page, not the image. + +### minCropBoxHeight + +- Type: `Number` +- Default: `0` + +The minimum height of the crop box. + +**Note:** This size is relative to the page, not the image. + +### ready + +- Type: `Function` +- Default: `null` + +A shortcut of the "ready" event. + +### cropstart + +- Type: `Function` +- Default: `null` + +A shortcut of the "cropstart" event. + +### cropmove + +- Type: `Function` +- Default: `null` + +A shortcut of the "cropmove" event. + +### cropend + +- Type: `Function` +- Default: `null` + +A shortcut of the "cropend" event. + +### crop + +- Type: `Function` +- Default: `null` + +A shortcut of the "crop" event. + +### zoom + +- Type: `Function` +- Default: `null` + +A shortcut of the "zoom" event. + +[⬆ back to top](#table-of-contents) + +## Methods + +As there is an **asynchronous** process when load the image, you **should call most of the methods after ready**, except "setAspectRatio", "replace" and "destroy". + +> If a method doesn't need to return any value, it will return the cropper instance (`this`) for chain composition. + +```js +new Cropper(image, { + ready: function () { + // this.cropper[method](argument1, , argument2, ..., argumentN); + this.cropper.move(1, -1); + + // Allows chain composition + this.cropper.move(1, -1).rotate(45).scale(1, -1); + } +}); +``` + +### crop() + +Show the crop box manually. + +```js +new Cropper(image, { + autoCrop: false, + ready: function () { + // Do something here + // ... + + // And then + this.cropper.crop(); + } +}); +``` + +### reset() + +Reset the image and crop box to their initial states. + +### clear() + +Clear the crop box. + +### replace(url[, onlyColorChanged]) + +- **url**: + - Type: `String` + - A new image url. + +- **onlyColorChanged** (optional): + - Type: `Boolean` + - If only change the color, not the size, then the cropper only need to change the srcs of all related images, not need to rebuild the cropper. This can be used for applying filters. + - If not present, its default value is `false`. + +Replace the image's src and rebuild the cropper. + +### enable() + +Enable (unfreeze) the cropper. + +### disable() + +Disable (freeze) the cropper. + +### destroy() + +Destroy the cropper and remove the instance from the image. + +### move(offsetX[, offsetY]) + +- **offsetX**: + - Type: `Number` + - Moving size (px) in the horizontal direction. + +- **offsetY** (optional): + - Type: `Number` + - Moving size (px) in the vertical direction. + - If not present, its default value is `offsetX`. + +Move the canvas (image wrapper) with relative offsets. + +```js +cropper.move(1); +cropper.move(1, 0); +cropper.move(0, -1); +``` + +### moveTo(x[, y]) + +- **x**: + - Type: `Number` + - The `left` value of the canvas + +- **y** (optional): + - Type: `Number` + - The `top` value of the canvas + - If not present, its default value is `x`. + +Move the canvas (image wrapper) to an absolute point. + +### zoom(ratio) + +- **ratio**: + - Type: `Number` + - Zoom in: requires a positive number (ratio > 0) + - Zoom out: requires a negative number (ratio < 0) + +Zoom the canvas (image wrapper) with a relative ratio. + +```js +cropper.zoom(0.1); +cropper.zoom(-0.1); +``` + +### zoomTo(ratio[, pivot]) + +- **ratio**: + - Type: `Number` + - Requires a positive number (ratio > 0) + +- **pivot** (optional): + - Type: `Object` + - Schema: `{ x: Number, y: Number }` + - The coordinate of the center point for zooming, base on the top left corner of the cropper container. + +Zoom the canvas (image wrapper) to an absolute ratio. + +```js +cropper.zoomTo(1); // 1:1 (canvasData.width === canvasData.naturalWidth) + +const containerData = cropper.getContainerData(); + +// Zoom to 50% from the center of the container. +cropper.zoomTo(.5, { + x: containerData.width / 2, + y: containerData.height / 2, +}); +``` + +### rotate(degree) + +- **degree**: + - Type: `Number` + - Rotate right: requires a positive number (degree > 0) + - Rotate left: requires a negative number (degree < 0) + +Rotate the image with a relative degree. + +> Requires [CSS3 2D Transforms](https://developer.mozilla.org/en-US/docs/Web/CSS/transform) support ([IE 9+](http://caniuse.com/transforms2d)). + +```js +cropper.rotate(90); +cropper.rotate(-90); +``` + +### rotateTo(degree) + +- **degree**: + - Type: `Number` + +Rotate the image to an absolute degree. + +### scale(scaleX[, scaleY]) + +- **scaleX**: + - Type: `Number` + - Default: `1` + - The scaling factor to apply on the abscissa of the image. + - When equal to `1` it does nothing. + +- **scaleY** (optional): + - Type: `Number` + - The scaling factor to apply on the ordinate of the image. + - If not present, its default value is `scaleX`. + +Scale the image. + +> Requires [CSS3 2D Transforms](https://developer.mozilla.org/en-US/docs/Web/CSS/transform) support ([IE 9+](http://caniuse.com/transforms2d)). + +```js +cropper.scale(-1); // Flip both horizontal and vertical +cropper.scale(-1, 1); // Flip horizontal +cropper.scale(1, -1); // Flip vertical +``` + +### scaleX(scaleX) + +- **scaleX**: + - Type: `Number` + - Default: `1` + - The scaling factor to apply on the abscissa of the image. + - When equal to `1` it does nothing. + +Scale the abscissa of the image. + +### scaleY(scaleY) + +- **scaleY**: + - Type: `Number` + - Default: `1` + - The scaling factor to apply on the ordinate of the image. + - When equal to `1` it does nothing. + +Scale the ordinate of the image. + +### getData([rounded]) + +- **rounded** (optional): + - Type: `Boolean` + - Default: `false` + - Set `true` to get rounded values. + +- (return value): + - Type: `Object` + - Properties: + - `x`: the offset left of the cropped area + - `y`: the offset top of the cropped area + - `width`: the width of the cropped area + - `height`: the height of the cropped area + - `rotate`: the rotated degrees of the image + - `scaleX`: the scaling factor to apply on the abscissa of the image + - `scaleY`: the scaling factor to apply on the ordinate of the image + +Output the final cropped area position and size data (base on the natural size of the original image). + +> You can send the data to server-side to crop the image directly: +> 1. Rotate the image with the `rotate` property. +> 1. Scale the image with the `scaleX` and `scaleY` properties. +> 1. Crop the image with the `x`, `y`, `width` and `height` properties. + +![A schematic diagram for data's properties](docs/images/data.jpg) + +### setData(data) + +- **data**: + - Type: `Object` + - Properties: See the [`getData`](#getdatarounded) method. + - You may need to round the data properties before passing them in. + +Change the cropped area position and size with new data (base on the original image). + +> **Note:** This method only available when the `viewMode` option great than or equal to `1`. + +### getContainerData() + +- (return value): + - Type: `Object` + - Properties: + - `width`: the current width of the container + - `height`: the current height of the container + +Output the container size data. + +![A schematic diagram for cropper's layers](docs/images/layers.jpg) + +### getImageData() + +- (return value): + - Type: `Object` + - Properties: + - `left`: the offset left of the image + - `top`: the offset top of the image + - `width`: the width of the image + - `height`: the height of the image + - `naturalWidth`: the natural width of the image + - `naturalHeight`: the natural height of the image + - `aspectRatio`: the aspect ratio of the image + - `rotate`: the rotated degrees of the image if rotated + - `scaleX`: the scaling factor to apply on the abscissa of the image if scaled + - `scaleY`: the scaling factor to apply on the ordinate of the image if scaled + +Output the image position, size and other related data. + +### getCanvasData() + +- (return value): + - Type: `Object` + - Properties: + - `left`: the offset left of the canvas + - `top`: the offset top of the canvas + - `width`: the width of the canvas + - `height`: the height of the canvas + - `naturalWidth`: the natural width of the canvas (read only) + - `naturalHeight`: the natural height of the canvas (read only) + +Output the canvas (image wrapper) position and size data. + +```js +var imageData = cropper.getImageData(); +var canvasData = cropper.getCanvasData(); + +if (imageData.rotate % 180 === 0) { + console.log(canvasData.naturalWidth === imageData.naturalWidth); // true +} +``` + +### setCanvasData(data) + +- **data**: + - Type: `Object` + - Properties: + - `left`: the new offset left of the canvas + - `top`: the new offset top of the canvas + - `width`: the new width of the canvas + - `height`: the new height of the canvas + +Change the canvas (image wrapper) position and size with new data. + +### getCropBoxData() + +- (return value): + - Type: `Object` + - Properties: + - `left`: the offset left of the crop box + - `top`: the offset top of the crop box + - `width`: the width of the crop box + - `height`: the height of the crop box + +Output the crop box position and size data. + +### setCropBoxData(data) + +- **data**: + - Type: `Object` + - Properties: + - `left`: the new offset left of the crop box + - `top`: the new offset top of the crop box + - `width`: the new width of the crop box + - `height`: the new height of the crop box + +Change the crop box position and size with new data. + +### getCroppedCanvas([options]) + +- **options** (optional): + - Type: `Object` + - Properties: + - `width`: the destination width of the output canvas. + - `height`: the destination height of the output canvas. + - `minWidth`: the minimum destination width of the output canvas, the default value is `0`. + - `minHeight`: the minimum destination height of the output canvas, the default value is `0`. + - `maxWidth`: the maximum destination width of the output canvas, the default value is `Infinity`. + - `maxHeight`: the maximum destination height of the output canvas, the default value is `Infinity`. + - `fillColor`: a color to fill any alpha values in the output canvas, the default value is `transparent`. + - [`imageSmoothingEnabled`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled): set to change if images are smoothed (`true`, default) or not (`false`). + - [`imageSmoothingQuality`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingQuality): set the quality of image smoothing, one of "low" (default), "medium", or "high". + +- (return value): + - Type: `HTMLCanvasElement` + - A canvas drawn the cropped image. + +- Notes: + - The aspect ratio of the output canvas will be fitted to aspect ratio of the crop box automatically. + - If you intend to get a JPEG image from the output canvas, you should set the `fillColor` option first, if not, the transparent part in the JPEG image will become black by default. + +- Browser support: + - Basic image: requires [Canvas](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement) support ([IE 9+](http://caniuse.com/canvas)). + - Rotated image: requires [CSS3 2D Transforms](https://developer.mozilla.org/en-US/docs/Web/CSS/transform) support ([IE 9+](http://caniuse.com/transforms2d)). + - Cross-origin image: requires HTML5 [CORS settings attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) support ([IE 11+](http://caniuse.com/cors)). + +Get a canvas drawn the cropped image. If it is not cropped, then returns a canvas drawn the whole image. + +> After then, you can display the canvas as an image directly, or use [HTMLCanvasElement.toDataURL](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL) to get a Data URL, or use [HTMLCanvasElement.toBlob](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob) to get a blob and upload it to server with [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) if the browser supports these APIs. + +Avoid to get a blank output image, you might need to set the `maxWidth` and `maxHeight` properties to limited numbers, because of [the size limits of a canvas element](https://stackoverflow.com/questions/6081483/maximum-size-of-a-canvas-element). + +```js +cropper.getCroppedCanvas(); + +cropper.getCroppedCanvas({ + width: 160, + height: 90, + minWidth: 256, + minHeight: 256, + maxWidth: 4096, + maxHeight: 4096, + fillColor: '#fff', + imageSmoothingEnabled: false, + imageSmoothingQuality: 'high', +}); + +// Upload cropped image to server if the browser supports `HTMLCanvasElement.toBlob` +cropper.getCroppedCanvas().toBlob(function (blob) { + var formData = new FormData(); + + formData.append('croppedImage', blob); + + // Use `jQuery.ajax` method + $.ajax('/path/to/upload', { + method: "POST", + data: formData, + processData: false, + contentType: false, + success: function () { + console.log('Upload success'); + }, + error: function () { + console.log('Upload error'); + } + }); +}); +``` + +### setAspectRatio(aspectRatio) + +- **aspectRatio**: + - Type: `Number` + - Requires a positive number. + +Change the aspect ratio of the crop box. + +### setDragMode([mode]) + +- **mode** (optional): + - Type: `String` + - Default: `'none'` + - Options: `'none'`, `'crop'`, `'move'` + +Change the drag mode. + +**Tips:** You can toggle the "crop" and "move" mode by double click on the cropper. + +[⬆ back to top](#table-of-contents) + +## Events + +### ready + +This event fires when the target image has been loaded and the cropper instance is ready for cropping. + +```js +var cropper; + +image.addEventListener('ready', function () { + console.log(this.cropper === cropper); + // -> true +}); + +cropper = new Cropper(image); +``` + +### cropstart + +- **event.detail.originalEvent**: + - Type: `Event` + - Options: `mousedown`, `touchstart` and `pointerdown` + +- **event.detail.action**: + - Type: `String` + - Options: + - `'crop'`: create a new crop box + - `'move'`: move the canvas (image wrapper) + - `'zoom'`: zoom in / out the canvas (image wrapper) by touch. + - `'e'`: resize the east side of the crop box + - `'w'`: resize the west side of the crop box + - `'s'`: resize the south side of the crop box + - `'n'`: resize the north side of the crop box + - `'se'`: resize the southeast side of the crop box + - `'sw'`: resize the southwest side of the crop box + - `'ne'`: resize the northeast side of the crop box + - `'nw'`: resize the northwest side of the crop box + - `'all'`: move the crop box (all directions) + +This event fires when the canvas (image wrapper) or the crop box starts to change. + +```js +image.addEventListener('cropstart', function (e) { + console.log(e.detail.originalEvent); + console.log(e.detail.action); +}); +``` + +### cropmove + +- **event.detail.originalEvent**: + - Type: `Event` + - Options: `mousemove`, `touchmove` and `pointermove`. + +- **event.detail.action**: the same as "cropstart". + +This event fires when the canvas (image wrapper) or the crop box is changing. + +### cropend + +- **event.detail.originalEvent**: + - Type: `Event` + - Options: `mouseup`, `touchend`, `touchcancel`, `pointerup` and `pointercancel`. + +- **event.detail.action**: the same as "cropstart". + +This event fires when the canvas (image wrapper) or the crop box stops to change. + +### crop + +- **event.detail.x** +- **event.detail.y** +- **event.detail.width** +- **event.detail.height** +- **event.detail.rotate** +- **event.detail.scaleX** +- **event.detail.scaleY** + +> About these properties, see the [`getData`](#getdatarounded) method. + +This event fires when the canvas (image wrapper) or the crop box changed. + +### zoom + +- **event.detail.originalEvent**: + - Type: `Event` + - Options: `wheel`, `touchmove`. + +- **event.detail.oldRatio**: + - Type: `Number` + - The old (current) ratio of the canvas + +- **event.detail.ratio**: + - Type: `Number` + - The new (next) ratio of the canvas (`canvasData.width / canvasData.naturalWidth`) + +This event fires when a cropper instance starts to zoom in or zoom out its canvas (image wrapper). + +```js +image.addEventListener('zoom', function (e) { + + // Zoom in + if (e.detail.ratio > e.detail.oldRatio) { + e.preventDefault(); // Prevent zoom in + } + + // Zoom out + // ... +}); +``` + +[⬆ back to top](#table-of-contents) + +## No conflict + +If you have to use other cropper with the same namespace, just call the `Cropper.noConflict` static method to revert to it. + +```html + + + +``` + +## Browser support + +- Chrome (latest) +- Firefox (latest) +- Safari (latest) +- Opera (latest) +- Edge (latest) +- Internet Explorer 9+ + +## Contributing + +Please read through our [contributing guidelines](CONTRIBUTING.md). + +## Versioning + +Maintained under the [Semantic Versioning guidelines](http://semver.org/). + +## License + +[MIT](http://opensource.org/licenses/MIT) © [Chen Fengyuan](http://chenfengyuan.com) + +## Related projects + +- [angular-cropperjs](https://github.com/matheusdavidson/angular-cropperjs) by @matheusdavidson +- [ember-cropperjs](https://github.com/danielthall/ember-cropperjs) by @danielthall +- [iron-cropper](https://www.webcomponents.org/element/safetychanger/iron-cropper) (web component) by @safetychanger +- [react-cropper](https://github.com/roadmanfong/react-cropper) by @roadmanfong +- [vue-cropperjs](https://github.com/Agontuk/vue-cropperjs) by @Agontuk + +[⬆ back to top](#table-of-contents) diff --git a/library/cropperjs/dist/cropper.common.js b/library/cropperjs/dist/cropper.common.js new file mode 100644 index 000000000..38c62e824 --- /dev/null +++ b/library/cropperjs/dist/cropper.common.js @@ -0,0 +1,3760 @@ +/*! + * Cropper.js v1.2.2 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2018 Chen Fengyuan + * Released under the MIT license + * + * Date: 2018-01-03T13:27:18.062Z + */ + +'use strict'; + +var WINDOW = typeof window !== 'undefined' ? window : {}; +var NAMESPACE = 'cropper'; + +// Actions +var ACTION_ALL = 'all'; +var ACTION_CROP = 'crop'; +var ACTION_MOVE = 'move'; +var ACTION_ZOOM = 'zoom'; +var ACTION_EAST = 'e'; +var ACTION_WEST = 'w'; +var ACTION_SOUTH = 's'; +var ACTION_NORTH = 'n'; +var ACTION_NORTH_EAST = 'ne'; +var ACTION_NORTH_WEST = 'nw'; +var ACTION_SOUTH_EAST = 'se'; +var ACTION_SOUTH_WEST = 'sw'; + +// Classes +var CLASS_CROP = NAMESPACE + '-crop'; +var CLASS_DISABLED = NAMESPACE + '-disabled'; +var CLASS_HIDDEN = NAMESPACE + '-hidden'; +var CLASS_HIDE = NAMESPACE + '-hide'; +var CLASS_INVISIBLE = NAMESPACE + '-invisible'; +var CLASS_MODAL = NAMESPACE + '-modal'; +var CLASS_MOVE = NAMESPACE + '-move'; + +// Data keys +var DATA_ACTION = 'action'; +var DATA_PREVIEW = 'preview'; + +// Drag modes +var DRAG_MODE_CROP = 'crop'; +var DRAG_MODE_MOVE = 'move'; +var DRAG_MODE_NONE = 'none'; + +// Events +var EVENT_CROP = 'crop'; +var EVENT_CROP_END = 'cropend'; +var EVENT_CROP_MOVE = 'cropmove'; +var EVENT_CROP_START = 'cropstart'; +var EVENT_DBLCLICK = 'dblclick'; +var EVENT_ERROR = 'error'; +var EVENT_LOAD = 'load'; +var EVENT_POINTER_DOWN = WINDOW.PointerEvent ? 'pointerdown' : 'touchstart mousedown'; +var EVENT_POINTER_MOVE = WINDOW.PointerEvent ? 'pointermove' : 'touchmove mousemove'; +var EVENT_POINTER_UP = WINDOW.PointerEvent ? 'pointerup pointercancel' : 'touchend touchcancel mouseup'; +var EVENT_READY = 'ready'; +var EVENT_RESIZE = 'resize'; +var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll'; +var EVENT_ZOOM = 'zoom'; + +// RegExps +var REGEXP_ACTIONS = /^(e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/; +var REGEXP_DATA_URL = /^data:/; +var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/; +var REGEXP_TAG_NAME = /^(img|canvas)$/i; + +var DEFAULTS = { + // Define the view mode of the cropper + viewMode: 0, // 0, 1, 2, 3 + + // Define the dragging mode of the cropper + dragMode: DRAG_MODE_CROP, // 'crop', 'move' or 'none' + + // Define the aspect ratio of the crop box + aspectRatio: NaN, + + // An object with the previous cropping result data + data: null, + + // A selector for adding extra containers to preview + preview: '', + + // Re-render the cropper when resize the window + responsive: true, + + // Restore the cropped area after resize the window + restore: true, + + // Check if the current image is a cross-origin image + checkCrossOrigin: true, + + // Check the current image's Exif Orientation information + checkOrientation: true, + + // Show the black modal + modal: true, + + // Show the dashed lines for guiding + guides: true, + + // Show the center indicator for guiding + center: true, + + // Show the white modal to highlight the crop box + highlight: true, + + // Show the grid background + background: true, + + // Enable to crop the image automatically when initialize + autoCrop: true, + + // Define the percentage of automatic cropping area when initializes + autoCropArea: 0.8, + + // Enable to move the image + movable: true, + + // Enable to rotate the image + rotatable: true, + + // Enable to scale the image + scalable: true, + + // Enable to zoom the image + zoomable: true, + + // Enable to zoom the image by dragging touch + zoomOnTouch: true, + + // Enable to zoom the image by wheeling mouse + zoomOnWheel: true, + + // Define zoom ratio when zoom the image by wheeling mouse + wheelZoomRatio: 0.1, + + // Enable to move the crop box + cropBoxMovable: true, + + // Enable to resize the crop box + cropBoxResizable: true, + + // Toggle drag mode between "crop" and "move" when click twice on the cropper + toggleDragModeOnDblclick: true, + + // Size limitation + minCanvasWidth: 0, + minCanvasHeight: 0, + minCropBoxWidth: 0, + minCropBoxHeight: 0, + minContainerWidth: 200, + minContainerHeight: 100, + + // Shortcuts of events + ready: null, + cropstart: null, + cropmove: null, + cropend: null, + crop: null, + zoom: null +}; + +var TEMPLATE = '
' + '
' + '
' + '
' + '
' + '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
' + '
'; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + + + + + + + + + + + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + +var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +var toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } else { + return Array.from(arr); + } +}; + +/** + * Check if the given value is not a number. + */ +var isNaN = Number.isNaN || WINDOW.isNaN; + +/** + * Check if the given value is a number. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a number, else `false`. + */ +function isNumber(value) { + return typeof value === 'number' && !isNaN(value); +} + +/** + * Check if the given value is undefined. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is undefined, else `false`. + */ +function isUndefined(value) { + return typeof value === 'undefined'; +} + +/** + * Check if the given value is an object. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is an object, else `false`. + */ +function isObject(value) { + return (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && value !== null; +} + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +/** + * Check if the given value is a plain object. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a plain object, else `false`. + */ + +function isPlainObject(value) { + if (!isObject(value)) { + return false; + } + + try { + var _constructor = value.constructor; + var prototype = _constructor.prototype; + + + return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf'); + } catch (e) { + return false; + } +} + +/** + * Check if the given value is a function. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a function, else `false`. + */ +function isFunction(value) { + return typeof value === 'function'; +} + +/** + * Iterate the given data. + * @param {*} data - The data to iterate. + * @param {Function} callback - The process function for each element. + * @returns {*} The original data. + */ +function each(data, callback) { + if (data && isFunction(callback)) { + if (Array.isArray(data) || isNumber(data.length) /* array-like */) { + var length = data.length; + + var i = void 0; + + for (i = 0; i < length; i += 1) { + if (callback.call(data, data[i], i, data) === false) { + break; + } + } + } else if (isObject(data)) { + Object.keys(data).forEach(function (key) { + callback.call(data, data[key], key, data); + }); + } + } + + return data; +} + +/** + * Extend the given object. + * @param {*} obj - The object to be extended. + * @param {*} args - The rest objects which will be merged to the first object. + * @returns {Object} The extended object. + */ +function extend(obj) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + if (isObject(obj) && args.length > 0) { + if (Object.assign) { + return Object.assign.apply(Object, [obj].concat(args)); + } + + args.forEach(function (arg) { + if (isObject(arg)) { + Object.keys(arg).forEach(function (key) { + obj[key] = arg[key]; + }); + } + }); + } + + return obj; +} + +/** + * Takes a function and returns a new one that will always have a particular context. + * @param {Function} fn - The target function. + * @param {Object} context - The new context for the function. + * @returns {boolean} The new function. + */ +function proxy(fn, context) { + for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { + args[_key2 - 2] = arguments[_key2]; + } + + return function () { + for (var _len3 = arguments.length, args2 = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args2[_key3] = arguments[_key3]; + } + + return fn.apply(context, args.concat(args2)); + }; +} + +var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/i; + +/** + * Normalize decimal number. + * Check out {@link http://0.30000000000000004.com/ } + * @param {number} value - The value to normalize. + * @param {number} [times=100000000000] - The times for normalizing. + * @returns {number} Returns the normalized number. + */ +function normalizeDecimalNumber(value) { + var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000; + + return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value; +} + +var REGEXP_SUFFIX = /^(width|height|left|top|marginLeft|marginTop)$/; + +/** + * Apply styles to the given element. + * @param {Element} element - The target element. + * @param {Object} styles - The styles for applying. + */ +function setStyle(element, styles) { + var style = element.style; + + + each(styles, function (value, property) { + if (REGEXP_SUFFIX.test(property) && isNumber(value)) { + value += 'px'; + } + + style[property] = value; + }); +} + +/** + * Check if the given element has a special class. + * @param {Element} element - The element to check. + * @param {string} value - The class to search. + * @returns {boolean} Returns `true` if the special class was found. + */ +function hasClass(element, value) { + return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1; +} + +/** + * Add classes to the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be added. + */ +function addClass(element, value) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + addClass(elem, value); + }); + return; + } + + if (element.classList) { + element.classList.add(value); + return; + } + + var className = element.className.trim(); + + if (!className) { + element.className = value; + } else if (className.indexOf(value) < 0) { + element.className = className + ' ' + value; + } +} + +/** + * Remove classes from the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be removed. + */ +function removeClass(element, value) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + removeClass(elem, value); + }); + return; + } + + if (element.classList) { + element.classList.remove(value); + return; + } + + if (element.className.indexOf(value) >= 0) { + element.className = element.className.replace(value, ''); + } +} + +/** + * Add or remove classes from the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be toggled. + * @param {boolean} added - Add only. + */ +function toggleClass(element, value, added) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + toggleClass(elem, value, added); + }); + return; + } + + // IE10-11 doesn't support the second parameter of `classList.toggle` + if (added) { + addClass(element, value); + } else { + removeClass(element, value); + } +} + +var REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g; + +/** + * Hyphenate the given value. + * @param {string} value - The value to hyphenate. + * @returns {string} The hyphenated value. + */ +function hyphenate(value) { + return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase(); +} + +/** + * Get data from the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to get. + * @returns {string} The data value. + */ +function getData(element, name) { + if (isObject(element[name])) { + return element[name]; + } else if (element.dataset) { + return element.dataset[name]; + } + + return element.getAttribute('data-' + hyphenate(name)); +} + +/** + * Set data to the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to set. + * @param {string} data - The data value. + */ +function setData(element, name, data) { + if (isObject(data)) { + element[name] = data; + } else if (element.dataset) { + element.dataset[name] = data; + } else { + element.setAttribute('data-' + hyphenate(name), data); + } +} + +/** + * Remove data from the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to remove. + */ +function removeData(element, name) { + if (isObject(element[name])) { + try { + delete element[name]; + } catch (e) { + element[name] = null; + } + } else if (element.dataset) { + // #128 Safari not allows to delete dataset property + try { + delete element.dataset[name]; + } catch (e) { + element.dataset[name] = null; + } + } else { + element.removeAttribute('data-' + hyphenate(name)); + } +} + +var REGEXP_SPACES = /\s+/; + +/** + * Remove event listener from the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Function} listener - The event listener. + * @param {Object} options - The event options. + */ +function removeListener(element, type, listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + if (!isFunction(listener)) { + return; + } + + var types = type.trim().split(REGEXP_SPACES); + + if (types.length > 1) { + each(types, function (t) { + removeListener(element, t, listener, options); + }); + return; + } + + if (element.removeEventListener) { + element.removeEventListener(type, listener, options); + } else if (element.detachEvent) { + element.detachEvent('on' + type, listener); + } +} + +/** + * Add event listener to the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Function} listener - The event listener. + * @param {Object} options - The event options. + */ +function addListener(element, type, _listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + if (!isFunction(_listener)) { + return; + } + + var types = type.trim().split(REGEXP_SPACES); + + if (types.length > 1) { + each(types, function (t) { + addListener(element, t, _listener, options); + }); + return; + } + + if (options.once) { + var originalListener = _listener; + + _listener = function listener() { + for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + removeListener(element, type, _listener, options); + return originalListener.apply(element, args); + }; + } + + if (element.addEventListener) { + element.addEventListener(type, _listener, options); + } else if (element.attachEvent) { + element.attachEvent('on' + type, _listener); + } +} + +/** + * Dispatch event on the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Object} data - The additional event data. + * @returns {boolean} Indicate if the event is default prevented or not. + */ +function dispatchEvent(element, type, data) { + if (element.dispatchEvent) { + var event = void 0; + + // Event and CustomEvent on IE9-11 are global objects, not constructors + if (isFunction(Event) && isFunction(CustomEvent)) { + if (isUndefined(data)) { + event = new Event(type, { + bubbles: true, + cancelable: true + }); + } else { + event = new CustomEvent(type, { + detail: data, + bubbles: true, + cancelable: true + }); + } + } else if (isUndefined(data)) { + event = document.createEvent('Event'); + event.initEvent(type, true, true); + } else { + event = document.createEvent('CustomEvent'); + event.initCustomEvent(type, true, true, data); + } + + // IE9+ + return element.dispatchEvent(event); + } else if (element.fireEvent) { + // IE6-10 (native events only) + return element.fireEvent('on' + type); + } + + return true; +} + +/** + * Get the offset base on the document. + * @param {Element} element - The target element. + * @returns {Object} The offset data. + */ +function getOffset(element) { + var doc = document.documentElement; + var box = element.getBoundingClientRect(); + + return { + left: box.left + ((window.scrollX || doc && doc.scrollLeft || 0) - (doc && doc.clientLeft || 0)), + top: box.top + ((window.scrollY || doc && doc.scrollTop || 0) - (doc && doc.clientTop || 0)) + }; +} + +/** + * Empty an element. + * @param {Element} element - The element to empty. + */ +function empty(element) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } +} + +var location = WINDOW.location; + +var REGEXP_ORIGINS = /^(https?:)\/\/([^:/?#]+):?(\d*)/i; + +/** + * Check if the given URL is a cross origin URL. + * @param {string} url - The target URL. + * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`. + */ +function isCrossOriginURL(url) { + var parts = url.match(REGEXP_ORIGINS); + + return parts && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port); +} + +/** + * Add timestamp to the given URL. + * @param {string} url - The target URL. + * @returns {string} The result URL. + */ +function addTimestamp(url) { + var timestamp = 'timestamp=' + new Date().getTime(); + + return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp; +} + +/** + * Get transforms base on the given object. + * @param {Object} obj - The target object. + * @returns {string} A string contains transform values. + */ +function getTransforms(_ref) { + var rotate = _ref.rotate, + scaleX = _ref.scaleX, + scaleY = _ref.scaleY, + translateX = _ref.translateX, + translateY = _ref.translateY; + + var values = []; + + if (isNumber(translateX) && translateX !== 0) { + values.push('translateX(' + translateX + 'px)'); + } + + if (isNumber(translateY) && translateY !== 0) { + values.push('translateY(' + translateY + 'px)'); + } + + // Rotate should come first before scale to match orientation transform + if (isNumber(rotate) && rotate !== 0) { + values.push('rotate(' + rotate + 'deg)'); + } + + if (isNumber(scaleX) && scaleX !== 1) { + values.push('scaleX(' + scaleX + ')'); + } + + if (isNumber(scaleY) && scaleY !== 1) { + values.push('scaleY(' + scaleY + ')'); + } + + var transform = values.length ? values.join(' ') : 'none'; + + return { + WebkitTransform: transform, + msTransform: transform, + transform: transform + }; +} + +var navigator = WINDOW.navigator; + +var IS_SAFARI_OR_UIWEBVIEW = navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent); + +/** + * Get an image's natural sizes. + * @param {string} image - The target image. + * @param {Function} callback - The callback function. + */ +function getImageNaturalSizes(image, callback) { + // Modern browsers (except Safari) + if (image.naturalWidth && !IS_SAFARI_OR_UIWEBVIEW) { + callback(image.naturalWidth, image.naturalHeight); + return; + } + + var newImage = document.createElement('img'); + var body = document.body || document.documentElement; + + newImage.onload = function () { + callback(newImage.width, newImage.height); + + if (!IS_SAFARI_OR_UIWEBVIEW) { + body.removeChild(newImage); + } + }; + + newImage.src = image.src; + + // iOS Safari will convert the image automatically + // with its orientation once append it into DOM (#279) + if (!IS_SAFARI_OR_UIWEBVIEW) { + newImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;'; + body.appendChild(newImage); + } +} + +/** + * Get the max ratio of a group of pointers. + * @param {string} pointers - The target pointers. + * @returns {number} The result ratio. + */ +function getMaxZoomRatio(pointers) { + var pointers2 = extend({}, pointers); + var ratios = []; + + each(pointers, function (pointer, pointerId) { + delete pointers2[pointerId]; + + each(pointers2, function (pointer2) { + var x1 = Math.abs(pointer.startX - pointer2.startX); + var y1 = Math.abs(pointer.startY - pointer2.startY); + var x2 = Math.abs(pointer.endX - pointer2.endX); + var y2 = Math.abs(pointer.endY - pointer2.endY); + var z1 = Math.sqrt(x1 * x1 + y1 * y1); + var z2 = Math.sqrt(x2 * x2 + y2 * y2); + var ratio = (z2 - z1) / z1; + + ratios.push(ratio); + }); + }); + + ratios.sort(function (a, b) { + return Math.abs(a) < Math.abs(b); + }); + + return ratios[0]; +} + +/** + * Get a pointer from an event object. + * @param {Object} event - The target event object. + * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not. + * @returns {Object} The result pointer contains start and/or end point coordinates. + */ +function getPointer(_ref2, endOnly) { + var pageX = _ref2.pageX, + pageY = _ref2.pageY; + + var end = { + endX: pageX, + endY: pageY + }; + + if (endOnly) { + return end; + } + + return extend({ + startX: pageX, + startY: pageY + }, end); +} + +/** + * Get the center point coordinate of a group of pointers. + * @param {Object} pointers - The target pointers. + * @returns {Object} The center point coordinate. + */ +function getPointersCenter(pointers) { + var pageX = 0; + var pageY = 0; + var count = 0; + + each(pointers, function (_ref3) { + var startX = _ref3.startX, + startY = _ref3.startY; + + pageX += startX; + pageY += startY; + count += 1; + }); + + pageX /= count; + pageY /= count; + + return { + pageX: pageX, + pageY: pageY + }; +} + +/** + * Check if the given value is a finite number. + */ +var isFinite = Number.isFinite || WINDOW.isFinite; + +/** + * Get the max sizes in a rectangle under the given aspect ratio. + * @param {Object} data - The original sizes. + * @returns {Object} The result sizes. + */ +function getContainSizes(_ref4) { + var aspectRatio = _ref4.aspectRatio, + height = _ref4.height, + width = _ref4.width; + + var isValidNumber = function isValidNumber(value) { + return isFinite(value) && value > 0; + }; + + if (isValidNumber(width) && isValidNumber(height)) { + if (height * aspectRatio > width) { + height = width / aspectRatio; + } else { + width = height * aspectRatio; + } + } else if (isValidNumber(width)) { + height = width / aspectRatio; + } else if (isValidNumber(height)) { + width = height * aspectRatio; + } + + return { + width: width, + height: height + }; +} + +/** + * Get the new sizes of a rectangle after rotated. + * @param {Object} data - The original sizes. + * @returns {Object} The result sizes. + */ +function getRotatedSizes(_ref5) { + var width = _ref5.width, + height = _ref5.height, + degree = _ref5.degree; + + degree = Math.abs(degree) % 180; + + if (degree === 90) { + return { + width: height, + height: width + }; + } + + var arc = degree % 90 * Math.PI / 180; + var sinArc = Math.sin(arc); + var cosArc = Math.cos(arc); + var newWidth = width * cosArc + height * sinArc; + var newHeight = width * sinArc + height * cosArc; + + return degree > 90 ? { + width: newHeight, + height: newWidth + } : { + width: newWidth, + height: newHeight + }; +} + +/** + * Get a canvas which drew the given image. + * @param {HTMLImageElement} image - The image for drawing. + * @param {Object} imageData - The image data. + * @param {Object} canvasData - The canvas data. + * @param {Object} options - The options. + * @returns {HTMLCanvasElement} The result canvas. + */ +function getSourceCanvas(image, _ref6, _ref7, _ref8) { + var imageNaturalWidth = _ref6.naturalWidth, + imageNaturalHeight = _ref6.naturalHeight, + _ref6$rotate = _ref6.rotate, + rotate = _ref6$rotate === undefined ? 0 : _ref6$rotate, + _ref6$scaleX = _ref6.scaleX, + scaleX = _ref6$scaleX === undefined ? 1 : _ref6$scaleX, + _ref6$scaleY = _ref6.scaleY, + scaleY = _ref6$scaleY === undefined ? 1 : _ref6$scaleY; + var aspectRatio = _ref7.aspectRatio, + naturalWidth = _ref7.naturalWidth, + naturalHeight = _ref7.naturalHeight; + var _ref8$fillColor = _ref8.fillColor, + fillColor = _ref8$fillColor === undefined ? 'transparent' : _ref8$fillColor, + _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled, + imageSmoothingEnabled = _ref8$imageSmoothingE === undefined ? true : _ref8$imageSmoothingE, + _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality, + imageSmoothingQuality = _ref8$imageSmoothingQ === undefined ? 'low' : _ref8$imageSmoothingQ, + _ref8$maxWidth = _ref8.maxWidth, + maxWidth = _ref8$maxWidth === undefined ? Infinity : _ref8$maxWidth, + _ref8$maxHeight = _ref8.maxHeight, + maxHeight = _ref8$maxHeight === undefined ? Infinity : _ref8$maxHeight, + _ref8$minWidth = _ref8.minWidth, + minWidth = _ref8$minWidth === undefined ? 0 : _ref8$minWidth, + _ref8$minHeight = _ref8.minHeight, + minHeight = _ref8$minHeight === undefined ? 0 : _ref8$minHeight; + + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + var maxSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: maxWidth, + height: maxHeight + }); + var minSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: minWidth, + height: minHeight + }); + var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth)); + var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight)); + var params = [-imageNaturalWidth / 2, -imageNaturalHeight / 2, imageNaturalWidth, imageNaturalHeight]; + + canvas.width = normalizeDecimalNumber(width); + canvas.height = normalizeDecimalNumber(height); + context.fillStyle = fillColor; + context.fillRect(0, 0, width, height); + context.save(); + context.translate(width / 2, height / 2); + context.rotate(rotate * Math.PI / 180); + context.scale(scaleX, scaleY); + context.imageSmoothingEnabled = imageSmoothingEnabled; + context.imageSmoothingQuality = imageSmoothingQuality; + context.drawImage.apply(context, [image].concat(toConsumableArray(params.map(function (param) { + return Math.floor(normalizeDecimalNumber(param)); + })))); + context.restore(); + return canvas; +} + +var fromCharCode = String.fromCharCode; + +/** + * Get string from char code in data view. + * @param {DataView} dataView - The data view for read. + * @param {number} start - The start index. + * @param {number} length - The read length. + * @returns {string} The read result. + */ + +function getStringFromCharCode(dataView, start, length) { + var str = ''; + var i = void 0; + + length += start; + + for (i = start; i < length; i += 1) { + str += fromCharCode(dataView.getUint8(i)); + } + + return str; +} + +var REGEXP_DATA_URL_HEAD = /^data:.*,/; + +/** + * Transform Data URL to array buffer. + * @param {string} dataURL - The Data URL to transform. + * @returns {ArrayBuffer} The result array buffer. + */ +function dataURLToArrayBuffer(dataURL) { + var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, ''); + var binary = atob(base64); + var arrayBuffer = new ArrayBuffer(binary.length); + var uint8 = new Uint8Array(arrayBuffer); + + each(uint8, function (value, i) { + uint8[i] = binary.charCodeAt(i); + }); + + return arrayBuffer; +} + +/** + * Transform array buffer to Data URL. + * @param {ArrayBuffer} arrayBuffer - The array buffer to transform. + * @param {string} mimeType - The mime type of the Data URL. + * @returns {string} The result Data URL. + */ +function arrayBufferToDataURL(arrayBuffer, mimeType) { + var uint8 = new Uint8Array(arrayBuffer); + var data = ''; + + // TypedArray.prototype.forEach is not supported in some browsers. + each(uint8, function (value) { + data += fromCharCode(value); + }); + + return 'data:' + mimeType + ';base64,' + btoa(data); +} + +/** + * Get orientation value from given array buffer. + * @param {ArrayBuffer} arrayBuffer - The array buffer to read. + * @returns {number} The read orientation value. + */ +function getOrientation(arrayBuffer) { + var dataView = new DataView(arrayBuffer); + var orientation = void 0; + var littleEndian = void 0; + var app1Start = void 0; + var ifdStart = void 0; + + // Only handle JPEG image (start by 0xFFD8) + if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) { + var length = dataView.byteLength; + var offset = 2; + + while (offset < length) { + if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) { + app1Start = offset; + break; + } + + offset += 1; + } + } + + if (app1Start) { + var exifIDCode = app1Start + 4; + var tiffOffset = app1Start + 10; + + if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') { + var endianness = dataView.getUint16(tiffOffset); + + littleEndian = endianness === 0x4949; + + if (littleEndian || endianness === 0x4D4D /* bigEndian */) { + if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) { + var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian); + + if (firstIFDOffset >= 0x00000008) { + ifdStart = tiffOffset + firstIFDOffset; + } + } + } + } + } + + if (ifdStart) { + var _length = dataView.getUint16(ifdStart, littleEndian); + var _offset = void 0; + var i = void 0; + + for (i = 0; i < _length; i += 1) { + _offset = ifdStart + i * 12 + 2; + + if (dataView.getUint16(_offset, littleEndian) === 0x0112 /* Orientation */) { + // 8 is the offset of the current tag's value + _offset += 8; + + // Get the original orientation value + orientation = dataView.getUint16(_offset, littleEndian); + + // Override the orientation with its default value + dataView.setUint16(_offset, 1, littleEndian); + break; + } + } + } + + return orientation; +} + +/** + * Parse Exif Orientation value. + * @param {number} orientation - The orientation to parse. + * @returns {Object} The parsed result. + */ +function parseOrientation(orientation) { + var rotate = 0; + var scaleX = 1; + var scaleY = 1; + + switch (orientation) { + // Flip horizontal + case 2: + scaleX = -1; + break; + + // Rotate left 180° + case 3: + rotate = -180; + break; + + // Flip vertical + case 4: + scaleY = -1; + break; + + // Flip vertical and rotate right 90° + case 5: + rotate = 90; + scaleY = -1; + break; + + // Rotate right 90° + case 6: + rotate = 90; + break; + + // Flip horizontal and rotate right 90° + case 7: + rotate = 90; + scaleX = -1; + break; + + // Rotate left 90° + case 8: + rotate = -90; + break; + + default: + } + + return { + rotate: rotate, + scaleX: scaleX, + scaleY: scaleY + }; +} + +var render = { + render: function render() { + this.initContainer(); + this.initCanvas(); + this.initCropBox(); + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + }, + initContainer: function initContainer() { + var element = this.element, + options = this.options, + container = this.container, + cropper = this.cropper; + + + addClass(cropper, CLASS_HIDDEN); + removeClass(element, CLASS_HIDDEN); + + var containerData = { + width: Math.max(container.offsetWidth, Number(options.minContainerWidth) || 200), + height: Math.max(container.offsetHeight, Number(options.minContainerHeight) || 100) + }; + + this.containerData = containerData; + + setStyle(cropper, { + width: containerData.width, + height: containerData.height + }); + + addClass(element, CLASS_HIDDEN); + removeClass(cropper, CLASS_HIDDEN); + }, + + + // Canvas (image wrapper) + initCanvas: function initCanvas() { + var containerData = this.containerData, + imageData = this.imageData; + var viewMode = this.options.viewMode; + + var rotated = Math.abs(imageData.rotate) % 180 === 90; + var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth; + var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight; + var aspectRatio = naturalWidth / naturalHeight; + var canvasWidth = containerData.width; + var canvasHeight = containerData.height; + + if (containerData.height * aspectRatio > containerData.width) { + if (viewMode === 3) { + canvasWidth = containerData.height * aspectRatio; + } else { + canvasHeight = containerData.width / aspectRatio; + } + } else if (viewMode === 3) { + canvasHeight = containerData.width / aspectRatio; + } else { + canvasWidth = containerData.height * aspectRatio; + } + + var canvasData = { + aspectRatio: aspectRatio, + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + width: canvasWidth, + height: canvasHeight + }; + + canvasData.left = (containerData.width - canvasWidth) / 2; + canvasData.top = (containerData.height - canvasHeight) / 2; + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; + + this.canvasData = canvasData; + this.limited = viewMode === 1 || viewMode === 2; + this.limitCanvas(true, true); + this.initialImageData = extend({}, imageData); + this.initialCanvasData = extend({}, canvasData); + }, + limitCanvas: function limitCanvas(sizeLimited, positionLimited) { + var options = this.options, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + var viewMode = options.viewMode; + var aspectRatio = canvasData.aspectRatio; + + var cropped = this.cropped && cropBoxData; + + if (sizeLimited) { + var minCanvasWidth = Number(options.minCanvasWidth) || 0; + var minCanvasHeight = Number(options.minCanvasHeight) || 0; + + if (viewMode > 1) { + minCanvasWidth = Math.max(minCanvasWidth, containerData.width); + minCanvasHeight = Math.max(minCanvasHeight, containerData.height); + + if (viewMode === 3) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } else if (viewMode > 0) { + if (minCanvasWidth) { + minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0); + } else if (minCanvasHeight) { + minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0); + } else if (cropped) { + minCanvasWidth = cropBoxData.width; + minCanvasHeight = cropBoxData.height; + + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } + + var _getContainSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: minCanvasWidth, + height: minCanvasHeight + }); + + minCanvasWidth = _getContainSizes.width; + minCanvasHeight = _getContainSizes.height; + + + canvasData.minWidth = minCanvasWidth; + canvasData.minHeight = minCanvasHeight; + canvasData.maxWidth = Infinity; + canvasData.maxHeight = Infinity; + } + + if (positionLimited) { + if (viewMode) { + var newCanvasLeft = containerData.width - canvasData.width; + var newCanvasTop = containerData.height - canvasData.height; + + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxLeft = Math.max(0, newCanvasLeft); + canvasData.maxTop = Math.max(0, newCanvasTop); + + if (cropped && this.limited) { + canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width)); + canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height)); + canvasData.maxLeft = cropBoxData.left; + canvasData.maxTop = cropBoxData.top; + + if (viewMode === 2) { + if (canvasData.width >= containerData.width) { + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.maxLeft = Math.max(0, newCanvasLeft); + } + + if (canvasData.height >= containerData.height) { + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxTop = Math.max(0, newCanvasTop); + } + } + } + } else { + canvasData.minLeft = -canvasData.width; + canvasData.minTop = -canvasData.height; + canvasData.maxLeft = containerData.width; + canvasData.maxTop = containerData.height; + } + } + }, + renderCanvas: function renderCanvas(changed, transformed) { + var canvasData = this.canvasData, + imageData = this.imageData; + + + if (transformed) { + var _getRotatedSizes = getRotatedSizes({ + width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1), + height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1), + degree: imageData.rotate || 0 + }), + naturalWidth = _getRotatedSizes.width, + naturalHeight = _getRotatedSizes.height; + + var width = canvasData.width * (naturalWidth / canvasData.naturalWidth); + var height = canvasData.height * (naturalHeight / canvasData.naturalHeight); + + canvasData.left -= (width - canvasData.width) / 2; + canvasData.top -= (height - canvasData.height) / 2; + canvasData.width = width; + canvasData.height = height; + canvasData.aspectRatio = naturalWidth / naturalHeight; + canvasData.naturalWidth = naturalWidth; + canvasData.naturalHeight = naturalHeight; + this.limitCanvas(true, false); + } + + if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) { + canvasData.left = canvasData.oldLeft; + } + + if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) { + canvasData.top = canvasData.oldTop; + } + + canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth); + canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight); + + this.limitCanvas(false, true); + + canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft); + canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop); + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; + + setStyle(this.canvas, extend({ + width: canvasData.width, + height: canvasData.height + }, getTransforms({ + translateX: canvasData.left, + translateY: canvasData.top + }))); + + this.renderImage(changed); + + if (this.cropped && this.limited) { + this.limitCropBox(true, true); + } + }, + renderImage: function renderImage(changed) { + var canvasData = this.canvasData, + imageData = this.imageData; + + var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth); + var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight); + + extend(imageData, { + width: width, + height: height, + left: (canvasData.width - width) / 2, + top: (canvasData.height - height) / 2 + }); + setStyle(this.image, extend({ + width: imageData.width, + height: imageData.height + }, getTransforms(extend({ + translateX: imageData.left, + translateY: imageData.top + }, imageData)))); + + if (changed) { + this.output(); + } + }, + initCropBox: function initCropBox() { + var options = this.options, + canvasData = this.canvasData; + var aspectRatio = options.aspectRatio; + + var autoCropArea = Number(options.autoCropArea) || 0.8; + var cropBoxData = { + width: canvasData.width, + height: canvasData.height + }; + + if (aspectRatio) { + if (canvasData.height * aspectRatio > canvasData.width) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + this.cropBoxData = cropBoxData; + this.limitCropBox(true, true); + + // Initialize auto crop area + cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth); + cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); + + // The width/height of auto crop area must large than "minWidth/Height" + cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea); + cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea); + cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2; + cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2; + cropBoxData.oldLeft = cropBoxData.left; + cropBoxData.oldTop = cropBoxData.top; + + this.initialCropBoxData = extend({}, cropBoxData); + }, + limitCropBox: function limitCropBox(sizeLimited, positionLimited) { + var options = this.options, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData, + limited = this.limited; + var aspectRatio = options.aspectRatio; + + + if (sizeLimited) { + var minCropBoxWidth = Number(options.minCropBoxWidth) || 0; + var minCropBoxHeight = Number(options.minCropBoxHeight) || 0; + var maxCropBoxWidth = Math.min(containerData.width, limited ? canvasData.width : containerData.width); + var maxCropBoxHeight = Math.min(containerData.height, limited ? canvasData.height : containerData.height); + + // The min/maxCropBoxWidth/Height must be less than container's width/height + minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width); + minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height); + + if (aspectRatio) { + if (minCropBoxWidth && minCropBoxHeight) { + if (minCropBoxHeight * aspectRatio > minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + } else if (minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else if (minCropBoxHeight) { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + + if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) { + maxCropBoxHeight = maxCropBoxWidth / aspectRatio; + } else { + maxCropBoxWidth = maxCropBoxHeight * aspectRatio; + } + } + + // The minWidth/Height must be less than maxWidth/Height + cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); + cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); + cropBoxData.maxWidth = maxCropBoxWidth; + cropBoxData.maxHeight = maxCropBoxHeight; + } + + if (positionLimited) { + if (limited) { + cropBoxData.minLeft = Math.max(0, canvasData.left); + cropBoxData.minTop = Math.max(0, canvasData.top); + cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width; + cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height; + } else { + cropBoxData.minLeft = 0; + cropBoxData.minTop = 0; + cropBoxData.maxLeft = containerData.width - cropBoxData.width; + cropBoxData.maxTop = containerData.height - cropBoxData.height; + } + } + }, + renderCropBox: function renderCropBox() { + var options = this.options, + containerData = this.containerData, + cropBoxData = this.cropBoxData; + + + if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) { + cropBoxData.left = cropBoxData.oldLeft; + } + + if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) { + cropBoxData.top = cropBoxData.oldTop; + } + + cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth); + cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); + + this.limitCropBox(false, true); + + cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft); + cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop); + cropBoxData.oldLeft = cropBoxData.left; + cropBoxData.oldTop = cropBoxData.top; + + if (options.movable && options.cropBoxMovable) { + // Turn to move the canvas when the crop box is equal to the container + setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL); + } + + setStyle(this.cropBox, extend({ + width: cropBoxData.width, + height: cropBoxData.height + }, getTransforms({ + translateX: cropBoxData.left, + translateY: cropBoxData.top + }))); + + if (this.cropped && this.limited) { + this.limitCanvas(true, true); + } + + if (!this.disabled) { + this.output(); + } + }, + output: function output() { + this.preview(); + + if (this.complete) { + dispatchEvent(this.element, EVENT_CROP, this.getData()); + } + } +}; + +var preview = { + initPreview: function initPreview() { + var crossOrigin = this.crossOrigin; + var preview = this.options.preview; + + var url = crossOrigin ? this.crossOriginUrl : this.url; + var image = document.createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = url; + this.viewBox.appendChild(image); + this.image2 = image; + + if (!preview) { + return; + } + + var previews = preview.querySelector ? [preview] : document.querySelectorAll(preview); + + this.previews = previews; + + each(previews, function (element) { + var img = document.createElement('img'); + + // Save the original size for recover + setData(element, DATA_PREVIEW, { + width: element.offsetWidth, + height: element.offsetHeight, + html: element.innerHTML + }); + + if (crossOrigin) { + img.crossOrigin = crossOrigin; + } + + img.src = url; + + /** + * Override img element styles + * Add `display:block` to avoid margin top issue + * Add `height:auto` to override `height` attribute on IE8 + * (Occur only when margin-top <= -height) + */ + img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"'; + + empty(element); + element.appendChild(img); + }); + }, + resetPreview: function resetPreview() { + each(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); + + setStyle(element, { + width: data.width, + height: data.height + }); + + element.innerHTML = data.html; + removeData(element, DATA_PREVIEW); + }); + }, + preview: function preview() { + var imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + var cropBoxWidth = cropBoxData.width, + cropBoxHeight = cropBoxData.height; + var width = imageData.width, + height = imageData.height; + + var left = cropBoxData.left - canvasData.left - imageData.left; + var top = cropBoxData.top - canvasData.top - imageData.top; + + if (!this.cropped || this.disabled) { + return; + } + + setStyle(this.image2, extend({ + width: width, + height: height + }, getTransforms(extend({ + translateX: -left, + translateY: -top + }, imageData)))); + + each(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); + var originalWidth = data.width; + var originalHeight = data.height; + var newWidth = originalWidth; + var newHeight = originalHeight; + var ratio = 1; + + if (cropBoxWidth) { + ratio = originalWidth / cropBoxWidth; + newHeight = cropBoxHeight * ratio; + } + + if (cropBoxHeight && newHeight > originalHeight) { + ratio = originalHeight / cropBoxHeight; + newWidth = cropBoxWidth * ratio; + newHeight = originalHeight; + } + + setStyle(element, { + width: newWidth, + height: newHeight + }); + + setStyle(element.getElementsByTagName('img')[0], extend({ + width: width * ratio, + height: height * ratio + }, getTransforms(extend({ + translateX: -left * ratio, + translateY: -top * ratio + }, imageData)))); + }); + } +}; + +var events = { + bind: function bind() { + var element = this.element, + options = this.options, + cropper = this.cropper; + + + if (isFunction(options.cropstart)) { + addListener(element, EVENT_CROP_START, options.cropstart); + } + + if (isFunction(options.cropmove)) { + addListener(element, EVENT_CROP_MOVE, options.cropmove); + } + + if (isFunction(options.cropend)) { + addListener(element, EVENT_CROP_END, options.cropend); + } + + if (isFunction(options.crop)) { + addListener(element, EVENT_CROP, options.crop); + } + + if (isFunction(options.zoom)) { + addListener(element, EVENT_ZOOM, options.zoom); + } + + addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = proxy(this.cropStart, this)); + + if (options.zoomable && options.zoomOnWheel) { + addListener(cropper, EVENT_WHEEL, this.onWheel = proxy(this.wheel, this)); + } + + if (options.toggleDragModeOnDblclick) { + addListener(cropper, EVENT_DBLCLICK, this.onDblclick = proxy(this.dblclick, this)); + } + + addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = proxy(this.cropMove, this)); + addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = proxy(this.cropEnd, this)); + + if (options.responsive) { + addListener(window, EVENT_RESIZE, this.onResize = proxy(this.resize, this)); + } + }, + unbind: function unbind() { + var element = this.element, + options = this.options, + cropper = this.cropper; + + + if (isFunction(options.cropstart)) { + removeListener(element, EVENT_CROP_START, options.cropstart); + } + + if (isFunction(options.cropmove)) { + removeListener(element, EVENT_CROP_MOVE, options.cropmove); + } + + if (isFunction(options.cropend)) { + removeListener(element, EVENT_CROP_END, options.cropend); + } + + if (isFunction(options.crop)) { + removeListener(element, EVENT_CROP, options.crop); + } + + if (isFunction(options.zoom)) { + removeListener(element, EVENT_ZOOM, options.zoom); + } + + removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart); + + if (options.zoomable && options.zoomOnWheel) { + removeListener(cropper, EVENT_WHEEL, this.onWheel); + } + + if (options.toggleDragModeOnDblclick) { + removeListener(cropper, EVENT_DBLCLICK, this.onDblclick); + } + + removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove); + removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd); + + if (options.responsive) { + removeListener(window, EVENT_RESIZE, this.onResize); + } + } +}; + +var handlers = { + resize: function resize() { + var options = this.options, + container = this.container, + containerData = this.containerData; + + var minContainerWidth = Number(options.minContainerWidth) || 200; + var minContainerHeight = Number(options.minContainerHeight) || 100; + + if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) { + return; + } + + var ratio = container.offsetWidth / containerData.width; + + // Resize when width changed or height changed + if (ratio !== 1 || container.offsetHeight !== containerData.height) { + var canvasData = void 0; + var cropBoxData = void 0; + + if (options.restore) { + canvasData = this.getCanvasData(); + cropBoxData = this.getCropBoxData(); + } + + this.render(); + + if (options.restore) { + this.setCanvasData(each(canvasData, function (n, i) { + canvasData[i] = n * ratio; + })); + this.setCropBoxData(each(cropBoxData, function (n, i) { + cropBoxData[i] = n * ratio; + })); + } + } + }, + dblclick: function dblclick() { + if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) { + return; + } + + this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); + }, + wheel: function wheel(e) { + var _this = this; + + var ratio = Number(this.options.wheelZoomRatio) || 0.1; + var delta = 1; + + if (this.disabled) { + return; + } + + e.preventDefault(); + + // Limit wheel speed to prevent zoom too fast (#21) + if (this.wheeling) { + return; + } + + this.wheeling = true; + + setTimeout(function () { + _this.wheeling = false; + }, 50); + + if (e.deltaY) { + delta = e.deltaY > 0 ? 1 : -1; + } else if (e.wheelDelta) { + delta = -e.wheelDelta / 120; + } else if (e.detail) { + delta = e.detail > 0 ? 1 : -1; + } + + this.zoom(-delta * ratio, e); + }, + cropStart: function cropStart(e) { + if (this.disabled) { + return; + } + + var options = this.options, + pointers = this.pointers; + + var action = void 0; + + if (e.changedTouches) { + // Handle touch event + each(e.changedTouches, function (touch) { + pointers[touch.identifier] = getPointer(touch); + }); + } else { + // Handle mouse event and pointer event + pointers[e.pointerId || 0] = getPointer(e); + } + + if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { + action = ACTION_ZOOM; + } else { + action = getData(e.target, DATA_ACTION); + } + + if (!REGEXP_ACTIONS.test(action)) { + return; + } + + if (dispatchEvent(this.element, EVENT_CROP_START, { + originalEvent: e, + action: action + }) === false) { + return; + } + + e.preventDefault(); + + this.action = action; + this.cropping = false; + + if (action === ACTION_CROP) { + this.cropping = true; + addClass(this.dragBox, CLASS_MODAL); + } + }, + cropMove: function cropMove(e) { + var action = this.action; + + + if (this.disabled || !action) { + return; + } + + var pointers = this.pointers; + + + e.preventDefault(); + + if (dispatchEvent(this.element, EVENT_CROP_MOVE, { + originalEvent: e, + action: action + }) === false) { + return; + } + + if (e.changedTouches) { + each(e.changedTouches, function (touch) { + extend(pointers[touch.identifier], getPointer(touch, true)); + }); + } else { + extend(pointers[e.pointerId || 0], getPointer(e, true)); + } + + this.change(e); + }, + cropEnd: function cropEnd(e) { + if (this.disabled) { + return; + } + + var action = this.action, + pointers = this.pointers; + + + if (e.changedTouches) { + each(e.changedTouches, function (touch) { + delete pointers[touch.identifier]; + }); + } else { + delete pointers[e.pointerId || 0]; + } + + if (!action) { + return; + } + + e.preventDefault(); + + if (!Object.keys(pointers).length) { + this.action = ''; + } + + if (this.cropping) { + this.cropping = false; + toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal); + } + + dispatchEvent(this.element, EVENT_CROP_END, { + originalEvent: e, + action: action + }); + } +}; + +var change = { + change: function change(e) { + var options = this.options, + canvasData = this.canvasData, + containerData = this.containerData, + cropBoxData = this.cropBoxData, + pointers = this.pointers; + var action = this.action; + var aspectRatio = options.aspectRatio; + var left = cropBoxData.left, + top = cropBoxData.top, + width = cropBoxData.width, + height = cropBoxData.height; + + var right = left + width; + var bottom = top + height; + var minLeft = 0; + var minTop = 0; + var maxWidth = containerData.width; + var maxHeight = containerData.height; + var renderable = true; + var offset = void 0; + + // Locking aspect ratio in "free mode" by holding shift key + if (!aspectRatio && e.shiftKey) { + aspectRatio = width && height ? width / height : 1; + } + + if (this.limited) { + minLeft = cropBoxData.minLeft; + minTop = cropBoxData.minTop; + + maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width); + maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height); + } + + var pointer = pointers[Object.keys(pointers)[0]]; + var range = { + x: pointer.endX - pointer.startX, + y: pointer.endY - pointer.startY + }; + var check = function check(side) { + switch (side) { + case ACTION_EAST: + if (right + range.x > maxWidth) { + range.x = maxWidth - right; + } + + break; + + case ACTION_WEST: + if (left + range.x < minLeft) { + range.x = minLeft - left; + } + + break; + + case ACTION_NORTH: + if (top + range.y < minTop) { + range.y = minTop - top; + } + + break; + + case ACTION_SOUTH: + if (bottom + range.y > maxHeight) { + range.y = maxHeight - bottom; + } + + break; + + default: + } + }; + + switch (action) { + // Move crop box + case ACTION_ALL: + left += range.x; + top += range.y; + break; + + // Resize crop box + case ACTION_EAST: + if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) { + renderable = false; + break; + } + + check(ACTION_EAST); + width += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top -= range.x / aspectRatio / 2; + } + + if (width < 0) { + action = ACTION_WEST; + width = 0; + } + + break; + + case ACTION_NORTH: + if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left += range.y * aspectRatio / 2; + } + + if (height < 0) { + action = ACTION_SOUTH; + height = 0; + } + + break; + + case ACTION_WEST: + if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) { + renderable = false; + break; + } + + check(ACTION_WEST); + width -= range.x; + left += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top += range.x / aspectRatio / 2; + } + + if (width < 0) { + action = ACTION_EAST; + width = 0; + } + + break; + + case ACTION_SOUTH: + if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) { + renderable = false; + break; + } + + check(ACTION_SOUTH); + height += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left -= range.y * aspectRatio / 2; + } + + if (height < 0) { + action = ACTION_NORTH; + height = 0; + } + + break; + + case ACTION_NORTH_EAST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || right >= maxWidth)) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + width = height * aspectRatio; + } else { + check(ACTION_NORTH); + check(ACTION_EAST); + + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + } + + break; + + case ACTION_NORTH_WEST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || left <= minLeft)) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + width = height * aspectRatio; + left += range.y * aspectRatio; + } else { + check(ACTION_NORTH); + check(ACTION_WEST); + + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_WEST: + if (aspectRatio) { + if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) { + renderable = false; + break; + } + + check(ACTION_WEST); + width -= range.x; + left += range.x; + height = width / aspectRatio; + } else { + check(ACTION_SOUTH); + check(ACTION_WEST); + + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_EAST: + if (aspectRatio) { + if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) { + renderable = false; + break; + } + + check(ACTION_EAST); + width += range.x; + height = width / aspectRatio; + } else { + check(ACTION_SOUTH); + check(ACTION_EAST); + + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + } + + break; + + // Move canvas + case ACTION_MOVE: + this.move(range.x, range.y); + renderable = false; + break; + + // Zoom canvas + case ACTION_ZOOM: + this.zoom(getMaxZoomRatio(pointers), e); + renderable = false; + break; + + // Create crop box + case ACTION_CROP: + if (!range.x || !range.y) { + renderable = false; + break; + } + + offset = getOffset(this.cropper); + left = pointer.startX - offset.left; + top = pointer.startY - offset.top; + width = cropBoxData.minWidth; + height = cropBoxData.minHeight; + + if (range.x > 0) { + action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST; + } else if (range.x < 0) { + left -= width; + action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST; + } + + if (range.y < 0) { + top -= height; + } + + // Show the crop box if is hidden + if (!this.cropped) { + removeClass(this.cropBox, CLASS_HIDDEN); + this.cropped = true; + + if (this.limited) { + this.limitCropBox(true, true); + } + } + + break; + + default: + } + + if (renderable) { + cropBoxData.width = width; + cropBoxData.height = height; + cropBoxData.left = left; + cropBoxData.top = top; + this.action = action; + this.renderCropBox(); + } + + // Override + each(pointers, function (p) { + p.startX = p.endX; + p.startY = p.endY; + }); + } +}; + +var methods = { + // Show the crop box manually + crop: function crop() { + if (this.ready && !this.disabled) { + if (!this.cropped) { + this.cropped = true; + this.limitCropBox(true, true); + + if (this.options.modal) { + addClass(this.dragBox, CLASS_MODAL); + } + + removeClass(this.cropBox, CLASS_HIDDEN); + } + + this.setCropBoxData(this.initialCropBoxData); + } + + return this; + }, + + + // Reset the image and crop box to their initial states + reset: function reset() { + if (this.ready && !this.disabled) { + this.imageData = extend({}, this.initialImageData); + this.canvasData = extend({}, this.initialCanvasData); + this.cropBoxData = extend({}, this.initialCropBoxData); + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + } + + return this; + }, + + + // Clear the crop box + clear: function clear() { + if (this.cropped && !this.disabled) { + extend(this.cropBoxData, { + left: 0, + top: 0, + width: 0, + height: 0 + }); + + this.cropped = false; + this.renderCropBox(); + this.limitCanvas(true, true); + + // Render canvas after crop box rendered + this.renderCanvas(); + removeClass(this.dragBox, CLASS_MODAL); + addClass(this.cropBox, CLASS_HIDDEN); + } + + return this; + }, + + + /** + * Replace the image's src and rebuild the cropper + * @param {string} url - The new URL. + * @param {boolean} [onlyColorChanged] - Indicate if the new image only changed color. + * @returns {Object} this + */ + replace: function replace(url) { + var onlyColorChanged = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (!this.disabled && url) { + if (this.isImg) { + this.element.src = url; + } + + if (onlyColorChanged) { + this.url = url; + this.image.src = url; + + if (this.ready) { + this.image2.src = url; + + each(this.previews, function (element) { + element.getElementsByTagName('img')[0].src = url; + }); + } + } else { + if (this.isImg) { + this.replaced = true; + } + + // Clear previous data + this.options.data = null; + this.load(url); + } + } + + return this; + }, + + + // Enable (unfreeze) the cropper + enable: function enable() { + if (this.ready) { + this.disabled = false; + removeClass(this.cropper, CLASS_DISABLED); + } + + return this; + }, + + + // Disable (freeze) the cropper + disable: function disable() { + if (this.ready) { + this.disabled = true; + addClass(this.cropper, CLASS_DISABLED); + } + + return this; + }, + + + // Destroy the cropper and remove the instance from the image + destroy: function destroy() { + var element = this.element, + image = this.image; + + + if (this.loaded) { + if (this.isImg && this.replaced) { + element.src = this.originalUrl; + } + + this.unbuild(); + removeClass(element, CLASS_HIDDEN); + } else if (this.isImg) { + removeListener(element, EVENT_LOAD, this.onStart); + } else if (image) { + image.parentNode.removeChild(image); + } + + removeData(element, NAMESPACE); + + return this; + }, + + + /** + * Move the canvas with relative offsets + * @param {number} offsetX - The relative offset distance on the x-axis. + * @param {number} offsetY - The relative offset distance on the y-axis. + * @returns {Object} this + */ + move: function move(offsetX, offsetY) { + var _canvasData = this.canvasData, + left = _canvasData.left, + top = _canvasData.top; + + + return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); + }, + + + /** + * Move the canvas to an absolute point + * @param {number} x - The x-axis coordinate. + * @param {number} [y=x] - The y-axis coordinate. + * @returns {Object} this + */ + moveTo: function moveTo(x) { + var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + var canvasData = this.canvasData; + + var changed = false; + + x = Number(x); + y = Number(y); + + if (this.ready && !this.disabled && this.options.movable) { + if (isNumber(x)) { + canvasData.left = x; + changed = true; + } + + if (isNumber(y)) { + canvasData.top = y; + changed = true; + } + + if (changed) { + this.renderCanvas(true); + } + } + + return this; + }, + + + /** + * Zoom the canvas with a relative ratio + * @param {number} ratio - The target ratio. + * @param {Event} _originalEvent - The original event if any. + * @returns {Object} this + */ + zoom: function zoom(ratio, _originalEvent) { + var canvasData = this.canvasData; + + + ratio = Number(ratio); + + if (ratio < 0) { + ratio = 1 / (1 - ratio); + } else { + ratio = 1 + ratio; + } + + return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent); + }, + + + /** + * Zoom the canvas to an absolute ratio + * @param {number} ratio - The target ratio. + * @param {Object} pivot - The zoom pivot point coordinate. + * @param {Event} _originalEvent - The original event if any. + * @returns {Object} this + */ + zoomTo: function zoomTo(ratio, pivot, _originalEvent) { + var options = this.options, + canvasData = this.canvasData; + var width = canvasData.width, + height = canvasData.height, + naturalWidth = canvasData.naturalWidth, + naturalHeight = canvasData.naturalHeight; + + + ratio = Number(ratio); + + if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) { + var newWidth = naturalWidth * ratio; + var newHeight = naturalHeight * ratio; + + if (dispatchEvent(this.element, EVENT_ZOOM, { + originalEvent: _originalEvent, + oldRatio: width / naturalWidth, + ratio: newWidth / naturalWidth + }) === false) { + return this; + } + + if (_originalEvent) { + var pointers = this.pointers; + + var offset = getOffset(this.cropper); + var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : { + pageX: _originalEvent.pageX, + pageY: _originalEvent.pageY + }; + + // Zoom from the triggering point of the event + canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width); + canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height); + } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) { + canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width); + canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height); + } else { + // Zoom from the center of the canvas + canvasData.left -= (newWidth - width) / 2; + canvasData.top -= (newHeight - height) / 2; + } + + canvasData.width = newWidth; + canvasData.height = newHeight; + this.renderCanvas(true); + } + + return this; + }, + + + /** + * Rotate the canvas with a relative degree + * @param {number} degree - The rotate degree. + * @returns {Object} this + */ + rotate: function rotate(degree) { + return this.rotateTo((this.imageData.rotate || 0) + Number(degree)); + }, + + + /** + * Rotate the canvas to an absolute degree + * @param {number} degree - The rotate degree. + * @returns {Object} this + */ + rotateTo: function rotateTo(degree) { + degree = Number(degree); + + if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) { + this.imageData.rotate = degree % 360; + this.renderCanvas(true, true); + } + + return this; + }, + + + /** + * Scale the image on the x-axis. + * @param {number} scaleX - The scale ratio on the x-axis. + * @returns {Object} this + */ + scaleX: function scaleX(_scaleX) { + var scaleY = this.imageData.scaleY; + + + return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1); + }, + + + /** + * Scale the image on the y-axis. + * @param {number} scaleY - The scale ratio on the y-axis. + * @returns {Object} this + */ + scaleY: function scaleY(_scaleY) { + var scaleX = this.imageData.scaleX; + + + return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); + }, + + + /** + * Scale the image + * @param {number} scaleX - The scale ratio on the x-axis. + * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis. + * @returns {Object} this + */ + scale: function scale(scaleX) { + var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX; + var imageData = this.imageData; + + var transformed = false; + + scaleX = Number(scaleX); + scaleY = Number(scaleY); + + if (this.ready && !this.disabled && this.options.scalable) { + if (isNumber(scaleX)) { + imageData.scaleX = scaleX; + transformed = true; + } + + if (isNumber(scaleY)) { + imageData.scaleY = scaleY; + transformed = true; + } + + if (transformed) { + this.renderCanvas(true, true); + } + } + + return this; + }, + + + /** + * Get the cropped area position and size data (base on the original image) + * @param {boolean} [rounded=false] - Indicate if round the data values or not. + * @returns {Object} The result cropped data. + */ + getData: function getData$$1() { + var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var options = this.options, + imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + + var data = void 0; + + if (this.ready && this.cropped) { + data = { + x: cropBoxData.left - canvasData.left, + y: cropBoxData.top - canvasData.top, + width: cropBoxData.width, + height: cropBoxData.height + }; + + var ratio = imageData.width / imageData.naturalWidth; + + each(data, function (n, i) { + n /= ratio; + data[i] = rounded ? Math.round(n) : n; + }); + } else { + data = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + } + + if (options.rotatable) { + data.rotate = imageData.rotate || 0; + } + + if (options.scalable) { + data.scaleX = imageData.scaleX || 1; + data.scaleY = imageData.scaleY || 1; + } + + return data; + }, + + + /** + * Set the cropped area position and size with new data + * @param {Object} data - The new data. + * @returns {Object} this + */ + setData: function setData$$1(data) { + var options = this.options, + imageData = this.imageData, + canvasData = this.canvasData; + + var cropBoxData = {}; + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && !this.disabled && isPlainObject(data)) { + var transformed = false; + + if (options.rotatable) { + if (isNumber(data.rotate) && data.rotate !== imageData.rotate) { + imageData.rotate = data.rotate; + transformed = true; + } + } + + if (options.scalable) { + if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) { + imageData.scaleX = data.scaleX; + transformed = true; + } + + if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) { + imageData.scaleY = data.scaleY; + transformed = true; + } + } + + if (transformed) { + this.renderCanvas(true, true); + } + + var ratio = imageData.width / imageData.naturalWidth; + + if (isNumber(data.x)) { + cropBoxData.left = data.x * ratio + canvasData.left; + } + + if (isNumber(data.y)) { + cropBoxData.top = data.y * ratio + canvasData.top; + } + + if (isNumber(data.width)) { + cropBoxData.width = data.width * ratio; + } + + if (isNumber(data.height)) { + cropBoxData.height = data.height * ratio; + } + + this.setCropBoxData(cropBoxData); + } + + return this; + }, + + + /** + * Get the container size data. + * @returns {Object} The result container data. + */ + getContainerData: function getContainerData() { + return this.ready ? extend({}, this.containerData) : {}; + }, + + + /** + * Get the image position and size data. + * @returns {Object} The result image data. + */ + getImageData: function getImageData() { + return this.loaded ? extend({}, this.imageData) : {}; + }, + + + /** + * Get the canvas position and size data. + * @returns {Object} The result canvas data. + */ + getCanvasData: function getCanvasData() { + var canvasData = this.canvasData; + + var data = {}; + + if (this.ready) { + each(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) { + data[n] = canvasData[n]; + }); + } + + return data; + }, + + + /** + * Set the canvas position and size with new data. + * @param {Object} data - The new canvas data. + * @returns {Object} this + */ + setCanvasData: function setCanvasData(data) { + var canvasData = this.canvasData; + var aspectRatio = canvasData.aspectRatio; + + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && !this.disabled && isPlainObject(data)) { + if (isNumber(data.left)) { + canvasData.left = data.left; + } + + if (isNumber(data.top)) { + canvasData.top = data.top; + } + + if (isNumber(data.width)) { + canvasData.width = data.width; + canvasData.height = data.width / aspectRatio; + } else if (isNumber(data.height)) { + canvasData.height = data.height; + canvasData.width = data.height * aspectRatio; + } + + this.renderCanvas(true); + } + + return this; + }, + + + /** + * Get the crop box position and size data. + * @returns {Object} The result crop box data. + */ + getCropBoxData: function getCropBoxData() { + var cropBoxData = this.cropBoxData; + + var data = void 0; + + if (this.ready && this.cropped) { + data = { + left: cropBoxData.left, + top: cropBoxData.top, + width: cropBoxData.width, + height: cropBoxData.height + }; + } + + return data || {}; + }, + + + /** + * Set the crop box position and size with new data. + * @param {Object} data - The new crop box data. + * @returns {Object} this + */ + setCropBoxData: function setCropBoxData(data) { + var cropBoxData = this.cropBoxData; + var aspectRatio = this.options.aspectRatio; + + var widthChanged = void 0; + var heightChanged = void 0; + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) { + if (isNumber(data.left)) { + cropBoxData.left = data.left; + } + + if (isNumber(data.top)) { + cropBoxData.top = data.top; + } + + if (isNumber(data.width) && data.width !== cropBoxData.width) { + widthChanged = true; + cropBoxData.width = data.width; + } + + if (isNumber(data.height) && data.height !== cropBoxData.height) { + heightChanged = true; + cropBoxData.height = data.height; + } + + if (aspectRatio) { + if (widthChanged) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else if (heightChanged) { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + this.renderCropBox(); + } + + return this; + }, + + + /** + * Get a canvas drawn the cropped image. + * @param {Object} [options={}] - The config options. + * @returns {HTMLCanvasElement} - The result canvas. + */ + getCroppedCanvas: function getCroppedCanvas() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (!this.ready || !window.HTMLCanvasElement) { + return null; + } + + var canvasData = this.canvasData; + + var source = getSourceCanvas(this.image, this.imageData, canvasData, options); + + // Returns the source canvas if it is not cropped. + if (!this.cropped) { + return source; + } + + var _getData = this.getData(), + x = _getData.x, + y = _getData.y, + initialWidth = _getData.width, + initialHeight = _getData.height; + + var aspectRatio = initialWidth / initialHeight; + var maxSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.maxWidth || Infinity, + height: options.maxHeight || Infinity + }); + var minSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.minWidth || 0, + height: options.minHeight || 0 + }); + + var _getContainSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.width || initialWidth, + height: options.height || initialHeight + }), + width = _getContainSizes.width, + height = _getContainSizes.height; + + width = Math.min(maxSizes.width, Math.max(minSizes.width, width)); + height = Math.min(maxSizes.height, Math.max(minSizes.height, height)); + + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + + canvas.width = normalizeDecimalNumber(width); + canvas.height = normalizeDecimalNumber(height); + + context.fillStyle = options.fillColor || 'transparent'; + context.fillRect(0, 0, width, height); + + var _options$imageSmoothi = options.imageSmoothingEnabled, + imageSmoothingEnabled = _options$imageSmoothi === undefined ? true : _options$imageSmoothi, + imageSmoothingQuality = options.imageSmoothingQuality; + + + context.imageSmoothingEnabled = imageSmoothingEnabled; + + if (imageSmoothingQuality) { + context.imageSmoothingQuality = imageSmoothingQuality; + } + + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage + var sourceWidth = source.width; + var sourceHeight = source.height; + + // Source canvas parameters + var srcX = x; + var srcY = y; + var srcWidth = void 0; + var srcHeight = void 0; + + // Destination canvas parameters + var dstX = void 0; + var dstY = void 0; + var dstWidth = void 0; + var dstHeight = void 0; + + if (srcX <= -initialWidth || srcX > sourceWidth) { + srcX = 0; + srcWidth = 0; + dstX = 0; + dstWidth = 0; + } else if (srcX <= 0) { + dstX = -srcX; + srcX = 0; + srcWidth = Math.min(sourceWidth, initialWidth + srcX); + dstWidth = srcWidth; + } else if (srcX <= sourceWidth) { + dstX = 0; + srcWidth = Math.min(initialWidth, sourceWidth - srcX); + dstWidth = srcWidth; + } + + if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) { + srcY = 0; + srcHeight = 0; + dstY = 0; + dstHeight = 0; + } else if (srcY <= 0) { + dstY = -srcY; + srcY = 0; + srcHeight = Math.min(sourceHeight, initialHeight + srcY); + dstHeight = srcHeight; + } else if (srcY <= sourceHeight) { + dstY = 0; + srcHeight = Math.min(initialHeight, sourceHeight - srcY); + dstHeight = srcHeight; + } + + // All the numerical parameters should be integer for `drawImage` + // https://github.com/fengyuanchen/cropper/issues/476 + var params = [srcX, srcY, srcWidth, srcHeight]; + + // Avoid "IndexSizeError" + if (dstWidth > 0 && dstHeight > 0) { + var scale = width / initialWidth; + + params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale); + } + + context.drawImage.apply(context, [source].concat(toConsumableArray(params.map(function (param) { + return Math.floor(normalizeDecimalNumber(param)); + })))); + + return canvas; + }, + + + /** + * Change the aspect ratio of the crop box. + * @param {number} aspectRatio - The new aspect ratio. + * @returns {Object} this + */ + setAspectRatio: function setAspectRatio(aspectRatio) { + var options = this.options; + + + if (!this.disabled && !isUndefined(aspectRatio)) { + // 0 -> NaN + options.aspectRatio = Math.max(0, aspectRatio) || NaN; + + if (this.ready) { + this.initCropBox(); + + if (this.cropped) { + this.renderCropBox(); + } + } + } + + return this; + }, + + + /** + * Change the drag mode. + * @param {string} mode - The new drag mode. + * @returns {Object} this + */ + setDragMode: function setDragMode(mode) { + var options = this.options, + dragBox = this.dragBox, + face = this.face; + + + if (this.loaded && !this.disabled) { + var croppable = mode === DRAG_MODE_CROP; + var movable = options.movable && mode === DRAG_MODE_MOVE; + + mode = croppable || movable ? mode : DRAG_MODE_NONE; + + setData(dragBox, DATA_ACTION, mode); + toggleClass(dragBox, CLASS_CROP, croppable); + toggleClass(dragBox, CLASS_MOVE, movable); + + if (!options.cropBoxMovable) { + // Sync drag mode to crop box when it is not movable + setData(face, DATA_ACTION, mode); + toggleClass(face, CLASS_CROP, croppable); + toggleClass(face, CLASS_MOVE, movable); + } + } + + return this; + } +}; + +var AnotherCropper = WINDOW.Cropper; + +var Cropper = function () { + /** + * Create a new Cropper. + * @param {Element} element - The target element for cropping. + * @param {Object} [options={}] - The configuration options. + */ + function Cropper(element) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + classCallCheck(this, Cropper); + + if (!element || !REGEXP_TAG_NAME.test(element.tagName)) { + throw new Error('The first argument is required and must be an or element.'); + } + + this.element = element; + this.options = extend({}, DEFAULTS, isPlainObject(options) && options); + this.complete = false; + this.cropped = false; + this.disabled = false; + this.isImg = false; + this.limited = false; + this.loaded = false; + this.ready = false; + this.replaced = false; + this.wheeling = false; + this.originalUrl = ''; + this.canvasData = null; + this.cropBoxData = null; + this.previews = null; + this.pointers = {}; + this.init(); + } + + createClass(Cropper, [{ + key: 'init', + value: function init() { + var element = this.element; + + var tagName = element.tagName.toLowerCase(); + var url = void 0; + + if (getData(element, NAMESPACE)) { + return; + } + + setData(element, NAMESPACE, this); + + if (tagName === 'img') { + this.isImg = true; + + // e.g.: "img/picture.jpg" + url = element.getAttribute('src') || ''; + this.originalUrl = url; + + // Stop when it's a blank image + if (!url) { + return; + } + + // e.g.: "http://example.com/img/picture.jpg" + url = element.src; + } else if (tagName === 'canvas' && window.HTMLCanvasElement) { + url = element.toDataURL(); + } + + this.load(url); + } + }, { + key: 'load', + value: function load(url) { + var _this = this; + + if (!url) { + return; + } + + this.url = url; + this.imageData = {}; + + var element = this.element, + options = this.options; + + + if (!options.checkOrientation || !window.ArrayBuffer) { + this.clone(); + return; + } + + // XMLHttpRequest disallows to open a Data URL in some browsers like IE11 and Safari + if (REGEXP_DATA_URL.test(url)) { + if (REGEXP_DATA_URL_JPEG.test(url)) { + this.read(dataURLToArrayBuffer(url)); + } else { + this.clone(); + } + + return; + } + + var xhr = new XMLHttpRequest(); + + xhr.onerror = function () { + _this.clone(); + }; + + xhr.onload = function () { + _this.read(xhr.response); + }; + + if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) { + url = addTimestamp(url); + } + + xhr.open('get', url); + xhr.responseType = 'arraybuffer'; + xhr.withCredentials = element.crossOrigin === 'use-credentials'; + xhr.send(); + } + }, { + key: 'read', + value: function read(arrayBuffer) { + var options = this.options, + imageData = this.imageData; + + var orientation = getOrientation(arrayBuffer); + var rotate = 0; + var scaleX = 1; + var scaleY = 1; + + if (orientation > 1) { + this.url = arrayBufferToDataURL(arrayBuffer, 'image/jpeg'); + + var _parseOrientation = parseOrientation(orientation); + + rotate = _parseOrientation.rotate; + scaleX = _parseOrientation.scaleX; + scaleY = _parseOrientation.scaleY; + } + + if (options.rotatable) { + imageData.rotate = rotate; + } + + if (options.scalable) { + imageData.scaleX = scaleX; + imageData.scaleY = scaleY; + } + + this.clone(); + } + }, { + key: 'clone', + value: function clone() { + var element = this.element, + url = this.url; + + var crossOrigin = void 0; + var crossOriginUrl = void 0; + + if (this.options.checkCrossOrigin && isCrossOriginURL(url)) { + crossOrigin = element.crossOrigin; + + + if (crossOrigin) { + crossOriginUrl = url; + } else { + crossOrigin = 'anonymous'; + + // Bust cache when there is not a "crossOrigin" property + crossOriginUrl = addTimestamp(url); + } + } + + this.crossOrigin = crossOrigin; + this.crossOriginUrl = crossOriginUrl; + + var image = document.createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = crossOriginUrl || url; + + var start = proxy(this.start, this); + var stop = proxy(this.stop, this); + + this.image = image; + this.onStart = start; + this.onStop = stop; + + if (this.isImg) { + if (element.complete) { + this.start(); + } else { + addListener(element, EVENT_LOAD, start); + } + } else { + addListener(image, EVENT_LOAD, start); + addListener(image, EVENT_ERROR, stop); + addClass(image, CLASS_HIDE); + element.parentNode.insertBefore(image, element.nextSibling); + } + } + }, { + key: 'start', + value: function start(event) { + var _this2 = this; + + var image = this.isImg ? this.element : this.image; + + if (event) { + removeListener(image, EVENT_LOAD, this.onStart); + removeListener(image, EVENT_ERROR, this.onStop); + } + + getImageNaturalSizes(image, function (naturalWidth, naturalHeight) { + extend(_this2.imageData, { + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + aspectRatio: naturalWidth / naturalHeight + }); + _this2.loaded = true; + _this2.build(); + }); + } + }, { + key: 'stop', + value: function stop() { + var image = this.image; + + + removeListener(image, EVENT_LOAD, this.onStart); + removeListener(image, EVENT_ERROR, this.onStop); + image.parentNode.removeChild(image); + this.image = null; + } + }, { + key: 'build', + value: function build() { + var _this3 = this; + + if (!this.loaded) { + return; + } + + // Unbuild first when replace + if (this.ready) { + this.unbuild(); + } + + var element = this.element, + options = this.options, + image = this.image; + + // Create cropper elements + + var container = element.parentNode; + var template = document.createElement('div'); + + template.innerHTML = TEMPLATE; + + var cropper = template.querySelector('.' + NAMESPACE + '-container'); + var canvas = cropper.querySelector('.' + NAMESPACE + '-canvas'); + var dragBox = cropper.querySelector('.' + NAMESPACE + '-drag-box'); + var cropBox = cropper.querySelector('.' + NAMESPACE + '-crop-box'); + var face = cropBox.querySelector('.' + NAMESPACE + '-face'); + + this.container = container; + this.cropper = cropper; + this.canvas = canvas; + this.dragBox = dragBox; + this.cropBox = cropBox; + this.viewBox = cropper.querySelector('.' + NAMESPACE + '-view-box'); + this.face = face; + + canvas.appendChild(image); + + // Hide the original image + addClass(element, CLASS_HIDDEN); + + // Inserts the cropper after to the current image + container.insertBefore(cropper, element.nextSibling); + + // Show the image if is hidden + if (!this.isImg) { + removeClass(image, CLASS_HIDE); + } + + this.initPreview(); + this.bind(); + + options.aspectRatio = Math.max(0, options.aspectRatio) || NaN; + options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0; + + this.cropped = options.autoCrop; + + if (options.autoCrop) { + if (options.modal) { + addClass(dragBox, CLASS_MODAL); + } + } else { + addClass(cropBox, CLASS_HIDDEN); + } + + if (!options.guides) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-dashed'), CLASS_HIDDEN); + } + + if (!options.center) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-center'), CLASS_HIDDEN); + } + + if (options.background) { + addClass(cropper, NAMESPACE + '-bg'); + } + + if (!options.highlight) { + addClass(face, CLASS_INVISIBLE); + } + + if (options.cropBoxMovable) { + addClass(face, CLASS_MOVE); + setData(face, DATA_ACTION, ACTION_ALL); + } + + if (!options.cropBoxResizable) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-line'), CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-point'), CLASS_HIDDEN); + } + + this.setDragMode(options.dragMode); + this.render(); + this.ready = true; + this.setData(options.data); + + // Call the "ready" option asynchronously to keep "image.cropper" is defined + this.completing = setTimeout(function () { + if (isFunction(options.ready)) { + addListener(element, EVENT_READY, options.ready, { + once: true + }); + } + + dispatchEvent(element, EVENT_READY); + dispatchEvent(element, EVENT_CROP, _this3.getData()); + + _this3.complete = true; + }, 0); + } + }, { + key: 'unbuild', + value: function unbuild() { + if (!this.ready) { + return; + } + + if (!this.complete) { + clearTimeout(this.completing); + } + + this.ready = false; + this.complete = false; + this.initialImageData = null; + + // Clear `initialCanvasData` is necessary when replace + this.initialCanvasData = null; + this.initialCropBoxData = null; + this.containerData = null; + this.canvasData = null; + + // Clear `cropBoxData` is necessary when replace + this.cropBoxData = null; + this.unbind(); + this.resetPreview(); + this.previews = null; + this.viewBox = null; + this.cropBox = null; + this.dragBox = null; + this.canvas = null; + this.container = null; + this.cropper.parentNode.removeChild(this.cropper); + this.cropper = null; + } + + /** + * Get the no conflict cropper class. + * @returns {Cropper} The cropper class. + */ + + }], [{ + key: 'noConflict', + value: function noConflict() { + window.Cropper = AnotherCropper; + return Cropper; + } + + /** + * Change the default options. + * @param {Object} options - The new default options. + */ + + }, { + key: 'setDefaults', + value: function setDefaults(options) { + extend(DEFAULTS, isPlainObject(options) && options); + } + }]); + return Cropper; +}(); + +extend(Cropper.prototype, render, preview, events, handlers, change, methods); + +module.exports = Cropper; diff --git a/library/cropperjs/dist/cropper.css b/library/cropperjs/dist/cropper.css new file mode 100644 index 000000000..dd22178fe --- /dev/null +++ b/library/cropperjs/dist/cropper.css @@ -0,0 +1,306 @@ +/*! + * Cropper.js v1.2.2 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2018 Chen Fengyuan + * Released under the MIT license + * + * Date: 2018-01-03T13:26:29.610Z + */ + +.cropper-container { + direction: ltr; + font-size: 0; + line-height: 0; + position: relative; + -ms-touch-action: none; + touch-action: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.cropper-container img {/*Avoid margin top issue (Occur only when margin-top <= -height) + */ + display: block; + height: 100%; + image-orientation: 0deg; + max-height: none !important; + max-width: none !important; + min-height: 0 !important; + min-width: 0 !important; + width: 100%; +} + +.cropper-wrap-box, +.cropper-canvas, +.cropper-drag-box, +.cropper-crop-box, +.cropper-modal { + bottom: 0; + left: 0; + position: absolute; + right: 0; + top: 0; +} + +.cropper-wrap-box, +.cropper-canvas { + overflow: hidden; +} + +.cropper-drag-box { + background-color: #fff; + opacity: 0; +} + +.cropper-modal { + background-color: #000; + opacity: .5; +} + +.cropper-view-box { + display: block; + height: 100%; + outline-color: rgba(51, 153, 255, 0.75); + outline: 1px solid #39f; + overflow: hidden; + width: 100%; +} + +.cropper-dashed { + border: 0 dashed #eee; + display: block; + opacity: .5; + position: absolute; +} + +.cropper-dashed.dashed-h { + border-bottom-width: 1px; + border-top-width: 1px; + height: 33.33333%; + left: 0; + top: 33.33333%; + width: 100%; +} + +.cropper-dashed.dashed-v { + border-left-width: 1px; + border-right-width: 1px; + height: 100%; + left: 33.33333%; + top: 0; + width: 33.33333%; +} + +.cropper-center { + display: block; + height: 0; + left: 50%; + opacity: .75; + position: absolute; + top: 50%; + width: 0; +} + +.cropper-center:before, +.cropper-center:after { + background-color: #eee; + content: ' '; + display: block; + position: absolute; +} + +.cropper-center:before { + height: 1px; + left: -3px; + top: 0; + width: 7px; +} + +.cropper-center:after { + height: 7px; + left: 0; + top: -3px; + width: 1px; +} + +.cropper-face, +.cropper-line, +.cropper-point { + display: block; + height: 100%; + opacity: .1; + position: absolute; + width: 100%; +} + +.cropper-face { + background-color: #fff; + left: 0; + top: 0; +} + +.cropper-line { + background-color: #39f; +} + +.cropper-line.line-e { + cursor: ew-resize; + right: -3px; + top: 0; + width: 5px; +} + +.cropper-line.line-n { + cursor: ns-resize; + height: 5px; + left: 0; + top: -3px; +} + +.cropper-line.line-w { + cursor: ew-resize; + left: -3px; + top: 0; + width: 5px; +} + +.cropper-line.line-s { + bottom: -3px; + cursor: ns-resize; + height: 5px; + left: 0; +} + +.cropper-point { + background-color: #39f; + height: 5px; + opacity: .75; + width: 5px; +} + +.cropper-point.point-e { + cursor: ew-resize; + margin-top: -3px; + right: -3px; + top: 50%; +} + +.cropper-point.point-n { + cursor: ns-resize; + left: 50%; + margin-left: -3px; + top: -3px; +} + +.cropper-point.point-w { + cursor: ew-resize; + left: -3px; + margin-top: -3px; + top: 50%; +} + +.cropper-point.point-s { + bottom: -3px; + cursor: s-resize; + left: 50%; + margin-left: -3px; +} + +.cropper-point.point-ne { + cursor: nesw-resize; + right: -3px; + top: -3px; +} + +.cropper-point.point-nw { + cursor: nwse-resize; + left: -3px; + top: -3px; +} + +.cropper-point.point-sw { + bottom: -3px; + cursor: nesw-resize; + left: -3px; +} + +.cropper-point.point-se { + bottom: -3px; + cursor: nwse-resize; + height: 20px; + opacity: 1; + right: -3px; + width: 20px; +} + +@media (min-width: 768px) { + .cropper-point.point-se { + height: 15px; + width: 15px; + } +} + +@media (min-width: 992px) { + .cropper-point.point-se { + height: 10px; + width: 10px; + } +} + +@media (min-width: 1200px) { + .cropper-point.point-se { + height: 5px; + opacity: .75; + width: 5px; + } +} + +.cropper-point.point-se:before { + background-color: #39f; + bottom: -50%; + content: ' '; + display: block; + height: 200%; + opacity: 0; + position: absolute; + right: -50%; + width: 200%; +} + +.cropper-invisible { + opacity: 0; +} + +.cropper-bg { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC'); +} + +.cropper-hide { + display: block; + height: 0; + position: absolute; + width: 0; +} + +.cropper-hidden { + display: none !important; +} + +.cropper-move { + cursor: move; +} + +.cropper-crop { + cursor: crosshair; +} + +.cropper-disabled .cropper-drag-box, +.cropper-disabled .cropper-face, +.cropper-disabled .cropper-line, +.cropper-disabled .cropper-point { + cursor: not-allowed; +} + diff --git a/library/cropperjs/dist/cropper.esm.js b/library/cropperjs/dist/cropper.esm.js new file mode 100644 index 000000000..929852d8a --- /dev/null +++ b/library/cropperjs/dist/cropper.esm.js @@ -0,0 +1,3758 @@ +/*! + * Cropper.js v1.2.2 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2018 Chen Fengyuan + * Released under the MIT license + * + * Date: 2018-01-03T13:27:18.062Z + */ + +var WINDOW = typeof window !== 'undefined' ? window : {}; +var NAMESPACE = 'cropper'; + +// Actions +var ACTION_ALL = 'all'; +var ACTION_CROP = 'crop'; +var ACTION_MOVE = 'move'; +var ACTION_ZOOM = 'zoom'; +var ACTION_EAST = 'e'; +var ACTION_WEST = 'w'; +var ACTION_SOUTH = 's'; +var ACTION_NORTH = 'n'; +var ACTION_NORTH_EAST = 'ne'; +var ACTION_NORTH_WEST = 'nw'; +var ACTION_SOUTH_EAST = 'se'; +var ACTION_SOUTH_WEST = 'sw'; + +// Classes +var CLASS_CROP = NAMESPACE + '-crop'; +var CLASS_DISABLED = NAMESPACE + '-disabled'; +var CLASS_HIDDEN = NAMESPACE + '-hidden'; +var CLASS_HIDE = NAMESPACE + '-hide'; +var CLASS_INVISIBLE = NAMESPACE + '-invisible'; +var CLASS_MODAL = NAMESPACE + '-modal'; +var CLASS_MOVE = NAMESPACE + '-move'; + +// Data keys +var DATA_ACTION = 'action'; +var DATA_PREVIEW = 'preview'; + +// Drag modes +var DRAG_MODE_CROP = 'crop'; +var DRAG_MODE_MOVE = 'move'; +var DRAG_MODE_NONE = 'none'; + +// Events +var EVENT_CROP = 'crop'; +var EVENT_CROP_END = 'cropend'; +var EVENT_CROP_MOVE = 'cropmove'; +var EVENT_CROP_START = 'cropstart'; +var EVENT_DBLCLICK = 'dblclick'; +var EVENT_ERROR = 'error'; +var EVENT_LOAD = 'load'; +var EVENT_POINTER_DOWN = WINDOW.PointerEvent ? 'pointerdown' : 'touchstart mousedown'; +var EVENT_POINTER_MOVE = WINDOW.PointerEvent ? 'pointermove' : 'touchmove mousemove'; +var EVENT_POINTER_UP = WINDOW.PointerEvent ? 'pointerup pointercancel' : 'touchend touchcancel mouseup'; +var EVENT_READY = 'ready'; +var EVENT_RESIZE = 'resize'; +var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll'; +var EVENT_ZOOM = 'zoom'; + +// RegExps +var REGEXP_ACTIONS = /^(e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/; +var REGEXP_DATA_URL = /^data:/; +var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/; +var REGEXP_TAG_NAME = /^(img|canvas)$/i; + +var DEFAULTS = { + // Define the view mode of the cropper + viewMode: 0, // 0, 1, 2, 3 + + // Define the dragging mode of the cropper + dragMode: DRAG_MODE_CROP, // 'crop', 'move' or 'none' + + // Define the aspect ratio of the crop box + aspectRatio: NaN, + + // An object with the previous cropping result data + data: null, + + // A selector for adding extra containers to preview + preview: '', + + // Re-render the cropper when resize the window + responsive: true, + + // Restore the cropped area after resize the window + restore: true, + + // Check if the current image is a cross-origin image + checkCrossOrigin: true, + + // Check the current image's Exif Orientation information + checkOrientation: true, + + // Show the black modal + modal: true, + + // Show the dashed lines for guiding + guides: true, + + // Show the center indicator for guiding + center: true, + + // Show the white modal to highlight the crop box + highlight: true, + + // Show the grid background + background: true, + + // Enable to crop the image automatically when initialize + autoCrop: true, + + // Define the percentage of automatic cropping area when initializes + autoCropArea: 0.8, + + // Enable to move the image + movable: true, + + // Enable to rotate the image + rotatable: true, + + // Enable to scale the image + scalable: true, + + // Enable to zoom the image + zoomable: true, + + // Enable to zoom the image by dragging touch + zoomOnTouch: true, + + // Enable to zoom the image by wheeling mouse + zoomOnWheel: true, + + // Define zoom ratio when zoom the image by wheeling mouse + wheelZoomRatio: 0.1, + + // Enable to move the crop box + cropBoxMovable: true, + + // Enable to resize the crop box + cropBoxResizable: true, + + // Toggle drag mode between "crop" and "move" when click twice on the cropper + toggleDragModeOnDblclick: true, + + // Size limitation + minCanvasWidth: 0, + minCanvasHeight: 0, + minCropBoxWidth: 0, + minCropBoxHeight: 0, + minContainerWidth: 200, + minContainerHeight: 100, + + // Shortcuts of events + ready: null, + cropstart: null, + cropmove: null, + cropend: null, + crop: null, + zoom: null +}; + +var TEMPLATE = '
' + '
' + '
' + '
' + '
' + '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
' + '
'; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + + + + + + + + + + + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + +var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +var toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } else { + return Array.from(arr); + } +}; + +/** + * Check if the given value is not a number. + */ +var isNaN = Number.isNaN || WINDOW.isNaN; + +/** + * Check if the given value is a number. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a number, else `false`. + */ +function isNumber(value) { + return typeof value === 'number' && !isNaN(value); +} + +/** + * Check if the given value is undefined. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is undefined, else `false`. + */ +function isUndefined(value) { + return typeof value === 'undefined'; +} + +/** + * Check if the given value is an object. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is an object, else `false`. + */ +function isObject(value) { + return (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && value !== null; +} + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +/** + * Check if the given value is a plain object. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a plain object, else `false`. + */ + +function isPlainObject(value) { + if (!isObject(value)) { + return false; + } + + try { + var _constructor = value.constructor; + var prototype = _constructor.prototype; + + + return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf'); + } catch (e) { + return false; + } +} + +/** + * Check if the given value is a function. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a function, else `false`. + */ +function isFunction(value) { + return typeof value === 'function'; +} + +/** + * Iterate the given data. + * @param {*} data - The data to iterate. + * @param {Function} callback - The process function for each element. + * @returns {*} The original data. + */ +function each(data, callback) { + if (data && isFunction(callback)) { + if (Array.isArray(data) || isNumber(data.length) /* array-like */) { + var length = data.length; + + var i = void 0; + + for (i = 0; i < length; i += 1) { + if (callback.call(data, data[i], i, data) === false) { + break; + } + } + } else if (isObject(data)) { + Object.keys(data).forEach(function (key) { + callback.call(data, data[key], key, data); + }); + } + } + + return data; +} + +/** + * Extend the given object. + * @param {*} obj - The object to be extended. + * @param {*} args - The rest objects which will be merged to the first object. + * @returns {Object} The extended object. + */ +function extend(obj) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + if (isObject(obj) && args.length > 0) { + if (Object.assign) { + return Object.assign.apply(Object, [obj].concat(args)); + } + + args.forEach(function (arg) { + if (isObject(arg)) { + Object.keys(arg).forEach(function (key) { + obj[key] = arg[key]; + }); + } + }); + } + + return obj; +} + +/** + * Takes a function and returns a new one that will always have a particular context. + * @param {Function} fn - The target function. + * @param {Object} context - The new context for the function. + * @returns {boolean} The new function. + */ +function proxy(fn, context) { + for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { + args[_key2 - 2] = arguments[_key2]; + } + + return function () { + for (var _len3 = arguments.length, args2 = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args2[_key3] = arguments[_key3]; + } + + return fn.apply(context, args.concat(args2)); + }; +} + +var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/i; + +/** + * Normalize decimal number. + * Check out {@link http://0.30000000000000004.com/ } + * @param {number} value - The value to normalize. + * @param {number} [times=100000000000] - The times for normalizing. + * @returns {number} Returns the normalized number. + */ +function normalizeDecimalNumber(value) { + var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000; + + return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value; +} + +var REGEXP_SUFFIX = /^(width|height|left|top|marginLeft|marginTop)$/; + +/** + * Apply styles to the given element. + * @param {Element} element - The target element. + * @param {Object} styles - The styles for applying. + */ +function setStyle(element, styles) { + var style = element.style; + + + each(styles, function (value, property) { + if (REGEXP_SUFFIX.test(property) && isNumber(value)) { + value += 'px'; + } + + style[property] = value; + }); +} + +/** + * Check if the given element has a special class. + * @param {Element} element - The element to check. + * @param {string} value - The class to search. + * @returns {boolean} Returns `true` if the special class was found. + */ +function hasClass(element, value) { + return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1; +} + +/** + * Add classes to the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be added. + */ +function addClass(element, value) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + addClass(elem, value); + }); + return; + } + + if (element.classList) { + element.classList.add(value); + return; + } + + var className = element.className.trim(); + + if (!className) { + element.className = value; + } else if (className.indexOf(value) < 0) { + element.className = className + ' ' + value; + } +} + +/** + * Remove classes from the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be removed. + */ +function removeClass(element, value) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + removeClass(elem, value); + }); + return; + } + + if (element.classList) { + element.classList.remove(value); + return; + } + + if (element.className.indexOf(value) >= 0) { + element.className = element.className.replace(value, ''); + } +} + +/** + * Add or remove classes from the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be toggled. + * @param {boolean} added - Add only. + */ +function toggleClass(element, value, added) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + toggleClass(elem, value, added); + }); + return; + } + + // IE10-11 doesn't support the second parameter of `classList.toggle` + if (added) { + addClass(element, value); + } else { + removeClass(element, value); + } +} + +var REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g; + +/** + * Hyphenate the given value. + * @param {string} value - The value to hyphenate. + * @returns {string} The hyphenated value. + */ +function hyphenate(value) { + return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase(); +} + +/** + * Get data from the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to get. + * @returns {string} The data value. + */ +function getData(element, name) { + if (isObject(element[name])) { + return element[name]; + } else if (element.dataset) { + return element.dataset[name]; + } + + return element.getAttribute('data-' + hyphenate(name)); +} + +/** + * Set data to the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to set. + * @param {string} data - The data value. + */ +function setData(element, name, data) { + if (isObject(data)) { + element[name] = data; + } else if (element.dataset) { + element.dataset[name] = data; + } else { + element.setAttribute('data-' + hyphenate(name), data); + } +} + +/** + * Remove data from the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to remove. + */ +function removeData(element, name) { + if (isObject(element[name])) { + try { + delete element[name]; + } catch (e) { + element[name] = null; + } + } else if (element.dataset) { + // #128 Safari not allows to delete dataset property + try { + delete element.dataset[name]; + } catch (e) { + element.dataset[name] = null; + } + } else { + element.removeAttribute('data-' + hyphenate(name)); + } +} + +var REGEXP_SPACES = /\s+/; + +/** + * Remove event listener from the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Function} listener - The event listener. + * @param {Object} options - The event options. + */ +function removeListener(element, type, listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + if (!isFunction(listener)) { + return; + } + + var types = type.trim().split(REGEXP_SPACES); + + if (types.length > 1) { + each(types, function (t) { + removeListener(element, t, listener, options); + }); + return; + } + + if (element.removeEventListener) { + element.removeEventListener(type, listener, options); + } else if (element.detachEvent) { + element.detachEvent('on' + type, listener); + } +} + +/** + * Add event listener to the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Function} listener - The event listener. + * @param {Object} options - The event options. + */ +function addListener(element, type, _listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + if (!isFunction(_listener)) { + return; + } + + var types = type.trim().split(REGEXP_SPACES); + + if (types.length > 1) { + each(types, function (t) { + addListener(element, t, _listener, options); + }); + return; + } + + if (options.once) { + var originalListener = _listener; + + _listener = function listener() { + for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + removeListener(element, type, _listener, options); + return originalListener.apply(element, args); + }; + } + + if (element.addEventListener) { + element.addEventListener(type, _listener, options); + } else if (element.attachEvent) { + element.attachEvent('on' + type, _listener); + } +} + +/** + * Dispatch event on the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Object} data - The additional event data. + * @returns {boolean} Indicate if the event is default prevented or not. + */ +function dispatchEvent(element, type, data) { + if (element.dispatchEvent) { + var event = void 0; + + // Event and CustomEvent on IE9-11 are global objects, not constructors + if (isFunction(Event) && isFunction(CustomEvent)) { + if (isUndefined(data)) { + event = new Event(type, { + bubbles: true, + cancelable: true + }); + } else { + event = new CustomEvent(type, { + detail: data, + bubbles: true, + cancelable: true + }); + } + } else if (isUndefined(data)) { + event = document.createEvent('Event'); + event.initEvent(type, true, true); + } else { + event = document.createEvent('CustomEvent'); + event.initCustomEvent(type, true, true, data); + } + + // IE9+ + return element.dispatchEvent(event); + } else if (element.fireEvent) { + // IE6-10 (native events only) + return element.fireEvent('on' + type); + } + + return true; +} + +/** + * Get the offset base on the document. + * @param {Element} element - The target element. + * @returns {Object} The offset data. + */ +function getOffset(element) { + var doc = document.documentElement; + var box = element.getBoundingClientRect(); + + return { + left: box.left + ((window.scrollX || doc && doc.scrollLeft || 0) - (doc && doc.clientLeft || 0)), + top: box.top + ((window.scrollY || doc && doc.scrollTop || 0) - (doc && doc.clientTop || 0)) + }; +} + +/** + * Empty an element. + * @param {Element} element - The element to empty. + */ +function empty(element) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } +} + +var location = WINDOW.location; + +var REGEXP_ORIGINS = /^(https?:)\/\/([^:/?#]+):?(\d*)/i; + +/** + * Check if the given URL is a cross origin URL. + * @param {string} url - The target URL. + * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`. + */ +function isCrossOriginURL(url) { + var parts = url.match(REGEXP_ORIGINS); + + return parts && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port); +} + +/** + * Add timestamp to the given URL. + * @param {string} url - The target URL. + * @returns {string} The result URL. + */ +function addTimestamp(url) { + var timestamp = 'timestamp=' + new Date().getTime(); + + return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp; +} + +/** + * Get transforms base on the given object. + * @param {Object} obj - The target object. + * @returns {string} A string contains transform values. + */ +function getTransforms(_ref) { + var rotate = _ref.rotate, + scaleX = _ref.scaleX, + scaleY = _ref.scaleY, + translateX = _ref.translateX, + translateY = _ref.translateY; + + var values = []; + + if (isNumber(translateX) && translateX !== 0) { + values.push('translateX(' + translateX + 'px)'); + } + + if (isNumber(translateY) && translateY !== 0) { + values.push('translateY(' + translateY + 'px)'); + } + + // Rotate should come first before scale to match orientation transform + if (isNumber(rotate) && rotate !== 0) { + values.push('rotate(' + rotate + 'deg)'); + } + + if (isNumber(scaleX) && scaleX !== 1) { + values.push('scaleX(' + scaleX + ')'); + } + + if (isNumber(scaleY) && scaleY !== 1) { + values.push('scaleY(' + scaleY + ')'); + } + + var transform = values.length ? values.join(' ') : 'none'; + + return { + WebkitTransform: transform, + msTransform: transform, + transform: transform + }; +} + +var navigator = WINDOW.navigator; + +var IS_SAFARI_OR_UIWEBVIEW = navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent); + +/** + * Get an image's natural sizes. + * @param {string} image - The target image. + * @param {Function} callback - The callback function. + */ +function getImageNaturalSizes(image, callback) { + // Modern browsers (except Safari) + if (image.naturalWidth && !IS_SAFARI_OR_UIWEBVIEW) { + callback(image.naturalWidth, image.naturalHeight); + return; + } + + var newImage = document.createElement('img'); + var body = document.body || document.documentElement; + + newImage.onload = function () { + callback(newImage.width, newImage.height); + + if (!IS_SAFARI_OR_UIWEBVIEW) { + body.removeChild(newImage); + } + }; + + newImage.src = image.src; + + // iOS Safari will convert the image automatically + // with its orientation once append it into DOM (#279) + if (!IS_SAFARI_OR_UIWEBVIEW) { + newImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;'; + body.appendChild(newImage); + } +} + +/** + * Get the max ratio of a group of pointers. + * @param {string} pointers - The target pointers. + * @returns {number} The result ratio. + */ +function getMaxZoomRatio(pointers) { + var pointers2 = extend({}, pointers); + var ratios = []; + + each(pointers, function (pointer, pointerId) { + delete pointers2[pointerId]; + + each(pointers2, function (pointer2) { + var x1 = Math.abs(pointer.startX - pointer2.startX); + var y1 = Math.abs(pointer.startY - pointer2.startY); + var x2 = Math.abs(pointer.endX - pointer2.endX); + var y2 = Math.abs(pointer.endY - pointer2.endY); + var z1 = Math.sqrt(x1 * x1 + y1 * y1); + var z2 = Math.sqrt(x2 * x2 + y2 * y2); + var ratio = (z2 - z1) / z1; + + ratios.push(ratio); + }); + }); + + ratios.sort(function (a, b) { + return Math.abs(a) < Math.abs(b); + }); + + return ratios[0]; +} + +/** + * Get a pointer from an event object. + * @param {Object} event - The target event object. + * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not. + * @returns {Object} The result pointer contains start and/or end point coordinates. + */ +function getPointer(_ref2, endOnly) { + var pageX = _ref2.pageX, + pageY = _ref2.pageY; + + var end = { + endX: pageX, + endY: pageY + }; + + if (endOnly) { + return end; + } + + return extend({ + startX: pageX, + startY: pageY + }, end); +} + +/** + * Get the center point coordinate of a group of pointers. + * @param {Object} pointers - The target pointers. + * @returns {Object} The center point coordinate. + */ +function getPointersCenter(pointers) { + var pageX = 0; + var pageY = 0; + var count = 0; + + each(pointers, function (_ref3) { + var startX = _ref3.startX, + startY = _ref3.startY; + + pageX += startX; + pageY += startY; + count += 1; + }); + + pageX /= count; + pageY /= count; + + return { + pageX: pageX, + pageY: pageY + }; +} + +/** + * Check if the given value is a finite number. + */ +var isFinite = Number.isFinite || WINDOW.isFinite; + +/** + * Get the max sizes in a rectangle under the given aspect ratio. + * @param {Object} data - The original sizes. + * @returns {Object} The result sizes. + */ +function getContainSizes(_ref4) { + var aspectRatio = _ref4.aspectRatio, + height = _ref4.height, + width = _ref4.width; + + var isValidNumber = function isValidNumber(value) { + return isFinite(value) && value > 0; + }; + + if (isValidNumber(width) && isValidNumber(height)) { + if (height * aspectRatio > width) { + height = width / aspectRatio; + } else { + width = height * aspectRatio; + } + } else if (isValidNumber(width)) { + height = width / aspectRatio; + } else if (isValidNumber(height)) { + width = height * aspectRatio; + } + + return { + width: width, + height: height + }; +} + +/** + * Get the new sizes of a rectangle after rotated. + * @param {Object} data - The original sizes. + * @returns {Object} The result sizes. + */ +function getRotatedSizes(_ref5) { + var width = _ref5.width, + height = _ref5.height, + degree = _ref5.degree; + + degree = Math.abs(degree) % 180; + + if (degree === 90) { + return { + width: height, + height: width + }; + } + + var arc = degree % 90 * Math.PI / 180; + var sinArc = Math.sin(arc); + var cosArc = Math.cos(arc); + var newWidth = width * cosArc + height * sinArc; + var newHeight = width * sinArc + height * cosArc; + + return degree > 90 ? { + width: newHeight, + height: newWidth + } : { + width: newWidth, + height: newHeight + }; +} + +/** + * Get a canvas which drew the given image. + * @param {HTMLImageElement} image - The image for drawing. + * @param {Object} imageData - The image data. + * @param {Object} canvasData - The canvas data. + * @param {Object} options - The options. + * @returns {HTMLCanvasElement} The result canvas. + */ +function getSourceCanvas(image, _ref6, _ref7, _ref8) { + var imageNaturalWidth = _ref6.naturalWidth, + imageNaturalHeight = _ref6.naturalHeight, + _ref6$rotate = _ref6.rotate, + rotate = _ref6$rotate === undefined ? 0 : _ref6$rotate, + _ref6$scaleX = _ref6.scaleX, + scaleX = _ref6$scaleX === undefined ? 1 : _ref6$scaleX, + _ref6$scaleY = _ref6.scaleY, + scaleY = _ref6$scaleY === undefined ? 1 : _ref6$scaleY; + var aspectRatio = _ref7.aspectRatio, + naturalWidth = _ref7.naturalWidth, + naturalHeight = _ref7.naturalHeight; + var _ref8$fillColor = _ref8.fillColor, + fillColor = _ref8$fillColor === undefined ? 'transparent' : _ref8$fillColor, + _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled, + imageSmoothingEnabled = _ref8$imageSmoothingE === undefined ? true : _ref8$imageSmoothingE, + _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality, + imageSmoothingQuality = _ref8$imageSmoothingQ === undefined ? 'low' : _ref8$imageSmoothingQ, + _ref8$maxWidth = _ref8.maxWidth, + maxWidth = _ref8$maxWidth === undefined ? Infinity : _ref8$maxWidth, + _ref8$maxHeight = _ref8.maxHeight, + maxHeight = _ref8$maxHeight === undefined ? Infinity : _ref8$maxHeight, + _ref8$minWidth = _ref8.minWidth, + minWidth = _ref8$minWidth === undefined ? 0 : _ref8$minWidth, + _ref8$minHeight = _ref8.minHeight, + minHeight = _ref8$minHeight === undefined ? 0 : _ref8$minHeight; + + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + var maxSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: maxWidth, + height: maxHeight + }); + var minSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: minWidth, + height: minHeight + }); + var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth)); + var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight)); + var params = [-imageNaturalWidth / 2, -imageNaturalHeight / 2, imageNaturalWidth, imageNaturalHeight]; + + canvas.width = normalizeDecimalNumber(width); + canvas.height = normalizeDecimalNumber(height); + context.fillStyle = fillColor; + context.fillRect(0, 0, width, height); + context.save(); + context.translate(width / 2, height / 2); + context.rotate(rotate * Math.PI / 180); + context.scale(scaleX, scaleY); + context.imageSmoothingEnabled = imageSmoothingEnabled; + context.imageSmoothingQuality = imageSmoothingQuality; + context.drawImage.apply(context, [image].concat(toConsumableArray(params.map(function (param) { + return Math.floor(normalizeDecimalNumber(param)); + })))); + context.restore(); + return canvas; +} + +var fromCharCode = String.fromCharCode; + +/** + * Get string from char code in data view. + * @param {DataView} dataView - The data view for read. + * @param {number} start - The start index. + * @param {number} length - The read length. + * @returns {string} The read result. + */ + +function getStringFromCharCode(dataView, start, length) { + var str = ''; + var i = void 0; + + length += start; + + for (i = start; i < length; i += 1) { + str += fromCharCode(dataView.getUint8(i)); + } + + return str; +} + +var REGEXP_DATA_URL_HEAD = /^data:.*,/; + +/** + * Transform Data URL to array buffer. + * @param {string} dataURL - The Data URL to transform. + * @returns {ArrayBuffer} The result array buffer. + */ +function dataURLToArrayBuffer(dataURL) { + var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, ''); + var binary = atob(base64); + var arrayBuffer = new ArrayBuffer(binary.length); + var uint8 = new Uint8Array(arrayBuffer); + + each(uint8, function (value, i) { + uint8[i] = binary.charCodeAt(i); + }); + + return arrayBuffer; +} + +/** + * Transform array buffer to Data URL. + * @param {ArrayBuffer} arrayBuffer - The array buffer to transform. + * @param {string} mimeType - The mime type of the Data URL. + * @returns {string} The result Data URL. + */ +function arrayBufferToDataURL(arrayBuffer, mimeType) { + var uint8 = new Uint8Array(arrayBuffer); + var data = ''; + + // TypedArray.prototype.forEach is not supported in some browsers. + each(uint8, function (value) { + data += fromCharCode(value); + }); + + return 'data:' + mimeType + ';base64,' + btoa(data); +} + +/** + * Get orientation value from given array buffer. + * @param {ArrayBuffer} arrayBuffer - The array buffer to read. + * @returns {number} The read orientation value. + */ +function getOrientation(arrayBuffer) { + var dataView = new DataView(arrayBuffer); + var orientation = void 0; + var littleEndian = void 0; + var app1Start = void 0; + var ifdStart = void 0; + + // Only handle JPEG image (start by 0xFFD8) + if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) { + var length = dataView.byteLength; + var offset = 2; + + while (offset < length) { + if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) { + app1Start = offset; + break; + } + + offset += 1; + } + } + + if (app1Start) { + var exifIDCode = app1Start + 4; + var tiffOffset = app1Start + 10; + + if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') { + var endianness = dataView.getUint16(tiffOffset); + + littleEndian = endianness === 0x4949; + + if (littleEndian || endianness === 0x4D4D /* bigEndian */) { + if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) { + var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian); + + if (firstIFDOffset >= 0x00000008) { + ifdStart = tiffOffset + firstIFDOffset; + } + } + } + } + } + + if (ifdStart) { + var _length = dataView.getUint16(ifdStart, littleEndian); + var _offset = void 0; + var i = void 0; + + for (i = 0; i < _length; i += 1) { + _offset = ifdStart + i * 12 + 2; + + if (dataView.getUint16(_offset, littleEndian) === 0x0112 /* Orientation */) { + // 8 is the offset of the current tag's value + _offset += 8; + + // Get the original orientation value + orientation = dataView.getUint16(_offset, littleEndian); + + // Override the orientation with its default value + dataView.setUint16(_offset, 1, littleEndian); + break; + } + } + } + + return orientation; +} + +/** + * Parse Exif Orientation value. + * @param {number} orientation - The orientation to parse. + * @returns {Object} The parsed result. + */ +function parseOrientation(orientation) { + var rotate = 0; + var scaleX = 1; + var scaleY = 1; + + switch (orientation) { + // Flip horizontal + case 2: + scaleX = -1; + break; + + // Rotate left 180° + case 3: + rotate = -180; + break; + + // Flip vertical + case 4: + scaleY = -1; + break; + + // Flip vertical and rotate right 90° + case 5: + rotate = 90; + scaleY = -1; + break; + + // Rotate right 90° + case 6: + rotate = 90; + break; + + // Flip horizontal and rotate right 90° + case 7: + rotate = 90; + scaleX = -1; + break; + + // Rotate left 90° + case 8: + rotate = -90; + break; + + default: + } + + return { + rotate: rotate, + scaleX: scaleX, + scaleY: scaleY + }; +} + +var render = { + render: function render() { + this.initContainer(); + this.initCanvas(); + this.initCropBox(); + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + }, + initContainer: function initContainer() { + var element = this.element, + options = this.options, + container = this.container, + cropper = this.cropper; + + + addClass(cropper, CLASS_HIDDEN); + removeClass(element, CLASS_HIDDEN); + + var containerData = { + width: Math.max(container.offsetWidth, Number(options.minContainerWidth) || 200), + height: Math.max(container.offsetHeight, Number(options.minContainerHeight) || 100) + }; + + this.containerData = containerData; + + setStyle(cropper, { + width: containerData.width, + height: containerData.height + }); + + addClass(element, CLASS_HIDDEN); + removeClass(cropper, CLASS_HIDDEN); + }, + + + // Canvas (image wrapper) + initCanvas: function initCanvas() { + var containerData = this.containerData, + imageData = this.imageData; + var viewMode = this.options.viewMode; + + var rotated = Math.abs(imageData.rotate) % 180 === 90; + var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth; + var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight; + var aspectRatio = naturalWidth / naturalHeight; + var canvasWidth = containerData.width; + var canvasHeight = containerData.height; + + if (containerData.height * aspectRatio > containerData.width) { + if (viewMode === 3) { + canvasWidth = containerData.height * aspectRatio; + } else { + canvasHeight = containerData.width / aspectRatio; + } + } else if (viewMode === 3) { + canvasHeight = containerData.width / aspectRatio; + } else { + canvasWidth = containerData.height * aspectRatio; + } + + var canvasData = { + aspectRatio: aspectRatio, + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + width: canvasWidth, + height: canvasHeight + }; + + canvasData.left = (containerData.width - canvasWidth) / 2; + canvasData.top = (containerData.height - canvasHeight) / 2; + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; + + this.canvasData = canvasData; + this.limited = viewMode === 1 || viewMode === 2; + this.limitCanvas(true, true); + this.initialImageData = extend({}, imageData); + this.initialCanvasData = extend({}, canvasData); + }, + limitCanvas: function limitCanvas(sizeLimited, positionLimited) { + var options = this.options, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + var viewMode = options.viewMode; + var aspectRatio = canvasData.aspectRatio; + + var cropped = this.cropped && cropBoxData; + + if (sizeLimited) { + var minCanvasWidth = Number(options.minCanvasWidth) || 0; + var minCanvasHeight = Number(options.minCanvasHeight) || 0; + + if (viewMode > 1) { + minCanvasWidth = Math.max(minCanvasWidth, containerData.width); + minCanvasHeight = Math.max(minCanvasHeight, containerData.height); + + if (viewMode === 3) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } else if (viewMode > 0) { + if (minCanvasWidth) { + minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0); + } else if (minCanvasHeight) { + minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0); + } else if (cropped) { + minCanvasWidth = cropBoxData.width; + minCanvasHeight = cropBoxData.height; + + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } + + var _getContainSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: minCanvasWidth, + height: minCanvasHeight + }); + + minCanvasWidth = _getContainSizes.width; + minCanvasHeight = _getContainSizes.height; + + + canvasData.minWidth = minCanvasWidth; + canvasData.minHeight = minCanvasHeight; + canvasData.maxWidth = Infinity; + canvasData.maxHeight = Infinity; + } + + if (positionLimited) { + if (viewMode) { + var newCanvasLeft = containerData.width - canvasData.width; + var newCanvasTop = containerData.height - canvasData.height; + + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxLeft = Math.max(0, newCanvasLeft); + canvasData.maxTop = Math.max(0, newCanvasTop); + + if (cropped && this.limited) { + canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width)); + canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height)); + canvasData.maxLeft = cropBoxData.left; + canvasData.maxTop = cropBoxData.top; + + if (viewMode === 2) { + if (canvasData.width >= containerData.width) { + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.maxLeft = Math.max(0, newCanvasLeft); + } + + if (canvasData.height >= containerData.height) { + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxTop = Math.max(0, newCanvasTop); + } + } + } + } else { + canvasData.minLeft = -canvasData.width; + canvasData.minTop = -canvasData.height; + canvasData.maxLeft = containerData.width; + canvasData.maxTop = containerData.height; + } + } + }, + renderCanvas: function renderCanvas(changed, transformed) { + var canvasData = this.canvasData, + imageData = this.imageData; + + + if (transformed) { + var _getRotatedSizes = getRotatedSizes({ + width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1), + height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1), + degree: imageData.rotate || 0 + }), + naturalWidth = _getRotatedSizes.width, + naturalHeight = _getRotatedSizes.height; + + var width = canvasData.width * (naturalWidth / canvasData.naturalWidth); + var height = canvasData.height * (naturalHeight / canvasData.naturalHeight); + + canvasData.left -= (width - canvasData.width) / 2; + canvasData.top -= (height - canvasData.height) / 2; + canvasData.width = width; + canvasData.height = height; + canvasData.aspectRatio = naturalWidth / naturalHeight; + canvasData.naturalWidth = naturalWidth; + canvasData.naturalHeight = naturalHeight; + this.limitCanvas(true, false); + } + + if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) { + canvasData.left = canvasData.oldLeft; + } + + if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) { + canvasData.top = canvasData.oldTop; + } + + canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth); + canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight); + + this.limitCanvas(false, true); + + canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft); + canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop); + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; + + setStyle(this.canvas, extend({ + width: canvasData.width, + height: canvasData.height + }, getTransforms({ + translateX: canvasData.left, + translateY: canvasData.top + }))); + + this.renderImage(changed); + + if (this.cropped && this.limited) { + this.limitCropBox(true, true); + } + }, + renderImage: function renderImage(changed) { + var canvasData = this.canvasData, + imageData = this.imageData; + + var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth); + var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight); + + extend(imageData, { + width: width, + height: height, + left: (canvasData.width - width) / 2, + top: (canvasData.height - height) / 2 + }); + setStyle(this.image, extend({ + width: imageData.width, + height: imageData.height + }, getTransforms(extend({ + translateX: imageData.left, + translateY: imageData.top + }, imageData)))); + + if (changed) { + this.output(); + } + }, + initCropBox: function initCropBox() { + var options = this.options, + canvasData = this.canvasData; + var aspectRatio = options.aspectRatio; + + var autoCropArea = Number(options.autoCropArea) || 0.8; + var cropBoxData = { + width: canvasData.width, + height: canvasData.height + }; + + if (aspectRatio) { + if (canvasData.height * aspectRatio > canvasData.width) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + this.cropBoxData = cropBoxData; + this.limitCropBox(true, true); + + // Initialize auto crop area + cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth); + cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); + + // The width/height of auto crop area must large than "minWidth/Height" + cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea); + cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea); + cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2; + cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2; + cropBoxData.oldLeft = cropBoxData.left; + cropBoxData.oldTop = cropBoxData.top; + + this.initialCropBoxData = extend({}, cropBoxData); + }, + limitCropBox: function limitCropBox(sizeLimited, positionLimited) { + var options = this.options, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData, + limited = this.limited; + var aspectRatio = options.aspectRatio; + + + if (sizeLimited) { + var minCropBoxWidth = Number(options.minCropBoxWidth) || 0; + var minCropBoxHeight = Number(options.minCropBoxHeight) || 0; + var maxCropBoxWidth = Math.min(containerData.width, limited ? canvasData.width : containerData.width); + var maxCropBoxHeight = Math.min(containerData.height, limited ? canvasData.height : containerData.height); + + // The min/maxCropBoxWidth/Height must be less than container's width/height + minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width); + minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height); + + if (aspectRatio) { + if (minCropBoxWidth && minCropBoxHeight) { + if (minCropBoxHeight * aspectRatio > minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + } else if (minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else if (minCropBoxHeight) { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + + if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) { + maxCropBoxHeight = maxCropBoxWidth / aspectRatio; + } else { + maxCropBoxWidth = maxCropBoxHeight * aspectRatio; + } + } + + // The minWidth/Height must be less than maxWidth/Height + cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); + cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); + cropBoxData.maxWidth = maxCropBoxWidth; + cropBoxData.maxHeight = maxCropBoxHeight; + } + + if (positionLimited) { + if (limited) { + cropBoxData.minLeft = Math.max(0, canvasData.left); + cropBoxData.minTop = Math.max(0, canvasData.top); + cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width; + cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height; + } else { + cropBoxData.minLeft = 0; + cropBoxData.minTop = 0; + cropBoxData.maxLeft = containerData.width - cropBoxData.width; + cropBoxData.maxTop = containerData.height - cropBoxData.height; + } + } + }, + renderCropBox: function renderCropBox() { + var options = this.options, + containerData = this.containerData, + cropBoxData = this.cropBoxData; + + + if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) { + cropBoxData.left = cropBoxData.oldLeft; + } + + if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) { + cropBoxData.top = cropBoxData.oldTop; + } + + cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth); + cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); + + this.limitCropBox(false, true); + + cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft); + cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop); + cropBoxData.oldLeft = cropBoxData.left; + cropBoxData.oldTop = cropBoxData.top; + + if (options.movable && options.cropBoxMovable) { + // Turn to move the canvas when the crop box is equal to the container + setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL); + } + + setStyle(this.cropBox, extend({ + width: cropBoxData.width, + height: cropBoxData.height + }, getTransforms({ + translateX: cropBoxData.left, + translateY: cropBoxData.top + }))); + + if (this.cropped && this.limited) { + this.limitCanvas(true, true); + } + + if (!this.disabled) { + this.output(); + } + }, + output: function output() { + this.preview(); + + if (this.complete) { + dispatchEvent(this.element, EVENT_CROP, this.getData()); + } + } +}; + +var preview = { + initPreview: function initPreview() { + var crossOrigin = this.crossOrigin; + var preview = this.options.preview; + + var url = crossOrigin ? this.crossOriginUrl : this.url; + var image = document.createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = url; + this.viewBox.appendChild(image); + this.image2 = image; + + if (!preview) { + return; + } + + var previews = preview.querySelector ? [preview] : document.querySelectorAll(preview); + + this.previews = previews; + + each(previews, function (element) { + var img = document.createElement('img'); + + // Save the original size for recover + setData(element, DATA_PREVIEW, { + width: element.offsetWidth, + height: element.offsetHeight, + html: element.innerHTML + }); + + if (crossOrigin) { + img.crossOrigin = crossOrigin; + } + + img.src = url; + + /** + * Override img element styles + * Add `display:block` to avoid margin top issue + * Add `height:auto` to override `height` attribute on IE8 + * (Occur only when margin-top <= -height) + */ + img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"'; + + empty(element); + element.appendChild(img); + }); + }, + resetPreview: function resetPreview() { + each(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); + + setStyle(element, { + width: data.width, + height: data.height + }); + + element.innerHTML = data.html; + removeData(element, DATA_PREVIEW); + }); + }, + preview: function preview() { + var imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + var cropBoxWidth = cropBoxData.width, + cropBoxHeight = cropBoxData.height; + var width = imageData.width, + height = imageData.height; + + var left = cropBoxData.left - canvasData.left - imageData.left; + var top = cropBoxData.top - canvasData.top - imageData.top; + + if (!this.cropped || this.disabled) { + return; + } + + setStyle(this.image2, extend({ + width: width, + height: height + }, getTransforms(extend({ + translateX: -left, + translateY: -top + }, imageData)))); + + each(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); + var originalWidth = data.width; + var originalHeight = data.height; + var newWidth = originalWidth; + var newHeight = originalHeight; + var ratio = 1; + + if (cropBoxWidth) { + ratio = originalWidth / cropBoxWidth; + newHeight = cropBoxHeight * ratio; + } + + if (cropBoxHeight && newHeight > originalHeight) { + ratio = originalHeight / cropBoxHeight; + newWidth = cropBoxWidth * ratio; + newHeight = originalHeight; + } + + setStyle(element, { + width: newWidth, + height: newHeight + }); + + setStyle(element.getElementsByTagName('img')[0], extend({ + width: width * ratio, + height: height * ratio + }, getTransforms(extend({ + translateX: -left * ratio, + translateY: -top * ratio + }, imageData)))); + }); + } +}; + +var events = { + bind: function bind() { + var element = this.element, + options = this.options, + cropper = this.cropper; + + + if (isFunction(options.cropstart)) { + addListener(element, EVENT_CROP_START, options.cropstart); + } + + if (isFunction(options.cropmove)) { + addListener(element, EVENT_CROP_MOVE, options.cropmove); + } + + if (isFunction(options.cropend)) { + addListener(element, EVENT_CROP_END, options.cropend); + } + + if (isFunction(options.crop)) { + addListener(element, EVENT_CROP, options.crop); + } + + if (isFunction(options.zoom)) { + addListener(element, EVENT_ZOOM, options.zoom); + } + + addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = proxy(this.cropStart, this)); + + if (options.zoomable && options.zoomOnWheel) { + addListener(cropper, EVENT_WHEEL, this.onWheel = proxy(this.wheel, this)); + } + + if (options.toggleDragModeOnDblclick) { + addListener(cropper, EVENT_DBLCLICK, this.onDblclick = proxy(this.dblclick, this)); + } + + addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = proxy(this.cropMove, this)); + addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = proxy(this.cropEnd, this)); + + if (options.responsive) { + addListener(window, EVENT_RESIZE, this.onResize = proxy(this.resize, this)); + } + }, + unbind: function unbind() { + var element = this.element, + options = this.options, + cropper = this.cropper; + + + if (isFunction(options.cropstart)) { + removeListener(element, EVENT_CROP_START, options.cropstart); + } + + if (isFunction(options.cropmove)) { + removeListener(element, EVENT_CROP_MOVE, options.cropmove); + } + + if (isFunction(options.cropend)) { + removeListener(element, EVENT_CROP_END, options.cropend); + } + + if (isFunction(options.crop)) { + removeListener(element, EVENT_CROP, options.crop); + } + + if (isFunction(options.zoom)) { + removeListener(element, EVENT_ZOOM, options.zoom); + } + + removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart); + + if (options.zoomable && options.zoomOnWheel) { + removeListener(cropper, EVENT_WHEEL, this.onWheel); + } + + if (options.toggleDragModeOnDblclick) { + removeListener(cropper, EVENT_DBLCLICK, this.onDblclick); + } + + removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove); + removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd); + + if (options.responsive) { + removeListener(window, EVENT_RESIZE, this.onResize); + } + } +}; + +var handlers = { + resize: function resize() { + var options = this.options, + container = this.container, + containerData = this.containerData; + + var minContainerWidth = Number(options.minContainerWidth) || 200; + var minContainerHeight = Number(options.minContainerHeight) || 100; + + if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) { + return; + } + + var ratio = container.offsetWidth / containerData.width; + + // Resize when width changed or height changed + if (ratio !== 1 || container.offsetHeight !== containerData.height) { + var canvasData = void 0; + var cropBoxData = void 0; + + if (options.restore) { + canvasData = this.getCanvasData(); + cropBoxData = this.getCropBoxData(); + } + + this.render(); + + if (options.restore) { + this.setCanvasData(each(canvasData, function (n, i) { + canvasData[i] = n * ratio; + })); + this.setCropBoxData(each(cropBoxData, function (n, i) { + cropBoxData[i] = n * ratio; + })); + } + } + }, + dblclick: function dblclick() { + if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) { + return; + } + + this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); + }, + wheel: function wheel(e) { + var _this = this; + + var ratio = Number(this.options.wheelZoomRatio) || 0.1; + var delta = 1; + + if (this.disabled) { + return; + } + + e.preventDefault(); + + // Limit wheel speed to prevent zoom too fast (#21) + if (this.wheeling) { + return; + } + + this.wheeling = true; + + setTimeout(function () { + _this.wheeling = false; + }, 50); + + if (e.deltaY) { + delta = e.deltaY > 0 ? 1 : -1; + } else if (e.wheelDelta) { + delta = -e.wheelDelta / 120; + } else if (e.detail) { + delta = e.detail > 0 ? 1 : -1; + } + + this.zoom(-delta * ratio, e); + }, + cropStart: function cropStart(e) { + if (this.disabled) { + return; + } + + var options = this.options, + pointers = this.pointers; + + var action = void 0; + + if (e.changedTouches) { + // Handle touch event + each(e.changedTouches, function (touch) { + pointers[touch.identifier] = getPointer(touch); + }); + } else { + // Handle mouse event and pointer event + pointers[e.pointerId || 0] = getPointer(e); + } + + if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { + action = ACTION_ZOOM; + } else { + action = getData(e.target, DATA_ACTION); + } + + if (!REGEXP_ACTIONS.test(action)) { + return; + } + + if (dispatchEvent(this.element, EVENT_CROP_START, { + originalEvent: e, + action: action + }) === false) { + return; + } + + e.preventDefault(); + + this.action = action; + this.cropping = false; + + if (action === ACTION_CROP) { + this.cropping = true; + addClass(this.dragBox, CLASS_MODAL); + } + }, + cropMove: function cropMove(e) { + var action = this.action; + + + if (this.disabled || !action) { + return; + } + + var pointers = this.pointers; + + + e.preventDefault(); + + if (dispatchEvent(this.element, EVENT_CROP_MOVE, { + originalEvent: e, + action: action + }) === false) { + return; + } + + if (e.changedTouches) { + each(e.changedTouches, function (touch) { + extend(pointers[touch.identifier], getPointer(touch, true)); + }); + } else { + extend(pointers[e.pointerId || 0], getPointer(e, true)); + } + + this.change(e); + }, + cropEnd: function cropEnd(e) { + if (this.disabled) { + return; + } + + var action = this.action, + pointers = this.pointers; + + + if (e.changedTouches) { + each(e.changedTouches, function (touch) { + delete pointers[touch.identifier]; + }); + } else { + delete pointers[e.pointerId || 0]; + } + + if (!action) { + return; + } + + e.preventDefault(); + + if (!Object.keys(pointers).length) { + this.action = ''; + } + + if (this.cropping) { + this.cropping = false; + toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal); + } + + dispatchEvent(this.element, EVENT_CROP_END, { + originalEvent: e, + action: action + }); + } +}; + +var change = { + change: function change(e) { + var options = this.options, + canvasData = this.canvasData, + containerData = this.containerData, + cropBoxData = this.cropBoxData, + pointers = this.pointers; + var action = this.action; + var aspectRatio = options.aspectRatio; + var left = cropBoxData.left, + top = cropBoxData.top, + width = cropBoxData.width, + height = cropBoxData.height; + + var right = left + width; + var bottom = top + height; + var minLeft = 0; + var minTop = 0; + var maxWidth = containerData.width; + var maxHeight = containerData.height; + var renderable = true; + var offset = void 0; + + // Locking aspect ratio in "free mode" by holding shift key + if (!aspectRatio && e.shiftKey) { + aspectRatio = width && height ? width / height : 1; + } + + if (this.limited) { + minLeft = cropBoxData.minLeft; + minTop = cropBoxData.minTop; + + maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width); + maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height); + } + + var pointer = pointers[Object.keys(pointers)[0]]; + var range = { + x: pointer.endX - pointer.startX, + y: pointer.endY - pointer.startY + }; + var check = function check(side) { + switch (side) { + case ACTION_EAST: + if (right + range.x > maxWidth) { + range.x = maxWidth - right; + } + + break; + + case ACTION_WEST: + if (left + range.x < minLeft) { + range.x = minLeft - left; + } + + break; + + case ACTION_NORTH: + if (top + range.y < minTop) { + range.y = minTop - top; + } + + break; + + case ACTION_SOUTH: + if (bottom + range.y > maxHeight) { + range.y = maxHeight - bottom; + } + + break; + + default: + } + }; + + switch (action) { + // Move crop box + case ACTION_ALL: + left += range.x; + top += range.y; + break; + + // Resize crop box + case ACTION_EAST: + if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) { + renderable = false; + break; + } + + check(ACTION_EAST); + width += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top -= range.x / aspectRatio / 2; + } + + if (width < 0) { + action = ACTION_WEST; + width = 0; + } + + break; + + case ACTION_NORTH: + if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left += range.y * aspectRatio / 2; + } + + if (height < 0) { + action = ACTION_SOUTH; + height = 0; + } + + break; + + case ACTION_WEST: + if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) { + renderable = false; + break; + } + + check(ACTION_WEST); + width -= range.x; + left += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top += range.x / aspectRatio / 2; + } + + if (width < 0) { + action = ACTION_EAST; + width = 0; + } + + break; + + case ACTION_SOUTH: + if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) { + renderable = false; + break; + } + + check(ACTION_SOUTH); + height += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left -= range.y * aspectRatio / 2; + } + + if (height < 0) { + action = ACTION_NORTH; + height = 0; + } + + break; + + case ACTION_NORTH_EAST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || right >= maxWidth)) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + width = height * aspectRatio; + } else { + check(ACTION_NORTH); + check(ACTION_EAST); + + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + } + + break; + + case ACTION_NORTH_WEST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || left <= minLeft)) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + width = height * aspectRatio; + left += range.y * aspectRatio; + } else { + check(ACTION_NORTH); + check(ACTION_WEST); + + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_WEST: + if (aspectRatio) { + if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) { + renderable = false; + break; + } + + check(ACTION_WEST); + width -= range.x; + left += range.x; + height = width / aspectRatio; + } else { + check(ACTION_SOUTH); + check(ACTION_WEST); + + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_EAST: + if (aspectRatio) { + if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) { + renderable = false; + break; + } + + check(ACTION_EAST); + width += range.x; + height = width / aspectRatio; + } else { + check(ACTION_SOUTH); + check(ACTION_EAST); + + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + } + + break; + + // Move canvas + case ACTION_MOVE: + this.move(range.x, range.y); + renderable = false; + break; + + // Zoom canvas + case ACTION_ZOOM: + this.zoom(getMaxZoomRatio(pointers), e); + renderable = false; + break; + + // Create crop box + case ACTION_CROP: + if (!range.x || !range.y) { + renderable = false; + break; + } + + offset = getOffset(this.cropper); + left = pointer.startX - offset.left; + top = pointer.startY - offset.top; + width = cropBoxData.minWidth; + height = cropBoxData.minHeight; + + if (range.x > 0) { + action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST; + } else if (range.x < 0) { + left -= width; + action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST; + } + + if (range.y < 0) { + top -= height; + } + + // Show the crop box if is hidden + if (!this.cropped) { + removeClass(this.cropBox, CLASS_HIDDEN); + this.cropped = true; + + if (this.limited) { + this.limitCropBox(true, true); + } + } + + break; + + default: + } + + if (renderable) { + cropBoxData.width = width; + cropBoxData.height = height; + cropBoxData.left = left; + cropBoxData.top = top; + this.action = action; + this.renderCropBox(); + } + + // Override + each(pointers, function (p) { + p.startX = p.endX; + p.startY = p.endY; + }); + } +}; + +var methods = { + // Show the crop box manually + crop: function crop() { + if (this.ready && !this.disabled) { + if (!this.cropped) { + this.cropped = true; + this.limitCropBox(true, true); + + if (this.options.modal) { + addClass(this.dragBox, CLASS_MODAL); + } + + removeClass(this.cropBox, CLASS_HIDDEN); + } + + this.setCropBoxData(this.initialCropBoxData); + } + + return this; + }, + + + // Reset the image and crop box to their initial states + reset: function reset() { + if (this.ready && !this.disabled) { + this.imageData = extend({}, this.initialImageData); + this.canvasData = extend({}, this.initialCanvasData); + this.cropBoxData = extend({}, this.initialCropBoxData); + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + } + + return this; + }, + + + // Clear the crop box + clear: function clear() { + if (this.cropped && !this.disabled) { + extend(this.cropBoxData, { + left: 0, + top: 0, + width: 0, + height: 0 + }); + + this.cropped = false; + this.renderCropBox(); + this.limitCanvas(true, true); + + // Render canvas after crop box rendered + this.renderCanvas(); + removeClass(this.dragBox, CLASS_MODAL); + addClass(this.cropBox, CLASS_HIDDEN); + } + + return this; + }, + + + /** + * Replace the image's src and rebuild the cropper + * @param {string} url - The new URL. + * @param {boolean} [onlyColorChanged] - Indicate if the new image only changed color. + * @returns {Object} this + */ + replace: function replace(url) { + var onlyColorChanged = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (!this.disabled && url) { + if (this.isImg) { + this.element.src = url; + } + + if (onlyColorChanged) { + this.url = url; + this.image.src = url; + + if (this.ready) { + this.image2.src = url; + + each(this.previews, function (element) { + element.getElementsByTagName('img')[0].src = url; + }); + } + } else { + if (this.isImg) { + this.replaced = true; + } + + // Clear previous data + this.options.data = null; + this.load(url); + } + } + + return this; + }, + + + // Enable (unfreeze) the cropper + enable: function enable() { + if (this.ready) { + this.disabled = false; + removeClass(this.cropper, CLASS_DISABLED); + } + + return this; + }, + + + // Disable (freeze) the cropper + disable: function disable() { + if (this.ready) { + this.disabled = true; + addClass(this.cropper, CLASS_DISABLED); + } + + return this; + }, + + + // Destroy the cropper and remove the instance from the image + destroy: function destroy() { + var element = this.element, + image = this.image; + + + if (this.loaded) { + if (this.isImg && this.replaced) { + element.src = this.originalUrl; + } + + this.unbuild(); + removeClass(element, CLASS_HIDDEN); + } else if (this.isImg) { + removeListener(element, EVENT_LOAD, this.onStart); + } else if (image) { + image.parentNode.removeChild(image); + } + + removeData(element, NAMESPACE); + + return this; + }, + + + /** + * Move the canvas with relative offsets + * @param {number} offsetX - The relative offset distance on the x-axis. + * @param {number} offsetY - The relative offset distance on the y-axis. + * @returns {Object} this + */ + move: function move(offsetX, offsetY) { + var _canvasData = this.canvasData, + left = _canvasData.left, + top = _canvasData.top; + + + return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); + }, + + + /** + * Move the canvas to an absolute point + * @param {number} x - The x-axis coordinate. + * @param {number} [y=x] - The y-axis coordinate. + * @returns {Object} this + */ + moveTo: function moveTo(x) { + var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + var canvasData = this.canvasData; + + var changed = false; + + x = Number(x); + y = Number(y); + + if (this.ready && !this.disabled && this.options.movable) { + if (isNumber(x)) { + canvasData.left = x; + changed = true; + } + + if (isNumber(y)) { + canvasData.top = y; + changed = true; + } + + if (changed) { + this.renderCanvas(true); + } + } + + return this; + }, + + + /** + * Zoom the canvas with a relative ratio + * @param {number} ratio - The target ratio. + * @param {Event} _originalEvent - The original event if any. + * @returns {Object} this + */ + zoom: function zoom(ratio, _originalEvent) { + var canvasData = this.canvasData; + + + ratio = Number(ratio); + + if (ratio < 0) { + ratio = 1 / (1 - ratio); + } else { + ratio = 1 + ratio; + } + + return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent); + }, + + + /** + * Zoom the canvas to an absolute ratio + * @param {number} ratio - The target ratio. + * @param {Object} pivot - The zoom pivot point coordinate. + * @param {Event} _originalEvent - The original event if any. + * @returns {Object} this + */ + zoomTo: function zoomTo(ratio, pivot, _originalEvent) { + var options = this.options, + canvasData = this.canvasData; + var width = canvasData.width, + height = canvasData.height, + naturalWidth = canvasData.naturalWidth, + naturalHeight = canvasData.naturalHeight; + + + ratio = Number(ratio); + + if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) { + var newWidth = naturalWidth * ratio; + var newHeight = naturalHeight * ratio; + + if (dispatchEvent(this.element, EVENT_ZOOM, { + originalEvent: _originalEvent, + oldRatio: width / naturalWidth, + ratio: newWidth / naturalWidth + }) === false) { + return this; + } + + if (_originalEvent) { + var pointers = this.pointers; + + var offset = getOffset(this.cropper); + var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : { + pageX: _originalEvent.pageX, + pageY: _originalEvent.pageY + }; + + // Zoom from the triggering point of the event + canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width); + canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height); + } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) { + canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width); + canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height); + } else { + // Zoom from the center of the canvas + canvasData.left -= (newWidth - width) / 2; + canvasData.top -= (newHeight - height) / 2; + } + + canvasData.width = newWidth; + canvasData.height = newHeight; + this.renderCanvas(true); + } + + return this; + }, + + + /** + * Rotate the canvas with a relative degree + * @param {number} degree - The rotate degree. + * @returns {Object} this + */ + rotate: function rotate(degree) { + return this.rotateTo((this.imageData.rotate || 0) + Number(degree)); + }, + + + /** + * Rotate the canvas to an absolute degree + * @param {number} degree - The rotate degree. + * @returns {Object} this + */ + rotateTo: function rotateTo(degree) { + degree = Number(degree); + + if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) { + this.imageData.rotate = degree % 360; + this.renderCanvas(true, true); + } + + return this; + }, + + + /** + * Scale the image on the x-axis. + * @param {number} scaleX - The scale ratio on the x-axis. + * @returns {Object} this + */ + scaleX: function scaleX(_scaleX) { + var scaleY = this.imageData.scaleY; + + + return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1); + }, + + + /** + * Scale the image on the y-axis. + * @param {number} scaleY - The scale ratio on the y-axis. + * @returns {Object} this + */ + scaleY: function scaleY(_scaleY) { + var scaleX = this.imageData.scaleX; + + + return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); + }, + + + /** + * Scale the image + * @param {number} scaleX - The scale ratio on the x-axis. + * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis. + * @returns {Object} this + */ + scale: function scale(scaleX) { + var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX; + var imageData = this.imageData; + + var transformed = false; + + scaleX = Number(scaleX); + scaleY = Number(scaleY); + + if (this.ready && !this.disabled && this.options.scalable) { + if (isNumber(scaleX)) { + imageData.scaleX = scaleX; + transformed = true; + } + + if (isNumber(scaleY)) { + imageData.scaleY = scaleY; + transformed = true; + } + + if (transformed) { + this.renderCanvas(true, true); + } + } + + return this; + }, + + + /** + * Get the cropped area position and size data (base on the original image) + * @param {boolean} [rounded=false] - Indicate if round the data values or not. + * @returns {Object} The result cropped data. + */ + getData: function getData$$1() { + var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var options = this.options, + imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + + var data = void 0; + + if (this.ready && this.cropped) { + data = { + x: cropBoxData.left - canvasData.left, + y: cropBoxData.top - canvasData.top, + width: cropBoxData.width, + height: cropBoxData.height + }; + + var ratio = imageData.width / imageData.naturalWidth; + + each(data, function (n, i) { + n /= ratio; + data[i] = rounded ? Math.round(n) : n; + }); + } else { + data = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + } + + if (options.rotatable) { + data.rotate = imageData.rotate || 0; + } + + if (options.scalable) { + data.scaleX = imageData.scaleX || 1; + data.scaleY = imageData.scaleY || 1; + } + + return data; + }, + + + /** + * Set the cropped area position and size with new data + * @param {Object} data - The new data. + * @returns {Object} this + */ + setData: function setData$$1(data) { + var options = this.options, + imageData = this.imageData, + canvasData = this.canvasData; + + var cropBoxData = {}; + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && !this.disabled && isPlainObject(data)) { + var transformed = false; + + if (options.rotatable) { + if (isNumber(data.rotate) && data.rotate !== imageData.rotate) { + imageData.rotate = data.rotate; + transformed = true; + } + } + + if (options.scalable) { + if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) { + imageData.scaleX = data.scaleX; + transformed = true; + } + + if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) { + imageData.scaleY = data.scaleY; + transformed = true; + } + } + + if (transformed) { + this.renderCanvas(true, true); + } + + var ratio = imageData.width / imageData.naturalWidth; + + if (isNumber(data.x)) { + cropBoxData.left = data.x * ratio + canvasData.left; + } + + if (isNumber(data.y)) { + cropBoxData.top = data.y * ratio + canvasData.top; + } + + if (isNumber(data.width)) { + cropBoxData.width = data.width * ratio; + } + + if (isNumber(data.height)) { + cropBoxData.height = data.height * ratio; + } + + this.setCropBoxData(cropBoxData); + } + + return this; + }, + + + /** + * Get the container size data. + * @returns {Object} The result container data. + */ + getContainerData: function getContainerData() { + return this.ready ? extend({}, this.containerData) : {}; + }, + + + /** + * Get the image position and size data. + * @returns {Object} The result image data. + */ + getImageData: function getImageData() { + return this.loaded ? extend({}, this.imageData) : {}; + }, + + + /** + * Get the canvas position and size data. + * @returns {Object} The result canvas data. + */ + getCanvasData: function getCanvasData() { + var canvasData = this.canvasData; + + var data = {}; + + if (this.ready) { + each(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) { + data[n] = canvasData[n]; + }); + } + + return data; + }, + + + /** + * Set the canvas position and size with new data. + * @param {Object} data - The new canvas data. + * @returns {Object} this + */ + setCanvasData: function setCanvasData(data) { + var canvasData = this.canvasData; + var aspectRatio = canvasData.aspectRatio; + + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && !this.disabled && isPlainObject(data)) { + if (isNumber(data.left)) { + canvasData.left = data.left; + } + + if (isNumber(data.top)) { + canvasData.top = data.top; + } + + if (isNumber(data.width)) { + canvasData.width = data.width; + canvasData.height = data.width / aspectRatio; + } else if (isNumber(data.height)) { + canvasData.height = data.height; + canvasData.width = data.height * aspectRatio; + } + + this.renderCanvas(true); + } + + return this; + }, + + + /** + * Get the crop box position and size data. + * @returns {Object} The result crop box data. + */ + getCropBoxData: function getCropBoxData() { + var cropBoxData = this.cropBoxData; + + var data = void 0; + + if (this.ready && this.cropped) { + data = { + left: cropBoxData.left, + top: cropBoxData.top, + width: cropBoxData.width, + height: cropBoxData.height + }; + } + + return data || {}; + }, + + + /** + * Set the crop box position and size with new data. + * @param {Object} data - The new crop box data. + * @returns {Object} this + */ + setCropBoxData: function setCropBoxData(data) { + var cropBoxData = this.cropBoxData; + var aspectRatio = this.options.aspectRatio; + + var widthChanged = void 0; + var heightChanged = void 0; + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) { + if (isNumber(data.left)) { + cropBoxData.left = data.left; + } + + if (isNumber(data.top)) { + cropBoxData.top = data.top; + } + + if (isNumber(data.width) && data.width !== cropBoxData.width) { + widthChanged = true; + cropBoxData.width = data.width; + } + + if (isNumber(data.height) && data.height !== cropBoxData.height) { + heightChanged = true; + cropBoxData.height = data.height; + } + + if (aspectRatio) { + if (widthChanged) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else if (heightChanged) { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + this.renderCropBox(); + } + + return this; + }, + + + /** + * Get a canvas drawn the cropped image. + * @param {Object} [options={}] - The config options. + * @returns {HTMLCanvasElement} - The result canvas. + */ + getCroppedCanvas: function getCroppedCanvas() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (!this.ready || !window.HTMLCanvasElement) { + return null; + } + + var canvasData = this.canvasData; + + var source = getSourceCanvas(this.image, this.imageData, canvasData, options); + + // Returns the source canvas if it is not cropped. + if (!this.cropped) { + return source; + } + + var _getData = this.getData(), + x = _getData.x, + y = _getData.y, + initialWidth = _getData.width, + initialHeight = _getData.height; + + var aspectRatio = initialWidth / initialHeight; + var maxSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.maxWidth || Infinity, + height: options.maxHeight || Infinity + }); + var minSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.minWidth || 0, + height: options.minHeight || 0 + }); + + var _getContainSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.width || initialWidth, + height: options.height || initialHeight + }), + width = _getContainSizes.width, + height = _getContainSizes.height; + + width = Math.min(maxSizes.width, Math.max(minSizes.width, width)); + height = Math.min(maxSizes.height, Math.max(minSizes.height, height)); + + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + + canvas.width = normalizeDecimalNumber(width); + canvas.height = normalizeDecimalNumber(height); + + context.fillStyle = options.fillColor || 'transparent'; + context.fillRect(0, 0, width, height); + + var _options$imageSmoothi = options.imageSmoothingEnabled, + imageSmoothingEnabled = _options$imageSmoothi === undefined ? true : _options$imageSmoothi, + imageSmoothingQuality = options.imageSmoothingQuality; + + + context.imageSmoothingEnabled = imageSmoothingEnabled; + + if (imageSmoothingQuality) { + context.imageSmoothingQuality = imageSmoothingQuality; + } + + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage + var sourceWidth = source.width; + var sourceHeight = source.height; + + // Source canvas parameters + var srcX = x; + var srcY = y; + var srcWidth = void 0; + var srcHeight = void 0; + + // Destination canvas parameters + var dstX = void 0; + var dstY = void 0; + var dstWidth = void 0; + var dstHeight = void 0; + + if (srcX <= -initialWidth || srcX > sourceWidth) { + srcX = 0; + srcWidth = 0; + dstX = 0; + dstWidth = 0; + } else if (srcX <= 0) { + dstX = -srcX; + srcX = 0; + srcWidth = Math.min(sourceWidth, initialWidth + srcX); + dstWidth = srcWidth; + } else if (srcX <= sourceWidth) { + dstX = 0; + srcWidth = Math.min(initialWidth, sourceWidth - srcX); + dstWidth = srcWidth; + } + + if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) { + srcY = 0; + srcHeight = 0; + dstY = 0; + dstHeight = 0; + } else if (srcY <= 0) { + dstY = -srcY; + srcY = 0; + srcHeight = Math.min(sourceHeight, initialHeight + srcY); + dstHeight = srcHeight; + } else if (srcY <= sourceHeight) { + dstY = 0; + srcHeight = Math.min(initialHeight, sourceHeight - srcY); + dstHeight = srcHeight; + } + + // All the numerical parameters should be integer for `drawImage` + // https://github.com/fengyuanchen/cropper/issues/476 + var params = [srcX, srcY, srcWidth, srcHeight]; + + // Avoid "IndexSizeError" + if (dstWidth > 0 && dstHeight > 0) { + var scale = width / initialWidth; + + params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale); + } + + context.drawImage.apply(context, [source].concat(toConsumableArray(params.map(function (param) { + return Math.floor(normalizeDecimalNumber(param)); + })))); + + return canvas; + }, + + + /** + * Change the aspect ratio of the crop box. + * @param {number} aspectRatio - The new aspect ratio. + * @returns {Object} this + */ + setAspectRatio: function setAspectRatio(aspectRatio) { + var options = this.options; + + + if (!this.disabled && !isUndefined(aspectRatio)) { + // 0 -> NaN + options.aspectRatio = Math.max(0, aspectRatio) || NaN; + + if (this.ready) { + this.initCropBox(); + + if (this.cropped) { + this.renderCropBox(); + } + } + } + + return this; + }, + + + /** + * Change the drag mode. + * @param {string} mode - The new drag mode. + * @returns {Object} this + */ + setDragMode: function setDragMode(mode) { + var options = this.options, + dragBox = this.dragBox, + face = this.face; + + + if (this.loaded && !this.disabled) { + var croppable = mode === DRAG_MODE_CROP; + var movable = options.movable && mode === DRAG_MODE_MOVE; + + mode = croppable || movable ? mode : DRAG_MODE_NONE; + + setData(dragBox, DATA_ACTION, mode); + toggleClass(dragBox, CLASS_CROP, croppable); + toggleClass(dragBox, CLASS_MOVE, movable); + + if (!options.cropBoxMovable) { + // Sync drag mode to crop box when it is not movable + setData(face, DATA_ACTION, mode); + toggleClass(face, CLASS_CROP, croppable); + toggleClass(face, CLASS_MOVE, movable); + } + } + + return this; + } +}; + +var AnotherCropper = WINDOW.Cropper; + +var Cropper = function () { + /** + * Create a new Cropper. + * @param {Element} element - The target element for cropping. + * @param {Object} [options={}] - The configuration options. + */ + function Cropper(element) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + classCallCheck(this, Cropper); + + if (!element || !REGEXP_TAG_NAME.test(element.tagName)) { + throw new Error('The first argument is required and must be an or element.'); + } + + this.element = element; + this.options = extend({}, DEFAULTS, isPlainObject(options) && options); + this.complete = false; + this.cropped = false; + this.disabled = false; + this.isImg = false; + this.limited = false; + this.loaded = false; + this.ready = false; + this.replaced = false; + this.wheeling = false; + this.originalUrl = ''; + this.canvasData = null; + this.cropBoxData = null; + this.previews = null; + this.pointers = {}; + this.init(); + } + + createClass(Cropper, [{ + key: 'init', + value: function init() { + var element = this.element; + + var tagName = element.tagName.toLowerCase(); + var url = void 0; + + if (getData(element, NAMESPACE)) { + return; + } + + setData(element, NAMESPACE, this); + + if (tagName === 'img') { + this.isImg = true; + + // e.g.: "img/picture.jpg" + url = element.getAttribute('src') || ''; + this.originalUrl = url; + + // Stop when it's a blank image + if (!url) { + return; + } + + // e.g.: "http://example.com/img/picture.jpg" + url = element.src; + } else if (tagName === 'canvas' && window.HTMLCanvasElement) { + url = element.toDataURL(); + } + + this.load(url); + } + }, { + key: 'load', + value: function load(url) { + var _this = this; + + if (!url) { + return; + } + + this.url = url; + this.imageData = {}; + + var element = this.element, + options = this.options; + + + if (!options.checkOrientation || !window.ArrayBuffer) { + this.clone(); + return; + } + + // XMLHttpRequest disallows to open a Data URL in some browsers like IE11 and Safari + if (REGEXP_DATA_URL.test(url)) { + if (REGEXP_DATA_URL_JPEG.test(url)) { + this.read(dataURLToArrayBuffer(url)); + } else { + this.clone(); + } + + return; + } + + var xhr = new XMLHttpRequest(); + + xhr.onerror = function () { + _this.clone(); + }; + + xhr.onload = function () { + _this.read(xhr.response); + }; + + if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) { + url = addTimestamp(url); + } + + xhr.open('get', url); + xhr.responseType = 'arraybuffer'; + xhr.withCredentials = element.crossOrigin === 'use-credentials'; + xhr.send(); + } + }, { + key: 'read', + value: function read(arrayBuffer) { + var options = this.options, + imageData = this.imageData; + + var orientation = getOrientation(arrayBuffer); + var rotate = 0; + var scaleX = 1; + var scaleY = 1; + + if (orientation > 1) { + this.url = arrayBufferToDataURL(arrayBuffer, 'image/jpeg'); + + var _parseOrientation = parseOrientation(orientation); + + rotate = _parseOrientation.rotate; + scaleX = _parseOrientation.scaleX; + scaleY = _parseOrientation.scaleY; + } + + if (options.rotatable) { + imageData.rotate = rotate; + } + + if (options.scalable) { + imageData.scaleX = scaleX; + imageData.scaleY = scaleY; + } + + this.clone(); + } + }, { + key: 'clone', + value: function clone() { + var element = this.element, + url = this.url; + + var crossOrigin = void 0; + var crossOriginUrl = void 0; + + if (this.options.checkCrossOrigin && isCrossOriginURL(url)) { + crossOrigin = element.crossOrigin; + + + if (crossOrigin) { + crossOriginUrl = url; + } else { + crossOrigin = 'anonymous'; + + // Bust cache when there is not a "crossOrigin" property + crossOriginUrl = addTimestamp(url); + } + } + + this.crossOrigin = crossOrigin; + this.crossOriginUrl = crossOriginUrl; + + var image = document.createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = crossOriginUrl || url; + + var start = proxy(this.start, this); + var stop = proxy(this.stop, this); + + this.image = image; + this.onStart = start; + this.onStop = stop; + + if (this.isImg) { + if (element.complete) { + this.start(); + } else { + addListener(element, EVENT_LOAD, start); + } + } else { + addListener(image, EVENT_LOAD, start); + addListener(image, EVENT_ERROR, stop); + addClass(image, CLASS_HIDE); + element.parentNode.insertBefore(image, element.nextSibling); + } + } + }, { + key: 'start', + value: function start(event) { + var _this2 = this; + + var image = this.isImg ? this.element : this.image; + + if (event) { + removeListener(image, EVENT_LOAD, this.onStart); + removeListener(image, EVENT_ERROR, this.onStop); + } + + getImageNaturalSizes(image, function (naturalWidth, naturalHeight) { + extend(_this2.imageData, { + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + aspectRatio: naturalWidth / naturalHeight + }); + _this2.loaded = true; + _this2.build(); + }); + } + }, { + key: 'stop', + value: function stop() { + var image = this.image; + + + removeListener(image, EVENT_LOAD, this.onStart); + removeListener(image, EVENT_ERROR, this.onStop); + image.parentNode.removeChild(image); + this.image = null; + } + }, { + key: 'build', + value: function build() { + var _this3 = this; + + if (!this.loaded) { + return; + } + + // Unbuild first when replace + if (this.ready) { + this.unbuild(); + } + + var element = this.element, + options = this.options, + image = this.image; + + // Create cropper elements + + var container = element.parentNode; + var template = document.createElement('div'); + + template.innerHTML = TEMPLATE; + + var cropper = template.querySelector('.' + NAMESPACE + '-container'); + var canvas = cropper.querySelector('.' + NAMESPACE + '-canvas'); + var dragBox = cropper.querySelector('.' + NAMESPACE + '-drag-box'); + var cropBox = cropper.querySelector('.' + NAMESPACE + '-crop-box'); + var face = cropBox.querySelector('.' + NAMESPACE + '-face'); + + this.container = container; + this.cropper = cropper; + this.canvas = canvas; + this.dragBox = dragBox; + this.cropBox = cropBox; + this.viewBox = cropper.querySelector('.' + NAMESPACE + '-view-box'); + this.face = face; + + canvas.appendChild(image); + + // Hide the original image + addClass(element, CLASS_HIDDEN); + + // Inserts the cropper after to the current image + container.insertBefore(cropper, element.nextSibling); + + // Show the image if is hidden + if (!this.isImg) { + removeClass(image, CLASS_HIDE); + } + + this.initPreview(); + this.bind(); + + options.aspectRatio = Math.max(0, options.aspectRatio) || NaN; + options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0; + + this.cropped = options.autoCrop; + + if (options.autoCrop) { + if (options.modal) { + addClass(dragBox, CLASS_MODAL); + } + } else { + addClass(cropBox, CLASS_HIDDEN); + } + + if (!options.guides) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-dashed'), CLASS_HIDDEN); + } + + if (!options.center) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-center'), CLASS_HIDDEN); + } + + if (options.background) { + addClass(cropper, NAMESPACE + '-bg'); + } + + if (!options.highlight) { + addClass(face, CLASS_INVISIBLE); + } + + if (options.cropBoxMovable) { + addClass(face, CLASS_MOVE); + setData(face, DATA_ACTION, ACTION_ALL); + } + + if (!options.cropBoxResizable) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-line'), CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-point'), CLASS_HIDDEN); + } + + this.setDragMode(options.dragMode); + this.render(); + this.ready = true; + this.setData(options.data); + + // Call the "ready" option asynchronously to keep "image.cropper" is defined + this.completing = setTimeout(function () { + if (isFunction(options.ready)) { + addListener(element, EVENT_READY, options.ready, { + once: true + }); + } + + dispatchEvent(element, EVENT_READY); + dispatchEvent(element, EVENT_CROP, _this3.getData()); + + _this3.complete = true; + }, 0); + } + }, { + key: 'unbuild', + value: function unbuild() { + if (!this.ready) { + return; + } + + if (!this.complete) { + clearTimeout(this.completing); + } + + this.ready = false; + this.complete = false; + this.initialImageData = null; + + // Clear `initialCanvasData` is necessary when replace + this.initialCanvasData = null; + this.initialCropBoxData = null; + this.containerData = null; + this.canvasData = null; + + // Clear `cropBoxData` is necessary when replace + this.cropBoxData = null; + this.unbind(); + this.resetPreview(); + this.previews = null; + this.viewBox = null; + this.cropBox = null; + this.dragBox = null; + this.canvas = null; + this.container = null; + this.cropper.parentNode.removeChild(this.cropper); + this.cropper = null; + } + + /** + * Get the no conflict cropper class. + * @returns {Cropper} The cropper class. + */ + + }], [{ + key: 'noConflict', + value: function noConflict() { + window.Cropper = AnotherCropper; + return Cropper; + } + + /** + * Change the default options. + * @param {Object} options - The new default options. + */ + + }, { + key: 'setDefaults', + value: function setDefaults(options) { + extend(DEFAULTS, isPlainObject(options) && options); + } + }]); + return Cropper; +}(); + +extend(Cropper.prototype, render, preview, events, handlers, change, methods); + +export default Cropper; diff --git a/library/cropperjs/dist/cropper.js b/library/cropperjs/dist/cropper.js new file mode 100644 index 000000000..0e837953c --- /dev/null +++ b/library/cropperjs/dist/cropper.js @@ -0,0 +1,3766 @@ +/*! + * Cropper.js v1.2.2 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2018 Chen Fengyuan + * Released under the MIT license + * + * Date: 2018-01-03T13:27:18.062Z + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.Cropper = factory()); +}(this, (function () { 'use strict'; + +var WINDOW = typeof window !== 'undefined' ? window : {}; +var NAMESPACE = 'cropper'; + +// Actions +var ACTION_ALL = 'all'; +var ACTION_CROP = 'crop'; +var ACTION_MOVE = 'move'; +var ACTION_ZOOM = 'zoom'; +var ACTION_EAST = 'e'; +var ACTION_WEST = 'w'; +var ACTION_SOUTH = 's'; +var ACTION_NORTH = 'n'; +var ACTION_NORTH_EAST = 'ne'; +var ACTION_NORTH_WEST = 'nw'; +var ACTION_SOUTH_EAST = 'se'; +var ACTION_SOUTH_WEST = 'sw'; + +// Classes +var CLASS_CROP = NAMESPACE + '-crop'; +var CLASS_DISABLED = NAMESPACE + '-disabled'; +var CLASS_HIDDEN = NAMESPACE + '-hidden'; +var CLASS_HIDE = NAMESPACE + '-hide'; +var CLASS_INVISIBLE = NAMESPACE + '-invisible'; +var CLASS_MODAL = NAMESPACE + '-modal'; +var CLASS_MOVE = NAMESPACE + '-move'; + +// Data keys +var DATA_ACTION = 'action'; +var DATA_PREVIEW = 'preview'; + +// Drag modes +var DRAG_MODE_CROP = 'crop'; +var DRAG_MODE_MOVE = 'move'; +var DRAG_MODE_NONE = 'none'; + +// Events +var EVENT_CROP = 'crop'; +var EVENT_CROP_END = 'cropend'; +var EVENT_CROP_MOVE = 'cropmove'; +var EVENT_CROP_START = 'cropstart'; +var EVENT_DBLCLICK = 'dblclick'; +var EVENT_ERROR = 'error'; +var EVENT_LOAD = 'load'; +var EVENT_POINTER_DOWN = WINDOW.PointerEvent ? 'pointerdown' : 'touchstart mousedown'; +var EVENT_POINTER_MOVE = WINDOW.PointerEvent ? 'pointermove' : 'touchmove mousemove'; +var EVENT_POINTER_UP = WINDOW.PointerEvent ? 'pointerup pointercancel' : 'touchend touchcancel mouseup'; +var EVENT_READY = 'ready'; +var EVENT_RESIZE = 'resize'; +var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll'; +var EVENT_ZOOM = 'zoom'; + +// RegExps +var REGEXP_ACTIONS = /^(e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/; +var REGEXP_DATA_URL = /^data:/; +var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/; +var REGEXP_TAG_NAME = /^(img|canvas)$/i; + +var DEFAULTS = { + // Define the view mode of the cropper + viewMode: 0, // 0, 1, 2, 3 + + // Define the dragging mode of the cropper + dragMode: DRAG_MODE_CROP, // 'crop', 'move' or 'none' + + // Define the aspect ratio of the crop box + aspectRatio: NaN, + + // An object with the previous cropping result data + data: null, + + // A selector for adding extra containers to preview + preview: '', + + // Re-render the cropper when resize the window + responsive: true, + + // Restore the cropped area after resize the window + restore: true, + + // Check if the current image is a cross-origin image + checkCrossOrigin: true, + + // Check the current image's Exif Orientation information + checkOrientation: true, + + // Show the black modal + modal: true, + + // Show the dashed lines for guiding + guides: true, + + // Show the center indicator for guiding + center: true, + + // Show the white modal to highlight the crop box + highlight: true, + + // Show the grid background + background: true, + + // Enable to crop the image automatically when initialize + autoCrop: true, + + // Define the percentage of automatic cropping area when initializes + autoCropArea: 0.8, + + // Enable to move the image + movable: true, + + // Enable to rotate the image + rotatable: true, + + // Enable to scale the image + scalable: true, + + // Enable to zoom the image + zoomable: true, + + // Enable to zoom the image by dragging touch + zoomOnTouch: true, + + // Enable to zoom the image by wheeling mouse + zoomOnWheel: true, + + // Define zoom ratio when zoom the image by wheeling mouse + wheelZoomRatio: 0.1, + + // Enable to move the crop box + cropBoxMovable: true, + + // Enable to resize the crop box + cropBoxResizable: true, + + // Toggle drag mode between "crop" and "move" when click twice on the cropper + toggleDragModeOnDblclick: true, + + // Size limitation + minCanvasWidth: 0, + minCanvasHeight: 0, + minCropBoxWidth: 0, + minCropBoxHeight: 0, + minContainerWidth: 200, + minContainerHeight: 100, + + // Shortcuts of events + ready: null, + cropstart: null, + cropmove: null, + cropend: null, + crop: null, + zoom: null +}; + +var TEMPLATE = '
' + '
' + '
' + '
' + '
' + '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
' + '
'; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + + + + + + + + + + + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + +var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +var toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } else { + return Array.from(arr); + } +}; + +/** + * Check if the given value is not a number. + */ +var isNaN = Number.isNaN || WINDOW.isNaN; + +/** + * Check if the given value is a number. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a number, else `false`. + */ +function isNumber(value) { + return typeof value === 'number' && !isNaN(value); +} + +/** + * Check if the given value is undefined. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is undefined, else `false`. + */ +function isUndefined(value) { + return typeof value === 'undefined'; +} + +/** + * Check if the given value is an object. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is an object, else `false`. + */ +function isObject(value) { + return (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && value !== null; +} + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +/** + * Check if the given value is a plain object. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a plain object, else `false`. + */ + +function isPlainObject(value) { + if (!isObject(value)) { + return false; + } + + try { + var _constructor = value.constructor; + var prototype = _constructor.prototype; + + + return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf'); + } catch (e) { + return false; + } +} + +/** + * Check if the given value is a function. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a function, else `false`. + */ +function isFunction(value) { + return typeof value === 'function'; +} + +/** + * Iterate the given data. + * @param {*} data - The data to iterate. + * @param {Function} callback - The process function for each element. + * @returns {*} The original data. + */ +function each(data, callback) { + if (data && isFunction(callback)) { + if (Array.isArray(data) || isNumber(data.length) /* array-like */) { + var length = data.length; + + var i = void 0; + + for (i = 0; i < length; i += 1) { + if (callback.call(data, data[i], i, data) === false) { + break; + } + } + } else if (isObject(data)) { + Object.keys(data).forEach(function (key) { + callback.call(data, data[key], key, data); + }); + } + } + + return data; +} + +/** + * Extend the given object. + * @param {*} obj - The object to be extended. + * @param {*} args - The rest objects which will be merged to the first object. + * @returns {Object} The extended object. + */ +function extend(obj) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + if (isObject(obj) && args.length > 0) { + if (Object.assign) { + return Object.assign.apply(Object, [obj].concat(args)); + } + + args.forEach(function (arg) { + if (isObject(arg)) { + Object.keys(arg).forEach(function (key) { + obj[key] = arg[key]; + }); + } + }); + } + + return obj; +} + +/** + * Takes a function and returns a new one that will always have a particular context. + * @param {Function} fn - The target function. + * @param {Object} context - The new context for the function. + * @returns {boolean} The new function. + */ +function proxy(fn, context) { + for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { + args[_key2 - 2] = arguments[_key2]; + } + + return function () { + for (var _len3 = arguments.length, args2 = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args2[_key3] = arguments[_key3]; + } + + return fn.apply(context, args.concat(args2)); + }; +} + +var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/i; + +/** + * Normalize decimal number. + * Check out {@link http://0.30000000000000004.com/ } + * @param {number} value - The value to normalize. + * @param {number} [times=100000000000] - The times for normalizing. + * @returns {number} Returns the normalized number. + */ +function normalizeDecimalNumber(value) { + var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000; + + return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value; +} + +var REGEXP_SUFFIX = /^(width|height|left|top|marginLeft|marginTop)$/; + +/** + * Apply styles to the given element. + * @param {Element} element - The target element. + * @param {Object} styles - The styles for applying. + */ +function setStyle(element, styles) { + var style = element.style; + + + each(styles, function (value, property) { + if (REGEXP_SUFFIX.test(property) && isNumber(value)) { + value += 'px'; + } + + style[property] = value; + }); +} + +/** + * Check if the given element has a special class. + * @param {Element} element - The element to check. + * @param {string} value - The class to search. + * @returns {boolean} Returns `true` if the special class was found. + */ +function hasClass(element, value) { + return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1; +} + +/** + * Add classes to the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be added. + */ +function addClass(element, value) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + addClass(elem, value); + }); + return; + } + + if (element.classList) { + element.classList.add(value); + return; + } + + var className = element.className.trim(); + + if (!className) { + element.className = value; + } else if (className.indexOf(value) < 0) { + element.className = className + ' ' + value; + } +} + +/** + * Remove classes from the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be removed. + */ +function removeClass(element, value) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + removeClass(elem, value); + }); + return; + } + + if (element.classList) { + element.classList.remove(value); + return; + } + + if (element.className.indexOf(value) >= 0) { + element.className = element.className.replace(value, ''); + } +} + +/** + * Add or remove classes from the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be toggled. + * @param {boolean} added - Add only. + */ +function toggleClass(element, value, added) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + toggleClass(elem, value, added); + }); + return; + } + + // IE10-11 doesn't support the second parameter of `classList.toggle` + if (added) { + addClass(element, value); + } else { + removeClass(element, value); + } +} + +var REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g; + +/** + * Hyphenate the given value. + * @param {string} value - The value to hyphenate. + * @returns {string} The hyphenated value. + */ +function hyphenate(value) { + return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase(); +} + +/** + * Get data from the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to get. + * @returns {string} The data value. + */ +function getData(element, name) { + if (isObject(element[name])) { + return element[name]; + } else if (element.dataset) { + return element.dataset[name]; + } + + return element.getAttribute('data-' + hyphenate(name)); +} + +/** + * Set data to the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to set. + * @param {string} data - The data value. + */ +function setData(element, name, data) { + if (isObject(data)) { + element[name] = data; + } else if (element.dataset) { + element.dataset[name] = data; + } else { + element.setAttribute('data-' + hyphenate(name), data); + } +} + +/** + * Remove data from the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to remove. + */ +function removeData(element, name) { + if (isObject(element[name])) { + try { + delete element[name]; + } catch (e) { + element[name] = null; + } + } else if (element.dataset) { + // #128 Safari not allows to delete dataset property + try { + delete element.dataset[name]; + } catch (e) { + element.dataset[name] = null; + } + } else { + element.removeAttribute('data-' + hyphenate(name)); + } +} + +var REGEXP_SPACES = /\s+/; + +/** + * Remove event listener from the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Function} listener - The event listener. + * @param {Object} options - The event options. + */ +function removeListener(element, type, listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + if (!isFunction(listener)) { + return; + } + + var types = type.trim().split(REGEXP_SPACES); + + if (types.length > 1) { + each(types, function (t) { + removeListener(element, t, listener, options); + }); + return; + } + + if (element.removeEventListener) { + element.removeEventListener(type, listener, options); + } else if (element.detachEvent) { + element.detachEvent('on' + type, listener); + } +} + +/** + * Add event listener to the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Function} listener - The event listener. + * @param {Object} options - The event options. + */ +function addListener(element, type, _listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + if (!isFunction(_listener)) { + return; + } + + var types = type.trim().split(REGEXP_SPACES); + + if (types.length > 1) { + each(types, function (t) { + addListener(element, t, _listener, options); + }); + return; + } + + if (options.once) { + var originalListener = _listener; + + _listener = function listener() { + for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + removeListener(element, type, _listener, options); + return originalListener.apply(element, args); + }; + } + + if (element.addEventListener) { + element.addEventListener(type, _listener, options); + } else if (element.attachEvent) { + element.attachEvent('on' + type, _listener); + } +} + +/** + * Dispatch event on the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Object} data - The additional event data. + * @returns {boolean} Indicate if the event is default prevented or not. + */ +function dispatchEvent(element, type, data) { + if (element.dispatchEvent) { + var event = void 0; + + // Event and CustomEvent on IE9-11 are global objects, not constructors + if (isFunction(Event) && isFunction(CustomEvent)) { + if (isUndefined(data)) { + event = new Event(type, { + bubbles: true, + cancelable: true + }); + } else { + event = new CustomEvent(type, { + detail: data, + bubbles: true, + cancelable: true + }); + } + } else if (isUndefined(data)) { + event = document.createEvent('Event'); + event.initEvent(type, true, true); + } else { + event = document.createEvent('CustomEvent'); + event.initCustomEvent(type, true, true, data); + } + + // IE9+ + return element.dispatchEvent(event); + } else if (element.fireEvent) { + // IE6-10 (native events only) + return element.fireEvent('on' + type); + } + + return true; +} + +/** + * Get the offset base on the document. + * @param {Element} element - The target element. + * @returns {Object} The offset data. + */ +function getOffset(element) { + var doc = document.documentElement; + var box = element.getBoundingClientRect(); + + return { + left: box.left + ((window.scrollX || doc && doc.scrollLeft || 0) - (doc && doc.clientLeft || 0)), + top: box.top + ((window.scrollY || doc && doc.scrollTop || 0) - (doc && doc.clientTop || 0)) + }; +} + +/** + * Empty an element. + * @param {Element} element - The element to empty. + */ +function empty(element) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } +} + +var location = WINDOW.location; + +var REGEXP_ORIGINS = /^(https?:)\/\/([^:/?#]+):?(\d*)/i; + +/** + * Check if the given URL is a cross origin URL. + * @param {string} url - The target URL. + * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`. + */ +function isCrossOriginURL(url) { + var parts = url.match(REGEXP_ORIGINS); + + return parts && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port); +} + +/** + * Add timestamp to the given URL. + * @param {string} url - The target URL. + * @returns {string} The result URL. + */ +function addTimestamp(url) { + var timestamp = 'timestamp=' + new Date().getTime(); + + return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp; +} + +/** + * Get transforms base on the given object. + * @param {Object} obj - The target object. + * @returns {string} A string contains transform values. + */ +function getTransforms(_ref) { + var rotate = _ref.rotate, + scaleX = _ref.scaleX, + scaleY = _ref.scaleY, + translateX = _ref.translateX, + translateY = _ref.translateY; + + var values = []; + + if (isNumber(translateX) && translateX !== 0) { + values.push('translateX(' + translateX + 'px)'); + } + + if (isNumber(translateY) && translateY !== 0) { + values.push('translateY(' + translateY + 'px)'); + } + + // Rotate should come first before scale to match orientation transform + if (isNumber(rotate) && rotate !== 0) { + values.push('rotate(' + rotate + 'deg)'); + } + + if (isNumber(scaleX) && scaleX !== 1) { + values.push('scaleX(' + scaleX + ')'); + } + + if (isNumber(scaleY) && scaleY !== 1) { + values.push('scaleY(' + scaleY + ')'); + } + + var transform = values.length ? values.join(' ') : 'none'; + + return { + WebkitTransform: transform, + msTransform: transform, + transform: transform + }; +} + +var navigator = WINDOW.navigator; + +var IS_SAFARI_OR_UIWEBVIEW = navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent); + +/** + * Get an image's natural sizes. + * @param {string} image - The target image. + * @param {Function} callback - The callback function. + */ +function getImageNaturalSizes(image, callback) { + // Modern browsers (except Safari) + if (image.naturalWidth && !IS_SAFARI_OR_UIWEBVIEW) { + callback(image.naturalWidth, image.naturalHeight); + return; + } + + var newImage = document.createElement('img'); + var body = document.body || document.documentElement; + + newImage.onload = function () { + callback(newImage.width, newImage.height); + + if (!IS_SAFARI_OR_UIWEBVIEW) { + body.removeChild(newImage); + } + }; + + newImage.src = image.src; + + // iOS Safari will convert the image automatically + // with its orientation once append it into DOM (#279) + if (!IS_SAFARI_OR_UIWEBVIEW) { + newImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;'; + body.appendChild(newImage); + } +} + +/** + * Get the max ratio of a group of pointers. + * @param {string} pointers - The target pointers. + * @returns {number} The result ratio. + */ +function getMaxZoomRatio(pointers) { + var pointers2 = extend({}, pointers); + var ratios = []; + + each(pointers, function (pointer, pointerId) { + delete pointers2[pointerId]; + + each(pointers2, function (pointer2) { + var x1 = Math.abs(pointer.startX - pointer2.startX); + var y1 = Math.abs(pointer.startY - pointer2.startY); + var x2 = Math.abs(pointer.endX - pointer2.endX); + var y2 = Math.abs(pointer.endY - pointer2.endY); + var z1 = Math.sqrt(x1 * x1 + y1 * y1); + var z2 = Math.sqrt(x2 * x2 + y2 * y2); + var ratio = (z2 - z1) / z1; + + ratios.push(ratio); + }); + }); + + ratios.sort(function (a, b) { + return Math.abs(a) < Math.abs(b); + }); + + return ratios[0]; +} + +/** + * Get a pointer from an event object. + * @param {Object} event - The target event object. + * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not. + * @returns {Object} The result pointer contains start and/or end point coordinates. + */ +function getPointer(_ref2, endOnly) { + var pageX = _ref2.pageX, + pageY = _ref2.pageY; + + var end = { + endX: pageX, + endY: pageY + }; + + if (endOnly) { + return end; + } + + return extend({ + startX: pageX, + startY: pageY + }, end); +} + +/** + * Get the center point coordinate of a group of pointers. + * @param {Object} pointers - The target pointers. + * @returns {Object} The center point coordinate. + */ +function getPointersCenter(pointers) { + var pageX = 0; + var pageY = 0; + var count = 0; + + each(pointers, function (_ref3) { + var startX = _ref3.startX, + startY = _ref3.startY; + + pageX += startX; + pageY += startY; + count += 1; + }); + + pageX /= count; + pageY /= count; + + return { + pageX: pageX, + pageY: pageY + }; +} + +/** + * Check if the given value is a finite number. + */ +var isFinite = Number.isFinite || WINDOW.isFinite; + +/** + * Get the max sizes in a rectangle under the given aspect ratio. + * @param {Object} data - The original sizes. + * @returns {Object} The result sizes. + */ +function getContainSizes(_ref4) { + var aspectRatio = _ref4.aspectRatio, + height = _ref4.height, + width = _ref4.width; + + var isValidNumber = function isValidNumber(value) { + return isFinite(value) && value > 0; + }; + + if (isValidNumber(width) && isValidNumber(height)) { + if (height * aspectRatio > width) { + height = width / aspectRatio; + } else { + width = height * aspectRatio; + } + } else if (isValidNumber(width)) { + height = width / aspectRatio; + } else if (isValidNumber(height)) { + width = height * aspectRatio; + } + + return { + width: width, + height: height + }; +} + +/** + * Get the new sizes of a rectangle after rotated. + * @param {Object} data - The original sizes. + * @returns {Object} The result sizes. + */ +function getRotatedSizes(_ref5) { + var width = _ref5.width, + height = _ref5.height, + degree = _ref5.degree; + + degree = Math.abs(degree) % 180; + + if (degree === 90) { + return { + width: height, + height: width + }; + } + + var arc = degree % 90 * Math.PI / 180; + var sinArc = Math.sin(arc); + var cosArc = Math.cos(arc); + var newWidth = width * cosArc + height * sinArc; + var newHeight = width * sinArc + height * cosArc; + + return degree > 90 ? { + width: newHeight, + height: newWidth + } : { + width: newWidth, + height: newHeight + }; +} + +/** + * Get a canvas which drew the given image. + * @param {HTMLImageElement} image - The image for drawing. + * @param {Object} imageData - The image data. + * @param {Object} canvasData - The canvas data. + * @param {Object} options - The options. + * @returns {HTMLCanvasElement} The result canvas. + */ +function getSourceCanvas(image, _ref6, _ref7, _ref8) { + var imageNaturalWidth = _ref6.naturalWidth, + imageNaturalHeight = _ref6.naturalHeight, + _ref6$rotate = _ref6.rotate, + rotate = _ref6$rotate === undefined ? 0 : _ref6$rotate, + _ref6$scaleX = _ref6.scaleX, + scaleX = _ref6$scaleX === undefined ? 1 : _ref6$scaleX, + _ref6$scaleY = _ref6.scaleY, + scaleY = _ref6$scaleY === undefined ? 1 : _ref6$scaleY; + var aspectRatio = _ref7.aspectRatio, + naturalWidth = _ref7.naturalWidth, + naturalHeight = _ref7.naturalHeight; + var _ref8$fillColor = _ref8.fillColor, + fillColor = _ref8$fillColor === undefined ? 'transparent' : _ref8$fillColor, + _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled, + imageSmoothingEnabled = _ref8$imageSmoothingE === undefined ? true : _ref8$imageSmoothingE, + _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality, + imageSmoothingQuality = _ref8$imageSmoothingQ === undefined ? 'low' : _ref8$imageSmoothingQ, + _ref8$maxWidth = _ref8.maxWidth, + maxWidth = _ref8$maxWidth === undefined ? Infinity : _ref8$maxWidth, + _ref8$maxHeight = _ref8.maxHeight, + maxHeight = _ref8$maxHeight === undefined ? Infinity : _ref8$maxHeight, + _ref8$minWidth = _ref8.minWidth, + minWidth = _ref8$minWidth === undefined ? 0 : _ref8$minWidth, + _ref8$minHeight = _ref8.minHeight, + minHeight = _ref8$minHeight === undefined ? 0 : _ref8$minHeight; + + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + var maxSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: maxWidth, + height: maxHeight + }); + var minSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: minWidth, + height: minHeight + }); + var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth)); + var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight)); + var params = [-imageNaturalWidth / 2, -imageNaturalHeight / 2, imageNaturalWidth, imageNaturalHeight]; + + canvas.width = normalizeDecimalNumber(width); + canvas.height = normalizeDecimalNumber(height); + context.fillStyle = fillColor; + context.fillRect(0, 0, width, height); + context.save(); + context.translate(width / 2, height / 2); + context.rotate(rotate * Math.PI / 180); + context.scale(scaleX, scaleY); + context.imageSmoothingEnabled = imageSmoothingEnabled; + context.imageSmoothingQuality = imageSmoothingQuality; + context.drawImage.apply(context, [image].concat(toConsumableArray(params.map(function (param) { + return Math.floor(normalizeDecimalNumber(param)); + })))); + context.restore(); + return canvas; +} + +var fromCharCode = String.fromCharCode; + +/** + * Get string from char code in data view. + * @param {DataView} dataView - The data view for read. + * @param {number} start - The start index. + * @param {number} length - The read length. + * @returns {string} The read result. + */ + +function getStringFromCharCode(dataView, start, length) { + var str = ''; + var i = void 0; + + length += start; + + for (i = start; i < length; i += 1) { + str += fromCharCode(dataView.getUint8(i)); + } + + return str; +} + +var REGEXP_DATA_URL_HEAD = /^data:.*,/; + +/** + * Transform Data URL to array buffer. + * @param {string} dataURL - The Data URL to transform. + * @returns {ArrayBuffer} The result array buffer. + */ +function dataURLToArrayBuffer(dataURL) { + var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, ''); + var binary = atob(base64); + var arrayBuffer = new ArrayBuffer(binary.length); + var uint8 = new Uint8Array(arrayBuffer); + + each(uint8, function (value, i) { + uint8[i] = binary.charCodeAt(i); + }); + + return arrayBuffer; +} + +/** + * Transform array buffer to Data URL. + * @param {ArrayBuffer} arrayBuffer - The array buffer to transform. + * @param {string} mimeType - The mime type of the Data URL. + * @returns {string} The result Data URL. + */ +function arrayBufferToDataURL(arrayBuffer, mimeType) { + var uint8 = new Uint8Array(arrayBuffer); + var data = ''; + + // TypedArray.prototype.forEach is not supported in some browsers. + each(uint8, function (value) { + data += fromCharCode(value); + }); + + return 'data:' + mimeType + ';base64,' + btoa(data); +} + +/** + * Get orientation value from given array buffer. + * @param {ArrayBuffer} arrayBuffer - The array buffer to read. + * @returns {number} The read orientation value. + */ +function getOrientation(arrayBuffer) { + var dataView = new DataView(arrayBuffer); + var orientation = void 0; + var littleEndian = void 0; + var app1Start = void 0; + var ifdStart = void 0; + + // Only handle JPEG image (start by 0xFFD8) + if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) { + var length = dataView.byteLength; + var offset = 2; + + while (offset < length) { + if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) { + app1Start = offset; + break; + } + + offset += 1; + } + } + + if (app1Start) { + var exifIDCode = app1Start + 4; + var tiffOffset = app1Start + 10; + + if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') { + var endianness = dataView.getUint16(tiffOffset); + + littleEndian = endianness === 0x4949; + + if (littleEndian || endianness === 0x4D4D /* bigEndian */) { + if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) { + var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian); + + if (firstIFDOffset >= 0x00000008) { + ifdStart = tiffOffset + firstIFDOffset; + } + } + } + } + } + + if (ifdStart) { + var _length = dataView.getUint16(ifdStart, littleEndian); + var _offset = void 0; + var i = void 0; + + for (i = 0; i < _length; i += 1) { + _offset = ifdStart + i * 12 + 2; + + if (dataView.getUint16(_offset, littleEndian) === 0x0112 /* Orientation */) { + // 8 is the offset of the current tag's value + _offset += 8; + + // Get the original orientation value + orientation = dataView.getUint16(_offset, littleEndian); + + // Override the orientation with its default value + dataView.setUint16(_offset, 1, littleEndian); + break; + } + } + } + + return orientation; +} + +/** + * Parse Exif Orientation value. + * @param {number} orientation - The orientation to parse. + * @returns {Object} The parsed result. + */ +function parseOrientation(orientation) { + var rotate = 0; + var scaleX = 1; + var scaleY = 1; + + switch (orientation) { + // Flip horizontal + case 2: + scaleX = -1; + break; + + // Rotate left 180° + case 3: + rotate = -180; + break; + + // Flip vertical + case 4: + scaleY = -1; + break; + + // Flip vertical and rotate right 90° + case 5: + rotate = 90; + scaleY = -1; + break; + + // Rotate right 90° + case 6: + rotate = 90; + break; + + // Flip horizontal and rotate right 90° + case 7: + rotate = 90; + scaleX = -1; + break; + + // Rotate left 90° + case 8: + rotate = -90; + break; + + default: + } + + return { + rotate: rotate, + scaleX: scaleX, + scaleY: scaleY + }; +} + +var render = { + render: function render() { + this.initContainer(); + this.initCanvas(); + this.initCropBox(); + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + }, + initContainer: function initContainer() { + var element = this.element, + options = this.options, + container = this.container, + cropper = this.cropper; + + + addClass(cropper, CLASS_HIDDEN); + removeClass(element, CLASS_HIDDEN); + + var containerData = { + width: Math.max(container.offsetWidth, Number(options.minContainerWidth) || 200), + height: Math.max(container.offsetHeight, Number(options.minContainerHeight) || 100) + }; + + this.containerData = containerData; + + setStyle(cropper, { + width: containerData.width, + height: containerData.height + }); + + addClass(element, CLASS_HIDDEN); + removeClass(cropper, CLASS_HIDDEN); + }, + + + // Canvas (image wrapper) + initCanvas: function initCanvas() { + var containerData = this.containerData, + imageData = this.imageData; + var viewMode = this.options.viewMode; + + var rotated = Math.abs(imageData.rotate) % 180 === 90; + var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth; + var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight; + var aspectRatio = naturalWidth / naturalHeight; + var canvasWidth = containerData.width; + var canvasHeight = containerData.height; + + if (containerData.height * aspectRatio > containerData.width) { + if (viewMode === 3) { + canvasWidth = containerData.height * aspectRatio; + } else { + canvasHeight = containerData.width / aspectRatio; + } + } else if (viewMode === 3) { + canvasHeight = containerData.width / aspectRatio; + } else { + canvasWidth = containerData.height * aspectRatio; + } + + var canvasData = { + aspectRatio: aspectRatio, + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + width: canvasWidth, + height: canvasHeight + }; + + canvasData.left = (containerData.width - canvasWidth) / 2; + canvasData.top = (containerData.height - canvasHeight) / 2; + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; + + this.canvasData = canvasData; + this.limited = viewMode === 1 || viewMode === 2; + this.limitCanvas(true, true); + this.initialImageData = extend({}, imageData); + this.initialCanvasData = extend({}, canvasData); + }, + limitCanvas: function limitCanvas(sizeLimited, positionLimited) { + var options = this.options, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + var viewMode = options.viewMode; + var aspectRatio = canvasData.aspectRatio; + + var cropped = this.cropped && cropBoxData; + + if (sizeLimited) { + var minCanvasWidth = Number(options.minCanvasWidth) || 0; + var minCanvasHeight = Number(options.minCanvasHeight) || 0; + + if (viewMode > 1) { + minCanvasWidth = Math.max(minCanvasWidth, containerData.width); + minCanvasHeight = Math.max(minCanvasHeight, containerData.height); + + if (viewMode === 3) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } else if (viewMode > 0) { + if (minCanvasWidth) { + minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0); + } else if (minCanvasHeight) { + minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0); + } else if (cropped) { + minCanvasWidth = cropBoxData.width; + minCanvasHeight = cropBoxData.height; + + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } + + var _getContainSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: minCanvasWidth, + height: minCanvasHeight + }); + + minCanvasWidth = _getContainSizes.width; + minCanvasHeight = _getContainSizes.height; + + + canvasData.minWidth = minCanvasWidth; + canvasData.minHeight = minCanvasHeight; + canvasData.maxWidth = Infinity; + canvasData.maxHeight = Infinity; + } + + if (positionLimited) { + if (viewMode) { + var newCanvasLeft = containerData.width - canvasData.width; + var newCanvasTop = containerData.height - canvasData.height; + + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxLeft = Math.max(0, newCanvasLeft); + canvasData.maxTop = Math.max(0, newCanvasTop); + + if (cropped && this.limited) { + canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width)); + canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height)); + canvasData.maxLeft = cropBoxData.left; + canvasData.maxTop = cropBoxData.top; + + if (viewMode === 2) { + if (canvasData.width >= containerData.width) { + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.maxLeft = Math.max(0, newCanvasLeft); + } + + if (canvasData.height >= containerData.height) { + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxTop = Math.max(0, newCanvasTop); + } + } + } + } else { + canvasData.minLeft = -canvasData.width; + canvasData.minTop = -canvasData.height; + canvasData.maxLeft = containerData.width; + canvasData.maxTop = containerData.height; + } + } + }, + renderCanvas: function renderCanvas(changed, transformed) { + var canvasData = this.canvasData, + imageData = this.imageData; + + + if (transformed) { + var _getRotatedSizes = getRotatedSizes({ + width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1), + height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1), + degree: imageData.rotate || 0 + }), + naturalWidth = _getRotatedSizes.width, + naturalHeight = _getRotatedSizes.height; + + var width = canvasData.width * (naturalWidth / canvasData.naturalWidth); + var height = canvasData.height * (naturalHeight / canvasData.naturalHeight); + + canvasData.left -= (width - canvasData.width) / 2; + canvasData.top -= (height - canvasData.height) / 2; + canvasData.width = width; + canvasData.height = height; + canvasData.aspectRatio = naturalWidth / naturalHeight; + canvasData.naturalWidth = naturalWidth; + canvasData.naturalHeight = naturalHeight; + this.limitCanvas(true, false); + } + + if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) { + canvasData.left = canvasData.oldLeft; + } + + if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) { + canvasData.top = canvasData.oldTop; + } + + canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth); + canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight); + + this.limitCanvas(false, true); + + canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft); + canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop); + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; + + setStyle(this.canvas, extend({ + width: canvasData.width, + height: canvasData.height + }, getTransforms({ + translateX: canvasData.left, + translateY: canvasData.top + }))); + + this.renderImage(changed); + + if (this.cropped && this.limited) { + this.limitCropBox(true, true); + } + }, + renderImage: function renderImage(changed) { + var canvasData = this.canvasData, + imageData = this.imageData; + + var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth); + var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight); + + extend(imageData, { + width: width, + height: height, + left: (canvasData.width - width) / 2, + top: (canvasData.height - height) / 2 + }); + setStyle(this.image, extend({ + width: imageData.width, + height: imageData.height + }, getTransforms(extend({ + translateX: imageData.left, + translateY: imageData.top + }, imageData)))); + + if (changed) { + this.output(); + } + }, + initCropBox: function initCropBox() { + var options = this.options, + canvasData = this.canvasData; + var aspectRatio = options.aspectRatio; + + var autoCropArea = Number(options.autoCropArea) || 0.8; + var cropBoxData = { + width: canvasData.width, + height: canvasData.height + }; + + if (aspectRatio) { + if (canvasData.height * aspectRatio > canvasData.width) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + this.cropBoxData = cropBoxData; + this.limitCropBox(true, true); + + // Initialize auto crop area + cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth); + cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); + + // The width/height of auto crop area must large than "minWidth/Height" + cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea); + cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea); + cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2; + cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2; + cropBoxData.oldLeft = cropBoxData.left; + cropBoxData.oldTop = cropBoxData.top; + + this.initialCropBoxData = extend({}, cropBoxData); + }, + limitCropBox: function limitCropBox(sizeLimited, positionLimited) { + var options = this.options, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData, + limited = this.limited; + var aspectRatio = options.aspectRatio; + + + if (sizeLimited) { + var minCropBoxWidth = Number(options.minCropBoxWidth) || 0; + var minCropBoxHeight = Number(options.minCropBoxHeight) || 0; + var maxCropBoxWidth = Math.min(containerData.width, limited ? canvasData.width : containerData.width); + var maxCropBoxHeight = Math.min(containerData.height, limited ? canvasData.height : containerData.height); + + // The min/maxCropBoxWidth/Height must be less than container's width/height + minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width); + minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height); + + if (aspectRatio) { + if (minCropBoxWidth && minCropBoxHeight) { + if (minCropBoxHeight * aspectRatio > minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + } else if (minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else if (minCropBoxHeight) { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + + if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) { + maxCropBoxHeight = maxCropBoxWidth / aspectRatio; + } else { + maxCropBoxWidth = maxCropBoxHeight * aspectRatio; + } + } + + // The minWidth/Height must be less than maxWidth/Height + cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); + cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); + cropBoxData.maxWidth = maxCropBoxWidth; + cropBoxData.maxHeight = maxCropBoxHeight; + } + + if (positionLimited) { + if (limited) { + cropBoxData.minLeft = Math.max(0, canvasData.left); + cropBoxData.minTop = Math.max(0, canvasData.top); + cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width; + cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height; + } else { + cropBoxData.minLeft = 0; + cropBoxData.minTop = 0; + cropBoxData.maxLeft = containerData.width - cropBoxData.width; + cropBoxData.maxTop = containerData.height - cropBoxData.height; + } + } + }, + renderCropBox: function renderCropBox() { + var options = this.options, + containerData = this.containerData, + cropBoxData = this.cropBoxData; + + + if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) { + cropBoxData.left = cropBoxData.oldLeft; + } + + if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) { + cropBoxData.top = cropBoxData.oldTop; + } + + cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth); + cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); + + this.limitCropBox(false, true); + + cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft); + cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop); + cropBoxData.oldLeft = cropBoxData.left; + cropBoxData.oldTop = cropBoxData.top; + + if (options.movable && options.cropBoxMovable) { + // Turn to move the canvas when the crop box is equal to the container + setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL); + } + + setStyle(this.cropBox, extend({ + width: cropBoxData.width, + height: cropBoxData.height + }, getTransforms({ + translateX: cropBoxData.left, + translateY: cropBoxData.top + }))); + + if (this.cropped && this.limited) { + this.limitCanvas(true, true); + } + + if (!this.disabled) { + this.output(); + } + }, + output: function output() { + this.preview(); + + if (this.complete) { + dispatchEvent(this.element, EVENT_CROP, this.getData()); + } + } +}; + +var preview = { + initPreview: function initPreview() { + var crossOrigin = this.crossOrigin; + var preview = this.options.preview; + + var url = crossOrigin ? this.crossOriginUrl : this.url; + var image = document.createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = url; + this.viewBox.appendChild(image); + this.image2 = image; + + if (!preview) { + return; + } + + var previews = preview.querySelector ? [preview] : document.querySelectorAll(preview); + + this.previews = previews; + + each(previews, function (element) { + var img = document.createElement('img'); + + // Save the original size for recover + setData(element, DATA_PREVIEW, { + width: element.offsetWidth, + height: element.offsetHeight, + html: element.innerHTML + }); + + if (crossOrigin) { + img.crossOrigin = crossOrigin; + } + + img.src = url; + + /** + * Override img element styles + * Add `display:block` to avoid margin top issue + * Add `height:auto` to override `height` attribute on IE8 + * (Occur only when margin-top <= -height) + */ + img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"'; + + empty(element); + element.appendChild(img); + }); + }, + resetPreview: function resetPreview() { + each(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); + + setStyle(element, { + width: data.width, + height: data.height + }); + + element.innerHTML = data.html; + removeData(element, DATA_PREVIEW); + }); + }, + preview: function preview() { + var imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + var cropBoxWidth = cropBoxData.width, + cropBoxHeight = cropBoxData.height; + var width = imageData.width, + height = imageData.height; + + var left = cropBoxData.left - canvasData.left - imageData.left; + var top = cropBoxData.top - canvasData.top - imageData.top; + + if (!this.cropped || this.disabled) { + return; + } + + setStyle(this.image2, extend({ + width: width, + height: height + }, getTransforms(extend({ + translateX: -left, + translateY: -top + }, imageData)))); + + each(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); + var originalWidth = data.width; + var originalHeight = data.height; + var newWidth = originalWidth; + var newHeight = originalHeight; + var ratio = 1; + + if (cropBoxWidth) { + ratio = originalWidth / cropBoxWidth; + newHeight = cropBoxHeight * ratio; + } + + if (cropBoxHeight && newHeight > originalHeight) { + ratio = originalHeight / cropBoxHeight; + newWidth = cropBoxWidth * ratio; + newHeight = originalHeight; + } + + setStyle(element, { + width: newWidth, + height: newHeight + }); + + setStyle(element.getElementsByTagName('img')[0], extend({ + width: width * ratio, + height: height * ratio + }, getTransforms(extend({ + translateX: -left * ratio, + translateY: -top * ratio + }, imageData)))); + }); + } +}; + +var events = { + bind: function bind() { + var element = this.element, + options = this.options, + cropper = this.cropper; + + + if (isFunction(options.cropstart)) { + addListener(element, EVENT_CROP_START, options.cropstart); + } + + if (isFunction(options.cropmove)) { + addListener(element, EVENT_CROP_MOVE, options.cropmove); + } + + if (isFunction(options.cropend)) { + addListener(element, EVENT_CROP_END, options.cropend); + } + + if (isFunction(options.crop)) { + addListener(element, EVENT_CROP, options.crop); + } + + if (isFunction(options.zoom)) { + addListener(element, EVENT_ZOOM, options.zoom); + } + + addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = proxy(this.cropStart, this)); + + if (options.zoomable && options.zoomOnWheel) { + addListener(cropper, EVENT_WHEEL, this.onWheel = proxy(this.wheel, this)); + } + + if (options.toggleDragModeOnDblclick) { + addListener(cropper, EVENT_DBLCLICK, this.onDblclick = proxy(this.dblclick, this)); + } + + addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = proxy(this.cropMove, this)); + addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = proxy(this.cropEnd, this)); + + if (options.responsive) { + addListener(window, EVENT_RESIZE, this.onResize = proxy(this.resize, this)); + } + }, + unbind: function unbind() { + var element = this.element, + options = this.options, + cropper = this.cropper; + + + if (isFunction(options.cropstart)) { + removeListener(element, EVENT_CROP_START, options.cropstart); + } + + if (isFunction(options.cropmove)) { + removeListener(element, EVENT_CROP_MOVE, options.cropmove); + } + + if (isFunction(options.cropend)) { + removeListener(element, EVENT_CROP_END, options.cropend); + } + + if (isFunction(options.crop)) { + removeListener(element, EVENT_CROP, options.crop); + } + + if (isFunction(options.zoom)) { + removeListener(element, EVENT_ZOOM, options.zoom); + } + + removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart); + + if (options.zoomable && options.zoomOnWheel) { + removeListener(cropper, EVENT_WHEEL, this.onWheel); + } + + if (options.toggleDragModeOnDblclick) { + removeListener(cropper, EVENT_DBLCLICK, this.onDblclick); + } + + removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove); + removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd); + + if (options.responsive) { + removeListener(window, EVENT_RESIZE, this.onResize); + } + } +}; + +var handlers = { + resize: function resize() { + var options = this.options, + container = this.container, + containerData = this.containerData; + + var minContainerWidth = Number(options.minContainerWidth) || 200; + var minContainerHeight = Number(options.minContainerHeight) || 100; + + if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) { + return; + } + + var ratio = container.offsetWidth / containerData.width; + + // Resize when width changed or height changed + if (ratio !== 1 || container.offsetHeight !== containerData.height) { + var canvasData = void 0; + var cropBoxData = void 0; + + if (options.restore) { + canvasData = this.getCanvasData(); + cropBoxData = this.getCropBoxData(); + } + + this.render(); + + if (options.restore) { + this.setCanvasData(each(canvasData, function (n, i) { + canvasData[i] = n * ratio; + })); + this.setCropBoxData(each(cropBoxData, function (n, i) { + cropBoxData[i] = n * ratio; + })); + } + } + }, + dblclick: function dblclick() { + if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) { + return; + } + + this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); + }, + wheel: function wheel(e) { + var _this = this; + + var ratio = Number(this.options.wheelZoomRatio) || 0.1; + var delta = 1; + + if (this.disabled) { + return; + } + + e.preventDefault(); + + // Limit wheel speed to prevent zoom too fast (#21) + if (this.wheeling) { + return; + } + + this.wheeling = true; + + setTimeout(function () { + _this.wheeling = false; + }, 50); + + if (e.deltaY) { + delta = e.deltaY > 0 ? 1 : -1; + } else if (e.wheelDelta) { + delta = -e.wheelDelta / 120; + } else if (e.detail) { + delta = e.detail > 0 ? 1 : -1; + } + + this.zoom(-delta * ratio, e); + }, + cropStart: function cropStart(e) { + if (this.disabled) { + return; + } + + var options = this.options, + pointers = this.pointers; + + var action = void 0; + + if (e.changedTouches) { + // Handle touch event + each(e.changedTouches, function (touch) { + pointers[touch.identifier] = getPointer(touch); + }); + } else { + // Handle mouse event and pointer event + pointers[e.pointerId || 0] = getPointer(e); + } + + if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { + action = ACTION_ZOOM; + } else { + action = getData(e.target, DATA_ACTION); + } + + if (!REGEXP_ACTIONS.test(action)) { + return; + } + + if (dispatchEvent(this.element, EVENT_CROP_START, { + originalEvent: e, + action: action + }) === false) { + return; + } + + e.preventDefault(); + + this.action = action; + this.cropping = false; + + if (action === ACTION_CROP) { + this.cropping = true; + addClass(this.dragBox, CLASS_MODAL); + } + }, + cropMove: function cropMove(e) { + var action = this.action; + + + if (this.disabled || !action) { + return; + } + + var pointers = this.pointers; + + + e.preventDefault(); + + if (dispatchEvent(this.element, EVENT_CROP_MOVE, { + originalEvent: e, + action: action + }) === false) { + return; + } + + if (e.changedTouches) { + each(e.changedTouches, function (touch) { + extend(pointers[touch.identifier], getPointer(touch, true)); + }); + } else { + extend(pointers[e.pointerId || 0], getPointer(e, true)); + } + + this.change(e); + }, + cropEnd: function cropEnd(e) { + if (this.disabled) { + return; + } + + var action = this.action, + pointers = this.pointers; + + + if (e.changedTouches) { + each(e.changedTouches, function (touch) { + delete pointers[touch.identifier]; + }); + } else { + delete pointers[e.pointerId || 0]; + } + + if (!action) { + return; + } + + e.preventDefault(); + + if (!Object.keys(pointers).length) { + this.action = ''; + } + + if (this.cropping) { + this.cropping = false; + toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal); + } + + dispatchEvent(this.element, EVENT_CROP_END, { + originalEvent: e, + action: action + }); + } +}; + +var change = { + change: function change(e) { + var options = this.options, + canvasData = this.canvasData, + containerData = this.containerData, + cropBoxData = this.cropBoxData, + pointers = this.pointers; + var action = this.action; + var aspectRatio = options.aspectRatio; + var left = cropBoxData.left, + top = cropBoxData.top, + width = cropBoxData.width, + height = cropBoxData.height; + + var right = left + width; + var bottom = top + height; + var minLeft = 0; + var minTop = 0; + var maxWidth = containerData.width; + var maxHeight = containerData.height; + var renderable = true; + var offset = void 0; + + // Locking aspect ratio in "free mode" by holding shift key + if (!aspectRatio && e.shiftKey) { + aspectRatio = width && height ? width / height : 1; + } + + if (this.limited) { + minLeft = cropBoxData.minLeft; + minTop = cropBoxData.minTop; + + maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width); + maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height); + } + + var pointer = pointers[Object.keys(pointers)[0]]; + var range = { + x: pointer.endX - pointer.startX, + y: pointer.endY - pointer.startY + }; + var check = function check(side) { + switch (side) { + case ACTION_EAST: + if (right + range.x > maxWidth) { + range.x = maxWidth - right; + } + + break; + + case ACTION_WEST: + if (left + range.x < minLeft) { + range.x = minLeft - left; + } + + break; + + case ACTION_NORTH: + if (top + range.y < minTop) { + range.y = minTop - top; + } + + break; + + case ACTION_SOUTH: + if (bottom + range.y > maxHeight) { + range.y = maxHeight - bottom; + } + + break; + + default: + } + }; + + switch (action) { + // Move crop box + case ACTION_ALL: + left += range.x; + top += range.y; + break; + + // Resize crop box + case ACTION_EAST: + if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) { + renderable = false; + break; + } + + check(ACTION_EAST); + width += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top -= range.x / aspectRatio / 2; + } + + if (width < 0) { + action = ACTION_WEST; + width = 0; + } + + break; + + case ACTION_NORTH: + if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left += range.y * aspectRatio / 2; + } + + if (height < 0) { + action = ACTION_SOUTH; + height = 0; + } + + break; + + case ACTION_WEST: + if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) { + renderable = false; + break; + } + + check(ACTION_WEST); + width -= range.x; + left += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top += range.x / aspectRatio / 2; + } + + if (width < 0) { + action = ACTION_EAST; + width = 0; + } + + break; + + case ACTION_SOUTH: + if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) { + renderable = false; + break; + } + + check(ACTION_SOUTH); + height += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left -= range.y * aspectRatio / 2; + } + + if (height < 0) { + action = ACTION_NORTH; + height = 0; + } + + break; + + case ACTION_NORTH_EAST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || right >= maxWidth)) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + width = height * aspectRatio; + } else { + check(ACTION_NORTH); + check(ACTION_EAST); + + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + } + + break; + + case ACTION_NORTH_WEST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || left <= minLeft)) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + width = height * aspectRatio; + left += range.y * aspectRatio; + } else { + check(ACTION_NORTH); + check(ACTION_WEST); + + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_WEST: + if (aspectRatio) { + if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) { + renderable = false; + break; + } + + check(ACTION_WEST); + width -= range.x; + left += range.x; + height = width / aspectRatio; + } else { + check(ACTION_SOUTH); + check(ACTION_WEST); + + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_EAST: + if (aspectRatio) { + if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) { + renderable = false; + break; + } + + check(ACTION_EAST); + width += range.x; + height = width / aspectRatio; + } else { + check(ACTION_SOUTH); + check(ACTION_EAST); + + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + } + + break; + + // Move canvas + case ACTION_MOVE: + this.move(range.x, range.y); + renderable = false; + break; + + // Zoom canvas + case ACTION_ZOOM: + this.zoom(getMaxZoomRatio(pointers), e); + renderable = false; + break; + + // Create crop box + case ACTION_CROP: + if (!range.x || !range.y) { + renderable = false; + break; + } + + offset = getOffset(this.cropper); + left = pointer.startX - offset.left; + top = pointer.startY - offset.top; + width = cropBoxData.minWidth; + height = cropBoxData.minHeight; + + if (range.x > 0) { + action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST; + } else if (range.x < 0) { + left -= width; + action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST; + } + + if (range.y < 0) { + top -= height; + } + + // Show the crop box if is hidden + if (!this.cropped) { + removeClass(this.cropBox, CLASS_HIDDEN); + this.cropped = true; + + if (this.limited) { + this.limitCropBox(true, true); + } + } + + break; + + default: + } + + if (renderable) { + cropBoxData.width = width; + cropBoxData.height = height; + cropBoxData.left = left; + cropBoxData.top = top; + this.action = action; + this.renderCropBox(); + } + + // Override + each(pointers, function (p) { + p.startX = p.endX; + p.startY = p.endY; + }); + } +}; + +var methods = { + // Show the crop box manually + crop: function crop() { + if (this.ready && !this.disabled) { + if (!this.cropped) { + this.cropped = true; + this.limitCropBox(true, true); + + if (this.options.modal) { + addClass(this.dragBox, CLASS_MODAL); + } + + removeClass(this.cropBox, CLASS_HIDDEN); + } + + this.setCropBoxData(this.initialCropBoxData); + } + + return this; + }, + + + // Reset the image and crop box to their initial states + reset: function reset() { + if (this.ready && !this.disabled) { + this.imageData = extend({}, this.initialImageData); + this.canvasData = extend({}, this.initialCanvasData); + this.cropBoxData = extend({}, this.initialCropBoxData); + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + } + + return this; + }, + + + // Clear the crop box + clear: function clear() { + if (this.cropped && !this.disabled) { + extend(this.cropBoxData, { + left: 0, + top: 0, + width: 0, + height: 0 + }); + + this.cropped = false; + this.renderCropBox(); + this.limitCanvas(true, true); + + // Render canvas after crop box rendered + this.renderCanvas(); + removeClass(this.dragBox, CLASS_MODAL); + addClass(this.cropBox, CLASS_HIDDEN); + } + + return this; + }, + + + /** + * Replace the image's src and rebuild the cropper + * @param {string} url - The new URL. + * @param {boolean} [onlyColorChanged] - Indicate if the new image only changed color. + * @returns {Object} this + */ + replace: function replace(url) { + var onlyColorChanged = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (!this.disabled && url) { + if (this.isImg) { + this.element.src = url; + } + + if (onlyColorChanged) { + this.url = url; + this.image.src = url; + + if (this.ready) { + this.image2.src = url; + + each(this.previews, function (element) { + element.getElementsByTagName('img')[0].src = url; + }); + } + } else { + if (this.isImg) { + this.replaced = true; + } + + // Clear previous data + this.options.data = null; + this.load(url); + } + } + + return this; + }, + + + // Enable (unfreeze) the cropper + enable: function enable() { + if (this.ready) { + this.disabled = false; + removeClass(this.cropper, CLASS_DISABLED); + } + + return this; + }, + + + // Disable (freeze) the cropper + disable: function disable() { + if (this.ready) { + this.disabled = true; + addClass(this.cropper, CLASS_DISABLED); + } + + return this; + }, + + + // Destroy the cropper and remove the instance from the image + destroy: function destroy() { + var element = this.element, + image = this.image; + + + if (this.loaded) { + if (this.isImg && this.replaced) { + element.src = this.originalUrl; + } + + this.unbuild(); + removeClass(element, CLASS_HIDDEN); + } else if (this.isImg) { + removeListener(element, EVENT_LOAD, this.onStart); + } else if (image) { + image.parentNode.removeChild(image); + } + + removeData(element, NAMESPACE); + + return this; + }, + + + /** + * Move the canvas with relative offsets + * @param {number} offsetX - The relative offset distance on the x-axis. + * @param {number} offsetY - The relative offset distance on the y-axis. + * @returns {Object} this + */ + move: function move(offsetX, offsetY) { + var _canvasData = this.canvasData, + left = _canvasData.left, + top = _canvasData.top; + + + return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); + }, + + + /** + * Move the canvas to an absolute point + * @param {number} x - The x-axis coordinate. + * @param {number} [y=x] - The y-axis coordinate. + * @returns {Object} this + */ + moveTo: function moveTo(x) { + var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + var canvasData = this.canvasData; + + var changed = false; + + x = Number(x); + y = Number(y); + + if (this.ready && !this.disabled && this.options.movable) { + if (isNumber(x)) { + canvasData.left = x; + changed = true; + } + + if (isNumber(y)) { + canvasData.top = y; + changed = true; + } + + if (changed) { + this.renderCanvas(true); + } + } + + return this; + }, + + + /** + * Zoom the canvas with a relative ratio + * @param {number} ratio - The target ratio. + * @param {Event} _originalEvent - The original event if any. + * @returns {Object} this + */ + zoom: function zoom(ratio, _originalEvent) { + var canvasData = this.canvasData; + + + ratio = Number(ratio); + + if (ratio < 0) { + ratio = 1 / (1 - ratio); + } else { + ratio = 1 + ratio; + } + + return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent); + }, + + + /** + * Zoom the canvas to an absolute ratio + * @param {number} ratio - The target ratio. + * @param {Object} pivot - The zoom pivot point coordinate. + * @param {Event} _originalEvent - The original event if any. + * @returns {Object} this + */ + zoomTo: function zoomTo(ratio, pivot, _originalEvent) { + var options = this.options, + canvasData = this.canvasData; + var width = canvasData.width, + height = canvasData.height, + naturalWidth = canvasData.naturalWidth, + naturalHeight = canvasData.naturalHeight; + + + ratio = Number(ratio); + + if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) { + var newWidth = naturalWidth * ratio; + var newHeight = naturalHeight * ratio; + + if (dispatchEvent(this.element, EVENT_ZOOM, { + originalEvent: _originalEvent, + oldRatio: width / naturalWidth, + ratio: newWidth / naturalWidth + }) === false) { + return this; + } + + if (_originalEvent) { + var pointers = this.pointers; + + var offset = getOffset(this.cropper); + var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : { + pageX: _originalEvent.pageX, + pageY: _originalEvent.pageY + }; + + // Zoom from the triggering point of the event + canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width); + canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height); + } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) { + canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width); + canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height); + } else { + // Zoom from the center of the canvas + canvasData.left -= (newWidth - width) / 2; + canvasData.top -= (newHeight - height) / 2; + } + + canvasData.width = newWidth; + canvasData.height = newHeight; + this.renderCanvas(true); + } + + return this; + }, + + + /** + * Rotate the canvas with a relative degree + * @param {number} degree - The rotate degree. + * @returns {Object} this + */ + rotate: function rotate(degree) { + return this.rotateTo((this.imageData.rotate || 0) + Number(degree)); + }, + + + /** + * Rotate the canvas to an absolute degree + * @param {number} degree - The rotate degree. + * @returns {Object} this + */ + rotateTo: function rotateTo(degree) { + degree = Number(degree); + + if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) { + this.imageData.rotate = degree % 360; + this.renderCanvas(true, true); + } + + return this; + }, + + + /** + * Scale the image on the x-axis. + * @param {number} scaleX - The scale ratio on the x-axis. + * @returns {Object} this + */ + scaleX: function scaleX(_scaleX) { + var scaleY = this.imageData.scaleY; + + + return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1); + }, + + + /** + * Scale the image on the y-axis. + * @param {number} scaleY - The scale ratio on the y-axis. + * @returns {Object} this + */ + scaleY: function scaleY(_scaleY) { + var scaleX = this.imageData.scaleX; + + + return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); + }, + + + /** + * Scale the image + * @param {number} scaleX - The scale ratio on the x-axis. + * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis. + * @returns {Object} this + */ + scale: function scale(scaleX) { + var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX; + var imageData = this.imageData; + + var transformed = false; + + scaleX = Number(scaleX); + scaleY = Number(scaleY); + + if (this.ready && !this.disabled && this.options.scalable) { + if (isNumber(scaleX)) { + imageData.scaleX = scaleX; + transformed = true; + } + + if (isNumber(scaleY)) { + imageData.scaleY = scaleY; + transformed = true; + } + + if (transformed) { + this.renderCanvas(true, true); + } + } + + return this; + }, + + + /** + * Get the cropped area position and size data (base on the original image) + * @param {boolean} [rounded=false] - Indicate if round the data values or not. + * @returns {Object} The result cropped data. + */ + getData: function getData$$1() { + var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var options = this.options, + imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + + var data = void 0; + + if (this.ready && this.cropped) { + data = { + x: cropBoxData.left - canvasData.left, + y: cropBoxData.top - canvasData.top, + width: cropBoxData.width, + height: cropBoxData.height + }; + + var ratio = imageData.width / imageData.naturalWidth; + + each(data, function (n, i) { + n /= ratio; + data[i] = rounded ? Math.round(n) : n; + }); + } else { + data = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + } + + if (options.rotatable) { + data.rotate = imageData.rotate || 0; + } + + if (options.scalable) { + data.scaleX = imageData.scaleX || 1; + data.scaleY = imageData.scaleY || 1; + } + + return data; + }, + + + /** + * Set the cropped area position and size with new data + * @param {Object} data - The new data. + * @returns {Object} this + */ + setData: function setData$$1(data) { + var options = this.options, + imageData = this.imageData, + canvasData = this.canvasData; + + var cropBoxData = {}; + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && !this.disabled && isPlainObject(data)) { + var transformed = false; + + if (options.rotatable) { + if (isNumber(data.rotate) && data.rotate !== imageData.rotate) { + imageData.rotate = data.rotate; + transformed = true; + } + } + + if (options.scalable) { + if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) { + imageData.scaleX = data.scaleX; + transformed = true; + } + + if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) { + imageData.scaleY = data.scaleY; + transformed = true; + } + } + + if (transformed) { + this.renderCanvas(true, true); + } + + var ratio = imageData.width / imageData.naturalWidth; + + if (isNumber(data.x)) { + cropBoxData.left = data.x * ratio + canvasData.left; + } + + if (isNumber(data.y)) { + cropBoxData.top = data.y * ratio + canvasData.top; + } + + if (isNumber(data.width)) { + cropBoxData.width = data.width * ratio; + } + + if (isNumber(data.height)) { + cropBoxData.height = data.height * ratio; + } + + this.setCropBoxData(cropBoxData); + } + + return this; + }, + + + /** + * Get the container size data. + * @returns {Object} The result container data. + */ + getContainerData: function getContainerData() { + return this.ready ? extend({}, this.containerData) : {}; + }, + + + /** + * Get the image position and size data. + * @returns {Object} The result image data. + */ + getImageData: function getImageData() { + return this.loaded ? extend({}, this.imageData) : {}; + }, + + + /** + * Get the canvas position and size data. + * @returns {Object} The result canvas data. + */ + getCanvasData: function getCanvasData() { + var canvasData = this.canvasData; + + var data = {}; + + if (this.ready) { + each(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) { + data[n] = canvasData[n]; + }); + } + + return data; + }, + + + /** + * Set the canvas position and size with new data. + * @param {Object} data - The new canvas data. + * @returns {Object} this + */ + setCanvasData: function setCanvasData(data) { + var canvasData = this.canvasData; + var aspectRatio = canvasData.aspectRatio; + + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && !this.disabled && isPlainObject(data)) { + if (isNumber(data.left)) { + canvasData.left = data.left; + } + + if (isNumber(data.top)) { + canvasData.top = data.top; + } + + if (isNumber(data.width)) { + canvasData.width = data.width; + canvasData.height = data.width / aspectRatio; + } else if (isNumber(data.height)) { + canvasData.height = data.height; + canvasData.width = data.height * aspectRatio; + } + + this.renderCanvas(true); + } + + return this; + }, + + + /** + * Get the crop box position and size data. + * @returns {Object} The result crop box data. + */ + getCropBoxData: function getCropBoxData() { + var cropBoxData = this.cropBoxData; + + var data = void 0; + + if (this.ready && this.cropped) { + data = { + left: cropBoxData.left, + top: cropBoxData.top, + width: cropBoxData.width, + height: cropBoxData.height + }; + } + + return data || {}; + }, + + + /** + * Set the crop box position and size with new data. + * @param {Object} data - The new crop box data. + * @returns {Object} this + */ + setCropBoxData: function setCropBoxData(data) { + var cropBoxData = this.cropBoxData; + var aspectRatio = this.options.aspectRatio; + + var widthChanged = void 0; + var heightChanged = void 0; + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) { + if (isNumber(data.left)) { + cropBoxData.left = data.left; + } + + if (isNumber(data.top)) { + cropBoxData.top = data.top; + } + + if (isNumber(data.width) && data.width !== cropBoxData.width) { + widthChanged = true; + cropBoxData.width = data.width; + } + + if (isNumber(data.height) && data.height !== cropBoxData.height) { + heightChanged = true; + cropBoxData.height = data.height; + } + + if (aspectRatio) { + if (widthChanged) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else if (heightChanged) { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + this.renderCropBox(); + } + + return this; + }, + + + /** + * Get a canvas drawn the cropped image. + * @param {Object} [options={}] - The config options. + * @returns {HTMLCanvasElement} - The result canvas. + */ + getCroppedCanvas: function getCroppedCanvas() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (!this.ready || !window.HTMLCanvasElement) { + return null; + } + + var canvasData = this.canvasData; + + var source = getSourceCanvas(this.image, this.imageData, canvasData, options); + + // Returns the source canvas if it is not cropped. + if (!this.cropped) { + return source; + } + + var _getData = this.getData(), + x = _getData.x, + y = _getData.y, + initialWidth = _getData.width, + initialHeight = _getData.height; + + var aspectRatio = initialWidth / initialHeight; + var maxSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.maxWidth || Infinity, + height: options.maxHeight || Infinity + }); + var minSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.minWidth || 0, + height: options.minHeight || 0 + }); + + var _getContainSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.width || initialWidth, + height: options.height || initialHeight + }), + width = _getContainSizes.width, + height = _getContainSizes.height; + + width = Math.min(maxSizes.width, Math.max(minSizes.width, width)); + height = Math.min(maxSizes.height, Math.max(minSizes.height, height)); + + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + + canvas.width = normalizeDecimalNumber(width); + canvas.height = normalizeDecimalNumber(height); + + context.fillStyle = options.fillColor || 'transparent'; + context.fillRect(0, 0, width, height); + + var _options$imageSmoothi = options.imageSmoothingEnabled, + imageSmoothingEnabled = _options$imageSmoothi === undefined ? true : _options$imageSmoothi, + imageSmoothingQuality = options.imageSmoothingQuality; + + + context.imageSmoothingEnabled = imageSmoothingEnabled; + + if (imageSmoothingQuality) { + context.imageSmoothingQuality = imageSmoothingQuality; + } + + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage + var sourceWidth = source.width; + var sourceHeight = source.height; + + // Source canvas parameters + var srcX = x; + var srcY = y; + var srcWidth = void 0; + var srcHeight = void 0; + + // Destination canvas parameters + var dstX = void 0; + var dstY = void 0; + var dstWidth = void 0; + var dstHeight = void 0; + + if (srcX <= -initialWidth || srcX > sourceWidth) { + srcX = 0; + srcWidth = 0; + dstX = 0; + dstWidth = 0; + } else if (srcX <= 0) { + dstX = -srcX; + srcX = 0; + srcWidth = Math.min(sourceWidth, initialWidth + srcX); + dstWidth = srcWidth; + } else if (srcX <= sourceWidth) { + dstX = 0; + srcWidth = Math.min(initialWidth, sourceWidth - srcX); + dstWidth = srcWidth; + } + + if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) { + srcY = 0; + srcHeight = 0; + dstY = 0; + dstHeight = 0; + } else if (srcY <= 0) { + dstY = -srcY; + srcY = 0; + srcHeight = Math.min(sourceHeight, initialHeight + srcY); + dstHeight = srcHeight; + } else if (srcY <= sourceHeight) { + dstY = 0; + srcHeight = Math.min(initialHeight, sourceHeight - srcY); + dstHeight = srcHeight; + } + + // All the numerical parameters should be integer for `drawImage` + // https://github.com/fengyuanchen/cropper/issues/476 + var params = [srcX, srcY, srcWidth, srcHeight]; + + // Avoid "IndexSizeError" + if (dstWidth > 0 && dstHeight > 0) { + var scale = width / initialWidth; + + params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale); + } + + context.drawImage.apply(context, [source].concat(toConsumableArray(params.map(function (param) { + return Math.floor(normalizeDecimalNumber(param)); + })))); + + return canvas; + }, + + + /** + * Change the aspect ratio of the crop box. + * @param {number} aspectRatio - The new aspect ratio. + * @returns {Object} this + */ + setAspectRatio: function setAspectRatio(aspectRatio) { + var options = this.options; + + + if (!this.disabled && !isUndefined(aspectRatio)) { + // 0 -> NaN + options.aspectRatio = Math.max(0, aspectRatio) || NaN; + + if (this.ready) { + this.initCropBox(); + + if (this.cropped) { + this.renderCropBox(); + } + } + } + + return this; + }, + + + /** + * Change the drag mode. + * @param {string} mode - The new drag mode. + * @returns {Object} this + */ + setDragMode: function setDragMode(mode) { + var options = this.options, + dragBox = this.dragBox, + face = this.face; + + + if (this.loaded && !this.disabled) { + var croppable = mode === DRAG_MODE_CROP; + var movable = options.movable && mode === DRAG_MODE_MOVE; + + mode = croppable || movable ? mode : DRAG_MODE_NONE; + + setData(dragBox, DATA_ACTION, mode); + toggleClass(dragBox, CLASS_CROP, croppable); + toggleClass(dragBox, CLASS_MOVE, movable); + + if (!options.cropBoxMovable) { + // Sync drag mode to crop box when it is not movable + setData(face, DATA_ACTION, mode); + toggleClass(face, CLASS_CROP, croppable); + toggleClass(face, CLASS_MOVE, movable); + } + } + + return this; + } +}; + +var AnotherCropper = WINDOW.Cropper; + +var Cropper = function () { + /** + * Create a new Cropper. + * @param {Element} element - The target element for cropping. + * @param {Object} [options={}] - The configuration options. + */ + function Cropper(element) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + classCallCheck(this, Cropper); + + if (!element || !REGEXP_TAG_NAME.test(element.tagName)) { + throw new Error('The first argument is required and must be an or element.'); + } + + this.element = element; + this.options = extend({}, DEFAULTS, isPlainObject(options) && options); + this.complete = false; + this.cropped = false; + this.disabled = false; + this.isImg = false; + this.limited = false; + this.loaded = false; + this.ready = false; + this.replaced = false; + this.wheeling = false; + this.originalUrl = ''; + this.canvasData = null; + this.cropBoxData = null; + this.previews = null; + this.pointers = {}; + this.init(); + } + + createClass(Cropper, [{ + key: 'init', + value: function init() { + var element = this.element; + + var tagName = element.tagName.toLowerCase(); + var url = void 0; + + if (getData(element, NAMESPACE)) { + return; + } + + setData(element, NAMESPACE, this); + + if (tagName === 'img') { + this.isImg = true; + + // e.g.: "img/picture.jpg" + url = element.getAttribute('src') || ''; + this.originalUrl = url; + + // Stop when it's a blank image + if (!url) { + return; + } + + // e.g.: "http://example.com/img/picture.jpg" + url = element.src; + } else if (tagName === 'canvas' && window.HTMLCanvasElement) { + url = element.toDataURL(); + } + + this.load(url); + } + }, { + key: 'load', + value: function load(url) { + var _this = this; + + if (!url) { + return; + } + + this.url = url; + this.imageData = {}; + + var element = this.element, + options = this.options; + + + if (!options.checkOrientation || !window.ArrayBuffer) { + this.clone(); + return; + } + + // XMLHttpRequest disallows to open a Data URL in some browsers like IE11 and Safari + if (REGEXP_DATA_URL.test(url)) { + if (REGEXP_DATA_URL_JPEG.test(url)) { + this.read(dataURLToArrayBuffer(url)); + } else { + this.clone(); + } + + return; + } + + var xhr = new XMLHttpRequest(); + + xhr.onerror = function () { + _this.clone(); + }; + + xhr.onload = function () { + _this.read(xhr.response); + }; + + if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) { + url = addTimestamp(url); + } + + xhr.open('get', url); + xhr.responseType = 'arraybuffer'; + xhr.withCredentials = element.crossOrigin === 'use-credentials'; + xhr.send(); + } + }, { + key: 'read', + value: function read(arrayBuffer) { + var options = this.options, + imageData = this.imageData; + + var orientation = getOrientation(arrayBuffer); + var rotate = 0; + var scaleX = 1; + var scaleY = 1; + + if (orientation > 1) { + this.url = arrayBufferToDataURL(arrayBuffer, 'image/jpeg'); + + var _parseOrientation = parseOrientation(orientation); + + rotate = _parseOrientation.rotate; + scaleX = _parseOrientation.scaleX; + scaleY = _parseOrientation.scaleY; + } + + if (options.rotatable) { + imageData.rotate = rotate; + } + + if (options.scalable) { + imageData.scaleX = scaleX; + imageData.scaleY = scaleY; + } + + this.clone(); + } + }, { + key: 'clone', + value: function clone() { + var element = this.element, + url = this.url; + + var crossOrigin = void 0; + var crossOriginUrl = void 0; + + if (this.options.checkCrossOrigin && isCrossOriginURL(url)) { + crossOrigin = element.crossOrigin; + + + if (crossOrigin) { + crossOriginUrl = url; + } else { + crossOrigin = 'anonymous'; + + // Bust cache when there is not a "crossOrigin" property + crossOriginUrl = addTimestamp(url); + } + } + + this.crossOrigin = crossOrigin; + this.crossOriginUrl = crossOriginUrl; + + var image = document.createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = crossOriginUrl || url; + + var start = proxy(this.start, this); + var stop = proxy(this.stop, this); + + this.image = image; + this.onStart = start; + this.onStop = stop; + + if (this.isImg) { + if (element.complete) { + this.start(); + } else { + addListener(element, EVENT_LOAD, start); + } + } else { + addListener(image, EVENT_LOAD, start); + addListener(image, EVENT_ERROR, stop); + addClass(image, CLASS_HIDE); + element.parentNode.insertBefore(image, element.nextSibling); + } + } + }, { + key: 'start', + value: function start(event) { + var _this2 = this; + + var image = this.isImg ? this.element : this.image; + + if (event) { + removeListener(image, EVENT_LOAD, this.onStart); + removeListener(image, EVENT_ERROR, this.onStop); + } + + getImageNaturalSizes(image, function (naturalWidth, naturalHeight) { + extend(_this2.imageData, { + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + aspectRatio: naturalWidth / naturalHeight + }); + _this2.loaded = true; + _this2.build(); + }); + } + }, { + key: 'stop', + value: function stop() { + var image = this.image; + + + removeListener(image, EVENT_LOAD, this.onStart); + removeListener(image, EVENT_ERROR, this.onStop); + image.parentNode.removeChild(image); + this.image = null; + } + }, { + key: 'build', + value: function build() { + var _this3 = this; + + if (!this.loaded) { + return; + } + + // Unbuild first when replace + if (this.ready) { + this.unbuild(); + } + + var element = this.element, + options = this.options, + image = this.image; + + // Create cropper elements + + var container = element.parentNode; + var template = document.createElement('div'); + + template.innerHTML = TEMPLATE; + + var cropper = template.querySelector('.' + NAMESPACE + '-container'); + var canvas = cropper.querySelector('.' + NAMESPACE + '-canvas'); + var dragBox = cropper.querySelector('.' + NAMESPACE + '-drag-box'); + var cropBox = cropper.querySelector('.' + NAMESPACE + '-crop-box'); + var face = cropBox.querySelector('.' + NAMESPACE + '-face'); + + this.container = container; + this.cropper = cropper; + this.canvas = canvas; + this.dragBox = dragBox; + this.cropBox = cropBox; + this.viewBox = cropper.querySelector('.' + NAMESPACE + '-view-box'); + this.face = face; + + canvas.appendChild(image); + + // Hide the original image + addClass(element, CLASS_HIDDEN); + + // Inserts the cropper after to the current image + container.insertBefore(cropper, element.nextSibling); + + // Show the image if is hidden + if (!this.isImg) { + removeClass(image, CLASS_HIDE); + } + + this.initPreview(); + this.bind(); + + options.aspectRatio = Math.max(0, options.aspectRatio) || NaN; + options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0; + + this.cropped = options.autoCrop; + + if (options.autoCrop) { + if (options.modal) { + addClass(dragBox, CLASS_MODAL); + } + } else { + addClass(cropBox, CLASS_HIDDEN); + } + + if (!options.guides) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-dashed'), CLASS_HIDDEN); + } + + if (!options.center) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-center'), CLASS_HIDDEN); + } + + if (options.background) { + addClass(cropper, NAMESPACE + '-bg'); + } + + if (!options.highlight) { + addClass(face, CLASS_INVISIBLE); + } + + if (options.cropBoxMovable) { + addClass(face, CLASS_MOVE); + setData(face, DATA_ACTION, ACTION_ALL); + } + + if (!options.cropBoxResizable) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-line'), CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-point'), CLASS_HIDDEN); + } + + this.setDragMode(options.dragMode); + this.render(); + this.ready = true; + this.setData(options.data); + + // Call the "ready" option asynchronously to keep "image.cropper" is defined + this.completing = setTimeout(function () { + if (isFunction(options.ready)) { + addListener(element, EVENT_READY, options.ready, { + once: true + }); + } + + dispatchEvent(element, EVENT_READY); + dispatchEvent(element, EVENT_CROP, _this3.getData()); + + _this3.complete = true; + }, 0); + } + }, { + key: 'unbuild', + value: function unbuild() { + if (!this.ready) { + return; + } + + if (!this.complete) { + clearTimeout(this.completing); + } + + this.ready = false; + this.complete = false; + this.initialImageData = null; + + // Clear `initialCanvasData` is necessary when replace + this.initialCanvasData = null; + this.initialCropBoxData = null; + this.containerData = null; + this.canvasData = null; + + // Clear `cropBoxData` is necessary when replace + this.cropBoxData = null; + this.unbind(); + this.resetPreview(); + this.previews = null; + this.viewBox = null; + this.cropBox = null; + this.dragBox = null; + this.canvas = null; + this.container = null; + this.cropper.parentNode.removeChild(this.cropper); + this.cropper = null; + } + + /** + * Get the no conflict cropper class. + * @returns {Cropper} The cropper class. + */ + + }], [{ + key: 'noConflict', + value: function noConflict() { + window.Cropper = AnotherCropper; + return Cropper; + } + + /** + * Change the default options. + * @param {Object} options - The new default options. + */ + + }, { + key: 'setDefaults', + value: function setDefaults(options) { + extend(DEFAULTS, isPlainObject(options) && options); + } + }]); + return Cropper; +}(); + +extend(Cropper.prototype, render, preview, events, handlers, change, methods); + +return Cropper; + +}))); diff --git a/library/cropperjs/dist/cropper.min.css b/library/cropperjs/dist/cropper.min.css new file mode 100644 index 000000000..89148848a --- /dev/null +++ b/library/cropperjs/dist/cropper.min.css @@ -0,0 +1,9 @@ +/*! + * Cropper.js v1.2.2 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2018 Chen Fengyuan + * Released under the MIT license + * + * Date: 2018-01-03T13:26:29.610Z + */.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline-color:rgba(51,153,255,.75);outline:1px solid #39f;overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed} \ No newline at end of file diff --git a/library/cropperjs/dist/cropper.min.js b/library/cropperjs/dist/cropper.min.js new file mode 100644 index 000000000..e213c6c41 --- /dev/null +++ b/library/cropperjs/dist/cropper.min.js @@ -0,0 +1,10 @@ +/*! + * Cropper.js v1.2.2 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2018 Chen Fengyuan + * Released under the MIT license + * + * Date: 2018-01-03T13:27:18.062Z + */ +!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):t.Cropper=i()}(this,function(){"use strict";var t="undefined"!=typeof window?window:{},i="cropper",e=i+"-crop",a=i+"-disabled",n=i+"-hidden",o=i+"-hide",h=i+"-modal",r=i+"-move",s="action",c="preview",l="crop",d="cropend",p="cropmove",m="cropstart",u="load",g=t.PointerEvent?"pointerdown":"touchstart mousedown",f=t.PointerEvent?"pointermove":"touchmove mousemove",v=t.PointerEvent?"pointerup pointercancel":"touchend touchcancel mouseup",w="wheel mousewheel DOMMouseScroll",x=/^(e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/,b=/^data:/,y=/^data:image\/jpeg;base64,/,C=/^(img|canvas)$/i,M={viewMode:0,dragMode:"crop",aspectRatio:NaN,data:null,preview:"",responsive:!0,restore:!0,checkCrossOrigin:!0,checkOrientation:!0,modal:!0,guides:!0,center:!0,highlight:!0,background:!0,autoCrop:!0,autoCropArea:.8,movable:!0,rotatable:!0,scalable:!0,zoomable:!0,zoomOnTouch:!0,zoomOnWheel:!0,wheelZoomRatio:.1,cropBoxMovable:!0,cropBoxResizable:!0,toggleDragModeOnDblclick:!0,minCanvasWidth:0,minCanvasHeight:0,minCropBoxWidth:0,minCropBoxHeight:0,minContainerWidth:200,minContainerHeight:100,ready:null,cropstart:null,cropmove:null,cropend:null,crop:null,zoom:null},D="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},B=function(t,i){if(!(t instanceof i))throw new TypeError("Cannot call a class as a function")},k=function(){function t(t,i){for(var e=0;e1?i-1:0),a=1;a0){if(Object.assign)return Object.assign.apply(Object,[t].concat(e));e.forEach(function(i){H(i)&&Object.keys(i).forEach(function(e){t[e]=i[e]})})}return t}function z(t,i){for(var e=arguments.length,a=Array(e>2?e-2:0),n=2;n1&&void 0!==arguments[1]?arguments[1]:1e11;return R.test(t)?Math.round(t*i)/i:t}var I=/^(width|height|left|top|marginLeft|marginTop)$/;function U(t,i){var e=t.style;O(i,function(t,i){I.test(i)&&W(t)&&(t+="px"),e[i]=t})}function j(t,i){if(i)if(W(t.length))O(t,function(t){j(t,i)});else if(t.classList)t.classList.add(i);else{var e=t.className.trim();e?e.indexOf(i)<0&&(t.className=e+" "+i):t.className=i}}function P(t,i){i&&(W(t.length)?O(t,function(t){P(t,i)}):t.classList?t.classList.remove(i):t.className.indexOf(i)>=0&&(t.className=t.className.replace(i,"")))}function q(t,i,e){i&&(W(t.length)?O(t,function(t){q(t,i,e)}):e?j(t,i):P(t,i))}var $=/([a-z\d])([A-Z])/g;function Q(t){return t.replace($,"$1-$2").toLowerCase()}function Z(t,i){return H(t[i])?t[i]:t.dataset?t.dataset[i]:t.getAttribute("data-"+Q(i))}function F(t,i,e){H(e)?t[i]=e:t.dataset?t.dataset[i]=e:t.setAttribute("data-"+Q(i),e)}function K(t,i){if(H(t[i]))try{delete t[i]}catch(e){t[i]=null}else if(t.dataset)try{delete t.dataset[i]}catch(e){t.dataset[i]=null}else t.removeAttribute("data-"+Q(i))}var V=/\s+/;function G(t,i,e){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(X(e)){var n=i.trim().split(V);n.length>1?O(n,function(i){G(t,i,e,a)}):t.removeEventListener?t.removeEventListener(i,e,a):t.detachEvent&&t.detachEvent("on"+i,e)}}function J(t,i,e){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(X(e)){var n=i.trim().split(V);if(n.length>1)O(n,function(i){J(t,i,e,a)});else{if(a.once){var o=e;e=function(){for(var n=arguments.length,h=Array(n),r=0;r0};return n(a)&&n(e)?e*i>a?e=a/i:a=e*i:n(a)?e=a/i:n(e)&&(a=e*i),{width:a,height:e}}var dt=String.fromCharCode;var pt=/^data:.*,/;function mt(t){var i=new DataView(t),e=void 0,a=void 0,n=void 0,o=void 0;if(255===i.getUint8(0)&&216===i.getUint8(1))for(var h=i.byteLength,r=2;r=8&&(o=s+l)}}}if(o){var d=i.getUint16(o,a),p=void 0,m=void 0;for(m=0;mt.width?3===e?r=t.height*h:s=t.width/h:3===e?s=t.width/h:r=t.height*h;var c={aspectRatio:h,naturalWidth:n,naturalHeight:o,width:r,height:s};c.left=(t.width-r)/2,c.top=(t.height-s)/2,c.oldLeft=c.left,c.oldTop=c.top,this.canvasData=c,this.limited=1===e||2===e,this.limitCanvas(!0,!0),this.initialImageData=S({},i),this.initialCanvasData=S({},c)},limitCanvas:function(t,i){var e=this.options,a=this.containerData,n=this.canvasData,o=this.cropBoxData,h=e.viewMode,r=n.aspectRatio,s=this.cropped&&o;if(t){var c=Number(e.minCanvasWidth)||0,l=Number(e.minCanvasHeight)||0;h>1?(c=Math.max(c,a.width),l=Math.max(l,a.height),3===h&&(l*r>c?c=l*r:l=c/r)):h>0&&(c?c=Math.max(c,s?o.width:0):l?l=Math.max(l,s?o.height:0):s&&(c=o.width,(l=o.height)*r>c?c=l*r:l=c/r));var d=lt({aspectRatio:r,width:c,height:l});c=d.width,l=d.height,n.minWidth=c,n.minHeight=l,n.maxWidth=1/0,n.maxHeight=1/0}if(i)if(h){var p=a.width-n.width,m=a.height-n.height;n.minLeft=Math.min(0,p),n.minTop=Math.min(0,m),n.maxLeft=Math.max(0,p),n.maxTop=Math.max(0,m),s&&this.limited&&(n.minLeft=Math.min(o.left,o.left+(o.width-n.width)),n.minTop=Math.min(o.top,o.top+(o.height-n.height)),n.maxLeft=o.left,n.maxTop=o.top,2===h&&(n.width>=a.width&&(n.minLeft=Math.min(0,p),n.maxLeft=Math.max(0,p)),n.height>=a.height&&(n.minTop=Math.min(0,m),n.maxTop=Math.max(0,m))))}else n.minLeft=-n.width,n.minTop=-n.height,n.maxLeft=a.width,n.maxTop=a.height},renderCanvas:function(t,i){var e=this.canvasData,a=this.imageData;if(i){var n=function(t){var i=t.width,e=t.height,a=t.degree;if(90==(a=Math.abs(a)%180))return{width:e,height:i};var n=a%90*Math.PI/180,o=Math.sin(n),h=Math.cos(n),r=i*h+e*o,s=i*o+e*h;return a>90?{width:s,height:r}:{width:r,height:s}}({width:a.naturalWidth*Math.abs(a.scaleX||1),height:a.naturalHeight*Math.abs(a.scaleY||1),degree:a.rotate||0}),o=n.width,h=n.height,r=e.width*(o/e.naturalWidth),s=e.height*(h/e.naturalHeight);e.left-=(r-e.width)/2,e.top-=(s-e.height)/2,e.width=r,e.height=s,e.aspectRatio=o/h,e.naturalWidth=o,e.naturalHeight=h,this.limitCanvas(!0,!1)}(e.width>e.maxWidth||e.widthe.maxHeight||e.heighti.width?n.height=n.width/e:n.width=n.height*e),this.cropBoxData=n,this.limitCropBox(!0,!0),n.width=Math.min(Math.max(n.width,n.minWidth),n.maxWidth),n.height=Math.min(Math.max(n.height,n.minHeight),n.maxHeight),n.width=Math.max(n.minWidth,n.width*a),n.height=Math.max(n.minHeight,n.height*a),n.left=i.left+(i.width-n.width)/2,n.top=i.top+(i.height-n.height)/2,n.oldLeft=n.left,n.oldTop=n.top,this.initialCropBoxData=S({},n)},limitCropBox:function(t,i){var e=this.options,a=this.containerData,n=this.canvasData,o=this.cropBoxData,h=this.limited,r=e.aspectRatio;if(t){var s=Number(e.minCropBoxWidth)||0,c=Number(e.minCropBoxHeight)||0,l=Math.min(a.width,h?n.width:a.width),d=Math.min(a.height,h?n.height:a.height);s=Math.min(s,a.width),c=Math.min(c,a.height),r&&(s&&c?c*r>s?c=s/r:s=c*r:s?c=s/r:c&&(s=c*r),d*r>l?d=l/r:l=d*r),o.minWidth=Math.min(s,l),o.minHeight=Math.min(c,d),o.maxWidth=l,o.maxHeight=d}i&&(h?(o.minLeft=Math.max(0,n.left),o.minTop=Math.max(0,n.top),o.maxLeft=Math.min(a.width,n.left+n.width)-o.width,o.maxTop=Math.min(a.height,n.top+n.height)-o.height):(o.minLeft=0,o.minTop=0,o.maxLeft=a.width-o.width,o.maxTop=a.height-o.height))},renderCropBox:function(){var t=this.options,i=this.containerData,e=this.cropBoxData;(e.width>e.maxWidth||e.widthe.maxHeight||e.height=i.width&&e.height>=i.height?"move":"all"),U(this.cropBox,S({width:e.width,height:e.height},ot({translateX:e.left,translateY:e.top}))),this.cropped&&this.limited&&this.limitCanvas(!0,!0),this.disabled||this.output()},output:function(){this.preview(),this.complete&&_(this.element,l,this.getData())}},gt={initPreview:function(){var t=this.crossOrigin,i=this.options.preview,e=t?this.crossOriginUrl:this.url,a=document.createElement("img");if(t&&(a.crossOrigin=t),a.src=e,this.viewBox.appendChild(a),this.image2=a,i){var n=i.querySelector?[i]:document.querySelectorAll(i);this.previews=n,O(n,function(i){var a=document.createElement("img");F(i,c,{width:i.offsetWidth,height:i.offsetHeight,html:i.innerHTML}),t&&(a.crossOrigin=t),a.src=e,a.style.cssText='display:block;width:100%;height:auto;min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important;image-orientation:0deg!important;"',function(t){for(;t.firstChild;)t.removeChild(t.firstChild)}(i),i.appendChild(a)})}},resetPreview:function(){O(this.previews,function(t){var i=Z(t,c);U(t,{width:i.width,height:i.height}),t.innerHTML=i.html,K(t,c)})},preview:function(){var t=this.imageData,i=this.canvasData,e=this.cropBoxData,a=e.width,n=e.height,o=t.width,h=t.height,r=e.left-i.left-t.left,s=e.top-i.top-t.top;this.cropped&&!this.disabled&&(U(this.image2,S({width:o,height:h},ot(S({translateX:-r,translateY:-s},t)))),O(this.previews,function(i){var e=Z(i,c),l=e.width,d=e.height,p=l,m=d,u=1;a&&(m=n*(u=l/a)),n&&m>d&&(p=a*(u=d/n),m=d),U(i,{width:p,height:m}),U(i.getElementsByTagName("img")[0],S({width:o*u,height:h*u},ot(S({translateX:-r*u,translateY:-s*u},t))))}))}},ft={bind:function(){var t=this.element,i=this.options,e=this.cropper;X(i.cropstart)&&J(t,m,i.cropstart),X(i.cropmove)&&J(t,p,i.cropmove),X(i.cropend)&&J(t,d,i.cropend),X(i.crop)&&J(t,l,i.crop),X(i.zoom)&&J(t,"zoom",i.zoom),J(e,g,this.onCropStart=z(this.cropStart,this)),i.zoomable&&i.zoomOnWheel&&J(e,w,this.onWheel=z(this.wheel,this)),i.toggleDragModeOnDblclick&&J(e,"dblclick",this.onDblclick=z(this.dblclick,this)),J(t.ownerDocument,f,this.onCropMove=z(this.cropMove,this)),J(t.ownerDocument,v,this.onCropEnd=z(this.cropEnd,this)),i.responsive&&J(window,"resize",this.onResize=z(this.resize,this))},unbind:function(){var t=this.element,i=this.options,e=this.cropper;X(i.cropstart)&&G(t,m,i.cropstart),X(i.cropmove)&&G(t,p,i.cropmove),X(i.cropend)&&G(t,d,i.cropend),X(i.crop)&&G(t,l,i.crop),X(i.zoom)&&G(t,"zoom",i.zoom),G(e,g,this.onCropStart),i.zoomable&&i.zoomOnWheel&&G(e,w,this.onWheel),i.toggleDragModeOnDblclick&&G(e,"dblclick",this.onDblclick),G(t.ownerDocument,f,this.onCropMove),G(t.ownerDocument,v,this.onCropEnd),i.responsive&&G(window,"resize",this.onResize)}},vt={resize:function(){var t=this.options,i=this.container,e=this.containerData,a=Number(t.minContainerWidth)||200,n=Number(t.minContainerHeight)||100;if(!(this.disabled||e.width<=a||e.height<=n)){var o=i.offsetWidth/e.width;if(1!==o||i.offsetHeight!==e.height){var h=void 0,r=void 0;t.restore&&(h=this.getCanvasData(),r=this.getCropBoxData()),this.render(),t.restore&&(this.setCanvasData(O(h,function(t,i){h[i]=t*o})),this.setCropBoxData(O(r,function(t,i){r[i]=t*o})))}}},dblclick:function(){if(!this.disabled&&"none"!==this.options.dragMode){this.setDragMode((t=this.dragBox,i=e,(t.classList?t.classList.contains(i):t.className.indexOf(i)>-1)?"move":"crop"));var t,i}},wheel:function(t){var i=this,e=Number(this.options.wheelZoomRatio)||.1,a=1;this.disabled||(t.preventDefault(),this.wheeling||(this.wheeling=!0,setTimeout(function(){i.wheeling=!1},50),t.deltaY?a=t.deltaY>0?1:-1:t.wheelDelta?a=-t.wheelDelta/120:t.detail&&(a=t.detail>0?1:-1),this.zoom(-a*e,t)))},cropStart:function(t){if(!this.disabled){var i=this.options,e=this.pointers,a=void 0;t.changedTouches?O(t.changedTouches,function(t){e[t.identifier]=st(t)}):e[t.pointerId||0]=st(t),a=Object.keys(e).length>1&&i.zoomable&&i.zoomOnTouch?"zoom":Z(t.target,s),x.test(a)&&!1!==_(this.element,m,{originalEvent:t,action:a})&&(t.preventDefault(),this.action=a,this.cropping=!1,"crop"===a&&(this.cropping=!0,j(this.dragBox,h)))}},cropMove:function(t){var i=this.action;if(!this.disabled&&i){var e=this.pointers;t.preventDefault(),!1!==_(this.element,p,{originalEvent:t,action:i})&&(t.changedTouches?O(t.changedTouches,function(t){S(e[t.identifier],st(t,!0))}):S(e[t.pointerId||0],st(t,!0)),this.change(t))}},cropEnd:function(t){if(!this.disabled){var i=this.action,e=this.pointers;t.changedTouches?O(t.changedTouches,function(t){delete e[t.identifier]}):delete e[t.pointerId||0],i&&(t.preventDefault(),Object.keys(e).length||(this.action=""),this.cropping&&(this.cropping=!1,q(this.dragBox,h,this.cropped&&this.options.modal)),_(this.element,d,{originalEvent:t,action:i}))}}},wt={change:function(t){var i=this.options,e=this.canvasData,a=this.containerData,o=this.cropBoxData,h=this.pointers,r=this.action,s=i.aspectRatio,c=o.left,l=o.top,d=o.width,p=o.height,m=c+d,u=l+p,g=0,f=0,v=a.width,w=a.height,x=!0,b=void 0;!s&&t.shiftKey&&(s=d&&p?d/p:1),this.limited&&(g=o.minLeft,f=o.minTop,v=g+Math.min(a.width,e.width,e.left+e.width),w=f+Math.min(a.height,e.height,e.top+e.height));var y=h[Object.keys(h)[0]],C={x:y.endX-y.startX,y:y.endY-y.startY},M=function(t){switch(t){case"e":m+C.x>v&&(C.x=v-m);break;case"w":c+C.xw&&(C.y=w-u)}};switch(r){case"all":c+=C.x,l+=C.y;break;case"e":if(C.x>=0&&(m>=v||s&&(l<=f||u>=w))){x=!1;break}M("e"),d+=C.x,s&&(p=d/s,l-=C.x/s/2),d<0&&(r="w",d=0);break;case"n":if(C.y<=0&&(l<=f||s&&(c<=g||m>=v))){x=!1;break}M("n"),p-=C.y,l+=C.y,s&&(d=p*s,c+=C.y*s/2),p<0&&(r="s",p=0);break;case"w":if(C.x<=0&&(c<=g||s&&(l<=f||u>=w))){x=!1;break}M("w"),d-=C.x,c+=C.x,s&&(p=d/s,l+=C.x/s/2),d<0&&(r="e",d=0);break;case"s":if(C.y>=0&&(u>=w||s&&(c<=g||m>=v))){x=!1;break}M("s"),p+=C.y,s&&(d=p*s,c-=C.y*s/2),p<0&&(r="n",p=0);break;case"ne":if(s){if(C.y<=0&&(l<=f||m>=v)){x=!1;break}M("n"),p-=C.y,l+=C.y,d=p*s}else M("n"),M("e"),C.x>=0?mf&&(p-=C.y,l+=C.y):(p-=C.y,l+=C.y);d<0&&p<0?(r="sw",p=0,d=0):d<0?(r="nw",d=0):p<0&&(r="se",p=0);break;case"nw":if(s){if(C.y<=0&&(l<=f||c<=g)){x=!1;break}M("n"),p-=C.y,l+=C.y,d=p*s,c+=C.y*s}else M("n"),M("w"),C.x<=0?c>g?(d-=C.x,c+=C.x):C.y<=0&&l<=f&&(x=!1):(d-=C.x,c+=C.x),C.y<=0?l>f&&(p-=C.y,l+=C.y):(p-=C.y,l+=C.y);d<0&&p<0?(r="se",p=0,d=0):d<0?(r="ne",d=0):p<0&&(r="sw",p=0);break;case"sw":if(s){if(C.x<=0&&(c<=g||u>=w)){x=!1;break}M("w"),d-=C.x,c+=C.x,p=d/s}else M("s"),M("w"),C.x<=0?c>g?(d-=C.x,c+=C.x):C.y>=0&&u>=w&&(x=!1):(d-=C.x,c+=C.x),C.y>=0?u=0&&(m>=v||u>=w)){x=!1;break}M("e"),p=(d+=C.x)/s}else M("s"),M("e"),C.x>=0?m=0&&u>=w&&(x=!1):d+=C.x,C.y>=0?u0?r=C.y>0?"se":"ne":C.x<0&&(c-=d,r=C.y>0?"sw":"nw"),C.y<0&&(l-=p),this.cropped||(P(this.cropBox,n),this.cropped=!0,this.limited&&this.limitCropBox(!0,!0))}x&&(o.width=d,o.height=p,o.left=c,o.top=l,this.action=r,this.renderCropBox()),O(h,function(t){t.startX=t.endX,t.startY=t.endY})}},xt={crop:function(){return this.ready&&!this.disabled&&(this.cropped||(this.cropped=!0,this.limitCropBox(!0,!0),this.options.modal&&j(this.dragBox,h),P(this.cropBox,n)),this.setCropBoxData(this.initialCropBoxData)),this},reset:function(){return this.ready&&!this.disabled&&(this.imageData=S({},this.initialImageData),this.canvasData=S({},this.initialCanvasData),this.cropBoxData=S({},this.initialCropBoxData),this.renderCanvas(),this.cropped&&this.renderCropBox()),this},clear:function(){return this.cropped&&!this.disabled&&(S(this.cropBoxData,{left:0,top:0,width:0,height:0}),this.cropped=!1,this.renderCropBox(),this.limitCanvas(!0,!0),this.renderCanvas(),P(this.dragBox,h),j(this.cropBox,n)),this},replace:function(t){var i=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return!this.disabled&&t&&(this.isImg&&(this.element.src=t),i?(this.url=t,this.image.src=t,this.ready&&(this.image2.src=t,O(this.previews,function(i){i.getElementsByTagName("img")[0].src=t}))):(this.isImg&&(this.replaced=!0),this.options.data=null,this.load(t))),this},enable:function(){return this.ready&&(this.disabled=!1,P(this.cropper,a)),this},disable:function(){return this.ready&&(this.disabled=!0,j(this.cropper,a)),this},destroy:function(){var t=this.element,e=this.image;return this.loaded?(this.isImg&&this.replaced&&(t.src=this.originalUrl),this.unbuild(),P(t,n)):this.isImg?G(t,u,this.onStart):e&&e.parentNode.removeChild(e),K(t,i),this},move:function(t,i){var e=this.canvasData,a=e.left,n=e.top;return this.moveTo(N(t)?t:a+Number(t),N(i)?i:n+Number(i))},moveTo:function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t,e=this.canvasData,a=!1;return t=Number(t),i=Number(i),this.ready&&!this.disabled&&this.options.movable&&(W(t)&&(e.left=t,a=!0),W(i)&&(e.top=i,a=!0),a&&this.renderCanvas(!0)),this},zoom:function(t,i){var e=this.canvasData;return t=(t=Number(t))<0?1/(1-t):1+t,this.zoomTo(e.width*t/e.naturalWidth,null,i)},zoomTo:function(t,i,e){var a=this.options,n=this.canvasData,o=n.width,h=n.height,r=n.naturalWidth,s=n.naturalHeight;if((t=Number(t))>=0&&this.ready&&!this.disabled&&a.zoomable){var c=r*t,l=s*t;if(!1===_(this.element,"zoom",{originalEvent:e,oldRatio:o/r,ratio:c/r}))return this;if(e){var d=this.pointers,p=tt(this.cropper),m=d&&Object.keys(d).length?function(t){var i=0,e=0,a=0;return O(t,function(t){var n=t.startX,o=t.startY;i+=n,e+=o,a+=1}),{pageX:i/=a,pageY:e/=a}}(d):{pageX:e.pageX,pageY:e.pageY};n.left-=(c-o)*((m.pageX-p.left-n.left)/o),n.top-=(l-h)*((m.pageY-p.top-n.top)/h)}else Y(i)&&W(i.x)&&W(i.y)?(n.left-=(c-o)*((i.x-n.left)/o),n.top-=(l-h)*((i.y-n.top)/h)):(n.left-=(c-o)/2,n.top-=(l-h)/2);n.width=c,n.height=l,this.renderCanvas(!0)}return this},rotate:function(t){return this.rotateTo((this.imageData.rotate||0)+Number(t))},rotateTo:function(t){return W(t=Number(t))&&this.ready&&!this.disabled&&this.options.rotatable&&(this.imageData.rotate=t%360,this.renderCanvas(!0,!0)),this},scaleX:function(t){var i=this.imageData.scaleY;return this.scale(t,W(i)?i:1)},scaleY:function(t){var i=this.imageData.scaleX;return this.scale(W(i)?i:1,t)},scale:function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t,e=this.imageData,a=!1;return t=Number(t),i=Number(i),this.ready&&!this.disabled&&this.options.scalable&&(W(t)&&(e.scaleX=t,a=!0),W(i)&&(e.scaleY=i,a=!0),a&&this.renderCanvas(!0,!0)),this},getData:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],i=this.options,e=this.imageData,a=this.canvasData,n=this.cropBoxData,o=void 0;if(this.ready&&this.cropped){o={x:n.left-a.left,y:n.top-a.top,width:n.width,height:n.height};var h=e.width/e.naturalWidth;O(o,function(i,e){i/=h,o[e]=t?Math.round(i):i})}else o={x:0,y:0,width:0,height:0};return i.rotatable&&(o.rotate=e.rotate||0),i.scalable&&(o.scaleX=e.scaleX||1,o.scaleY=e.scaleY||1),o},setData:function(t){var i=this.options,e=this.imageData,a=this.canvasData,n={};if(X(t)&&(t=t.call(this.element)),this.ready&&!this.disabled&&Y(t)){var o=!1;i.rotatable&&W(t.rotate)&&t.rotate!==e.rotate&&(e.rotate=t.rotate,o=!0),i.scalable&&(W(t.scaleX)&&t.scaleX!==e.scaleX&&(e.scaleX=t.scaleX,o=!0),W(t.scaleY)&&t.scaleY!==e.scaleY&&(e.scaleY=t.scaleY,o=!0)),o&&this.renderCanvas(!0,!0);var h=e.width/e.naturalWidth;W(t.x)&&(n.left=t.x*h+a.left),W(t.y)&&(n.top=t.y*h+a.top),W(t.width)&&(n.width=t.width*h),W(t.height)&&(n.height=t.height*h),this.setCropBoxData(n)}return this},getContainerData:function(){return this.ready?S({},this.containerData):{}},getImageData:function(){return this.loaded?S({},this.imageData):{}},getCanvasData:function(){var t=this.canvasData,i={};return this.ready&&O(["left","top","width","height","naturalWidth","naturalHeight"],function(e){i[e]=t[e]}),i},setCanvasData:function(t){var i=this.canvasData,e=i.aspectRatio;return X(t)&&(t=t.call(this.element)),this.ready&&!this.disabled&&Y(t)&&(W(t.left)&&(i.left=t.left),W(t.top)&&(i.top=t.top),W(t.width)?(i.width=t.width,i.height=t.width/e):W(t.height)&&(i.height=t.height,i.width=t.height*e),this.renderCanvas(!0)),this},getCropBoxData:function(){var t=this.cropBoxData,i=void 0;return this.ready&&this.cropped&&(i={left:t.left,top:t.top,width:t.width,height:t.height}),i||{}},setCropBoxData:function(t){var i=this.cropBoxData,e=this.options.aspectRatio,a=void 0,n=void 0;return X(t)&&(t=t.call(this.element)),this.ready&&this.cropped&&!this.disabled&&Y(t)&&(W(t.left)&&(i.left=t.left),W(t.top)&&(i.top=t.top),W(t.width)&&t.width!==i.width&&(a=!0,i.width=t.width),W(t.height)&&t.height!==i.height&&(n=!0,i.height=t.height),e&&(a?i.height=i.width/e:n&&(i.width=i.height*e)),this.renderCropBox()),this},getCroppedCanvas:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!this.ready||!window.HTMLCanvasElement)return null;var i=this.canvasData,e=function(t,i,e,a){var n=i.naturalWidth,o=i.naturalHeight,h=i.rotate,r=void 0===h?0:h,s=i.scaleX,c=void 0===s?1:s,l=i.scaleY,d=void 0===l?1:l,p=e.aspectRatio,m=e.naturalWidth,u=e.naturalHeight,g=a.fillColor,f=void 0===g?"transparent":g,v=a.imageSmoothingEnabled,w=void 0===v||v,x=a.imageSmoothingQuality,b=void 0===x?"low":x,y=a.maxWidth,C=void 0===y?1/0:y,M=a.maxHeight,D=void 0===M?1/0:M,B=a.minWidth,k=void 0===B?0:B,T=a.minHeight,W=void 0===T?0:T,N=document.createElement("canvas"),H=N.getContext("2d"),L=lt({aspectRatio:p,width:C,height:D}),Y=lt({aspectRatio:p,width:k,height:W}),X=Math.min(L.width,Math.max(Y.width,m)),O=Math.min(L.height,Math.max(Y.height,u)),S=[-n/2,-o/2,n,o];return N.width=A(X),N.height=A(O),H.fillStyle=f,H.fillRect(0,0,X,O),H.save(),H.translate(X/2,O/2),H.rotate(r*Math.PI/180),H.scale(c,d),H.imageSmoothingEnabled=w,H.imageSmoothingQuality=b,H.drawImage.apply(H,[t].concat(E(S.map(function(t){return Math.floor(A(t))})))),H.restore(),N}(this.image,this.imageData,i,t);if(!this.cropped)return e;var a=this.getData(),n=a.x,o=a.y,h=a.width,r=a.height,s=h/r,c=lt({aspectRatio:s,width:t.maxWidth||1/0,height:t.maxHeight||1/0}),l=lt({aspectRatio:s,width:t.minWidth||0,height:t.minHeight||0}),d=lt({aspectRatio:s,width:t.width||h,height:t.height||r}),p=d.width,m=d.height;p=Math.min(c.width,Math.max(l.width,p)),m=Math.min(c.height,Math.max(l.height,m));var u=document.createElement("canvas"),g=u.getContext("2d");u.width=A(p),u.height=A(m),g.fillStyle=t.fillColor||"transparent",g.fillRect(0,0,p,m);var f=t.imageSmoothingEnabled,v=void 0===f||f,w=t.imageSmoothingQuality;g.imageSmoothingEnabled=v,w&&(g.imageSmoothingQuality=w);var x=e.width,b=e.height,y=n,C=o,M=void 0,D=void 0,B=void 0,k=void 0,T=void 0,W=void 0;y<=-h||y>x?(y=0,M=0,B=0,T=0):y<=0?(B=-y,y=0,T=M=Math.min(x,h+y)):y<=x&&(B=0,T=M=Math.min(h,x-y)),M<=0||C<=-r||C>b?(C=0,D=0,k=0,W=0):C<=0?(k=-C,C=0,W=D=Math.min(b,r+C)):C<=b&&(k=0,W=D=Math.min(r,b-C));var N=[y,C,M,D];if(T>0&&W>0){var H=p/h;N.push(B*H,k*H,T*H,W*H)}return g.drawImage.apply(g,[e].concat(E(N.map(function(t){return Math.floor(A(t))})))),u},setAspectRatio:function(t){var i=this.options;return this.disabled||N(t)||(i.aspectRatio=Math.max(0,t)||NaN,this.ready&&(this.initCropBox(),this.cropped&&this.renderCropBox())),this},setDragMode:function(t){var i=this.options,a=this.dragBox,n=this.face;if(this.loaded&&!this.disabled){var o="crop"===t,h=i.movable&&"move"===t;F(a,s,t=o||h?t:"none"),q(a,e,o),q(a,r,h),i.cropBoxMovable||(F(n,s,t),q(n,e,o),q(n,r,h))}return this}},bt=t.Cropper,yt=function(){function t(i){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(B(this,t),!i||!C.test(i.tagName))throw new Error("The first argument is required and must be an or element.");this.element=i,this.options=S({},M,Y(e)&&e),this.complete=!1,this.cropped=!1,this.disabled=!1,this.isImg=!1,this.limited=!1,this.loaded=!1,this.ready=!1,this.replaced=!1,this.wheeling=!1,this.originalUrl="",this.canvasData=null,this.cropBoxData=null,this.previews=null,this.pointers={},this.init()}return k(t,[{key:"init",value:function(){var t=this.element,e=t.tagName.toLowerCase(),a=void 0;if(!Z(t,i)){if(F(t,i,this),"img"===e){if(this.isImg=!0,a=t.getAttribute("src")||"",this.originalUrl=a,!a)return;a=t.src}else"canvas"===e&&window.HTMLCanvasElement&&(a=t.toDataURL());this.load(a)}}},{key:"load",value:function(t){var i=this;if(t){this.url=t,this.imageData={};var e=this.element,a=this.options;if(a.checkOrientation&&window.ArrayBuffer)if(b.test(t))y.test(t)?this.read(function(t){var i=t.replace(pt,""),e=atob(i),a=new ArrayBuffer(e.length),n=new Uint8Array(a);return O(n,function(t,i){n[i]=e.charCodeAt(i)}),a}(t)):this.clone();else{var n=new XMLHttpRequest;n.onerror=function(){i.clone()},n.onload=function(){i.read(n.response)},a.checkCrossOrigin&&at(t)&&e.crossOrigin&&(t=nt(t)),n.open("get",t),n.responseType="arraybuffer",n.withCredentials="use-credentials"===e.crossOrigin,n.send()}else this.clone()}}},{key:"read",value:function(t){var i=this.options,e=this.imageData,a=mt(t),n=0,o=1,h=1;if(a>1){this.url=function(t,i){var e="";return O(new Uint8Array(t),function(t){e+=dt(t)}),"data:"+i+";base64,"+btoa(e)}(t,"image/jpeg");var r=function(t){var i=0,e=1,a=1;switch(t){case 2:e=-1;break;case 3:i=-180;break;case 4:a=-1;break;case 5:i=90,a=-1;break;case 6:i=90;break;case 7:i=90,e=-1;break;case 8:i=-90}return{rotate:i,scaleX:e,scaleY:a}}(a);n=r.rotate,o=r.scaleX,h=r.scaleY}i.rotatable&&(e.rotate=n),i.scalable&&(e.scaleX=o,e.scaleY=h),this.clone()}},{key:"clone",value:function(){var t=this.element,i=this.url,e=void 0,a=void 0;this.options.checkCrossOrigin&&at(i)&&((e=t.crossOrigin)?a=i:(e="anonymous",a=nt(i))),this.crossOrigin=e,this.crossOriginUrl=a;var n=document.createElement("img");e&&(n.crossOrigin=e),n.src=a||i;var h=z(this.start,this),r=z(this.stop,this);this.image=n,this.onStart=h,this.onStop=r,this.isImg?t.complete?this.start():J(t,u,h):(J(n,u,h),J(n,"error",r),j(n,o),t.parentNode.insertBefore(n,t.nextSibling))}},{key:"start",value:function(t){var i=this,e=this.isImg?this.element:this.image;t&&(G(e,u,this.onStart),G(e,"error",this.onStop)),function(t,i){if(!t.naturalWidth||rt){var e=document.createElement("img"),a=document.body||document.documentElement;e.onload=function(){i(e.width,e.height),rt||a.removeChild(e)},e.src=t.src,rt||(e.style.cssText="left:0;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;opacity:0;position:absolute;top:0;z-index:-1;",a.appendChild(e))}else i(t.naturalWidth,t.naturalHeight)}(e,function(t,e){S(i.imageData,{naturalWidth:t,naturalHeight:e,aspectRatio:t/e}),i.loaded=!0,i.build()})}},{key:"stop",value:function(){var t=this.image;G(t,u,this.onStart),G(t,"error",this.onStop),t.parentNode.removeChild(t),this.image=null}},{key:"build",value:function(){var t=this;if(this.loaded){this.ready&&this.unbuild();var e=this.element,a=this.options,c=this.image,d=e.parentNode,p=document.createElement("div");p.innerHTML='
';var m=p.querySelector("."+i+"-container"),u=m.querySelector("."+i+"-canvas"),g=m.querySelector("."+i+"-drag-box"),f=m.querySelector("."+i+"-crop-box"),v=f.querySelector("."+i+"-face");this.container=d,this.cropper=m,this.canvas=u,this.dragBox=g,this.cropBox=f,this.viewBox=m.querySelector("."+i+"-view-box"),this.face=v,u.appendChild(c),j(e,n),d.insertBefore(m,e.nextSibling),this.isImg||P(c,o),this.initPreview(),this.bind(),a.aspectRatio=Math.max(0,a.aspectRatio)||NaN,a.viewMode=Math.max(0,Math.min(3,Math.round(a.viewMode)))||0,this.cropped=a.autoCrop,a.autoCrop?a.modal&&j(g,h):j(f,n),a.guides||j(f.getElementsByClassName(i+"-dashed"),n),a.center||j(f.getElementsByClassName(i+"-center"),n),a.background&&j(m,i+"-bg"),a.highlight||j(v,"cropper-invisible"),a.cropBoxMovable&&(j(v,r),F(v,s,"all")),a.cropBoxResizable||(j(f.getElementsByClassName(i+"-line"),n),j(f.getElementsByClassName(i+"-point"),n)),this.setDragMode(a.dragMode),this.render(),this.ready=!0,this.setData(a.data),this.completing=setTimeout(function(){X(a.ready)&&J(e,"ready",a.ready,{once:!0}),_(e,"ready"),_(e,l,t.getData()),t.complete=!0},0)}}},{key:"unbuild",value:function(){this.ready&&(this.complete||clearTimeout(this.completing),this.ready=!1,this.complete=!1,this.initialImageData=null,this.initialCanvasData=null,this.initialCropBoxData=null,this.containerData=null,this.canvasData=null,this.cropBoxData=null,this.unbind(),this.resetPreview(),this.previews=null,this.viewBox=null,this.cropBox=null,this.dragBox=null,this.canvas=null,this.container=null,this.cropper.parentNode.removeChild(this.cropper),this.cropper=null)}}],[{key:"noConflict",value:function(){return window.Cropper=bt,t}},{key:"setDefaults",value:function(t){S(M,Y(t)&&t)}}]),t}();return S(yt.prototype,ut,gt,ft,vt,wt,xt),yt}); \ No newline at end of file diff --git a/library/cropperjs/docs/css/cropper.css b/library/cropperjs/docs/css/cropper.css new file mode 100644 index 000000000..dd22178fe --- /dev/null +++ b/library/cropperjs/docs/css/cropper.css @@ -0,0 +1,306 @@ +/*! + * Cropper.js v1.2.2 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2018 Chen Fengyuan + * Released under the MIT license + * + * Date: 2018-01-03T13:26:29.610Z + */ + +.cropper-container { + direction: ltr; + font-size: 0; + line-height: 0; + position: relative; + -ms-touch-action: none; + touch-action: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.cropper-container img {/*Avoid margin top issue (Occur only when margin-top <= -height) + */ + display: block; + height: 100%; + image-orientation: 0deg; + max-height: none !important; + max-width: none !important; + min-height: 0 !important; + min-width: 0 !important; + width: 100%; +} + +.cropper-wrap-box, +.cropper-canvas, +.cropper-drag-box, +.cropper-crop-box, +.cropper-modal { + bottom: 0; + left: 0; + position: absolute; + right: 0; + top: 0; +} + +.cropper-wrap-box, +.cropper-canvas { + overflow: hidden; +} + +.cropper-drag-box { + background-color: #fff; + opacity: 0; +} + +.cropper-modal { + background-color: #000; + opacity: .5; +} + +.cropper-view-box { + display: block; + height: 100%; + outline-color: rgba(51, 153, 255, 0.75); + outline: 1px solid #39f; + overflow: hidden; + width: 100%; +} + +.cropper-dashed { + border: 0 dashed #eee; + display: block; + opacity: .5; + position: absolute; +} + +.cropper-dashed.dashed-h { + border-bottom-width: 1px; + border-top-width: 1px; + height: 33.33333%; + left: 0; + top: 33.33333%; + width: 100%; +} + +.cropper-dashed.dashed-v { + border-left-width: 1px; + border-right-width: 1px; + height: 100%; + left: 33.33333%; + top: 0; + width: 33.33333%; +} + +.cropper-center { + display: block; + height: 0; + left: 50%; + opacity: .75; + position: absolute; + top: 50%; + width: 0; +} + +.cropper-center:before, +.cropper-center:after { + background-color: #eee; + content: ' '; + display: block; + position: absolute; +} + +.cropper-center:before { + height: 1px; + left: -3px; + top: 0; + width: 7px; +} + +.cropper-center:after { + height: 7px; + left: 0; + top: -3px; + width: 1px; +} + +.cropper-face, +.cropper-line, +.cropper-point { + display: block; + height: 100%; + opacity: .1; + position: absolute; + width: 100%; +} + +.cropper-face { + background-color: #fff; + left: 0; + top: 0; +} + +.cropper-line { + background-color: #39f; +} + +.cropper-line.line-e { + cursor: ew-resize; + right: -3px; + top: 0; + width: 5px; +} + +.cropper-line.line-n { + cursor: ns-resize; + height: 5px; + left: 0; + top: -3px; +} + +.cropper-line.line-w { + cursor: ew-resize; + left: -3px; + top: 0; + width: 5px; +} + +.cropper-line.line-s { + bottom: -3px; + cursor: ns-resize; + height: 5px; + left: 0; +} + +.cropper-point { + background-color: #39f; + height: 5px; + opacity: .75; + width: 5px; +} + +.cropper-point.point-e { + cursor: ew-resize; + margin-top: -3px; + right: -3px; + top: 50%; +} + +.cropper-point.point-n { + cursor: ns-resize; + left: 50%; + margin-left: -3px; + top: -3px; +} + +.cropper-point.point-w { + cursor: ew-resize; + left: -3px; + margin-top: -3px; + top: 50%; +} + +.cropper-point.point-s { + bottom: -3px; + cursor: s-resize; + left: 50%; + margin-left: -3px; +} + +.cropper-point.point-ne { + cursor: nesw-resize; + right: -3px; + top: -3px; +} + +.cropper-point.point-nw { + cursor: nwse-resize; + left: -3px; + top: -3px; +} + +.cropper-point.point-sw { + bottom: -3px; + cursor: nesw-resize; + left: -3px; +} + +.cropper-point.point-se { + bottom: -3px; + cursor: nwse-resize; + height: 20px; + opacity: 1; + right: -3px; + width: 20px; +} + +@media (min-width: 768px) { + .cropper-point.point-se { + height: 15px; + width: 15px; + } +} + +@media (min-width: 992px) { + .cropper-point.point-se { + height: 10px; + width: 10px; + } +} + +@media (min-width: 1200px) { + .cropper-point.point-se { + height: 5px; + opacity: .75; + width: 5px; + } +} + +.cropper-point.point-se:before { + background-color: #39f; + bottom: -50%; + content: ' '; + display: block; + height: 200%; + opacity: 0; + position: absolute; + right: -50%; + width: 200%; +} + +.cropper-invisible { + opacity: 0; +} + +.cropper-bg { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC'); +} + +.cropper-hide { + display: block; + height: 0; + position: absolute; + width: 0; +} + +.cropper-hidden { + display: none !important; +} + +.cropper-move { + cursor: move; +} + +.cropper-crop { + cursor: crosshair; +} + +.cropper-disabled .cropper-drag-box, +.cropper-disabled .cropper-face, +.cropper-disabled .cropper-line, +.cropper-disabled .cropper-point { + cursor: not-allowed; +} + diff --git a/library/cropperjs/docs/css/main.css b/library/cropperjs/docs/css/main.css new file mode 100644 index 000000000..d89f82d27 --- /dev/null +++ b/library/cropperjs/docs/css/main.css @@ -0,0 +1,252 @@ +.btn { + padding-left: .75rem; + padding-right: .75rem; +} + +label.btn { + margin-bottom: 0; +} + +.d-flex > .btn { + flex: 1; +} + +.carbonads { + border-radius: .25rem; + border: 1px solid #ccc; + font-size: .875rem; + overflow: hidden; + padding: 1rem; +} + +.carbon-wrap { + overflow: hidden; +} + +.carbon-img { + clear: left; + display: block; + float: left; +} + +.carbon-text, +.carbon-poweredby { + display: block; + margin-left: 140px; +} + +.carbon-text, +.carbon-text:hover, +.carbon-text:focus { + color: #fff; + text-decoration: none; +} + +.carbon-poweredby, +.carbon-poweredby:hover, +.carbon-poweredby:focus { + color: #ddd; + text-decoration: none; +} + +@media (min-width: 768px) { + .carbonads { + float: right; + margin-bottom: -1rem; + margin-top: -1rem; + max-width: 360px; + } +} + +.footer { + font-size: .875rem; +} + +.heart { + color: #ddd; + display: block; + height: 2rem; + line-height: 2rem; + margin-bottom: 0; + margin-top: 1rem; + position: relative; + text-align: center; + width: 100%; +} + +.heart:hover { + color: #ff4136; +} + +.heart::before { + border-top: 1px solid #eee; + content: " "; + display: block; + height: 0; + left: 0; + position: absolute; + right: 0; + top: 50%; +} + +.heart::after { + background-color: #fff; + content: "♥"; + padding-left: .5rem; + padding-right: .5rem; + position: relative; + z-index: 1; +} + +.img-container, +.img-preview { + background-color: #f7f7f7; + text-align: center; + width: 100%; +} + +.img-container { + margin-bottom: 1rem; + max-height: 497px; + min-height: 200px; +} + +@media (min-width: 768px) { + .img-container { + min-height: 497px; + } +} + +.img-container > img { + max-width: 100%; +} + +.docs-preview { + margin-right: -1rem; +} + +.img-preview { + float: left; + margin-bottom: .5rem; + margin-right: .5rem; + overflow: hidden; +} + +.img-preview > img { + max-width: 100%; +} + +.preview-lg { + height: 9rem; + width: 16rem; +} + +.preview-md { + height: 4.5rem; + width: 8rem; +} + +.preview-sm { + height: 2.25rem; + width: 4rem; +} + +.preview-xs { + height: 1.125rem; + margin-right: 0; + width: 2rem; +} + +.docs-data > .input-group { + margin-bottom: .5rem; +} + +.docs-data .input-group-prepend .input-group-text { + min-width: 4rem; +} + +.docs-data .input-group-append .input-group-text { + min-width: 3rem; +} + +.docs-buttons > .btn, +.docs-buttons > .btn-group, +.docs-buttons > .form-control { + margin-bottom: .5rem; + margin-right: .25rem; +} + +.docs-toggles > .btn, +.docs-toggles > .btn-group, +.docs-toggles > .dropdown { + margin-bottom: .5rem; +} + +.docs-tooltip { + display: block; + margin: -.5rem -.75rem; + padding: .5rem .75rem; +} + +.docs-tooltip > .icon { + margin: 0 -.25rem; + vertical-align: top; +} + +.tooltip-inner { + white-space: normal; +} + +.btn-upload .tooltip-inner, +.btn-toggle .tooltip-inner { + white-space: nowrap; +} + +.btn-toggle { + padding: .5rem; +} + +.btn-toggle > .docs-tooltip { + margin: -.5rem; + padding: .5rem; +} + +@media (max-width: 400px) { + .btn-group-crop { + margin-right: -1rem!important; + } + + .btn-group-crop > .btn { + padding-left: .5rem; + padding-right: .5rem; + } + + .btn-group-crop .docs-tooltip { + margin-left: -.5rem; + margin-right: -.5rem; + padding-left: .5rem; + padding-right: .5rem; + } +} + +.docs-options .dropdown-menu { + width: 100%; +} + +.docs-options .dropdown-menu > li { + font-size: .875rem; + padding: .125rem 1rem; +} + +.docs-options .dropdown-menu .form-check-label { + display: block; +} + +.docs-cropped .modal-body { + text-align: center; +} + +.docs-cropped .modal-body > img, +.docs-cropped .modal-body > canvas { + max-width: 100%; +} diff --git a/library/cropperjs/docs/images/data.jpg b/library/cropperjs/docs/images/data.jpg new file mode 100644 index 0000000000000000000000000000000000000000..56926a274d80ba3197d036645a9a9795f5f38677 GIT binary patch literal 16534 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 literal 0 HcmV?d00001 diff --git a/library/cropperjs/docs/images/layers.jpg b/library/cropperjs/docs/images/layers.jpg new file mode 100644 index 0000000000000000000000000000000000000000..02b77e7b2afcef789be940e444af43f522f3ca31 GIT binary patch literal 26921 zcmeEubyQqS)^8IC5+pdJ(crF)TW|~R9-O9ecL)Rs9y~yR;10n(I0SchcXtTzI#*`y zeQVZxZ{Aune|=|B(A24_U8nk2ySAREnWt3%zPKCM3;>XprUM`X{&_te05HUyjUny; z7yul!njZjoT7|W>aB{NaWoEW2IH<0AdzB7;(MFfrp*7L)jc7W6*>vOgZm)zy{B zm7U4f!JL_uhll6a7;J2e&=!o2?lw+_Zj3gLe4wZR6-pCtWazg{>W_s0t@3 zjRx4p#Maf3_Se_*`_qb#-2_8{y307`yVX{B^n*9H)88dV;%)h|#7qI+U1x4VmkNiMIRWJk0@6V4=h@U@-tffRx0|tC!zu97{4CQ?Zc0XpTuU z;(x&tpRZJLYs$6r&uopKwQk6D6d6wCKi0DTxW#mBqj&c0zUGvg*L|tHoUoIr-+Gcg z84G$_b0*U0*kyB>{$-;rrej{}J^{vn$U)7b3Qq>l_|Rp<|8)MJ1^XY6{6B4sw*4?q zds|uz7W5u;QHis$$=Uj1edS93tk#3-8;fT66NY2kW`-&*rHlT7GP3H)zQO8&`q)FV zI=s^+{LYxp*@98asGaK4P2TD;FJ!jPgK_g3E9rDob@gkOCHcF5_4XNwMdFhvCT7Od1FunUXvmeVnIU{JQM28#C3$h?b{lX zY4E^_Gg7ooPv%OVCxA=8QSaFeiK{)td906uIdW;fDgf=ye-jWP#zK<^xx7alY-6;|{hpMWbIT#mTf3ER^?PoN# zv>)-ivl*V>NaVs5*pJl~MKk1gxr!F2TuGLX5hln6PNShl#GilcT;Y;}-K2q&g3bR= z7G$2p-D&-91=SLU;}V+UYpo>P-Kp>0LaLO9*Et_;vIuGjBo@jVpKssEf1Drbc@>+% zYqT5Yp{KAql{rxEac;@J-_LID=wtvJAoeAQ;|$(CQyMsOOZ%21*q~0u)$U} zaf@Lc?mE#9{Y$Y~q0O0`PS&5!EaXd5JF?gO@*rQ#T%x;(s*VD`$;}x}d}T~j<s5-sa z!!Yd<-PV1*_*(Ka>v9qf+WpG|XE$|7 zK`rCXc;6F%+5r7f+QfPMju=l8q?9GZPw!3QC=&YU30p-CaSqWfoQV=)ZD?T4t!xO9nVxpa^6lXchS%} z7)F2KiDV>q!hF$0O~cz&^|)3cy)r4kbW%@jXBGFb8Z}3wAvu_SOUX!ouIjzXgK=Q( zT}|vdKU=3B^&xeQc=_92db6H>#aV%*1pV2msS8yF=sr~Vq;52(Dz;9(;L(!4NJgh3 z?8y7#h`we@b=vp+3mx}Wp~;AW(ujBBUNV){G`3V>65tKf&7^mGFqnXUvpi!mJiQj2 zd@R=!FmDzDHN7pikrZKMGFJTCIM0Sm@0_R0V<+il`SxY#1*Xh&?wrfYqbC0l7{V(V z{w^+v_dg2G&s9z#=Ve`IY(<5{KlECd<_uW=E>h?<<5W6=E=p0!TbGpXcd8N(E1m#X zU>{_>C%{Ir!OyTGgS?4T)(=Fa)pq$QGLjrdD6eURzmBURVX4r>;efURHY7sc?j1mMKw^B&wF+5CE+ zD6+TTjQ@RmG1xwxo*mNCd0DeJd*_@bh*2y!8nsZIXQo%mYp*?h`MRKZxbd(!;hJR7MP6A+a^$!#i$L z7K<*Jwhb5!!^pLw`+oAU5LlPUdvP@_S^_ZO6FiKJ3CIBuVI0X9s{Fb#?9H<*bXOcD zGdoY@FXP&77?~=3Z>Ld#IhzL$JxYW3M2ZdMlX{`Klj`Q769bF+f*tiqA)_FX#zWq` zCqNw|o*G{BOWC|hHyjs(n|^&E(XLtRDq3nz zJ~@8vtLjQCV8+)SM;bTdIm&YeE`rb9%MUx`VJ6>y4g9sq|8E5bkLBh*-SP>bS(;Y4 zl%A|lrOrj3feYmkf9nim&i25&KhwJx|A#cl&iKGPJ=3%Iq51noIqHOjR>I%Ec(TnW z0EzXX*8cPH(fg5e$sZR;bLDP$Klv4z7pZK0#*VUtvh2vYAW&2PuHX7vL6-EuiE(T8hx{};e)!=7lQkXBKMBxSmoS> z)j>XkrdbZmFBnt>#~z@q6iL?FivJJTmga>UK5>l1LE9b02g@ ze53cjsXCN(KW_!7?fwb}_&<+~f1t^1e>LZVsI{u{dsSxTqM7zjkbZ#M?_#)Ol9}e; z4}V$P+tWL_RXqWc=9eI^w`E7NqNq&9O261OaZR>^be39faQl(es?Mw@oyuz1)Dyt+ zv>uLm6G{NYfHwoWP6VL7QA7j59liS+`&pe1d`FWhmQ}1& znm1Dzk8BE>`N7-$em-RnTiSuoK9^o37>S@nw2lkMBuso{U0Vo6M_71Ot(0OMHntkp z*CaOf>en?EL;FtYhyLQI_no$Z8uf7ngLMw-*{}#1cxk+>Pr$eU9)L#My6K4+U=wnmsSF=Sa{YVn8@;9rg8Qi zPNznEYQFZ^5`6!)esg7{3PwBbdDWj9B%E%?`jL0hgHeOWu!j%WElG1B@`JW+cgEi| z%zs-03`_j!U0ZEljHe)ZEILSnMSmYN(hn7>egQPzTB3Ezhc->`5#Nu*-FKm?F)*$! zXOU#`8Yi?kWuVFT!~>7kQ4&Y_Z7wz<$_RDiW~Gd)s*IlDHoXquh+ znS~?bkc_K}5OeFI?9erySJ+3Rgr)G|R6!qBR~5%871KSVx28Bt($1LPMq}E3-4j`zqN`4XroZ{S5|7tZ3e#|t7>oH6mPSggz&+lRFwAhp* zwOtf1RMgVUG7L-oJdo)g%U%~WC%JZ%Aj%NjiywPT*SB_nhHA7<%Ii23Tkc9 zY-%S+tmhG5UQj1d#%oB`4b1OUoP2+Vqh zXspi%#W?CQD03V#MM|J=)v0o0d?Y<$a>Y%3Rp>035_1?BsbdY>Va}yK=$T}*B?^+S zvm?*7s+iJ*ym!=O&5ef(K8yJ7oRjnQi~d#9cj^wCeVs};;#a6F7XJ{_eqLg7yE zs4Bdsq^qmfZf1QbK}}<>NvzBagsR$|*&ZTV6iGoUpd%Vb*h1YrOj&F7awrA0krY^J z<(Pz0EB~>kWa80}k&&BIPOsfB@(-(=to`kohdh*{|5I%KlcWDr2p^p8klo>X|EERk zchmImhRqDNfp344F8~S4=j#_K?F}A69>f+mNd^lEK|tN^OsIwFIiy*|do?5?+-;b4 z*)#6aCRS-R)F4u0sjH;#RA~GRqz;#?MzJ(<9apA}q*7QQvAWCSj9(EUR@MsI8x`iwb_LBA(H=@lt}QTn)|n1yuz~2YE$yEmxwP*C6YX7P8cqzf|uz;kIu3x*vSQ z*Q%XSH9DzKV!7M_w)>x(x>V65>b+$pAlT5&-uCW7{-Fn;&ba*f!1${KZVu3rTX96P41$wo+*QaWWDo%Xqh zrGC#2#i#p_f@UW|<5Inmp&n`237p2rc#-HZST|Q(2Vv?zsE; zsWgik%TXcnx=yZ$Rz3xTTU)Q398ifUD;F_N6I!wndd1PyHxoc-EhWBWz79Vw(#Oxr4NSmOuB3SIkZ)iw z6M+_pW#OIsSb>_k<_((BkCXBDHo0-7K#OvwKTXQw1A>Cvb1hT!dBxXxTZtj@5kGds z|DhlLsZ0L5CSk;S-=29-b&ocu3!e-A(NngTdPbD0`Uuf{xM+Zhg`lSL*GDY!v97dA}%!%92TD*P+s?@Dh~RFDTDq zbG?0*3~MeDgG%zkUrwS&njXKEZVgEPT@HIb;7gpk`fjm|3~lWURAiYOEWg!!xbTAb z$hF+RF7zGgPh!GbyySQSRL>hhWG(iD&a>8)`f8s5CPL{K1P-g-%PI!V$F%(L zX;NrM!$xfpN+OA5T;Ln?>#5U33+#BmhfQq8C%`!$>Vj|2Jz@Gq52U(U&l<;R zogLv&`Ec$DPywZnsGN?{5;d{5oYSZ;JXsq)t#Fy7P*d2{XmHi>YyM0QE5CXtT@*o5 zv~?sPEg&y&KXmRU913^nN6@*4LFaCBXHWwx*W`02$bq(4cK>VEfjmN|zCC+xj;O)I z6*oj2BmRiVblcy}`~>?lYpqvGe_NblWBVt-hnA=-LF=ldb5Vomxz46m2$W|SPTRg8 zDiES*=nI!ciD!Fmp8zVf%Xv2~>z9J=o?u&dR;D?fR}}Ucj!B>Ed-`W(_VgGuZhLNh zRq$LC7z|t|a$>w+51;=?5!CU7@V|tsFlW1?S%BX+V5|h%cRVYw*ACM8^k^`#G?`M% zWyrjKiJ|R#+G8oJ$GCV{^g0~E-@T0qe<(XQ=fE=iIp*$F#BFrUtjlLQugIKvdePGN5~*y5k-(=Z={I!^yh;KpP&% znb2oZSq-=239wJ3@)#6dEp(TD^4O|Zai>RYV6`8@#83xQj^AvV(MGU3 zpgdIdJ*P{cNBE%K;l5z+flgVbLiTj>Ze$xQcWq8ivX5@=>ucuTkG&S=yB>8Y;xEn%N9!kPAhPJDkfQaY-g+ha)Lx{H!8xquTED%#O9 zCLDxzP5772mr|~D+2E6GWlU=$OACAx#~(#OLD5;As`A_)nJu6~MWV&RS7ohk)Jrr`M{8`3lW3(G z)mMp3lUi&OZ?v)bxEELzuP=H|Jwa07UOKA#qjeoMp_UANZvq9z{?x`ozd7Xv@-a`@ zC7LEfaQ~5xyDv*5Zd$~gsk5j;qPq(Nt2t)pU1a+~WS_~D-LhH2;Q+gA3?E}tmZl1< z(yLatA0S<>YWF5Xcw3S+VC{R9-?ct)0neaU!Bmb1H~TiS%N zxL?{hg^wYD=E=@M$W-(;0{;$ZrF3m5m}4nNr#C!|ZBC~R*6_VQw=uBTSR8<)E6*)g zs}UFC(yAvSIGL@rY@JSWw@hL6VyH0(nMy_2kW?v|M0zImb&f3 zap`;l49;%f2TosqDVg-FJQu>E=L-{|glVWBd?_C3nY1|+w|NaeJLWe_@ea88bt<`2 z^~EtwoJt><@TH4REuWmB9pzzEy|uf&E*7~ie_hmT)%g7H?R!>tLxbB>NlUs+haX?! zDx(Wt)l($)Qn0Rvn)qk|C7J&wrD&R_}~x;Y@>y20B^K(5D<- z5Axg!>V?p++Vj_SSIYBUfao(9cXfQLt25%_>xStHcKWWugm@;joM$3k`l-sKUP&T$ zQ+8;myjj){3~QRDq)0w&k2>y^KaYIKft#~E%+CAlOTdeN=o6s!tpH^^deWn`l zGwq6WWfz3vTdKjn$V!neo3~IdDQ?}ev}7eDl(B7PSOxoL1dpmW%b5p<;#Kjee`toN zQL@@ckeU`17!j?X_bQ+D3BcO)+UY{@g8%fC{g+Vjz@{zkDzSFHV`*`9LkXT zlDIfJkxLbG@8i(Tg6_pEFJ01<=te|kT>{US%sxZWpaP|M)f!1L*ZC^TSFrDyOW@zD z)QglopEKpJ8USyu;IbzWh!*9{?7|lkn`oJvbFTm^!cbA9(`sRjAR_oM+;`A@yGtGFqN46BAGlptvnNT~&@_MpI zJ*LRMhBtiflMf>k^t6u?YMM`6Xp$tbxZedr@&^ToB-dRR8nPJZ>>3RkO&_V{1~)Jk zlE^-CQhl0-xP$^)<#WFkbWV4Ft|Cw?)O2}KV?W--lMIHf)XC5?^I`O-+JQ)(L=0Yb zx#w-_ZI_Kvr9U3m-9NT(;GUYEZu4|T_z%?T&&Z29&)H*sZ@hb>`$}ti(wUJl%&otw z#P^bKcd@k6Yz|p!uI;|(0D$5ZrVwU-#okvsq^%)C(Xw|uew%B;IXj?%Dg9>T$0k{x zxO@&mydY&)Ji*)-f*hs&Il`f(_Rb|;ZZ>o}eLHN`THHm9o%zfXC_@pNOl__hWV**G z*zGh4<|meuKfC6IFd<`gKLN}qCH7|{#pk^GH0oRH{1&a-R_L?OVi>ILNKRecxG8`4-EW9h*WQ6L(?#0{Fj zBb4C#dQ6|I$DY&t9lc$9?Cv(3Sn+f{%Mpj0HSS7_<1DGnh7pcUY@84iO9P9U;t4=i zakwjF`K4%9q1zxwUOwxm@%4>Q6_)OA?lbkp-?dT(s59q3q?IB>-<9}^fyCf^)I&*{ z4T=(fM)C{Qs_Wk+%^B3xpK`R;52E70r8<;vsHM3Eiwr55u1$lRJy7g2tzQrZ1Vv0b z^;Ow~O7WEl(ves!p*J)z`~0c(`Xo_9S%@cxM1WI-0q{eJ)jEUl3P&qCE5WMRy0S5y z32&0c6sn>{-(;4(SqYx2rG3&G3#>R&CkbZpBC@dRjxn(f@;AV$lAfSivSu=8jfIDE zwYHp8Zt5}SXy3=ac>bdpzvNxrMu|d-{oX|xRKC7Exw^pf&w3#7_#AhR*4r7M<#KBT z(HiO=&U=fq=5()wQx@H&zSWWW>6p23mF(pOQgCVfq8XE!fcVV3)`nNjmDS)N3Lqsc z#;h^U=#4$dT6z(=n)?wUno_81&9U#SK+hiQ<5Zn{PL;m1u3bJX9-l{OZ2kM@Ftiq5 z!)xX|A@S0=EwdCA7}G|n1cver$S_qxgB`t8&ymg1>ictBXQGdXa*}ZSOk>v*4^_Qa z9`iK@riXP&M<^zV7)iOMpc5zpG&*Gakvm*Q+j#5m12YpK&McTUW zF(7_gjc+GXQ`0e)f%XO?J`El<{2zd@vc-XfJI)c<=LlniF3YNbt@?GV)UD#rhB}HKMt-hUmg8 zvSJymu99=wXJ%4eEXP3>FJu{a!gx(sTDo*YGJ?RF=D9FN!;hmJt%f-yuj}w*VO3I~ zGgfDHGM^jfufyr1ZM|!;FuwXxpDhTIxUTK>s=Ssra{d&I=~D#l?}Q zED)7`@s_skpmI1=XQr`g|qA37RLto2isFQPDzREE|PMZc)CUQQbDxrs(<4~FSuEnxOg}NoNV&iJKoTYyBhaR;w ze@yyv2BU>V3E;j8#ae&1&t+jpcZyr6@f`gDd#2wyZ4P<%D09~lx4PJRqN&#Jv{+QO z+~&;L^=hr)(|VL>e|V$5SxS$s zjt6uXzMURlOdrUB>YqrSJQQMkxS(2L3qjjxFmWNI>cY^QBV2{S#8V*AWGbTe+ecCK zk*On_VjEqDK2w+T1ft-I!}5LzhzSr3T5)a9*3ywHpz@*r-n&@dqOxe{4b`7ZQQq-8 zkbv#>U{xmfVb?A1WL-HACr!CawbjeUWUr>{Q%RK14!#fb=6tb^?$vu>7o~GeZDRSYbC$iE*Z}F@qW7^UTP+o5Dtq zc`xzp3iPh^>6$8sAzDz}seSP>GNH+&zqMW>?j>-SIerdUM zFLW2`AZs|Lv+)g<)Qr*T10-2Rfk{qfP0vNh#Bwk@bt|Sf4)NybjDKVMZR*uDZf6ai zc)*8umWZt#F<0+|PfFt{IVwz64*RXINZjwl4g$be9y$l*hgJ13G!; zM3P`bY=j;~{>RLP3_AW`tCraUnyRXdtO|8)`CXXeA=3H{fGz+4L5%W ztid|Lh@C^%JQOq3=`fX-G`&0@BW<${yTy~bd4M6fC(00!B^G)9(V{)iRX%Q; zlR-g#<_R!4d;CjJTPm5nABXB`e0$n6cXQsO(8 z#3PHvZzNcp`c9^}6&Llil2ysJNJtzH4fb(Hr##2cWjlwUn}F<(D1v|58yL0>^7K4k z2`K;Rk2Y<|)4s=lQ2aeu^0x0ChIz`BPbHi!6?75v|*Q zy-&tXl}G>J)Nim8o!VqdeM9KKDUplyRzC0*%+yac3OxejWMP|qJM{=ea0<5uA;zaj z?!p9~aU4q=zJo`qUpvA1m(nzP%KDqq#7?fgvur-~_`Pf!?vHZZB21Mr<4au(vlAE~V^v z#{VKZ!U5MN=`93#k4WV7qaEMJEL~Wq-cNgszLYuH%GKl;>s?B@`uPVC{aK(cJOWmW znn|){j*hAztGTtcVa>ftsz5{T96>?a8dA}sD}OkJ2MQ|G^jR-HtEOZwphJIE)}eG- zmhY-Qv|0J=x(Xf)u!MNGxj0qN(LVN;q*4zbIC>4!4<6b&q|_gj&h50-RY#Bf5KR-d zsYI4Th2Og%#Lkk4!ez^jnyWXHH0q@oI^2YMGwO|j1_GVqRU)ht5fwabS*LC?x3$!t z?q12q%pNdwYU?O{E&TlBC}M)fY;=jDJw!zyHmC?G)8Ddf-oBRaRpRVmqTZGg?|ICs zEmlBU4{O^XQ*J2k&9rzCrdw(%Ws{ZXP5TEy(`FoUM3!5^=v-uRa(m9x2{6nn( z_|k9rI5^02yTx_g@%)bsd&+J6sdcKiW+qqP*FP<)E7pMw<&4#)hUpM$txo0+&O1Kq z`Fih8-b0NOm^ECuAH=9}-j{#)%ApER%8JB_DA;(hBXyW=)dLT~edZhN?%>RfmD#;> zOcS6g#~w`gK4Pf{OWtxmN41vLJlmIRb;;aEEyf^fUW-*&iLqz9cb6~F>30UtR$fnp z2&#_|`+KDKzZHe8<2xKRX8YnVL6i9Q;f_mFTzK4m2p?9yh3h8E(t~V5b5imUborw| zMCvywek<~YG8#l|Cfc}&B{@=A`R~4gKzlYjitW5Bv5%4&w_LdGJ_LaKXvKQUX1mrneYH(KYmqrix*V6#O<1L zT-NQR#WlCN*&uyKWV6lB<>4kCR8d^To9gk%ujndC2s~?RCG#BOMh4ayin=x|GQ=p28}fRSOlx` z0+t3HNQ3gm>X{;m`JJOV0|5u21A_ncD}vJJG{=jbD|N@~;HWqE6HYVI{efH;$6p&mbG-zY->(#|7L+GHgN;Dq zwOe>mMU{&i5UNOJMu!A~f24$&nL{rPtyCoiD+#MqOf{Fj{H2V0K$USQmY08FIh*)S zRSISrgu1LR>poOf2}Fq$)GX3wC5=a-3}KR6aSRN%pezA!Pr$4$YD7M#+H>KFV3;f@ z0cB?p<&l)s>n@82O@B$ ziYK?uPaU=M(t}UKm~Lati;LwBBhkR@Wn*1ke8O>7#202%3*WWZL&jf#@>}UIcB1qs z3KTl`o&Y}^+2VCPUS?R84s6_WC4OX^mpc4Br0UP2yRG6pnDCP)Wd7M{M@Z9b6&{s=CEJ zjdw_Et}mdI`ZSzBHN_<|&sCE)6T$V2`a22z94dd2LF7hZc$rS9Q_mTWX^MFCmJ*WH zQD&XlZbaL%H6DLSACJ;te{63^(hxX)R$Filtc3-n(_I66J&9)tu=&`W-(UOsHf-N) zamK8o%hZ_N6yk2{h$WsRiWOQ!_oHa5lf?p;3 zV7RKQgF0+#YPDl+HT_MAlH-SM@{+8VTr1O2ru5)AS(}9>dBRw>nkWQT_`ku~U(t0n z)Kmz$NW#Cw64z_TA(;IYNbK|zm-&pEVS1s-XW$@T*Q{GLIUwT=yEytQnOzy!=x1@t zs%x+6>xwG0^BB8~a>EL8#HBN4EmmwvVI`%0p`ZE*!2iqA`@Lm7A;>4DZud^=ju+mz z6dd*5-IZP!Enhh@j|?_N{gF|Sq#9T%l4p1B+(cqDiEXY^tuL-EUy#oW0~*UeWhe~y z#D_?PrcPppB2`9moJ;2dZsKJLDU%V6+4>&T*&6JrUHokF+l+dZ;!@H1c<&+-Mb3Vh zo4g}Z)SOnJ^!;gg_~K_#OfQhRVv*8P!uWlQ2udS3enGlKV81$FZ%nsFGa1O` zya~~SzoM(yE!`>&m*00SmV~?Vec_hcyl-{IapfT?Vc+xm=SCxcl{JvIWD~@HYm1l(W11wa1?daz77Isj5`4 z_*f_^9!ZG_g<-uR6)rO4f})p>HedU#Hbe11eXE625ft$|7YX!Xv{TNyDNZ^AKTjc4 z_8b#Q5lu0zChm~Dz@hNOFV4^$MtS;4rys+~^D$kf^xH{3Qx`0R)2ww~Dk_=Q6UWYw z%=ew?-`sWz@Q6G0H;x3ZE@QK1b&q5r{WUtgvJm*{>sU~PX2%a$%@|gWk;t_Y_N4sY z+_4|-$jF-f)RF->j#!OWJwKQK!1=y>*&-C@3BSaP@cO~GZ>(WHqPzjaTn%S)g*Wz+ z+e&C3G!H}4oVafX$@^9^JHf8Df!3C7t|NMh2eU)FS3i;I$=WIYixGN#iFt89dR8o` zyARxGD)zq3Mp|4qdC_Q3akwuBA;dKTZAy7l6x$4dunB81C_oHYI=_wV0>7^;qcF3O zQ#((n83!75d;&G&K+O*}P$g9Bebrx<;en;^PV~Tu?c~l2J zg@!y|fV1*oz1-@jF>A`}59zp$Re`lhGtN1&`TJg}Ij!GNB;T$U%GOGeA1FEee7B3z zWFT78qY!*Fc_|QWGBwIlGdEidr+8tN<7I-PLH{Kutn)ZLix39`kGHQLjXAt(7mYM9 z+hlas#y;(pLgFE6_N;YVnqbTln>3e;s#OHvnFLL5(1ZO+nZ)E_wY2foke#ytdCgVH z<047&AwQ4r1mQY!0@Kv1&pIvmr6m!_b8`>}M8XUu^%V(xMSrtxnZ_5hP)`6utlEe- zHTB%vBL4ot#Se!mSsTN+WKya36%y`pf*c)u^2}Ic)h_IdrgEusn#K(Yy~i*s5Ei1T zqvBGXL;4AAl^>q$iy8j(=5;@w!{6!D%+uNo4Kdu>*j^GPtgVz^j*W_5l}RkisUR;O zye16p+dKe zA^5h^0-b(@x^~7er^if^?zQ?IwQCII2?~wJg6;xU!CX6aPMVx!92Jdc>J~fQfoS12x$Bk6{S(?ch2MLLsM`<<(2xBUv-T z>YH6S^G}-dGjEIw>N(gj{4z@LM7Odxc6QWp}M4g=E=zu);3k8 z{WR&$9WGKD<0=0KYRIwL%L?(R6 z&izV5(Q8>;UjKH)Q#(w4n^Y2`A^HQNqw{ z8uAT-YF1xL?4(>7Ptg6zb?;j^rYAGG06}dI_hH-P&Zh8}@jd?fh^o0^R+%;x*eDtd z?f2jD#CV;ec(3niMpp_Hq~#PI`J{)R02239>p7}Q@KUIn8!9$7&v{K+eZhLd%+x_4zm&Fh*)xZDXUtLi)7qF~bU&7MI;lMq{Y?0iFMf$IFR1i;*1UP* zm}imn;rv3HSC~cVTIaXsA()v@Yj)!yFA^wgu@$sz6S>~{z3tnAgh)HfKjM3*v^i5a z^zba#7(d$mu@ilMJKBB|;o2ON381H1JoI==X@j|gP}bnqQyJJ6YK_kKsHc)91c+{^ zxA=!U(%qGxWM~@A-y6QCbWBG4gyHxys{X3%GIV!eVD~m>&D7X|7vrCqhJU0b;yN;q zmo|r|75teq&bB;W;vMdjFFSuMi@qpknq>IT$X96k*fS=B)2pRP=zjQ1*26E~$hq!T z9Zz<3hcG@4og8l_Fh68y`e%3W-5ac{T^+$(1&^4qqUFSj~;2Mwox*l>#OOKEWy9?tpkPlUqYuR8i4we8hF zylDZaIH2V=*?yV*@I>#;$*Oh~r(vr8yu>KhGUG%wdbhsl8)C;LSNz3Ei_65b`r(Nm zF0b3Gv8-$=B^z_SFZVc_oRMCgCH@kGT3=aW#ZymTi&xCk9u?=4J6q#5Ip? z12`f&^E5})j@G4|Yj<0qt2fKJH4|firpF*4&|Jo@2%^bEi$$SG~8iKl^<2 zj(8xZdifg8mb^prhf(6AuA5h-H8r*1MD41))DmqstWEv(gc=1ZLV9JI-kKDJ(Kmc+ zH$+Oso^K~PmN(th1b-VLHO0xG+LBLV=8(J6;@ET11(Wb-l$NS-qp>@~*|n&JS%tB; zwz8p`Tnl&dkiQnIi^|!Typ<`EOLsst09C$#xors*LE|Z{U_~3& z6rK%DTy14GYPmDU%^wgf^p7n_la4^c6;BpOjK(gmwl-7aK7g^qipW+cp6Nsl$Bwza z_zO=!hw_Ave@jw^xA_h<5MDt3BQ4altV4W<>;3O82aUr6X>NeU`~RU@DZ{ExXD%DFos0xy)+HX~yqA$(kxy(lAOQ zFtBaP-sf}NsvqF%jwC5po3CV|c>+-0`k2<_Rtg>$Y*;aV@|97S)@$A4J8&tu$Fq8Y3FsTF2v&?Ye#79MC5d*gLQXR=j4OI zb)gO6F69I>CE+o=%MMpR5X81&Z&IQbEV7e<-V=;~UTO(?;j$k%+%Ou7YBb%Vz25X$ zSziW?zgCT4a(!OCX+n_sTo|(mo0M}~o;D`Yq`T>!__~6qr}1Px_dCw$bAtw{Zk4?F zbfKXfTbY|=2!U*JyHkX&Hmd8JHfR1|x<1KL(&OSm6dE)-Bu-Yl(ufI!QuBSDV%t^h z!a~$I;EqWRBNO!976|R|$4f!Ng-{G+}o-u3lf~Lhve<)eyy@^c@ z8gPg=V5)FAQ`I3I#dC=y)fZMUV!znIrYrM8060%?VMp7;dg> zdi8U8WKDxFYFHgyW|=XycwypsqE=4;UQ)Ds9_pixBjs%*TVWrP+KVIXm>-wxch|A= zjIrIAyyVT~mOO(6k7|-eMoKHWUBat9P){F+D^(T# zIH8(`q+{i^MNcEMJ=0H5yD@hr9cdkWoBVgEsH1Q2a60!TLkf5t1?^Mq{#GONOxy8X1%fGe}6Xr1Z?aou21(pYuGY?$gt`fArV)oZs@# z_k6zR`#In5`}I;e&D5S~*0E06qqNJyDF~JLE11XKEt`3c#utZZSxd%vlZ_?W4Lo@- zpx9YFshvP{mFmNS$@SZ{G*wudoc#RUe0VA9H~PIo$v2|=y`C#tQ>D!k0GxWRS8d^n z%u;-I`6jZv@F zi8CG3V;z`6-Up7hmbMv*c?jDTzMOe7LvC#9UA&KP=&Er<@H00jVP|!mhTpA39C*aZ zOrz_)?(^D4|EqHZLcsd(FkJo7eI(Z#4)hOf7Y+Xq8+>1A`=7+=CtN6!EulwQmz1ARX_iFx z1ftKK6-81;uVTR)6)sdx%-SKd&7WSWCygw14)niJcRwIm;uO_FcYbiCU-^cv;!Snk z0p%_=@pbza@r)iPloBeR6rG&^N)Wf`XI^#NrFA_Sl~uEWAJhK8c6V@)2sya2lXXBT zmi8Q>von@#8Dityryr=VabeU5{`}bg)p{-U;~Cwk}Lf--=&TVp)b$@m7anbZb5_NoxLH zp*k6sp>Zke0^`XIhR(PUwNHD&fx9%nnQo9^U_W!j0vG7vMHmvQucTJA9+h2~M>(T+ zhM5qME``%h7gXmi@p3y;?a$n>Z_IuacHC9z=#>LM>l}~r2BXXHjqf7FGB{gU8z1-g zJO9u4Gpzn^)O);;hJuNea%ta{G_rn%Nw>^CVp3Yio^079&T&Z@H``^XW+OSR8J2Mq z=l&XM2M1GD3VIN!ojoC3K3h{qIt8O7C60w5%TXW{fEM!lI(e|rBrnW!bhBu4`2}pF zftHfa*kg{L&SMUnbJE>R15S*Iq%S7O_c9f%?4l~IYe_qnY6Fqht?F5maH?z4`*doz zTvDouHu$Z|?R#~X?ZSP4rMD<~?j~o%kV*OAY5mjHn8jXT*XzRIDF225nAc!=2nT0X z%*DjX-K6yEtGtQ>t+mbo0wmLFw4j7vMDNm3t|+aa7UfMRyq;z{%CFc z<0F#w)Z&6os}y3W9XW^3I`g=Tl}CMb2Gs^g2X=*>n!FgM%|Wcp10nzgXxSxhmB5zM zPL`l6ghQzj#`@(W(hTcWNxPIey^8z5wq%ijNuc}h#j3IOycJY>sRH48<8i_@s8YdGZEQVE-7$6G<&&*+y(DdpmUjaL+n)9 zOT>mkLeToKuDlqG-nWYp9WD5D&@+3B2Ms6!nj_d3j)Z`iRUCJ$@8!l|Oh zmpnhbvP9#~mf=HEnYZ>Y67B6~#a_+$qM^-QHoy9CBi#%5&UDp`$LiU*d9cYK{1j+p~QyP8cD^rmn#>^!m4H zP6D|NZHu^mkMR%N4Yw}rg6JMQi8b#m zf*zc$zJTo?#*03J|7_m$LM^Rqq&toQho^o-5x=YI;j`nBFEI7+uw4Zj^ox|}i`Q0F z)q5bP>YOY&9Bz4QS=zGT^V#)XhO_hG^;qq-Y+cp47L%=W12dq`u{g+}IdY%Qmi?J( zwZ+X=X>)<152;U`KMJ0Nv}9R5z`*ug5oKsnl+IpcU_#9SJ)?>{p1%C6ac}b4LZSf_nZ`Rng=Az39 zp}%a&7dFcWMuQ18;z^T>Le6bmC$2n{D|n!wFf5Pq(OH=oLpbvD`37m&1`a+yjM-$R z#ksU9ouH7GYa9lDOwIpIM%2D*rFDF38H=tHL`cefV9Nm^Cy-IBY+eMu_i=3w?A;Fw z+z(IQ7nuY{PGnWZX+8BA_v7}A**51GXE|t0Rn0jozT;&zhD4n2T2YtjnhmNXm@xqj zRw<4~bWBy+ddBiB=uNef>dyyL>Usz)h0!aHXVH@PZ%UXvh3ioZZMt_qWycLh(3Z+- zA`}VpM;FTnT0>Erw&#0tFU^Da=(j5cErrIA1&ERylEQA!ek$)pF%h6D|`5j42$^9-z{x0 zbkHVh{boG=kJMK8|B~AJES&hsi1Ka6uQsQ|2*#6}4oFKs?-!eSjMG?>f|9bP*6SZ_ zyzG8(Nmu*S_$hd(MhF2K-$f-+plYNJTnn5%{OYtkKSSKdd=%GE6`6CmpyHY%gGzlu zpq*S~5ahSFU+(eLpW(p@fiQ!d&Y7G8VoaG@Y{!kxKv!N!lP>08+{b7cM4TZ@w~Y^|Z^F zmPz}FFODxUgkM@KPTxBT$B7NbU7fhF&K!&ab?1$cnL9EV!>Q)m$CGIjhqmdY6R+-v zsP5&*x|%IW2|6>^dn_|sG=_g2nBTKoJlsuLcKTLwdO+oUNP5W>skUgz7sxioVz|rj z3#$^13-#>Nf3hciPRxEH{=a7YD$4frF!;X`vETCf*QRT~ZQ=fhjy|{iN@icgmQOlK z|3%7K{_&4@F^0&$Bm?|{mgK**FkdYR{F;*ZtKa_ZOUdV^N|&PeiGU%u)*&sqZ5s9Y z7Xe^xtTHV(w`od&=dPkD;_e96M_X}Sz3YwGNb>20NaQn3fw~~TX`k#_iI5({myTop zI!!vP*Zf4L@@fX+warG`s}i}$8wJ(CN#)0ZRD7OrnqIHXkDq@`*pDLlvV{R6605bA bVib53gW0r$l$2a@a#+hz=dPahhv9z!%1KK! literal 0 HcmV?d00001 diff --git a/library/cropperjs/docs/images/picture-2.jpg b/library/cropperjs/docs/images/picture-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..05df6dc31819a058455e49bdbfa9d47a47ab5f06 GIT binary patch literal 182998 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 VzfHY`6pSp=s_#+?w^XEW|JfH>e4PLQ literal 0 HcmV?d00001 diff --git a/library/cropperjs/docs/images/picture-3.jpg b/library/cropperjs/docs/images/picture-3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..472d721b6edd5334e48235a13e0675ea9fa1e7a9 GIT binary patch literal 224777 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 L0yU&*HO#Mfh3zw+3V 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�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 literal 0 HcmV?d00001 diff --git a/library/cropperjs/docs/index.html b/library/cropperjs/docs/index.html new file mode 100644 index 000000000..7c3354cb1 --- /dev/null +++ b/library/cropperjs/docs/index.html @@ -0,0 +1,578 @@ + + + + + + + + + + Cropper.js + + + + + + + + + + + + +
+
+
+
+

Cropper.js v1.2.2

+

JavaScript image cropper.

+
+
+
+ +
+
+
+
+
+ + +
+
+
+ +
+ Picture +
+
+
+ +
+
+
+
+
+
+ + + +
+
+ + + + + + px + +
+
+ + + + + + px + +
+
+ + + + + + px + +
+
+ + + + + + px + +
+
+ + + + + + deg + +
+
+ + + + +
+
+ + + + +
+
+
+
+
+
+ +
+ + +
+ +
+ + +
+ +
+ + + + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + +
+ +
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + +
+ + + + Photo Editor + +
+
+
+ + + + + + + + + + + + diff --git a/library/cropperjs/docs/js/cropper.js b/library/cropperjs/docs/js/cropper.js new file mode 100644 index 000000000..0e837953c --- /dev/null +++ b/library/cropperjs/docs/js/cropper.js @@ -0,0 +1,3766 @@ +/*! + * Cropper.js v1.2.2 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2018 Chen Fengyuan + * Released under the MIT license + * + * Date: 2018-01-03T13:27:18.062Z + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.Cropper = factory()); +}(this, (function () { 'use strict'; + +var WINDOW = typeof window !== 'undefined' ? window : {}; +var NAMESPACE = 'cropper'; + +// Actions +var ACTION_ALL = 'all'; +var ACTION_CROP = 'crop'; +var ACTION_MOVE = 'move'; +var ACTION_ZOOM = 'zoom'; +var ACTION_EAST = 'e'; +var ACTION_WEST = 'w'; +var ACTION_SOUTH = 's'; +var ACTION_NORTH = 'n'; +var ACTION_NORTH_EAST = 'ne'; +var ACTION_NORTH_WEST = 'nw'; +var ACTION_SOUTH_EAST = 'se'; +var ACTION_SOUTH_WEST = 'sw'; + +// Classes +var CLASS_CROP = NAMESPACE + '-crop'; +var CLASS_DISABLED = NAMESPACE + '-disabled'; +var CLASS_HIDDEN = NAMESPACE + '-hidden'; +var CLASS_HIDE = NAMESPACE + '-hide'; +var CLASS_INVISIBLE = NAMESPACE + '-invisible'; +var CLASS_MODAL = NAMESPACE + '-modal'; +var CLASS_MOVE = NAMESPACE + '-move'; + +// Data keys +var DATA_ACTION = 'action'; +var DATA_PREVIEW = 'preview'; + +// Drag modes +var DRAG_MODE_CROP = 'crop'; +var DRAG_MODE_MOVE = 'move'; +var DRAG_MODE_NONE = 'none'; + +// Events +var EVENT_CROP = 'crop'; +var EVENT_CROP_END = 'cropend'; +var EVENT_CROP_MOVE = 'cropmove'; +var EVENT_CROP_START = 'cropstart'; +var EVENT_DBLCLICK = 'dblclick'; +var EVENT_ERROR = 'error'; +var EVENT_LOAD = 'load'; +var EVENT_POINTER_DOWN = WINDOW.PointerEvent ? 'pointerdown' : 'touchstart mousedown'; +var EVENT_POINTER_MOVE = WINDOW.PointerEvent ? 'pointermove' : 'touchmove mousemove'; +var EVENT_POINTER_UP = WINDOW.PointerEvent ? 'pointerup pointercancel' : 'touchend touchcancel mouseup'; +var EVENT_READY = 'ready'; +var EVENT_RESIZE = 'resize'; +var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll'; +var EVENT_ZOOM = 'zoom'; + +// RegExps +var REGEXP_ACTIONS = /^(e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/; +var REGEXP_DATA_URL = /^data:/; +var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/; +var REGEXP_TAG_NAME = /^(img|canvas)$/i; + +var DEFAULTS = { + // Define the view mode of the cropper + viewMode: 0, // 0, 1, 2, 3 + + // Define the dragging mode of the cropper + dragMode: DRAG_MODE_CROP, // 'crop', 'move' or 'none' + + // Define the aspect ratio of the crop box + aspectRatio: NaN, + + // An object with the previous cropping result data + data: null, + + // A selector for adding extra containers to preview + preview: '', + + // Re-render the cropper when resize the window + responsive: true, + + // Restore the cropped area after resize the window + restore: true, + + // Check if the current image is a cross-origin image + checkCrossOrigin: true, + + // Check the current image's Exif Orientation information + checkOrientation: true, + + // Show the black modal + modal: true, + + // Show the dashed lines for guiding + guides: true, + + // Show the center indicator for guiding + center: true, + + // Show the white modal to highlight the crop box + highlight: true, + + // Show the grid background + background: true, + + // Enable to crop the image automatically when initialize + autoCrop: true, + + // Define the percentage of automatic cropping area when initializes + autoCropArea: 0.8, + + // Enable to move the image + movable: true, + + // Enable to rotate the image + rotatable: true, + + // Enable to scale the image + scalable: true, + + // Enable to zoom the image + zoomable: true, + + // Enable to zoom the image by dragging touch + zoomOnTouch: true, + + // Enable to zoom the image by wheeling mouse + zoomOnWheel: true, + + // Define zoom ratio when zoom the image by wheeling mouse + wheelZoomRatio: 0.1, + + // Enable to move the crop box + cropBoxMovable: true, + + // Enable to resize the crop box + cropBoxResizable: true, + + // Toggle drag mode between "crop" and "move" when click twice on the cropper + toggleDragModeOnDblclick: true, + + // Size limitation + minCanvasWidth: 0, + minCanvasHeight: 0, + minCropBoxWidth: 0, + minCropBoxHeight: 0, + minContainerWidth: 200, + minContainerHeight: 100, + + // Shortcuts of events + ready: null, + cropstart: null, + cropmove: null, + cropend: null, + crop: null, + zoom: null +}; + +var TEMPLATE = '
' + '
' + '
' + '
' + '
' + '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
' + '
'; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + + + + + + + + + + + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + +var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +var toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } else { + return Array.from(arr); + } +}; + +/** + * Check if the given value is not a number. + */ +var isNaN = Number.isNaN || WINDOW.isNaN; + +/** + * Check if the given value is a number. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a number, else `false`. + */ +function isNumber(value) { + return typeof value === 'number' && !isNaN(value); +} + +/** + * Check if the given value is undefined. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is undefined, else `false`. + */ +function isUndefined(value) { + return typeof value === 'undefined'; +} + +/** + * Check if the given value is an object. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is an object, else `false`. + */ +function isObject(value) { + return (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && value !== null; +} + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +/** + * Check if the given value is a plain object. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a plain object, else `false`. + */ + +function isPlainObject(value) { + if (!isObject(value)) { + return false; + } + + try { + var _constructor = value.constructor; + var prototype = _constructor.prototype; + + + return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf'); + } catch (e) { + return false; + } +} + +/** + * Check if the given value is a function. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a function, else `false`. + */ +function isFunction(value) { + return typeof value === 'function'; +} + +/** + * Iterate the given data. + * @param {*} data - The data to iterate. + * @param {Function} callback - The process function for each element. + * @returns {*} The original data. + */ +function each(data, callback) { + if (data && isFunction(callback)) { + if (Array.isArray(data) || isNumber(data.length) /* array-like */) { + var length = data.length; + + var i = void 0; + + for (i = 0; i < length; i += 1) { + if (callback.call(data, data[i], i, data) === false) { + break; + } + } + } else if (isObject(data)) { + Object.keys(data).forEach(function (key) { + callback.call(data, data[key], key, data); + }); + } + } + + return data; +} + +/** + * Extend the given object. + * @param {*} obj - The object to be extended. + * @param {*} args - The rest objects which will be merged to the first object. + * @returns {Object} The extended object. + */ +function extend(obj) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + if (isObject(obj) && args.length > 0) { + if (Object.assign) { + return Object.assign.apply(Object, [obj].concat(args)); + } + + args.forEach(function (arg) { + if (isObject(arg)) { + Object.keys(arg).forEach(function (key) { + obj[key] = arg[key]; + }); + } + }); + } + + return obj; +} + +/** + * Takes a function and returns a new one that will always have a particular context. + * @param {Function} fn - The target function. + * @param {Object} context - The new context for the function. + * @returns {boolean} The new function. + */ +function proxy(fn, context) { + for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { + args[_key2 - 2] = arguments[_key2]; + } + + return function () { + for (var _len3 = arguments.length, args2 = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args2[_key3] = arguments[_key3]; + } + + return fn.apply(context, args.concat(args2)); + }; +} + +var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/i; + +/** + * Normalize decimal number. + * Check out {@link http://0.30000000000000004.com/ } + * @param {number} value - The value to normalize. + * @param {number} [times=100000000000] - The times for normalizing. + * @returns {number} Returns the normalized number. + */ +function normalizeDecimalNumber(value) { + var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000; + + return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value; +} + +var REGEXP_SUFFIX = /^(width|height|left|top|marginLeft|marginTop)$/; + +/** + * Apply styles to the given element. + * @param {Element} element - The target element. + * @param {Object} styles - The styles for applying. + */ +function setStyle(element, styles) { + var style = element.style; + + + each(styles, function (value, property) { + if (REGEXP_SUFFIX.test(property) && isNumber(value)) { + value += 'px'; + } + + style[property] = value; + }); +} + +/** + * Check if the given element has a special class. + * @param {Element} element - The element to check. + * @param {string} value - The class to search. + * @returns {boolean} Returns `true` if the special class was found. + */ +function hasClass(element, value) { + return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1; +} + +/** + * Add classes to the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be added. + */ +function addClass(element, value) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + addClass(elem, value); + }); + return; + } + + if (element.classList) { + element.classList.add(value); + return; + } + + var className = element.className.trim(); + + if (!className) { + element.className = value; + } else if (className.indexOf(value) < 0) { + element.className = className + ' ' + value; + } +} + +/** + * Remove classes from the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be removed. + */ +function removeClass(element, value) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + removeClass(elem, value); + }); + return; + } + + if (element.classList) { + element.classList.remove(value); + return; + } + + if (element.className.indexOf(value) >= 0) { + element.className = element.className.replace(value, ''); + } +} + +/** + * Add or remove classes from the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be toggled. + * @param {boolean} added - Add only. + */ +function toggleClass(element, value, added) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, function (elem) { + toggleClass(elem, value, added); + }); + return; + } + + // IE10-11 doesn't support the second parameter of `classList.toggle` + if (added) { + addClass(element, value); + } else { + removeClass(element, value); + } +} + +var REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g; + +/** + * Hyphenate the given value. + * @param {string} value - The value to hyphenate. + * @returns {string} The hyphenated value. + */ +function hyphenate(value) { + return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase(); +} + +/** + * Get data from the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to get. + * @returns {string} The data value. + */ +function getData(element, name) { + if (isObject(element[name])) { + return element[name]; + } else if (element.dataset) { + return element.dataset[name]; + } + + return element.getAttribute('data-' + hyphenate(name)); +} + +/** + * Set data to the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to set. + * @param {string} data - The data value. + */ +function setData(element, name, data) { + if (isObject(data)) { + element[name] = data; + } else if (element.dataset) { + element.dataset[name] = data; + } else { + element.setAttribute('data-' + hyphenate(name), data); + } +} + +/** + * Remove data from the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to remove. + */ +function removeData(element, name) { + if (isObject(element[name])) { + try { + delete element[name]; + } catch (e) { + element[name] = null; + } + } else if (element.dataset) { + // #128 Safari not allows to delete dataset property + try { + delete element.dataset[name]; + } catch (e) { + element.dataset[name] = null; + } + } else { + element.removeAttribute('data-' + hyphenate(name)); + } +} + +var REGEXP_SPACES = /\s+/; + +/** + * Remove event listener from the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Function} listener - The event listener. + * @param {Object} options - The event options. + */ +function removeListener(element, type, listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + if (!isFunction(listener)) { + return; + } + + var types = type.trim().split(REGEXP_SPACES); + + if (types.length > 1) { + each(types, function (t) { + removeListener(element, t, listener, options); + }); + return; + } + + if (element.removeEventListener) { + element.removeEventListener(type, listener, options); + } else if (element.detachEvent) { + element.detachEvent('on' + type, listener); + } +} + +/** + * Add event listener to the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Function} listener - The event listener. + * @param {Object} options - The event options. + */ +function addListener(element, type, _listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + if (!isFunction(_listener)) { + return; + } + + var types = type.trim().split(REGEXP_SPACES); + + if (types.length > 1) { + each(types, function (t) { + addListener(element, t, _listener, options); + }); + return; + } + + if (options.once) { + var originalListener = _listener; + + _listener = function listener() { + for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + removeListener(element, type, _listener, options); + return originalListener.apply(element, args); + }; + } + + if (element.addEventListener) { + element.addEventListener(type, _listener, options); + } else if (element.attachEvent) { + element.attachEvent('on' + type, _listener); + } +} + +/** + * Dispatch event on the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Object} data - The additional event data. + * @returns {boolean} Indicate if the event is default prevented or not. + */ +function dispatchEvent(element, type, data) { + if (element.dispatchEvent) { + var event = void 0; + + // Event and CustomEvent on IE9-11 are global objects, not constructors + if (isFunction(Event) && isFunction(CustomEvent)) { + if (isUndefined(data)) { + event = new Event(type, { + bubbles: true, + cancelable: true + }); + } else { + event = new CustomEvent(type, { + detail: data, + bubbles: true, + cancelable: true + }); + } + } else if (isUndefined(data)) { + event = document.createEvent('Event'); + event.initEvent(type, true, true); + } else { + event = document.createEvent('CustomEvent'); + event.initCustomEvent(type, true, true, data); + } + + // IE9+ + return element.dispatchEvent(event); + } else if (element.fireEvent) { + // IE6-10 (native events only) + return element.fireEvent('on' + type); + } + + return true; +} + +/** + * Get the offset base on the document. + * @param {Element} element - The target element. + * @returns {Object} The offset data. + */ +function getOffset(element) { + var doc = document.documentElement; + var box = element.getBoundingClientRect(); + + return { + left: box.left + ((window.scrollX || doc && doc.scrollLeft || 0) - (doc && doc.clientLeft || 0)), + top: box.top + ((window.scrollY || doc && doc.scrollTop || 0) - (doc && doc.clientTop || 0)) + }; +} + +/** + * Empty an element. + * @param {Element} element - The element to empty. + */ +function empty(element) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } +} + +var location = WINDOW.location; + +var REGEXP_ORIGINS = /^(https?:)\/\/([^:/?#]+):?(\d*)/i; + +/** + * Check if the given URL is a cross origin URL. + * @param {string} url - The target URL. + * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`. + */ +function isCrossOriginURL(url) { + var parts = url.match(REGEXP_ORIGINS); + + return parts && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port); +} + +/** + * Add timestamp to the given URL. + * @param {string} url - The target URL. + * @returns {string} The result URL. + */ +function addTimestamp(url) { + var timestamp = 'timestamp=' + new Date().getTime(); + + return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp; +} + +/** + * Get transforms base on the given object. + * @param {Object} obj - The target object. + * @returns {string} A string contains transform values. + */ +function getTransforms(_ref) { + var rotate = _ref.rotate, + scaleX = _ref.scaleX, + scaleY = _ref.scaleY, + translateX = _ref.translateX, + translateY = _ref.translateY; + + var values = []; + + if (isNumber(translateX) && translateX !== 0) { + values.push('translateX(' + translateX + 'px)'); + } + + if (isNumber(translateY) && translateY !== 0) { + values.push('translateY(' + translateY + 'px)'); + } + + // Rotate should come first before scale to match orientation transform + if (isNumber(rotate) && rotate !== 0) { + values.push('rotate(' + rotate + 'deg)'); + } + + if (isNumber(scaleX) && scaleX !== 1) { + values.push('scaleX(' + scaleX + ')'); + } + + if (isNumber(scaleY) && scaleY !== 1) { + values.push('scaleY(' + scaleY + ')'); + } + + var transform = values.length ? values.join(' ') : 'none'; + + return { + WebkitTransform: transform, + msTransform: transform, + transform: transform + }; +} + +var navigator = WINDOW.navigator; + +var IS_SAFARI_OR_UIWEBVIEW = navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent); + +/** + * Get an image's natural sizes. + * @param {string} image - The target image. + * @param {Function} callback - The callback function. + */ +function getImageNaturalSizes(image, callback) { + // Modern browsers (except Safari) + if (image.naturalWidth && !IS_SAFARI_OR_UIWEBVIEW) { + callback(image.naturalWidth, image.naturalHeight); + return; + } + + var newImage = document.createElement('img'); + var body = document.body || document.documentElement; + + newImage.onload = function () { + callback(newImage.width, newImage.height); + + if (!IS_SAFARI_OR_UIWEBVIEW) { + body.removeChild(newImage); + } + }; + + newImage.src = image.src; + + // iOS Safari will convert the image automatically + // with its orientation once append it into DOM (#279) + if (!IS_SAFARI_OR_UIWEBVIEW) { + newImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;'; + body.appendChild(newImage); + } +} + +/** + * Get the max ratio of a group of pointers. + * @param {string} pointers - The target pointers. + * @returns {number} The result ratio. + */ +function getMaxZoomRatio(pointers) { + var pointers2 = extend({}, pointers); + var ratios = []; + + each(pointers, function (pointer, pointerId) { + delete pointers2[pointerId]; + + each(pointers2, function (pointer2) { + var x1 = Math.abs(pointer.startX - pointer2.startX); + var y1 = Math.abs(pointer.startY - pointer2.startY); + var x2 = Math.abs(pointer.endX - pointer2.endX); + var y2 = Math.abs(pointer.endY - pointer2.endY); + var z1 = Math.sqrt(x1 * x1 + y1 * y1); + var z2 = Math.sqrt(x2 * x2 + y2 * y2); + var ratio = (z2 - z1) / z1; + + ratios.push(ratio); + }); + }); + + ratios.sort(function (a, b) { + return Math.abs(a) < Math.abs(b); + }); + + return ratios[0]; +} + +/** + * Get a pointer from an event object. + * @param {Object} event - The target event object. + * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not. + * @returns {Object} The result pointer contains start and/or end point coordinates. + */ +function getPointer(_ref2, endOnly) { + var pageX = _ref2.pageX, + pageY = _ref2.pageY; + + var end = { + endX: pageX, + endY: pageY + }; + + if (endOnly) { + return end; + } + + return extend({ + startX: pageX, + startY: pageY + }, end); +} + +/** + * Get the center point coordinate of a group of pointers. + * @param {Object} pointers - The target pointers. + * @returns {Object} The center point coordinate. + */ +function getPointersCenter(pointers) { + var pageX = 0; + var pageY = 0; + var count = 0; + + each(pointers, function (_ref3) { + var startX = _ref3.startX, + startY = _ref3.startY; + + pageX += startX; + pageY += startY; + count += 1; + }); + + pageX /= count; + pageY /= count; + + return { + pageX: pageX, + pageY: pageY + }; +} + +/** + * Check if the given value is a finite number. + */ +var isFinite = Number.isFinite || WINDOW.isFinite; + +/** + * Get the max sizes in a rectangle under the given aspect ratio. + * @param {Object} data - The original sizes. + * @returns {Object} The result sizes. + */ +function getContainSizes(_ref4) { + var aspectRatio = _ref4.aspectRatio, + height = _ref4.height, + width = _ref4.width; + + var isValidNumber = function isValidNumber(value) { + return isFinite(value) && value > 0; + }; + + if (isValidNumber(width) && isValidNumber(height)) { + if (height * aspectRatio > width) { + height = width / aspectRatio; + } else { + width = height * aspectRatio; + } + } else if (isValidNumber(width)) { + height = width / aspectRatio; + } else if (isValidNumber(height)) { + width = height * aspectRatio; + } + + return { + width: width, + height: height + }; +} + +/** + * Get the new sizes of a rectangle after rotated. + * @param {Object} data - The original sizes. + * @returns {Object} The result sizes. + */ +function getRotatedSizes(_ref5) { + var width = _ref5.width, + height = _ref5.height, + degree = _ref5.degree; + + degree = Math.abs(degree) % 180; + + if (degree === 90) { + return { + width: height, + height: width + }; + } + + var arc = degree % 90 * Math.PI / 180; + var sinArc = Math.sin(arc); + var cosArc = Math.cos(arc); + var newWidth = width * cosArc + height * sinArc; + var newHeight = width * sinArc + height * cosArc; + + return degree > 90 ? { + width: newHeight, + height: newWidth + } : { + width: newWidth, + height: newHeight + }; +} + +/** + * Get a canvas which drew the given image. + * @param {HTMLImageElement} image - The image for drawing. + * @param {Object} imageData - The image data. + * @param {Object} canvasData - The canvas data. + * @param {Object} options - The options. + * @returns {HTMLCanvasElement} The result canvas. + */ +function getSourceCanvas(image, _ref6, _ref7, _ref8) { + var imageNaturalWidth = _ref6.naturalWidth, + imageNaturalHeight = _ref6.naturalHeight, + _ref6$rotate = _ref6.rotate, + rotate = _ref6$rotate === undefined ? 0 : _ref6$rotate, + _ref6$scaleX = _ref6.scaleX, + scaleX = _ref6$scaleX === undefined ? 1 : _ref6$scaleX, + _ref6$scaleY = _ref6.scaleY, + scaleY = _ref6$scaleY === undefined ? 1 : _ref6$scaleY; + var aspectRatio = _ref7.aspectRatio, + naturalWidth = _ref7.naturalWidth, + naturalHeight = _ref7.naturalHeight; + var _ref8$fillColor = _ref8.fillColor, + fillColor = _ref8$fillColor === undefined ? 'transparent' : _ref8$fillColor, + _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled, + imageSmoothingEnabled = _ref8$imageSmoothingE === undefined ? true : _ref8$imageSmoothingE, + _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality, + imageSmoothingQuality = _ref8$imageSmoothingQ === undefined ? 'low' : _ref8$imageSmoothingQ, + _ref8$maxWidth = _ref8.maxWidth, + maxWidth = _ref8$maxWidth === undefined ? Infinity : _ref8$maxWidth, + _ref8$maxHeight = _ref8.maxHeight, + maxHeight = _ref8$maxHeight === undefined ? Infinity : _ref8$maxHeight, + _ref8$minWidth = _ref8.minWidth, + minWidth = _ref8$minWidth === undefined ? 0 : _ref8$minWidth, + _ref8$minHeight = _ref8.minHeight, + minHeight = _ref8$minHeight === undefined ? 0 : _ref8$minHeight; + + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + var maxSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: maxWidth, + height: maxHeight + }); + var minSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: minWidth, + height: minHeight + }); + var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth)); + var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight)); + var params = [-imageNaturalWidth / 2, -imageNaturalHeight / 2, imageNaturalWidth, imageNaturalHeight]; + + canvas.width = normalizeDecimalNumber(width); + canvas.height = normalizeDecimalNumber(height); + context.fillStyle = fillColor; + context.fillRect(0, 0, width, height); + context.save(); + context.translate(width / 2, height / 2); + context.rotate(rotate * Math.PI / 180); + context.scale(scaleX, scaleY); + context.imageSmoothingEnabled = imageSmoothingEnabled; + context.imageSmoothingQuality = imageSmoothingQuality; + context.drawImage.apply(context, [image].concat(toConsumableArray(params.map(function (param) { + return Math.floor(normalizeDecimalNumber(param)); + })))); + context.restore(); + return canvas; +} + +var fromCharCode = String.fromCharCode; + +/** + * Get string from char code in data view. + * @param {DataView} dataView - The data view for read. + * @param {number} start - The start index. + * @param {number} length - The read length. + * @returns {string} The read result. + */ + +function getStringFromCharCode(dataView, start, length) { + var str = ''; + var i = void 0; + + length += start; + + for (i = start; i < length; i += 1) { + str += fromCharCode(dataView.getUint8(i)); + } + + return str; +} + +var REGEXP_DATA_URL_HEAD = /^data:.*,/; + +/** + * Transform Data URL to array buffer. + * @param {string} dataURL - The Data URL to transform. + * @returns {ArrayBuffer} The result array buffer. + */ +function dataURLToArrayBuffer(dataURL) { + var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, ''); + var binary = atob(base64); + var arrayBuffer = new ArrayBuffer(binary.length); + var uint8 = new Uint8Array(arrayBuffer); + + each(uint8, function (value, i) { + uint8[i] = binary.charCodeAt(i); + }); + + return arrayBuffer; +} + +/** + * Transform array buffer to Data URL. + * @param {ArrayBuffer} arrayBuffer - The array buffer to transform. + * @param {string} mimeType - The mime type of the Data URL. + * @returns {string} The result Data URL. + */ +function arrayBufferToDataURL(arrayBuffer, mimeType) { + var uint8 = new Uint8Array(arrayBuffer); + var data = ''; + + // TypedArray.prototype.forEach is not supported in some browsers. + each(uint8, function (value) { + data += fromCharCode(value); + }); + + return 'data:' + mimeType + ';base64,' + btoa(data); +} + +/** + * Get orientation value from given array buffer. + * @param {ArrayBuffer} arrayBuffer - The array buffer to read. + * @returns {number} The read orientation value. + */ +function getOrientation(arrayBuffer) { + var dataView = new DataView(arrayBuffer); + var orientation = void 0; + var littleEndian = void 0; + var app1Start = void 0; + var ifdStart = void 0; + + // Only handle JPEG image (start by 0xFFD8) + if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) { + var length = dataView.byteLength; + var offset = 2; + + while (offset < length) { + if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) { + app1Start = offset; + break; + } + + offset += 1; + } + } + + if (app1Start) { + var exifIDCode = app1Start + 4; + var tiffOffset = app1Start + 10; + + if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') { + var endianness = dataView.getUint16(tiffOffset); + + littleEndian = endianness === 0x4949; + + if (littleEndian || endianness === 0x4D4D /* bigEndian */) { + if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) { + var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian); + + if (firstIFDOffset >= 0x00000008) { + ifdStart = tiffOffset + firstIFDOffset; + } + } + } + } + } + + if (ifdStart) { + var _length = dataView.getUint16(ifdStart, littleEndian); + var _offset = void 0; + var i = void 0; + + for (i = 0; i < _length; i += 1) { + _offset = ifdStart + i * 12 + 2; + + if (dataView.getUint16(_offset, littleEndian) === 0x0112 /* Orientation */) { + // 8 is the offset of the current tag's value + _offset += 8; + + // Get the original orientation value + orientation = dataView.getUint16(_offset, littleEndian); + + // Override the orientation with its default value + dataView.setUint16(_offset, 1, littleEndian); + break; + } + } + } + + return orientation; +} + +/** + * Parse Exif Orientation value. + * @param {number} orientation - The orientation to parse. + * @returns {Object} The parsed result. + */ +function parseOrientation(orientation) { + var rotate = 0; + var scaleX = 1; + var scaleY = 1; + + switch (orientation) { + // Flip horizontal + case 2: + scaleX = -1; + break; + + // Rotate left 180° + case 3: + rotate = -180; + break; + + // Flip vertical + case 4: + scaleY = -1; + break; + + // Flip vertical and rotate right 90° + case 5: + rotate = 90; + scaleY = -1; + break; + + // Rotate right 90° + case 6: + rotate = 90; + break; + + // Flip horizontal and rotate right 90° + case 7: + rotate = 90; + scaleX = -1; + break; + + // Rotate left 90° + case 8: + rotate = -90; + break; + + default: + } + + return { + rotate: rotate, + scaleX: scaleX, + scaleY: scaleY + }; +} + +var render = { + render: function render() { + this.initContainer(); + this.initCanvas(); + this.initCropBox(); + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + }, + initContainer: function initContainer() { + var element = this.element, + options = this.options, + container = this.container, + cropper = this.cropper; + + + addClass(cropper, CLASS_HIDDEN); + removeClass(element, CLASS_HIDDEN); + + var containerData = { + width: Math.max(container.offsetWidth, Number(options.minContainerWidth) || 200), + height: Math.max(container.offsetHeight, Number(options.minContainerHeight) || 100) + }; + + this.containerData = containerData; + + setStyle(cropper, { + width: containerData.width, + height: containerData.height + }); + + addClass(element, CLASS_HIDDEN); + removeClass(cropper, CLASS_HIDDEN); + }, + + + // Canvas (image wrapper) + initCanvas: function initCanvas() { + var containerData = this.containerData, + imageData = this.imageData; + var viewMode = this.options.viewMode; + + var rotated = Math.abs(imageData.rotate) % 180 === 90; + var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth; + var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight; + var aspectRatio = naturalWidth / naturalHeight; + var canvasWidth = containerData.width; + var canvasHeight = containerData.height; + + if (containerData.height * aspectRatio > containerData.width) { + if (viewMode === 3) { + canvasWidth = containerData.height * aspectRatio; + } else { + canvasHeight = containerData.width / aspectRatio; + } + } else if (viewMode === 3) { + canvasHeight = containerData.width / aspectRatio; + } else { + canvasWidth = containerData.height * aspectRatio; + } + + var canvasData = { + aspectRatio: aspectRatio, + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + width: canvasWidth, + height: canvasHeight + }; + + canvasData.left = (containerData.width - canvasWidth) / 2; + canvasData.top = (containerData.height - canvasHeight) / 2; + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; + + this.canvasData = canvasData; + this.limited = viewMode === 1 || viewMode === 2; + this.limitCanvas(true, true); + this.initialImageData = extend({}, imageData); + this.initialCanvasData = extend({}, canvasData); + }, + limitCanvas: function limitCanvas(sizeLimited, positionLimited) { + var options = this.options, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + var viewMode = options.viewMode; + var aspectRatio = canvasData.aspectRatio; + + var cropped = this.cropped && cropBoxData; + + if (sizeLimited) { + var minCanvasWidth = Number(options.minCanvasWidth) || 0; + var minCanvasHeight = Number(options.minCanvasHeight) || 0; + + if (viewMode > 1) { + minCanvasWidth = Math.max(minCanvasWidth, containerData.width); + minCanvasHeight = Math.max(minCanvasHeight, containerData.height); + + if (viewMode === 3) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } else if (viewMode > 0) { + if (minCanvasWidth) { + minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0); + } else if (minCanvasHeight) { + minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0); + } else if (cropped) { + minCanvasWidth = cropBoxData.width; + minCanvasHeight = cropBoxData.height; + + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } + + var _getContainSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: minCanvasWidth, + height: minCanvasHeight + }); + + minCanvasWidth = _getContainSizes.width; + minCanvasHeight = _getContainSizes.height; + + + canvasData.minWidth = minCanvasWidth; + canvasData.minHeight = minCanvasHeight; + canvasData.maxWidth = Infinity; + canvasData.maxHeight = Infinity; + } + + if (positionLimited) { + if (viewMode) { + var newCanvasLeft = containerData.width - canvasData.width; + var newCanvasTop = containerData.height - canvasData.height; + + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxLeft = Math.max(0, newCanvasLeft); + canvasData.maxTop = Math.max(0, newCanvasTop); + + if (cropped && this.limited) { + canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width)); + canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height)); + canvasData.maxLeft = cropBoxData.left; + canvasData.maxTop = cropBoxData.top; + + if (viewMode === 2) { + if (canvasData.width >= containerData.width) { + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.maxLeft = Math.max(0, newCanvasLeft); + } + + if (canvasData.height >= containerData.height) { + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxTop = Math.max(0, newCanvasTop); + } + } + } + } else { + canvasData.minLeft = -canvasData.width; + canvasData.minTop = -canvasData.height; + canvasData.maxLeft = containerData.width; + canvasData.maxTop = containerData.height; + } + } + }, + renderCanvas: function renderCanvas(changed, transformed) { + var canvasData = this.canvasData, + imageData = this.imageData; + + + if (transformed) { + var _getRotatedSizes = getRotatedSizes({ + width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1), + height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1), + degree: imageData.rotate || 0 + }), + naturalWidth = _getRotatedSizes.width, + naturalHeight = _getRotatedSizes.height; + + var width = canvasData.width * (naturalWidth / canvasData.naturalWidth); + var height = canvasData.height * (naturalHeight / canvasData.naturalHeight); + + canvasData.left -= (width - canvasData.width) / 2; + canvasData.top -= (height - canvasData.height) / 2; + canvasData.width = width; + canvasData.height = height; + canvasData.aspectRatio = naturalWidth / naturalHeight; + canvasData.naturalWidth = naturalWidth; + canvasData.naturalHeight = naturalHeight; + this.limitCanvas(true, false); + } + + if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) { + canvasData.left = canvasData.oldLeft; + } + + if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) { + canvasData.top = canvasData.oldTop; + } + + canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth); + canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight); + + this.limitCanvas(false, true); + + canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft); + canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop); + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; + + setStyle(this.canvas, extend({ + width: canvasData.width, + height: canvasData.height + }, getTransforms({ + translateX: canvasData.left, + translateY: canvasData.top + }))); + + this.renderImage(changed); + + if (this.cropped && this.limited) { + this.limitCropBox(true, true); + } + }, + renderImage: function renderImage(changed) { + var canvasData = this.canvasData, + imageData = this.imageData; + + var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth); + var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight); + + extend(imageData, { + width: width, + height: height, + left: (canvasData.width - width) / 2, + top: (canvasData.height - height) / 2 + }); + setStyle(this.image, extend({ + width: imageData.width, + height: imageData.height + }, getTransforms(extend({ + translateX: imageData.left, + translateY: imageData.top + }, imageData)))); + + if (changed) { + this.output(); + } + }, + initCropBox: function initCropBox() { + var options = this.options, + canvasData = this.canvasData; + var aspectRatio = options.aspectRatio; + + var autoCropArea = Number(options.autoCropArea) || 0.8; + var cropBoxData = { + width: canvasData.width, + height: canvasData.height + }; + + if (aspectRatio) { + if (canvasData.height * aspectRatio > canvasData.width) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + this.cropBoxData = cropBoxData; + this.limitCropBox(true, true); + + // Initialize auto crop area + cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth); + cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); + + // The width/height of auto crop area must large than "minWidth/Height" + cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea); + cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea); + cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2; + cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2; + cropBoxData.oldLeft = cropBoxData.left; + cropBoxData.oldTop = cropBoxData.top; + + this.initialCropBoxData = extend({}, cropBoxData); + }, + limitCropBox: function limitCropBox(sizeLimited, positionLimited) { + var options = this.options, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData, + limited = this.limited; + var aspectRatio = options.aspectRatio; + + + if (sizeLimited) { + var minCropBoxWidth = Number(options.minCropBoxWidth) || 0; + var minCropBoxHeight = Number(options.minCropBoxHeight) || 0; + var maxCropBoxWidth = Math.min(containerData.width, limited ? canvasData.width : containerData.width); + var maxCropBoxHeight = Math.min(containerData.height, limited ? canvasData.height : containerData.height); + + // The min/maxCropBoxWidth/Height must be less than container's width/height + minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width); + minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height); + + if (aspectRatio) { + if (minCropBoxWidth && minCropBoxHeight) { + if (minCropBoxHeight * aspectRatio > minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + } else if (minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else if (minCropBoxHeight) { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + + if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) { + maxCropBoxHeight = maxCropBoxWidth / aspectRatio; + } else { + maxCropBoxWidth = maxCropBoxHeight * aspectRatio; + } + } + + // The minWidth/Height must be less than maxWidth/Height + cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); + cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); + cropBoxData.maxWidth = maxCropBoxWidth; + cropBoxData.maxHeight = maxCropBoxHeight; + } + + if (positionLimited) { + if (limited) { + cropBoxData.minLeft = Math.max(0, canvasData.left); + cropBoxData.minTop = Math.max(0, canvasData.top); + cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width; + cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height; + } else { + cropBoxData.minLeft = 0; + cropBoxData.minTop = 0; + cropBoxData.maxLeft = containerData.width - cropBoxData.width; + cropBoxData.maxTop = containerData.height - cropBoxData.height; + } + } + }, + renderCropBox: function renderCropBox() { + var options = this.options, + containerData = this.containerData, + cropBoxData = this.cropBoxData; + + + if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) { + cropBoxData.left = cropBoxData.oldLeft; + } + + if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) { + cropBoxData.top = cropBoxData.oldTop; + } + + cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth); + cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); + + this.limitCropBox(false, true); + + cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft); + cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop); + cropBoxData.oldLeft = cropBoxData.left; + cropBoxData.oldTop = cropBoxData.top; + + if (options.movable && options.cropBoxMovable) { + // Turn to move the canvas when the crop box is equal to the container + setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL); + } + + setStyle(this.cropBox, extend({ + width: cropBoxData.width, + height: cropBoxData.height + }, getTransforms({ + translateX: cropBoxData.left, + translateY: cropBoxData.top + }))); + + if (this.cropped && this.limited) { + this.limitCanvas(true, true); + } + + if (!this.disabled) { + this.output(); + } + }, + output: function output() { + this.preview(); + + if (this.complete) { + dispatchEvent(this.element, EVENT_CROP, this.getData()); + } + } +}; + +var preview = { + initPreview: function initPreview() { + var crossOrigin = this.crossOrigin; + var preview = this.options.preview; + + var url = crossOrigin ? this.crossOriginUrl : this.url; + var image = document.createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = url; + this.viewBox.appendChild(image); + this.image2 = image; + + if (!preview) { + return; + } + + var previews = preview.querySelector ? [preview] : document.querySelectorAll(preview); + + this.previews = previews; + + each(previews, function (element) { + var img = document.createElement('img'); + + // Save the original size for recover + setData(element, DATA_PREVIEW, { + width: element.offsetWidth, + height: element.offsetHeight, + html: element.innerHTML + }); + + if (crossOrigin) { + img.crossOrigin = crossOrigin; + } + + img.src = url; + + /** + * Override img element styles + * Add `display:block` to avoid margin top issue + * Add `height:auto` to override `height` attribute on IE8 + * (Occur only when margin-top <= -height) + */ + img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"'; + + empty(element); + element.appendChild(img); + }); + }, + resetPreview: function resetPreview() { + each(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); + + setStyle(element, { + width: data.width, + height: data.height + }); + + element.innerHTML = data.html; + removeData(element, DATA_PREVIEW); + }); + }, + preview: function preview() { + var imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + var cropBoxWidth = cropBoxData.width, + cropBoxHeight = cropBoxData.height; + var width = imageData.width, + height = imageData.height; + + var left = cropBoxData.left - canvasData.left - imageData.left; + var top = cropBoxData.top - canvasData.top - imageData.top; + + if (!this.cropped || this.disabled) { + return; + } + + setStyle(this.image2, extend({ + width: width, + height: height + }, getTransforms(extend({ + translateX: -left, + translateY: -top + }, imageData)))); + + each(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); + var originalWidth = data.width; + var originalHeight = data.height; + var newWidth = originalWidth; + var newHeight = originalHeight; + var ratio = 1; + + if (cropBoxWidth) { + ratio = originalWidth / cropBoxWidth; + newHeight = cropBoxHeight * ratio; + } + + if (cropBoxHeight && newHeight > originalHeight) { + ratio = originalHeight / cropBoxHeight; + newWidth = cropBoxWidth * ratio; + newHeight = originalHeight; + } + + setStyle(element, { + width: newWidth, + height: newHeight + }); + + setStyle(element.getElementsByTagName('img')[0], extend({ + width: width * ratio, + height: height * ratio + }, getTransforms(extend({ + translateX: -left * ratio, + translateY: -top * ratio + }, imageData)))); + }); + } +}; + +var events = { + bind: function bind() { + var element = this.element, + options = this.options, + cropper = this.cropper; + + + if (isFunction(options.cropstart)) { + addListener(element, EVENT_CROP_START, options.cropstart); + } + + if (isFunction(options.cropmove)) { + addListener(element, EVENT_CROP_MOVE, options.cropmove); + } + + if (isFunction(options.cropend)) { + addListener(element, EVENT_CROP_END, options.cropend); + } + + if (isFunction(options.crop)) { + addListener(element, EVENT_CROP, options.crop); + } + + if (isFunction(options.zoom)) { + addListener(element, EVENT_ZOOM, options.zoom); + } + + addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = proxy(this.cropStart, this)); + + if (options.zoomable && options.zoomOnWheel) { + addListener(cropper, EVENT_WHEEL, this.onWheel = proxy(this.wheel, this)); + } + + if (options.toggleDragModeOnDblclick) { + addListener(cropper, EVENT_DBLCLICK, this.onDblclick = proxy(this.dblclick, this)); + } + + addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = proxy(this.cropMove, this)); + addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = proxy(this.cropEnd, this)); + + if (options.responsive) { + addListener(window, EVENT_RESIZE, this.onResize = proxy(this.resize, this)); + } + }, + unbind: function unbind() { + var element = this.element, + options = this.options, + cropper = this.cropper; + + + if (isFunction(options.cropstart)) { + removeListener(element, EVENT_CROP_START, options.cropstart); + } + + if (isFunction(options.cropmove)) { + removeListener(element, EVENT_CROP_MOVE, options.cropmove); + } + + if (isFunction(options.cropend)) { + removeListener(element, EVENT_CROP_END, options.cropend); + } + + if (isFunction(options.crop)) { + removeListener(element, EVENT_CROP, options.crop); + } + + if (isFunction(options.zoom)) { + removeListener(element, EVENT_ZOOM, options.zoom); + } + + removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart); + + if (options.zoomable && options.zoomOnWheel) { + removeListener(cropper, EVENT_WHEEL, this.onWheel); + } + + if (options.toggleDragModeOnDblclick) { + removeListener(cropper, EVENT_DBLCLICK, this.onDblclick); + } + + removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove); + removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd); + + if (options.responsive) { + removeListener(window, EVENT_RESIZE, this.onResize); + } + } +}; + +var handlers = { + resize: function resize() { + var options = this.options, + container = this.container, + containerData = this.containerData; + + var minContainerWidth = Number(options.minContainerWidth) || 200; + var minContainerHeight = Number(options.minContainerHeight) || 100; + + if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) { + return; + } + + var ratio = container.offsetWidth / containerData.width; + + // Resize when width changed or height changed + if (ratio !== 1 || container.offsetHeight !== containerData.height) { + var canvasData = void 0; + var cropBoxData = void 0; + + if (options.restore) { + canvasData = this.getCanvasData(); + cropBoxData = this.getCropBoxData(); + } + + this.render(); + + if (options.restore) { + this.setCanvasData(each(canvasData, function (n, i) { + canvasData[i] = n * ratio; + })); + this.setCropBoxData(each(cropBoxData, function (n, i) { + cropBoxData[i] = n * ratio; + })); + } + } + }, + dblclick: function dblclick() { + if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) { + return; + } + + this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); + }, + wheel: function wheel(e) { + var _this = this; + + var ratio = Number(this.options.wheelZoomRatio) || 0.1; + var delta = 1; + + if (this.disabled) { + return; + } + + e.preventDefault(); + + // Limit wheel speed to prevent zoom too fast (#21) + if (this.wheeling) { + return; + } + + this.wheeling = true; + + setTimeout(function () { + _this.wheeling = false; + }, 50); + + if (e.deltaY) { + delta = e.deltaY > 0 ? 1 : -1; + } else if (e.wheelDelta) { + delta = -e.wheelDelta / 120; + } else if (e.detail) { + delta = e.detail > 0 ? 1 : -1; + } + + this.zoom(-delta * ratio, e); + }, + cropStart: function cropStart(e) { + if (this.disabled) { + return; + } + + var options = this.options, + pointers = this.pointers; + + var action = void 0; + + if (e.changedTouches) { + // Handle touch event + each(e.changedTouches, function (touch) { + pointers[touch.identifier] = getPointer(touch); + }); + } else { + // Handle mouse event and pointer event + pointers[e.pointerId || 0] = getPointer(e); + } + + if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { + action = ACTION_ZOOM; + } else { + action = getData(e.target, DATA_ACTION); + } + + if (!REGEXP_ACTIONS.test(action)) { + return; + } + + if (dispatchEvent(this.element, EVENT_CROP_START, { + originalEvent: e, + action: action + }) === false) { + return; + } + + e.preventDefault(); + + this.action = action; + this.cropping = false; + + if (action === ACTION_CROP) { + this.cropping = true; + addClass(this.dragBox, CLASS_MODAL); + } + }, + cropMove: function cropMove(e) { + var action = this.action; + + + if (this.disabled || !action) { + return; + } + + var pointers = this.pointers; + + + e.preventDefault(); + + if (dispatchEvent(this.element, EVENT_CROP_MOVE, { + originalEvent: e, + action: action + }) === false) { + return; + } + + if (e.changedTouches) { + each(e.changedTouches, function (touch) { + extend(pointers[touch.identifier], getPointer(touch, true)); + }); + } else { + extend(pointers[e.pointerId || 0], getPointer(e, true)); + } + + this.change(e); + }, + cropEnd: function cropEnd(e) { + if (this.disabled) { + return; + } + + var action = this.action, + pointers = this.pointers; + + + if (e.changedTouches) { + each(e.changedTouches, function (touch) { + delete pointers[touch.identifier]; + }); + } else { + delete pointers[e.pointerId || 0]; + } + + if (!action) { + return; + } + + e.preventDefault(); + + if (!Object.keys(pointers).length) { + this.action = ''; + } + + if (this.cropping) { + this.cropping = false; + toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal); + } + + dispatchEvent(this.element, EVENT_CROP_END, { + originalEvent: e, + action: action + }); + } +}; + +var change = { + change: function change(e) { + var options = this.options, + canvasData = this.canvasData, + containerData = this.containerData, + cropBoxData = this.cropBoxData, + pointers = this.pointers; + var action = this.action; + var aspectRatio = options.aspectRatio; + var left = cropBoxData.left, + top = cropBoxData.top, + width = cropBoxData.width, + height = cropBoxData.height; + + var right = left + width; + var bottom = top + height; + var minLeft = 0; + var minTop = 0; + var maxWidth = containerData.width; + var maxHeight = containerData.height; + var renderable = true; + var offset = void 0; + + // Locking aspect ratio in "free mode" by holding shift key + if (!aspectRatio && e.shiftKey) { + aspectRatio = width && height ? width / height : 1; + } + + if (this.limited) { + minLeft = cropBoxData.minLeft; + minTop = cropBoxData.minTop; + + maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width); + maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height); + } + + var pointer = pointers[Object.keys(pointers)[0]]; + var range = { + x: pointer.endX - pointer.startX, + y: pointer.endY - pointer.startY + }; + var check = function check(side) { + switch (side) { + case ACTION_EAST: + if (right + range.x > maxWidth) { + range.x = maxWidth - right; + } + + break; + + case ACTION_WEST: + if (left + range.x < minLeft) { + range.x = minLeft - left; + } + + break; + + case ACTION_NORTH: + if (top + range.y < minTop) { + range.y = minTop - top; + } + + break; + + case ACTION_SOUTH: + if (bottom + range.y > maxHeight) { + range.y = maxHeight - bottom; + } + + break; + + default: + } + }; + + switch (action) { + // Move crop box + case ACTION_ALL: + left += range.x; + top += range.y; + break; + + // Resize crop box + case ACTION_EAST: + if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) { + renderable = false; + break; + } + + check(ACTION_EAST); + width += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top -= range.x / aspectRatio / 2; + } + + if (width < 0) { + action = ACTION_WEST; + width = 0; + } + + break; + + case ACTION_NORTH: + if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left += range.y * aspectRatio / 2; + } + + if (height < 0) { + action = ACTION_SOUTH; + height = 0; + } + + break; + + case ACTION_WEST: + if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) { + renderable = false; + break; + } + + check(ACTION_WEST); + width -= range.x; + left += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top += range.x / aspectRatio / 2; + } + + if (width < 0) { + action = ACTION_EAST; + width = 0; + } + + break; + + case ACTION_SOUTH: + if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) { + renderable = false; + break; + } + + check(ACTION_SOUTH); + height += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left -= range.y * aspectRatio / 2; + } + + if (height < 0) { + action = ACTION_NORTH; + height = 0; + } + + break; + + case ACTION_NORTH_EAST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || right >= maxWidth)) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + width = height * aspectRatio; + } else { + check(ACTION_NORTH); + check(ACTION_EAST); + + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + } + + break; + + case ACTION_NORTH_WEST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || left <= minLeft)) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + width = height * aspectRatio; + left += range.y * aspectRatio; + } else { + check(ACTION_NORTH); + check(ACTION_WEST); + + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_WEST: + if (aspectRatio) { + if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) { + renderable = false; + break; + } + + check(ACTION_WEST); + width -= range.x; + left += range.x; + height = width / aspectRatio; + } else { + check(ACTION_SOUTH); + check(ACTION_WEST); + + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_EAST: + if (aspectRatio) { + if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) { + renderable = false; + break; + } + + check(ACTION_EAST); + width += range.x; + height = width / aspectRatio; + } else { + check(ACTION_SOUTH); + check(ACTION_EAST); + + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + } + + break; + + // Move canvas + case ACTION_MOVE: + this.move(range.x, range.y); + renderable = false; + break; + + // Zoom canvas + case ACTION_ZOOM: + this.zoom(getMaxZoomRatio(pointers), e); + renderable = false; + break; + + // Create crop box + case ACTION_CROP: + if (!range.x || !range.y) { + renderable = false; + break; + } + + offset = getOffset(this.cropper); + left = pointer.startX - offset.left; + top = pointer.startY - offset.top; + width = cropBoxData.minWidth; + height = cropBoxData.minHeight; + + if (range.x > 0) { + action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST; + } else if (range.x < 0) { + left -= width; + action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST; + } + + if (range.y < 0) { + top -= height; + } + + // Show the crop box if is hidden + if (!this.cropped) { + removeClass(this.cropBox, CLASS_HIDDEN); + this.cropped = true; + + if (this.limited) { + this.limitCropBox(true, true); + } + } + + break; + + default: + } + + if (renderable) { + cropBoxData.width = width; + cropBoxData.height = height; + cropBoxData.left = left; + cropBoxData.top = top; + this.action = action; + this.renderCropBox(); + } + + // Override + each(pointers, function (p) { + p.startX = p.endX; + p.startY = p.endY; + }); + } +}; + +var methods = { + // Show the crop box manually + crop: function crop() { + if (this.ready && !this.disabled) { + if (!this.cropped) { + this.cropped = true; + this.limitCropBox(true, true); + + if (this.options.modal) { + addClass(this.dragBox, CLASS_MODAL); + } + + removeClass(this.cropBox, CLASS_HIDDEN); + } + + this.setCropBoxData(this.initialCropBoxData); + } + + return this; + }, + + + // Reset the image and crop box to their initial states + reset: function reset() { + if (this.ready && !this.disabled) { + this.imageData = extend({}, this.initialImageData); + this.canvasData = extend({}, this.initialCanvasData); + this.cropBoxData = extend({}, this.initialCropBoxData); + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + } + + return this; + }, + + + // Clear the crop box + clear: function clear() { + if (this.cropped && !this.disabled) { + extend(this.cropBoxData, { + left: 0, + top: 0, + width: 0, + height: 0 + }); + + this.cropped = false; + this.renderCropBox(); + this.limitCanvas(true, true); + + // Render canvas after crop box rendered + this.renderCanvas(); + removeClass(this.dragBox, CLASS_MODAL); + addClass(this.cropBox, CLASS_HIDDEN); + } + + return this; + }, + + + /** + * Replace the image's src and rebuild the cropper + * @param {string} url - The new URL. + * @param {boolean} [onlyColorChanged] - Indicate if the new image only changed color. + * @returns {Object} this + */ + replace: function replace(url) { + var onlyColorChanged = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (!this.disabled && url) { + if (this.isImg) { + this.element.src = url; + } + + if (onlyColorChanged) { + this.url = url; + this.image.src = url; + + if (this.ready) { + this.image2.src = url; + + each(this.previews, function (element) { + element.getElementsByTagName('img')[0].src = url; + }); + } + } else { + if (this.isImg) { + this.replaced = true; + } + + // Clear previous data + this.options.data = null; + this.load(url); + } + } + + return this; + }, + + + // Enable (unfreeze) the cropper + enable: function enable() { + if (this.ready) { + this.disabled = false; + removeClass(this.cropper, CLASS_DISABLED); + } + + return this; + }, + + + // Disable (freeze) the cropper + disable: function disable() { + if (this.ready) { + this.disabled = true; + addClass(this.cropper, CLASS_DISABLED); + } + + return this; + }, + + + // Destroy the cropper and remove the instance from the image + destroy: function destroy() { + var element = this.element, + image = this.image; + + + if (this.loaded) { + if (this.isImg && this.replaced) { + element.src = this.originalUrl; + } + + this.unbuild(); + removeClass(element, CLASS_HIDDEN); + } else if (this.isImg) { + removeListener(element, EVENT_LOAD, this.onStart); + } else if (image) { + image.parentNode.removeChild(image); + } + + removeData(element, NAMESPACE); + + return this; + }, + + + /** + * Move the canvas with relative offsets + * @param {number} offsetX - The relative offset distance on the x-axis. + * @param {number} offsetY - The relative offset distance on the y-axis. + * @returns {Object} this + */ + move: function move(offsetX, offsetY) { + var _canvasData = this.canvasData, + left = _canvasData.left, + top = _canvasData.top; + + + return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); + }, + + + /** + * Move the canvas to an absolute point + * @param {number} x - The x-axis coordinate. + * @param {number} [y=x] - The y-axis coordinate. + * @returns {Object} this + */ + moveTo: function moveTo(x) { + var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + var canvasData = this.canvasData; + + var changed = false; + + x = Number(x); + y = Number(y); + + if (this.ready && !this.disabled && this.options.movable) { + if (isNumber(x)) { + canvasData.left = x; + changed = true; + } + + if (isNumber(y)) { + canvasData.top = y; + changed = true; + } + + if (changed) { + this.renderCanvas(true); + } + } + + return this; + }, + + + /** + * Zoom the canvas with a relative ratio + * @param {number} ratio - The target ratio. + * @param {Event} _originalEvent - The original event if any. + * @returns {Object} this + */ + zoom: function zoom(ratio, _originalEvent) { + var canvasData = this.canvasData; + + + ratio = Number(ratio); + + if (ratio < 0) { + ratio = 1 / (1 - ratio); + } else { + ratio = 1 + ratio; + } + + return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent); + }, + + + /** + * Zoom the canvas to an absolute ratio + * @param {number} ratio - The target ratio. + * @param {Object} pivot - The zoom pivot point coordinate. + * @param {Event} _originalEvent - The original event if any. + * @returns {Object} this + */ + zoomTo: function zoomTo(ratio, pivot, _originalEvent) { + var options = this.options, + canvasData = this.canvasData; + var width = canvasData.width, + height = canvasData.height, + naturalWidth = canvasData.naturalWidth, + naturalHeight = canvasData.naturalHeight; + + + ratio = Number(ratio); + + if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) { + var newWidth = naturalWidth * ratio; + var newHeight = naturalHeight * ratio; + + if (dispatchEvent(this.element, EVENT_ZOOM, { + originalEvent: _originalEvent, + oldRatio: width / naturalWidth, + ratio: newWidth / naturalWidth + }) === false) { + return this; + } + + if (_originalEvent) { + var pointers = this.pointers; + + var offset = getOffset(this.cropper); + var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : { + pageX: _originalEvent.pageX, + pageY: _originalEvent.pageY + }; + + // Zoom from the triggering point of the event + canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width); + canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height); + } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) { + canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width); + canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height); + } else { + // Zoom from the center of the canvas + canvasData.left -= (newWidth - width) / 2; + canvasData.top -= (newHeight - height) / 2; + } + + canvasData.width = newWidth; + canvasData.height = newHeight; + this.renderCanvas(true); + } + + return this; + }, + + + /** + * Rotate the canvas with a relative degree + * @param {number} degree - The rotate degree. + * @returns {Object} this + */ + rotate: function rotate(degree) { + return this.rotateTo((this.imageData.rotate || 0) + Number(degree)); + }, + + + /** + * Rotate the canvas to an absolute degree + * @param {number} degree - The rotate degree. + * @returns {Object} this + */ + rotateTo: function rotateTo(degree) { + degree = Number(degree); + + if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) { + this.imageData.rotate = degree % 360; + this.renderCanvas(true, true); + } + + return this; + }, + + + /** + * Scale the image on the x-axis. + * @param {number} scaleX - The scale ratio on the x-axis. + * @returns {Object} this + */ + scaleX: function scaleX(_scaleX) { + var scaleY = this.imageData.scaleY; + + + return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1); + }, + + + /** + * Scale the image on the y-axis. + * @param {number} scaleY - The scale ratio on the y-axis. + * @returns {Object} this + */ + scaleY: function scaleY(_scaleY) { + var scaleX = this.imageData.scaleX; + + + return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); + }, + + + /** + * Scale the image + * @param {number} scaleX - The scale ratio on the x-axis. + * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis. + * @returns {Object} this + */ + scale: function scale(scaleX) { + var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX; + var imageData = this.imageData; + + var transformed = false; + + scaleX = Number(scaleX); + scaleY = Number(scaleY); + + if (this.ready && !this.disabled && this.options.scalable) { + if (isNumber(scaleX)) { + imageData.scaleX = scaleX; + transformed = true; + } + + if (isNumber(scaleY)) { + imageData.scaleY = scaleY; + transformed = true; + } + + if (transformed) { + this.renderCanvas(true, true); + } + } + + return this; + }, + + + /** + * Get the cropped area position and size data (base on the original image) + * @param {boolean} [rounded=false] - Indicate if round the data values or not. + * @returns {Object} The result cropped data. + */ + getData: function getData$$1() { + var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var options = this.options, + imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; + + var data = void 0; + + if (this.ready && this.cropped) { + data = { + x: cropBoxData.left - canvasData.left, + y: cropBoxData.top - canvasData.top, + width: cropBoxData.width, + height: cropBoxData.height + }; + + var ratio = imageData.width / imageData.naturalWidth; + + each(data, function (n, i) { + n /= ratio; + data[i] = rounded ? Math.round(n) : n; + }); + } else { + data = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + } + + if (options.rotatable) { + data.rotate = imageData.rotate || 0; + } + + if (options.scalable) { + data.scaleX = imageData.scaleX || 1; + data.scaleY = imageData.scaleY || 1; + } + + return data; + }, + + + /** + * Set the cropped area position and size with new data + * @param {Object} data - The new data. + * @returns {Object} this + */ + setData: function setData$$1(data) { + var options = this.options, + imageData = this.imageData, + canvasData = this.canvasData; + + var cropBoxData = {}; + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && !this.disabled && isPlainObject(data)) { + var transformed = false; + + if (options.rotatable) { + if (isNumber(data.rotate) && data.rotate !== imageData.rotate) { + imageData.rotate = data.rotate; + transformed = true; + } + } + + if (options.scalable) { + if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) { + imageData.scaleX = data.scaleX; + transformed = true; + } + + if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) { + imageData.scaleY = data.scaleY; + transformed = true; + } + } + + if (transformed) { + this.renderCanvas(true, true); + } + + var ratio = imageData.width / imageData.naturalWidth; + + if (isNumber(data.x)) { + cropBoxData.left = data.x * ratio + canvasData.left; + } + + if (isNumber(data.y)) { + cropBoxData.top = data.y * ratio + canvasData.top; + } + + if (isNumber(data.width)) { + cropBoxData.width = data.width * ratio; + } + + if (isNumber(data.height)) { + cropBoxData.height = data.height * ratio; + } + + this.setCropBoxData(cropBoxData); + } + + return this; + }, + + + /** + * Get the container size data. + * @returns {Object} The result container data. + */ + getContainerData: function getContainerData() { + return this.ready ? extend({}, this.containerData) : {}; + }, + + + /** + * Get the image position and size data. + * @returns {Object} The result image data. + */ + getImageData: function getImageData() { + return this.loaded ? extend({}, this.imageData) : {}; + }, + + + /** + * Get the canvas position and size data. + * @returns {Object} The result canvas data. + */ + getCanvasData: function getCanvasData() { + var canvasData = this.canvasData; + + var data = {}; + + if (this.ready) { + each(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) { + data[n] = canvasData[n]; + }); + } + + return data; + }, + + + /** + * Set the canvas position and size with new data. + * @param {Object} data - The new canvas data. + * @returns {Object} this + */ + setCanvasData: function setCanvasData(data) { + var canvasData = this.canvasData; + var aspectRatio = canvasData.aspectRatio; + + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && !this.disabled && isPlainObject(data)) { + if (isNumber(data.left)) { + canvasData.left = data.left; + } + + if (isNumber(data.top)) { + canvasData.top = data.top; + } + + if (isNumber(data.width)) { + canvasData.width = data.width; + canvasData.height = data.width / aspectRatio; + } else if (isNumber(data.height)) { + canvasData.height = data.height; + canvasData.width = data.height * aspectRatio; + } + + this.renderCanvas(true); + } + + return this; + }, + + + /** + * Get the crop box position and size data. + * @returns {Object} The result crop box data. + */ + getCropBoxData: function getCropBoxData() { + var cropBoxData = this.cropBoxData; + + var data = void 0; + + if (this.ready && this.cropped) { + data = { + left: cropBoxData.left, + top: cropBoxData.top, + width: cropBoxData.width, + height: cropBoxData.height + }; + } + + return data || {}; + }, + + + /** + * Set the crop box position and size with new data. + * @param {Object} data - The new crop box data. + * @returns {Object} this + */ + setCropBoxData: function setCropBoxData(data) { + var cropBoxData = this.cropBoxData; + var aspectRatio = this.options.aspectRatio; + + var widthChanged = void 0; + var heightChanged = void 0; + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) { + if (isNumber(data.left)) { + cropBoxData.left = data.left; + } + + if (isNumber(data.top)) { + cropBoxData.top = data.top; + } + + if (isNumber(data.width) && data.width !== cropBoxData.width) { + widthChanged = true; + cropBoxData.width = data.width; + } + + if (isNumber(data.height) && data.height !== cropBoxData.height) { + heightChanged = true; + cropBoxData.height = data.height; + } + + if (aspectRatio) { + if (widthChanged) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else if (heightChanged) { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + this.renderCropBox(); + } + + return this; + }, + + + /** + * Get a canvas drawn the cropped image. + * @param {Object} [options={}] - The config options. + * @returns {HTMLCanvasElement} - The result canvas. + */ + getCroppedCanvas: function getCroppedCanvas() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (!this.ready || !window.HTMLCanvasElement) { + return null; + } + + var canvasData = this.canvasData; + + var source = getSourceCanvas(this.image, this.imageData, canvasData, options); + + // Returns the source canvas if it is not cropped. + if (!this.cropped) { + return source; + } + + var _getData = this.getData(), + x = _getData.x, + y = _getData.y, + initialWidth = _getData.width, + initialHeight = _getData.height; + + var aspectRatio = initialWidth / initialHeight; + var maxSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.maxWidth || Infinity, + height: options.maxHeight || Infinity + }); + var minSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.minWidth || 0, + height: options.minHeight || 0 + }); + + var _getContainSizes = getContainSizes({ + aspectRatio: aspectRatio, + width: options.width || initialWidth, + height: options.height || initialHeight + }), + width = _getContainSizes.width, + height = _getContainSizes.height; + + width = Math.min(maxSizes.width, Math.max(minSizes.width, width)); + height = Math.min(maxSizes.height, Math.max(minSizes.height, height)); + + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + + canvas.width = normalizeDecimalNumber(width); + canvas.height = normalizeDecimalNumber(height); + + context.fillStyle = options.fillColor || 'transparent'; + context.fillRect(0, 0, width, height); + + var _options$imageSmoothi = options.imageSmoothingEnabled, + imageSmoothingEnabled = _options$imageSmoothi === undefined ? true : _options$imageSmoothi, + imageSmoothingQuality = options.imageSmoothingQuality; + + + context.imageSmoothingEnabled = imageSmoothingEnabled; + + if (imageSmoothingQuality) { + context.imageSmoothingQuality = imageSmoothingQuality; + } + + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage + var sourceWidth = source.width; + var sourceHeight = source.height; + + // Source canvas parameters + var srcX = x; + var srcY = y; + var srcWidth = void 0; + var srcHeight = void 0; + + // Destination canvas parameters + var dstX = void 0; + var dstY = void 0; + var dstWidth = void 0; + var dstHeight = void 0; + + if (srcX <= -initialWidth || srcX > sourceWidth) { + srcX = 0; + srcWidth = 0; + dstX = 0; + dstWidth = 0; + } else if (srcX <= 0) { + dstX = -srcX; + srcX = 0; + srcWidth = Math.min(sourceWidth, initialWidth + srcX); + dstWidth = srcWidth; + } else if (srcX <= sourceWidth) { + dstX = 0; + srcWidth = Math.min(initialWidth, sourceWidth - srcX); + dstWidth = srcWidth; + } + + if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) { + srcY = 0; + srcHeight = 0; + dstY = 0; + dstHeight = 0; + } else if (srcY <= 0) { + dstY = -srcY; + srcY = 0; + srcHeight = Math.min(sourceHeight, initialHeight + srcY); + dstHeight = srcHeight; + } else if (srcY <= sourceHeight) { + dstY = 0; + srcHeight = Math.min(initialHeight, sourceHeight - srcY); + dstHeight = srcHeight; + } + + // All the numerical parameters should be integer for `drawImage` + // https://github.com/fengyuanchen/cropper/issues/476 + var params = [srcX, srcY, srcWidth, srcHeight]; + + // Avoid "IndexSizeError" + if (dstWidth > 0 && dstHeight > 0) { + var scale = width / initialWidth; + + params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale); + } + + context.drawImage.apply(context, [source].concat(toConsumableArray(params.map(function (param) { + return Math.floor(normalizeDecimalNumber(param)); + })))); + + return canvas; + }, + + + /** + * Change the aspect ratio of the crop box. + * @param {number} aspectRatio - The new aspect ratio. + * @returns {Object} this + */ + setAspectRatio: function setAspectRatio(aspectRatio) { + var options = this.options; + + + if (!this.disabled && !isUndefined(aspectRatio)) { + // 0 -> NaN + options.aspectRatio = Math.max(0, aspectRatio) || NaN; + + if (this.ready) { + this.initCropBox(); + + if (this.cropped) { + this.renderCropBox(); + } + } + } + + return this; + }, + + + /** + * Change the drag mode. + * @param {string} mode - The new drag mode. + * @returns {Object} this + */ + setDragMode: function setDragMode(mode) { + var options = this.options, + dragBox = this.dragBox, + face = this.face; + + + if (this.loaded && !this.disabled) { + var croppable = mode === DRAG_MODE_CROP; + var movable = options.movable && mode === DRAG_MODE_MOVE; + + mode = croppable || movable ? mode : DRAG_MODE_NONE; + + setData(dragBox, DATA_ACTION, mode); + toggleClass(dragBox, CLASS_CROP, croppable); + toggleClass(dragBox, CLASS_MOVE, movable); + + if (!options.cropBoxMovable) { + // Sync drag mode to crop box when it is not movable + setData(face, DATA_ACTION, mode); + toggleClass(face, CLASS_CROP, croppable); + toggleClass(face, CLASS_MOVE, movable); + } + } + + return this; + } +}; + +var AnotherCropper = WINDOW.Cropper; + +var Cropper = function () { + /** + * Create a new Cropper. + * @param {Element} element - The target element for cropping. + * @param {Object} [options={}] - The configuration options. + */ + function Cropper(element) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + classCallCheck(this, Cropper); + + if (!element || !REGEXP_TAG_NAME.test(element.tagName)) { + throw new Error('The first argument is required and must be an or element.'); + } + + this.element = element; + this.options = extend({}, DEFAULTS, isPlainObject(options) && options); + this.complete = false; + this.cropped = false; + this.disabled = false; + this.isImg = false; + this.limited = false; + this.loaded = false; + this.ready = false; + this.replaced = false; + this.wheeling = false; + this.originalUrl = ''; + this.canvasData = null; + this.cropBoxData = null; + this.previews = null; + this.pointers = {}; + this.init(); + } + + createClass(Cropper, [{ + key: 'init', + value: function init() { + var element = this.element; + + var tagName = element.tagName.toLowerCase(); + var url = void 0; + + if (getData(element, NAMESPACE)) { + return; + } + + setData(element, NAMESPACE, this); + + if (tagName === 'img') { + this.isImg = true; + + // e.g.: "img/picture.jpg" + url = element.getAttribute('src') || ''; + this.originalUrl = url; + + // Stop when it's a blank image + if (!url) { + return; + } + + // e.g.: "http://example.com/img/picture.jpg" + url = element.src; + } else if (tagName === 'canvas' && window.HTMLCanvasElement) { + url = element.toDataURL(); + } + + this.load(url); + } + }, { + key: 'load', + value: function load(url) { + var _this = this; + + if (!url) { + return; + } + + this.url = url; + this.imageData = {}; + + var element = this.element, + options = this.options; + + + if (!options.checkOrientation || !window.ArrayBuffer) { + this.clone(); + return; + } + + // XMLHttpRequest disallows to open a Data URL in some browsers like IE11 and Safari + if (REGEXP_DATA_URL.test(url)) { + if (REGEXP_DATA_URL_JPEG.test(url)) { + this.read(dataURLToArrayBuffer(url)); + } else { + this.clone(); + } + + return; + } + + var xhr = new XMLHttpRequest(); + + xhr.onerror = function () { + _this.clone(); + }; + + xhr.onload = function () { + _this.read(xhr.response); + }; + + if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) { + url = addTimestamp(url); + } + + xhr.open('get', url); + xhr.responseType = 'arraybuffer'; + xhr.withCredentials = element.crossOrigin === 'use-credentials'; + xhr.send(); + } + }, { + key: 'read', + value: function read(arrayBuffer) { + var options = this.options, + imageData = this.imageData; + + var orientation = getOrientation(arrayBuffer); + var rotate = 0; + var scaleX = 1; + var scaleY = 1; + + if (orientation > 1) { + this.url = arrayBufferToDataURL(arrayBuffer, 'image/jpeg'); + + var _parseOrientation = parseOrientation(orientation); + + rotate = _parseOrientation.rotate; + scaleX = _parseOrientation.scaleX; + scaleY = _parseOrientation.scaleY; + } + + if (options.rotatable) { + imageData.rotate = rotate; + } + + if (options.scalable) { + imageData.scaleX = scaleX; + imageData.scaleY = scaleY; + } + + this.clone(); + } + }, { + key: 'clone', + value: function clone() { + var element = this.element, + url = this.url; + + var crossOrigin = void 0; + var crossOriginUrl = void 0; + + if (this.options.checkCrossOrigin && isCrossOriginURL(url)) { + crossOrigin = element.crossOrigin; + + + if (crossOrigin) { + crossOriginUrl = url; + } else { + crossOrigin = 'anonymous'; + + // Bust cache when there is not a "crossOrigin" property + crossOriginUrl = addTimestamp(url); + } + } + + this.crossOrigin = crossOrigin; + this.crossOriginUrl = crossOriginUrl; + + var image = document.createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = crossOriginUrl || url; + + var start = proxy(this.start, this); + var stop = proxy(this.stop, this); + + this.image = image; + this.onStart = start; + this.onStop = stop; + + if (this.isImg) { + if (element.complete) { + this.start(); + } else { + addListener(element, EVENT_LOAD, start); + } + } else { + addListener(image, EVENT_LOAD, start); + addListener(image, EVENT_ERROR, stop); + addClass(image, CLASS_HIDE); + element.parentNode.insertBefore(image, element.nextSibling); + } + } + }, { + key: 'start', + value: function start(event) { + var _this2 = this; + + var image = this.isImg ? this.element : this.image; + + if (event) { + removeListener(image, EVENT_LOAD, this.onStart); + removeListener(image, EVENT_ERROR, this.onStop); + } + + getImageNaturalSizes(image, function (naturalWidth, naturalHeight) { + extend(_this2.imageData, { + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + aspectRatio: naturalWidth / naturalHeight + }); + _this2.loaded = true; + _this2.build(); + }); + } + }, { + key: 'stop', + value: function stop() { + var image = this.image; + + + removeListener(image, EVENT_LOAD, this.onStart); + removeListener(image, EVENT_ERROR, this.onStop); + image.parentNode.removeChild(image); + this.image = null; + } + }, { + key: 'build', + value: function build() { + var _this3 = this; + + if (!this.loaded) { + return; + } + + // Unbuild first when replace + if (this.ready) { + this.unbuild(); + } + + var element = this.element, + options = this.options, + image = this.image; + + // Create cropper elements + + var container = element.parentNode; + var template = document.createElement('div'); + + template.innerHTML = TEMPLATE; + + var cropper = template.querySelector('.' + NAMESPACE + '-container'); + var canvas = cropper.querySelector('.' + NAMESPACE + '-canvas'); + var dragBox = cropper.querySelector('.' + NAMESPACE + '-drag-box'); + var cropBox = cropper.querySelector('.' + NAMESPACE + '-crop-box'); + var face = cropBox.querySelector('.' + NAMESPACE + '-face'); + + this.container = container; + this.cropper = cropper; + this.canvas = canvas; + this.dragBox = dragBox; + this.cropBox = cropBox; + this.viewBox = cropper.querySelector('.' + NAMESPACE + '-view-box'); + this.face = face; + + canvas.appendChild(image); + + // Hide the original image + addClass(element, CLASS_HIDDEN); + + // Inserts the cropper after to the current image + container.insertBefore(cropper, element.nextSibling); + + // Show the image if is hidden + if (!this.isImg) { + removeClass(image, CLASS_HIDE); + } + + this.initPreview(); + this.bind(); + + options.aspectRatio = Math.max(0, options.aspectRatio) || NaN; + options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0; + + this.cropped = options.autoCrop; + + if (options.autoCrop) { + if (options.modal) { + addClass(dragBox, CLASS_MODAL); + } + } else { + addClass(cropBox, CLASS_HIDDEN); + } + + if (!options.guides) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-dashed'), CLASS_HIDDEN); + } + + if (!options.center) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-center'), CLASS_HIDDEN); + } + + if (options.background) { + addClass(cropper, NAMESPACE + '-bg'); + } + + if (!options.highlight) { + addClass(face, CLASS_INVISIBLE); + } + + if (options.cropBoxMovable) { + addClass(face, CLASS_MOVE); + setData(face, DATA_ACTION, ACTION_ALL); + } + + if (!options.cropBoxResizable) { + addClass(cropBox.getElementsByClassName(NAMESPACE + '-line'), CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-point'), CLASS_HIDDEN); + } + + this.setDragMode(options.dragMode); + this.render(); + this.ready = true; + this.setData(options.data); + + // Call the "ready" option asynchronously to keep "image.cropper" is defined + this.completing = setTimeout(function () { + if (isFunction(options.ready)) { + addListener(element, EVENT_READY, options.ready, { + once: true + }); + } + + dispatchEvent(element, EVENT_READY); + dispatchEvent(element, EVENT_CROP, _this3.getData()); + + _this3.complete = true; + }, 0); + } + }, { + key: 'unbuild', + value: function unbuild() { + if (!this.ready) { + return; + } + + if (!this.complete) { + clearTimeout(this.completing); + } + + this.ready = false; + this.complete = false; + this.initialImageData = null; + + // Clear `initialCanvasData` is necessary when replace + this.initialCanvasData = null; + this.initialCropBoxData = null; + this.containerData = null; + this.canvasData = null; + + // Clear `cropBoxData` is necessary when replace + this.cropBoxData = null; + this.unbind(); + this.resetPreview(); + this.previews = null; + this.viewBox = null; + this.cropBox = null; + this.dragBox = null; + this.canvas = null; + this.container = null; + this.cropper.parentNode.removeChild(this.cropper); + this.cropper = null; + } + + /** + * Get the no conflict cropper class. + * @returns {Cropper} The cropper class. + */ + + }], [{ + key: 'noConflict', + value: function noConflict() { + window.Cropper = AnotherCropper; + return Cropper; + } + + /** + * Change the default options. + * @param {Object} options - The new default options. + */ + + }, { + key: 'setDefaults', + value: function setDefaults(options) { + extend(DEFAULTS, isPlainObject(options) && options); + } + }]); + return Cropper; +}(); + +extend(Cropper.prototype, render, preview, events, handlers, change, methods); + +return Cropper; + +}))); diff --git a/library/cropperjs/docs/js/main.js b/library/cropperjs/docs/js/main.js new file mode 100644 index 000000000..d74afbd60 --- /dev/null +++ b/library/cropperjs/docs/js/main.js @@ -0,0 +1,298 @@ +window.onload = function () { + + 'use strict'; + + var Cropper = window.Cropper; + var URL = window.URL || window.webkitURL; + var container = document.querySelector('.img-container'); + var image = container.getElementsByTagName('img').item(0); + var download = document.getElementById('download'); + var actions = document.getElementById('actions'); + var dataX = document.getElementById('dataX'); + var dataY = document.getElementById('dataY'); + var dataHeight = document.getElementById('dataHeight'); + var dataWidth = document.getElementById('dataWidth'); + var dataRotate = document.getElementById('dataRotate'); + var dataScaleX = document.getElementById('dataScaleX'); + var dataScaleY = document.getElementById('dataScaleY'); + var options = { + aspectRatio: 16 / 9, + preview: '.img-preview', + ready: function (e) { + console.log(e.type); + }, + cropstart: function (e) { + console.log(e.type, e.detail.action); + }, + cropmove: function (e) { + console.log(e.type, e.detail.action); + }, + cropend: function (e) { + console.log(e.type, e.detail.action); + }, + crop: function (e) { + var data = e.detail; + + console.log(e.type); + dataX.value = Math.round(data.x); + dataY.value = Math.round(data.y); + dataHeight.value = Math.round(data.height); + dataWidth.value = Math.round(data.width); + dataRotate.value = typeof data.rotate !== 'undefined' ? data.rotate : ''; + dataScaleX.value = typeof data.scaleX !== 'undefined' ? data.scaleX : ''; + dataScaleY.value = typeof data.scaleY !== 'undefined' ? data.scaleY : ''; + }, + zoom: function (e) { + console.log(e.type, e.detail.ratio); + } + }; + var cropper = new Cropper(image, options); + var originalImageURL = image.src; + var uploadedImageType = 'image/jpeg'; + var uploadedImageURL; + + // Tooltip + $('[data-toggle="tooltip"]').tooltip(); + + // Buttons + if (!document.createElement('canvas').getContext) { + $('button[data-method="getCroppedCanvas"]').prop('disabled', true); + } + + if (typeof document.createElement('cropper').style.transition === 'undefined') { + $('button[data-method="rotate"]').prop('disabled', true); + $('button[data-method="scale"]').prop('disabled', true); + } + + // Download + if (typeof download.download === 'undefined') { + download.className += ' disabled'; + } + + // Options + actions.querySelector('.docs-toggles').onchange = function (event) { + var e = event || window.event; + var target = e.target || e.srcElement; + var cropBoxData; + var canvasData; + var isCheckbox; + var isRadio; + + if (!cropper) { + return; + } + + if (target.tagName.toLowerCase() === 'label') { + target = target.querySelector('input'); + } + + isCheckbox = target.type === 'checkbox'; + isRadio = target.type === 'radio'; + + if (isCheckbox || isRadio) { + if (isCheckbox) { + options[target.name] = target.checked; + cropBoxData = cropper.getCropBoxData(); + canvasData = cropper.getCanvasData(); + + options.ready = function () { + console.log('ready'); + cropper.setCropBoxData(cropBoxData).setCanvasData(canvasData); + }; + } else { + options[target.name] = target.value; + options.ready = function () { + console.log('ready'); + }; + } + + // Restart + cropper.destroy(); + cropper = new Cropper(image, options); + } + }; + + // Methods + actions.querySelector('.docs-buttons').onclick = function (event) { + var e = event || window.event; + var target = e.target || e.srcElement; + var cropped; + var result; + var input; + var data; + + if (!cropper) { + return; + } + + while (target !== this) { + if (target.getAttribute('data-method')) { + break; + } + + target = target.parentNode; + } + + if (target === this || target.disabled || target.className.indexOf('disabled') > -1) { + return; + } + + data = { + method: target.getAttribute('data-method'), + target: target.getAttribute('data-target'), + option: target.getAttribute('data-option') || undefined, + secondOption: target.getAttribute('data-second-option') || undefined + }; + + cropped = cropper.cropped; + + if (data.method) { + if (typeof data.target !== 'undefined') { + input = document.querySelector(data.target); + + if (!target.hasAttribute('data-option') && data.target && input) { + try { + data.option = JSON.parse(input.value); + } catch (e) { + console.log(e.message); + } + } + } + + switch (data.method) { + case 'rotate': + if (cropped && options.viewMode > 0) { + cropper.clear(); + } + + break; + + case 'getCroppedCanvas': + try { + data.option = JSON.parse(data.option); + } catch (e) { + console.log(e.message); + } + + if (uploadedImageType === 'image/jpeg') { + if (!data.option) { + data.option = {}; + } + + data.option.fillColor = '#fff'; + } + + break; + } + + result = cropper[data.method](data.option, data.secondOption); + + switch (data.method) { + case 'rotate': + if (cropped && options.viewMode > 0) { + cropper.crop(); + } + + break; + + case 'scaleX': + case 'scaleY': + target.setAttribute('data-option', -data.option); + break; + + case 'getCroppedCanvas': + if (result) { + // Bootstrap's Modal + $('#getCroppedCanvasModal').modal().find('.modal-body').html(result); + + if (!download.disabled) { + download.href = result.toDataURL(uploadedImageType); + } + } + + break; + + case 'destroy': + cropper = null; + + if (uploadedImageURL) { + URL.revokeObjectURL(uploadedImageURL); + uploadedImageURL = ''; + image.src = originalImageURL; + } + + break; + } + + if (typeof result === 'object' && result !== cropper && input) { + try { + input.value = JSON.stringify(result); + } catch (e) { + console.log(e.message); + } + } + } + }; + + document.body.onkeydown = function (event) { + var e = event || window.event; + + if (!cropper || this.scrollTop > 300) { + return; + } + + switch (e.keyCode) { + case 37: + e.preventDefault(); + cropper.move(-1, 0); + break; + + case 38: + e.preventDefault(); + cropper.move(0, -1); + break; + + case 39: + e.preventDefault(); + cropper.move(1, 0); + break; + + case 40: + e.preventDefault(); + cropper.move(0, 1); + break; + } + }; + + // Import image + var inputImage = document.getElementById('inputImage'); + + if (URL) { + inputImage.onchange = function () { + var files = this.files; + var file; + + if (cropper && files && files.length) { + file = files[0]; + + if (/^image\/\w+/.test(file.type)) { + uploadedImageType = file.type; + + if (uploadedImageURL) { + URL.revokeObjectURL(uploadedImageURL); + } + + image.src = uploadedImageURL = URL.createObjectURL(file); + cropper.destroy(); + cropper = new Cropper(image, options); + inputImage.value = null; + } else { + window.alert('Please choose an image file.'); + } + } + }; + } else { + inputImage.disabled = true; + inputImage.parentNode.className += ' disabled'; + } +}; diff --git a/library/cropperjs/examples/a-range-of-aspect-ratio.html b/library/cropperjs/examples/a-range-of-aspect-ratio.html new file mode 100644 index 000000000..fae5cb60b --- /dev/null +++ b/library/cropperjs/examples/a-range-of-aspect-ratio.html @@ -0,0 +1,71 @@ + + + + + + + Cropper.js + + + + + +
+

Cropper with a range of aspect ratio

+
+ Picture +
+
+ + + + + diff --git a/library/cropperjs/examples/crop-a-round-image.html b/library/cropperjs/examples/crop-a-round-image.html new file mode 100644 index 000000000..da027d847 --- /dev/null +++ b/library/cropperjs/examples/crop-a-round-image.html @@ -0,0 +1,103 @@ + + + + + + + Cropper.js + + + + + +
+

Crop a round image

+

Image

+
+ Picture +
+

Result

+

+ +

+
+
+ + + + + diff --git a/library/cropperjs/examples/crop-cross-origin-image.html b/library/cropperjs/examples/crop-cross-origin-image.html new file mode 100644 index 000000000..54f08664a --- /dev/null +++ b/library/cropperjs/examples/crop-cross-origin-image.html @@ -0,0 +1,49 @@ + + + + + + + Cropper.js + + + + + +
+

Crop a cross origin image

+

A cross origin image with a crossorigin attribute and an available Access-Control-Allow-Origin response header can be cropped by Cropper.

+

Image

+
+ +
+

Result

+
+
+ + + + + diff --git a/library/cropperjs/examples/crop-on-canvas.html b/library/cropperjs/examples/crop-on-canvas.html new file mode 100644 index 000000000..228e36f75 --- /dev/null +++ b/library/cropperjs/examples/crop-on-canvas.html @@ -0,0 +1,64 @@ + + + + + + + Cropper.js + + + + + +
+

Crop on canvas with Cropper

+

Image

+
+ Picture +
+

Canvas

+
+ +
+
+ + + + + diff --git a/library/cropperjs/examples/cropper-in-modal.html b/library/cropperjs/examples/cropper-in-modal.html new file mode 100644 index 000000000..a9ce3e80b --- /dev/null +++ b/library/cropperjs/examples/cropper-in-modal.html @@ -0,0 +1,76 @@ + + + + + + + Cropper.js + + + + + + +
+

Cropper in a Bootstrap modal

+ + + + + + +
+ + + + + + + diff --git a/library/cropperjs/examples/customize-preview.html b/library/cropperjs/examples/customize-preview.html new file mode 100644 index 000000000..ea1c24b88 --- /dev/null +++ b/library/cropperjs/examples/customize-preview.html @@ -0,0 +1,123 @@ + + + + + + + Cropper.js + + + + + +
+

Customize preview for Cropper

+
+
+ Picture +
+
+
+
+
+
+
+
+
+
+
+
+ + + + + diff --git a/library/cropperjs/examples/fixed-crop-box.html b/library/cropperjs/examples/fixed-crop-box.html new file mode 100644 index 000000000..b9f1101fb --- /dev/null +++ b/library/cropperjs/examples/fixed-crop-box.html @@ -0,0 +1,48 @@ + + + + + + + Cropper.js + + + + + +
+

Cropper with fixed crop box

+
+ Picture +
+
+ + + + + diff --git a/library/cropperjs/examples/full-crop-box.html b/library/cropperjs/examples/full-crop-box.html new file mode 100644 index 000000000..7065eab94 --- /dev/null +++ b/library/cropperjs/examples/full-crop-box.html @@ -0,0 +1,48 @@ + + + + + + + Cropper.js + + + + + +
+

Cropper with full crop box

+
+ Picture +
+
+ + + + + diff --git a/library/cropperjs/examples/mask-an-image.html b/library/cropperjs/examples/mask-an-image.html new file mode 100644 index 000000000..d821da43b --- /dev/null +++ b/library/cropperjs/examples/mask-an-image.html @@ -0,0 +1,123 @@ + + + + + + + + Cropper.js + + + + + + +
+

Mask an image (Redaction)

+

Image

+
+ Picture +
+

Result

+

+
+
+ + + + + + diff --git a/library/cropperjs/examples/multiple-croppers.html b/library/cropperjs/examples/multiple-croppers.html new file mode 100644 index 000000000..6b12e70b2 --- /dev/null +++ b/library/cropperjs/examples/multiple-croppers.html @@ -0,0 +1,48 @@ + + + + + + + Cropper.js + + + + + +
+

Multiple Croppers

+

Cropper

+
+ Picture +
+

Another

+
+ Picture +
+
+ + + + + diff --git a/library/cropperjs/examples/responsive-container.html b/library/cropperjs/examples/responsive-container.html new file mode 100644 index 000000000..c1aa7483b --- /dev/null +++ b/library/cropperjs/examples/responsive-container.html @@ -0,0 +1,49 @@ + + + + + + + Cropper.js + + + + + +
+

Cropper with responsive container

+

+ +

+
+ Picture +
+
+ + + + + diff --git a/library/cropperjs/package-lock.json b/library/cropperjs/package-lock.json new file mode 100644 index 000000000..229ee70fa --- /dev/null +++ b/library/cropperjs/package-lock.json @@ -0,0 +1,9111 @@ +{ + "name": "cropperjs", + "version": "1.2.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "JSONStream": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-0.8.4.tgz", + "integrity": "sha1-kWV9/m/4V0gwZhMrRhi2Lo9Ih70=", + "dev": true, + "requires": { + "jsonparse": "0.0.5", + "through": "2.3.8" + } + }, + "acorn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz", + "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "json-schema-traverse": "0.3.1", + "json-stable-stringify": "1.0.1" + } + }, + "ajv-keywords": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz", + "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=", + "dev": true + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "2.1.1" + } + }, + "ansi-escapes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", + "dev": true + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "autoprefixer": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000744", + "normalize-range": "0.1.2", + "num2fraction": "1.2.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, + "requires": { + "caniuse-db": "1.0.30000744", + "electron-to-chromium": "1.3.24" + } + } + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-core": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.0", + "debug": "2.6.9", + "json5": "0.5.1", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.7", + "slash": "1.0.0", + "source-map": "0.5.7" + } + }, + "babel-generator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", + "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", + "dev": true, + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.4", + "source-map": "0.5.7", + "trim-right": "1.0.1" + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-external-helpers": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz", + "integrity": "sha1-IoX0iwK9Xe3oUXXK+MYuhq3M76E=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "requires": { + "babel-helper-define-map": "6.26.0", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", + "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "regexpu-core": "2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "requires": { + "regenerator-transform": "0.10.1" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-preset-env": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", + "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0", + "browserslist": "2.5.0", + "invariant": "2.2.2", + "semver": "5.4.1" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "6.26.0", + "babel-runtime": "6.26.0", + "core-js": "2.5.1", + "home-or-tmp": "2.0.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "2.5.1", + "regenerator-runtime": "0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "binary-extensions": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", + "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=", + "dev": true + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "dev": true, + "requires": { + "hoek": "4.2.0" + } + }, + "boxen": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.2.2.tgz", + "integrity": "sha1-Px1AMsMP/qnUsCwyLq8up0HcvOU=", + "dev": true, + "requires": { + "ansi-align": "2.0.0", + "camelcase": "4.1.0", + "chalk": "2.3.0", + "cli-boxes": "1.0.0", + "string-width": "2.1.1", + "term-size": "1.2.0", + "widest-line": "1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "browserslist": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.5.0.tgz", + "integrity": "sha512-6Vw1LIigGw8zCK0gxczksUMZlO+oPUwBazAztMmFL/F8D5wB0qCuxRJGYgYM3JzaO0v2ZMRIg+nnnOgNsPGHeA==", + "dev": true, + "requires": { + "caniuse-lite": "1.0.30000744", + "electron-to-chromium": "1.3.24" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + } + }, + "caniuse-api": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", + "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000744", + "lodash.memoize": "4.1.2", + "lodash.uniq": "4.5.0" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, + "requires": { + "caniuse-db": "1.0.30000744", + "electron-to-chromium": "1.3.24" + } + } + } + }, + "caniuse-db": { + "version": "1.0.30000744", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000744.tgz", + "integrity": "sha1-AHWP991fcTjTShVgjcz3Glllb/4=", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30000744", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000744.tgz", + "integrity": "sha1-hg+lyDujT+YZOX1gfzC7R0ghZxs=", + "dev": true + }, + "capture-stack-trace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", + "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "clap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", + "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", + "dev": true, + "requires": { + "chalk": "1.1.3" + } + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-spinners": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.1.0.tgz", + "integrity": "sha1-8YR7FohE2RemceudFH499JfJDQY=", + "dev": true + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "clone-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.0.tgz", + "integrity": "sha1-6uCiQT9VwJQvgYwin+/OhF1/Oxw=", + "dev": true, + "requires": { + "is-regexp": "1.0.0", + "is-supported-regexp-flag": "1.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "coa": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", + "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", + "dev": true, + "requires": { + "q": "1.5.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", + "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", + "dev": true, + "requires": { + "clone": "1.0.2", + "color-convert": "1.9.0", + "color-string": "0.3.0" + } + }, + "color-convert": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", + "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-diff": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/color-diff/-/color-diff-0.1.7.tgz", + "integrity": "sha1-bbeM2UgqjkWdQIIer0tQMoPcuOI=", + "dev": true + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "color-string": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", + "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "colorguard": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/colorguard/-/colorguard-1.2.0.tgz", + "integrity": "sha1-8/rK9cquuk71RlPZ+yW7cxd8DYQ=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "color-diff": "0.1.7", + "log-symbols": "1.0.2", + "object-assign": "4.1.1", + "pipetteur": "2.0.3", + "plur": "2.1.2", + "postcss": "5.2.18", + "postcss-reporter": "1.4.1", + "text-table": "0.2.0", + "yargs": "1.3.3" + }, + "dependencies": { + "postcss-reporter": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-1.4.1.tgz", + "integrity": "sha1-wTbwpbFhkV83ndN2XGEHX357mvI=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "lodash": "4.17.4", + "log-symbols": "1.0.2", + "postcss": "5.2.18" + } + }, + "yargs": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.3.3.tgz", + "integrity": "sha1-BU3oth8i7v23IHBZ6u+da4P7kxo=", + "dev": true + } + } + }, + "colormin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", + "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", + "dev": true, + "requires": { + "color": "0.11.4", + "css-color-names": "0.0.4", + "has": "1.0.1" + } + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "configstore": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.1.tgz", + "integrity": "sha512-5oNkD/L++l0O6xGXxb1EWS7SivtjfGQlRyxJsYgE0Z495/L81e2h4/d3r969hoPXuFItzNOKMtsXgYG4c7dYvw==", + "dev": true, + "requires": { + "dot-prop": "4.2.0", + "graceful-fs": "4.1.11", + "make-dir": "1.1.0", + "unique-string": "1.0.0", + "write-file-atomic": "2.3.0", + "xdg-basedir": "3.0.0" + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "convert-source-map": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", + "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", + "dev": true + }, + "core-js": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", + "dev": true, + "requires": { + "is-directory": "0.3.1", + "js-yaml": "3.7.0", + "minimist": "1.2.0", + "object-assign": "4.1.1", + "os-homedir": "1.0.2", + "parse-json": "2.2.0", + "require-from-string": "1.2.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "cp-file": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-3.2.0.tgz", + "integrity": "sha1-b4NhYlRiTwrViqSqjQdvAmvn4Yg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "nested-error-stacks": "1.0.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "readable-stream": "2.3.3" + } + }, + "cpy": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cpy/-/cpy-4.0.1.tgz", + "integrity": "sha1-tnJn66LzlgugalphrJQDNCKDNCQ=", + "dev": true, + "requires": { + "cp-file": "3.2.0", + "globby": "4.1.0", + "meow": "3.7.0", + "nested-error-stacks": "1.0.2", + "object-assign": "4.1.1", + "pinkie-promise": "2.0.1" + } + }, + "cpy-cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cpy-cli/-/cpy-cli-1.0.1.tgz", + "integrity": "sha1-Z/taSi3sKMqKv/N13kuecfanVhw=", + "dev": true, + "requires": { + "cpy": "4.0.1", + "meow": "3.7.0" + } + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "1.0.0" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "dev": true, + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "dev": true, + "requires": { + "hoek": "4.2.0" + } + } + } + }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, + "css-color-function": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/css-color-function/-/css-color-function-1.3.3.tgz", + "integrity": "sha1-jtJMLAIFBzM5+voAS8jBQfzLKC4=", + "dev": true, + "requires": { + "balanced-match": "0.1.0", + "color": "0.11.4", + "debug": "3.1.0", + "rgb": "0.1.0" + }, + "dependencies": { + "balanced-match": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.1.0.tgz", + "integrity": "sha1-tQS9BYabOSWd0MXvw12EMXbczEo=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "css-color-list": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/css-color-list/-/css-color-list-0.0.1.tgz", + "integrity": "sha1-hxjoaVrnosyHh76HFfHACKfyixU=", + "dev": true, + "requires": { + "css-color-names": "0.0.1" + }, + "dependencies": { + "css-color-names": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.1.tgz", + "integrity": "sha1-XQVI+iVkVu3kqaDCrHqxnT6xrYE=", + "dev": true + } + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "css-rule-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-rule-stream/-/css-rule-stream-1.1.0.tgz", + "integrity": "sha1-N4bnGYmD2WWibjGVfgkHjLt3BaI=", + "dev": true, + "requires": { + "css-tokenize": "1.0.1", + "duplexer2": "0.0.2", + "ldjson-stream": "1.2.1", + "through2": "0.6.5" + } + }, + "css-tokenize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-tokenize/-/css-tokenize-1.0.1.tgz", + "integrity": "sha1-RiXLHtohwUOFi3+B1oA8HSb8FL4=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "1.1.14" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "css-unit-converter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", + "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=", + "dev": true + }, + "cssnano": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "dev": true, + "requires": { + "autoprefixer": "6.7.7", + "decamelize": "1.2.0", + "defined": "1.0.0", + "has": "1.0.1", + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-calc": "5.3.1", + "postcss-colormin": "2.2.2", + "postcss-convert-values": "2.6.1", + "postcss-discard-comments": "2.0.4", + "postcss-discard-duplicates": "2.1.0", + "postcss-discard-empty": "2.1.0", + "postcss-discard-overridden": "0.1.1", + "postcss-discard-unused": "2.2.3", + "postcss-filter-plugins": "2.0.2", + "postcss-merge-idents": "2.1.7", + "postcss-merge-longhand": "2.0.2", + "postcss-merge-rules": "2.1.2", + "postcss-minify-font-values": "1.0.5", + "postcss-minify-gradients": "1.0.5", + "postcss-minify-params": "1.2.2", + "postcss-minify-selectors": "2.1.1", + "postcss-normalize-charset": "1.1.1", + "postcss-normalize-url": "3.0.8", + "postcss-ordered-values": "2.2.3", + "postcss-reduce-idents": "2.4.0", + "postcss-reduce-initial": "1.0.1", + "postcss-reduce-transforms": "1.0.4", + "postcss-svgo": "2.1.6", + "postcss-unique-selectors": "2.0.2", + "postcss-value-parser": "3.3.0", + "postcss-zindex": "2.2.0" + } + }, + "csso": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "dev": true, + "requires": { + "clap": "1.2.3", + "source-map": "0.5.7" + } + }, + "cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.2" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + } + } + }, + "del-cli": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/del-cli/-/del-cli-1.1.0.tgz", + "integrity": "sha1-J1V9aaC335ncuqHjSgnmrGWR0sQ=", + "dev": true, + "requires": { + "del": "3.0.0", + "meow": "3.7.0", + "update-notifier": "2.3.0" + }, + "dependencies": { + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "dev": true, + "requires": { + "globby": "6.1.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "p-map": "1.2.0", + "pify": "3.0.0", + "rimraf": "2.6.2" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "dependency-graph": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.5.1.tgz", + "integrity": "sha512-nk3OjiI68T3876/tsm4Hm57ye7zc4Kl87hkcALBMCuSrN1q1NvuY5HCnSSkoJjGdrMo5gmu0WTN2cV/D76q/mw==", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "diff": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", + "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", + "dev": true + }, + "doctrine": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", + "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + }, + "doiuse": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-2.6.0.tgz", + "integrity": "sha1-GJLRC2Gpo1at2/K2FJM+gfi7ODQ=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000744", + "css-rule-stream": "1.1.0", + "duplexer2": "0.0.2", + "jsonfilter": "1.1.2", + "ldjson-stream": "1.2.1", + "lodash": "4.17.4", + "multimatch": "2.1.0", + "postcss": "5.2.18", + "source-map": "0.4.4", + "through2": "0.6.5", + "yargs": "3.32.0" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, + "requires": { + "caniuse-db": "1.0.30000744", + "electron-to-chromium": "1.3.24" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "os-locale": "1.4.0", + "string-width": "1.0.2", + "window-size": "0.1.4", + "y18n": "3.2.1" + } + } + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "1.0.1" + } + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "editorconfig": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.13.3.tgz", + "integrity": "sha512-WkjsUNVCu+ITKDj73QDvi0trvpdDWdkDyHybDGSXPfekLCqwmpD7CP7iPbvBgosNuLcI96XTDwNa75JyFl7tEQ==", + "dev": true, + "requires": { + "bluebird": "3.5.1", + "commander": "2.11.0", + "lru-cache": "3.2.0", + "semver": "5.4.1", + "sigmund": "1.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz", + "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", + "dev": true, + "requires": { + "pseudomap": "1.0.2" + } + } + } + }, + "electron-to-chromium": { + "version": "1.3.24", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz", + "integrity": "sha1-m3uIuwXOufoBahd4M8wt3jiPIbY=", + "dev": true + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es-abstract": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.9.0.tgz", + "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==", + "dev": true, + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, + "es6-promise": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz", + "integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.14.0.tgz", + "integrity": "sha512-Ul6CSGRjKscEyg0X/EeNs7o2XdnbTEOD1OM8cTjmx85RPcBJQrEhZLevhuJZNAE/vS2iVl5Uhgiqf3h5uLMCJQ==", + "dev": true, + "requires": { + "ajv": "5.5.2", + "babel-code-frame": "6.26.0", + "chalk": "2.3.0", + "concat-stream": "1.6.0", + "cross-spawn": "5.1.0", + "debug": "3.1.0", + "doctrine": "2.0.2", + "eslint-scope": "3.7.1", + "eslint-visitor-keys": "1.0.0", + "espree": "3.5.2", + "esquery": "1.0.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.2", + "globals": "11.1.0", + "ignore": "3.3.5", + "imurmurhash": "0.1.4", + "inquirer": "3.3.0", + "is-resolvable": "1.0.1", + "js-yaml": "3.10.0", + "json-stable-stringify-without-jsonify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "7.0.0", + "progress": "2.0.0", + "require-uncached": "1.0.3", + "semver": "5.4.1", + "strip-ansi": "4.0.0", + "strip-json-comments": "2.0.1", + "table": "4.0.2", + "text-table": "0.2.0" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globals": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz", + "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "eslint-config-airbnb-base": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz", + "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==", + "dev": true, + "requires": { + "eslint-restricted-globals": "0.1.1" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", + "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", + "dev": true, + "requires": { + "debug": "2.6.9", + "resolve": "1.4.0" + } + }, + "eslint-module-utils": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", + "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", + "dev": true, + "requires": { + "debug": "2.6.9", + "pkg-dir": "1.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", + "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", + "dev": true, + "requires": { + "builtin-modules": "1.1.1", + "contains-path": "0.1.0", + "debug": "2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "0.3.1", + "eslint-module-utils": "2.1.1", + "has": "1.0.1", + "lodash.cond": "4.5.2", + "minimatch": "3.0.4", + "read-pkg-up": "2.0.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", + "dev": true + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", + "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "dev": true, + "requires": { + "acorn": "5.3.0", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "estree-walker": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz", + "integrity": "sha1-va/oCVOD2EFNXcLs9MkXO225QS4=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "dev": true, + "requires": { + "duplexer": "0.1.1", + "from": "0.1.7", + "map-stream": "0.1.0", + "pause-stream": "0.0.11", + "split": "0.3.3", + "stream-combiner": "0.0.4", + "through": "2.3.8" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "execall": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-1.0.0.tgz", + "integrity": "sha1-c9CQTjlbPKsGWLCNCewlMH8pu3M=", + "dev": true, + "requires": { + "clone-regexp": "1.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "external-editor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", + "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "dev": true, + "requires": { + "chardet": "0.4.2", + "iconv-lite": "0.4.19", + "tmp": "0.0.33" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "1.2.0" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, + "fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gather-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gather-stream/-/gather-stream-1.0.0.tgz", + "integrity": "sha1-szmUr0V6gRVwDUEPMXczy+egkEs=", + "dev": true + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + } + }, + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "global-dirs": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.0.tgz", + "integrity": "sha1-ENNAOeDfBCcuJizyQiT3IJQ0308=", + "dev": true, + "requires": { + "ini": "1.3.4" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", + "integrity": "sha1-CA9UVJ7BuCpsYOYx/ILhIR2+lfg=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "6.0.4", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "3.0.2", + "duplexer3": "0.1.4", + "get-stream": "3.0.0", + "is-redirect": "1.0.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "lowercase-keys": "1.0.0", + "safe-buffer": "5.1.1", + "timed-out": "4.0.1", + "unzip-response": "2.0.1", + "url-parse-lax": "1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "dev": true, + "requires": { + "ajv": "5.2.3", + "har-schema": "2.0.0" + } + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "hasha": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", + "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", + "dev": true, + "requires": { + "is-stream": "1.1.0", + "pinkie-promise": "2.0.1" + } + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "dev": true, + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.1.0" + } + }, + "hoek": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", + "dev": true + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "html-comment-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", + "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=", + "dev": true + }, + "html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", + "dev": true + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "ignore": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", + "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==", + "dev": true + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "3.0.0", + "chalk": "2.3.0", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.1.0", + "figures": "2.0.0", + "lodash": "4.17.4", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true, + "requires": { + "loose-envify": "1.3.1" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "irregular-plurals": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.3.0.tgz", + "integrity": "sha512-njf5A+Mxb3kojuHd1DzISjjIl+XhyzovXEOyPPSzdQozq/Lf2tN27mOrAAsxEPZxpn6I4MGzs1oo9TxXxPFpaA==", + "dev": true + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "1.10.0" + } + }, + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "0.1.0", + "is-path-inside": "1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "1.0.1" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "is-resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", + "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", + "dev": true + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-supported-regexp-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz", + "integrity": "sha1-i1IMhfrnolM4LUsCZS4EVXbhO7g=", + "dev": true + }, + "is-svg": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "dev": true, + "requires": { + "html-comment-regex": "1.1.1" + } + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isnumeric": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/isnumeric/-/isnumeric-0.2.0.tgz", + "integrity": "sha1-ojR7o2DeGeM9D/1ZD933dVy/LmQ=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "js-base64": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz", + "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "2.7.3" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz", + "integrity": "sha512-xyQpxeWWMKyJps9CuGJYeng6ssI5bpqS9ltQpdVQ90t4ql6NdnxFKh95JcRt2cun/DjMVNrdjniLPuMA69xmCw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsonfilter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/jsonfilter/-/jsonfilter-1.1.2.tgz", + "integrity": "sha1-Ie987cdRk4E8dZMulqmL4gW6WhE=", + "dev": true, + "requires": { + "JSONStream": "0.8.4", + "minimist": "1.2.0", + "stream-combiner": "0.2.2", + "through2": "0.6.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", + "dev": true, + "requires": { + "duplexer": "0.1.1", + "through": "2.3.8" + } + } + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonparse": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-0.0.5.tgz", + "integrity": "sha1-MwVCrT8KZUZlt3jz6y2an6UHrGQ=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kew": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "known-css-properties": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.2.0.tgz", + "integrity": "sha512-UTCzU28rRI9wkb8qSGoZa9pgWvxr4LjP2MEhi9XHb/1XMOJy0uTnIxaxzj8My/PORG+kQG6VzAcGvRw66eIOfA==", + "dev": true + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "4.0.1" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "ldjson-stream": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz", + "integrity": "sha1-kb7O2lrE7SsX5kn7d356v6AYnCs=", + "dev": true, + "requires": { + "split2": "0.2.1", + "through2": "0.6.5" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.templatesettings": "4.1.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0" + } + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "1.1.3" + } + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "requires": { + "js-tokens": "3.0.2" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "macaddress": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz", + "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=", + "dev": true + }, + "make-dir": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz", + "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==", + "dev": true, + "requires": { + "pify": "3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "dev": true + }, + "math-expression-evaluator": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", + "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", + "dev": true + }, + "mathml-tag-names": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.0.1.tgz", + "integrity": "sha1-jUEmgWi/htEQK5gQnijlMeejRXg=", + "dev": true + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "dev": true + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "dev": true, + "requires": { + "mime-db": "1.30.0" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-union": "1.0.2", + "arrify": "1.0.1", + "minimatch": "3.0.4" + } + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nested-error-stacks": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.2.tgz", + "integrity": "sha1-GfYZWRUZ8JZ2mlupqG5u7sgjw88=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "node-qunit-phantomjs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-qunit-phantomjs/-/node-qunit-phantomjs-2.0.0.tgz", + "integrity": "sha512-xZV0J8fBbe8h04IkBxLtwvGVbP0ViUhkJzjFx/tb7uWT02w6iMt5X6HDmdTZuQXBMsgahyaIGjW30l3HSlj2yA==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "minimist": "1.2.0", + "phantomjs-prebuilt": "2.1.16", + "qunit-phantomjs-runner": "2.3.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "qunit-phantomjs-runner": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/qunit-phantomjs-runner/-/qunit-phantomjs-runner-2.3.1.tgz", + "integrity": "sha512-RLg51606zm6/HwZi29NciAMAqifyJE1oGg77tEuk05vEa7kuqEaI0Mkjw976Ynnq7GXurATnbFd+471c024tBQ==", + "dev": true, + "requires": { + "qunit-reporter-junit": "1.1.1" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "dev": true + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "prepend-http": "1.0.4", + "query-string": "4.3.4", + "sort-keys": "1.1.2" + } + }, + "npm-run-all": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.2.tgz", + "integrity": "sha512-Z2aRlajMK4SQ8u19ZA75NZZu7wupfCNQWdYosIi8S6FgBdGf/8Y6Hgyjdc8zU2cYmIRVCx1nM80tJPkdEd+UYg==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "chalk": "2.3.0", + "cross-spawn": "5.1.0", + "memorystream": "0.3.1", + "minimatch": "3.0.4", + "ps-tree": "1.1.0", + "read-pkg": "3.0.0", + "shell-quote": "1.6.1", + "string.prototype.padend": "3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "4.0.0", + "pify": "3.0.0", + "strip-bom": "3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "1.3.1", + "json-parse-better-errors": "1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "4.0.0", + "normalize-package-data": "2.4.0", + "path-type": "3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "onecolor": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/onecolor/-/onecolor-3.0.4.tgz", + "integrity": "sha1-daRvgNpseqpbTarhekcZi9llJJQ=", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "ora": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-1.3.0.tgz", + "integrity": "sha1-gAeN0rkqk0r2ajrXKluRBpTt5Ro=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cli-cursor": "2.1.0", + "cli-spinners": "1.1.0", + "log-symbols": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.1.0" + } + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "6.7.1", + "registry-auth-token": "3.3.1", + "registry-url": "3.1.0", + "semver": "5.4.1" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "dev": true, + "requires": { + "through": "2.3.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "phantomjs-prebuilt": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", + "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", + "dev": true, + "requires": { + "es6-promise": "4.1.1", + "extract-zip": "1.6.6", + "fs-extra": "1.0.0", + "hasha": "2.2.0", + "kew": "0.7.0", + "progress": "1.1.8", + "request": "2.83.0", + "request-progress": "2.0.1", + "which": "1.3.0" + }, + "dependencies": { + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pipetteur": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pipetteur/-/pipetteur-2.0.3.tgz", + "integrity": "sha1-GVV2CVno0aEcsqUOyD7sRwYz5J8=", + "dev": true, + "requires": { + "onecolor": "3.0.4", + "synesthesia": "1.0.1" + } + }, + "pixrem": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pixrem/-/pixrem-4.0.1.tgz", + "integrity": "sha1-LaSh3m7EQjxfw3lOkwuB1EkOxoY=", + "dev": true, + "requires": { + "browserslist": "2.5.0", + "postcss": "6.0.13", + "reduce-css-calc": "1.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "requires": { + "find-up": "1.1.2" + } + }, + "pleeease-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pleeease-filters/-/pleeease-filters-4.0.0.tgz", + "integrity": "sha1-ZjKy+wVkjSdY2GU4T7zteeHMrsc=", + "dev": true, + "requires": { + "onecolor": "3.0.4", + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "plur": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", + "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", + "dev": true, + "requires": { + "irregular-plurals": "1.3.0" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + }, + "dependencies": { + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-apply": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/postcss-apply/-/postcss-apply-0.8.0.tgz", + "integrity": "sha1-FOVEu7XLbxweBIhXll15rgZrE0M=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "balanced-match": "0.4.2", + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-attribute-case-insensitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-2.0.0.tgz", + "integrity": "sha1-lNxCLI+QmX8WvTOjZUu77AhJY7Q=", + "dev": true, + "requires": { + "postcss": "6.0.13", + "postcss-selector-parser": "2.2.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-calc": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-message-helpers": "2.0.0", + "reduce-css-calc": "1.3.0" + } + }, + "postcss-cli": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-4.1.1.tgz", + "integrity": "sha1-uUvY//u3rB9i8mB+ePyTl/f2Ol0=", + "dev": true, + "requires": { + "chalk": "2.1.0", + "chokidar": "1.7.0", + "dependency-graph": "0.5.1", + "fs-extra": "4.0.2", + "get-stdin": "5.0.1", + "globby": "6.1.0", + "ora": "1.3.0", + "postcss": "6.0.13", + "postcss-load-config": "1.2.0", + "postcss-reporter": "5.0.0", + "pretty-hrtime": "1.0.3", + "read-cache": "1.0.0", + "yargs": "8.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "fs-extra": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz", + "integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "4.0.0", + "universalify": "0.1.1" + } + }, + "get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-function": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-function/-/postcss-color-function-4.0.0.tgz", + "integrity": "sha1-fgEG9Pah7LGtWzqFU6zl6Ciq4Yc=", + "dev": true, + "requires": { + "css-color-function": "1.3.3", + "postcss": "6.0.13", + "postcss-message-helpers": "2.0.0", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-gray": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-4.0.0.tgz", + "integrity": "sha1-aBvzBQl91mv+8OHmKC1dmbWsyV0=", + "dev": true, + "requires": { + "color": "1.0.3", + "postcss": "6.0.13", + "postcss-message-helpers": "2.0.0", + "reduce-function-call": "1.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz", + "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=", + "dev": true, + "requires": { + "color-convert": "1.9.0", + "color-string": "1.5.2" + } + }, + "color-string": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz", + "integrity": "sha1-JuRYFLw8mny9Z1FkikFDRRSnc6k=", + "dev": true, + "requires": { + "color-name": "1.1.3", + "simple-swizzle": "0.2.2" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-hex-alpha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-3.0.0.tgz", + "integrity": "sha1-HlPmyKyyN5Vej9CLfs2xuLgwn5U=", + "dev": true, + "requires": { + "color": "1.0.3", + "postcss": "6.0.13", + "postcss-message-helpers": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz", + "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=", + "dev": true, + "requires": { + "color-convert": "1.9.0", + "color-string": "1.5.2" + } + }, + "color-string": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz", + "integrity": "sha1-JuRYFLw8mny9Z1FkikFDRRSnc6k=", + "dev": true, + "requires": { + "color-name": "1.1.3", + "simple-swizzle": "0.2.2" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-hsl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hsl/-/postcss-color-hsl-2.0.0.tgz", + "integrity": "sha1-EnA2ZvoxBDDj8wpFTawThjF9WEQ=", + "dev": true, + "requires": { + "postcss": "6.0.13", + "postcss-value-parser": "3.3.0", + "units-css": "0.4.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-hwb": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hwb/-/postcss-color-hwb-3.0.0.tgz", + "integrity": "sha1-NAKxnvTYSXVAwftQcr6YY8qVVx4=", + "dev": true, + "requires": { + "color": "1.0.3", + "postcss": "6.0.13", + "postcss-message-helpers": "2.0.0", + "reduce-function-call": "1.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz", + "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=", + "dev": true, + "requires": { + "color-convert": "1.9.0", + "color-string": "1.5.2" + } + }, + "color-string": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz", + "integrity": "sha1-JuRYFLw8mny9Z1FkikFDRRSnc6k=", + "dev": true, + "requires": { + "color-name": "1.1.3", + "simple-swizzle": "0.2.2" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-rebeccapurple": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-3.0.0.tgz", + "integrity": "sha1-7rrwPTY7QwC5Z5K9MIHBntZlE9M=", + "dev": true, + "requires": { + "postcss": "6.0.13", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-rgb": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rgb/-/postcss-color-rgb-2.0.0.tgz", + "integrity": "sha1-FFOcinExSUtILg3RzCZf9lFLUmM=", + "dev": true, + "requires": { + "postcss": "6.0.13", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-rgba-fallback": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rgba-fallback/-/postcss-color-rgba-fallback-3.0.0.tgz", + "integrity": "sha1-N9XJNToHoJJwkSqCYGu0Kg1wLAQ=", + "dev": true, + "requires": { + "postcss": "6.0.13", + "postcss-value-parser": "3.3.0", + "rgb-hex": "2.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-colormin": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", + "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", + "dev": true, + "requires": { + "colormin": "1.1.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-convert-values": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", + "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-cssnext": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postcss-cssnext/-/postcss-cssnext-3.0.2.tgz", + "integrity": "sha512-jA6kGdcUMZqLUgw6MdpyNWGFhk0LIITVhC/jTnLRZLoXSTR88qT2cFOn3LbY06udt1PVdTCHDG3plBjxVKf8BQ==", + "dev": true, + "requires": { + "autoprefixer": "7.1.5", + "caniuse-api": "2.0.0", + "chalk": "2.1.0", + "pixrem": "4.0.1", + "pleeease-filters": "4.0.0", + "postcss": "6.0.13", + "postcss-apply": "0.8.0", + "postcss-attribute-case-insensitive": "2.0.0", + "postcss-calc": "6.0.0", + "postcss-color-function": "4.0.0", + "postcss-color-gray": "4.0.0", + "postcss-color-hex-alpha": "3.0.0", + "postcss-color-hsl": "2.0.0", + "postcss-color-hwb": "3.0.0", + "postcss-color-rebeccapurple": "3.0.0", + "postcss-color-rgb": "2.0.0", + "postcss-color-rgba-fallback": "3.0.0", + "postcss-custom-media": "6.0.0", + "postcss-custom-properties": "6.2.0", + "postcss-custom-selectors": "4.0.1", + "postcss-font-family-system-ui": "2.0.1", + "postcss-font-variant": "3.0.0", + "postcss-image-set-polyfill": "0.3.5", + "postcss-initial": "2.0.0", + "postcss-media-minmax": "3.0.0", + "postcss-nesting": "4.2.1", + "postcss-pseudo-class-any-link": "4.0.0", + "postcss-pseudoelements": "5.0.0", + "postcss-replace-overflow-wrap": "2.0.0", + "postcss-selector-matches": "3.0.1", + "postcss-selector-not": "3.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "autoprefixer": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.1.5.tgz", + "integrity": "sha512-sMN453qIm8Z+tunzYWW+Y490wWkICHhCYm/VohLjjl+N7ARSFuF5au7E6tr7oEbeeXj8mNjpSw2kxjJaO6YCOw==", + "dev": true, + "requires": { + "browserslist": "2.5.0", + "caniuse-lite": "1.0.30000744", + "normalize-range": "0.1.2", + "num2fraction": "1.2.2", + "postcss": "6.0.13", + "postcss-value-parser": "3.3.0" + } + }, + "caniuse-api": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-2.0.0.tgz", + "integrity": "sha1-sd21pZZrFvSNxJmERNS7xsfZ2DQ=", + "dev": true, + "requires": { + "browserslist": "2.5.0", + "caniuse-lite": "1.0.30000744", + "lodash.memoize": "4.1.2", + "lodash.uniq": "4.5.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "postcss-calc": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-6.0.0.tgz", + "integrity": "sha1-toGyecbST74OM+2QRYA3BURdYTs=", + "dev": true, + "requires": { + "css-unit-converter": "1.1.1", + "postcss": "6.0.13", + "postcss-selector-parser": "2.2.3", + "reduce-css-calc": "2.0.5" + } + }, + "reduce-css-calc": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.0.5.tgz", + "integrity": "sha1-M8l4OMXUxxGlwU74XOT95BSD970=", + "dev": true, + "requires": { + "css-unit-converter": "1.1.1", + "postcss-value-parser": "3.3.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-custom-media": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-6.0.0.tgz", + "integrity": "sha1-vlMnhBEOyylQRPtTlaGABushpzc=", + "dev": true, + "requires": { + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-custom-properties": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-6.2.0.tgz", + "integrity": "sha512-eNR2h9T9ciKMoQEORrPjH33XeN/nuvVuxArOKmHtsFbGbNss631tgTrKou3/pmjAZbA4QQkhLIkPQkIk3WW+8w==", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-custom-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-4.0.1.tgz", + "integrity": "sha1-eBOC+UxS5yfvXKR3bqKt9JphE4I=", + "dev": true, + "requires": { + "postcss": "6.0.13", + "postcss-selector-matches": "3.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-discard-comments": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-duplicates": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", + "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-empty": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-overridden": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-unused": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "uniqs": "2.0.0" + } + }, + "postcss-filter-plugins": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz", + "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "uniqid": "4.1.1" + } + }, + "postcss-font-family-system-ui": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-font-family-system-ui/-/postcss-font-family-system-ui-2.0.1.tgz", + "integrity": "sha1-MYoHX9y4S4ZKqCOlGTXvClhy6RE=", + "dev": true, + "requires": { + "lodash": "4.17.4", + "postcss": "6.0.13", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-font-variant": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-3.0.0.tgz", + "integrity": "sha1-CMzIj2BQuoLtjvLMdsDGprQfGD4=", + "dev": true, + "requires": { + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-header": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postcss-header/-/postcss-header-1.0.0.tgz", + "integrity": "sha512-YUcU2oHQNsNVUDPdQg6/TXBWvI7dBGf2bsLQdVlLiLM5kiGLGCcszYDlVTaicmXpKANdS1T7bxpJtCacrMButw==", + "dev": true, + "requires": { + "babel-register": "6.26.0", + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-image-set-polyfill": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/postcss-image-set-polyfill/-/postcss-image-set-polyfill-0.3.5.tgz", + "integrity": "sha1-Dxk0E3AM8fgr05Bm7wFtZaShgYE=", + "dev": true, + "requires": { + "postcss": "6.0.13", + "postcss-media-query-parser": "0.2.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-initial": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-2.0.0.tgz", + "integrity": "sha1-cnFfczbgu3k1HZnuZcSiU6hEG6Q=", + "dev": true, + "requires": { + "lodash.template": "4.4.0", + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-less": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-0.14.0.tgz", + "integrity": "sha1-xjGwicbM5CK5oQ86lY0r7dOBkyQ=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-load-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz", + "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1", + "postcss-load-options": "1.2.0", + "postcss-load-plugins": "2.3.0" + } + }, + "postcss-load-options": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz", + "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1" + } + }, + "postcss-load-plugins": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz", + "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1" + } + }, + "postcss-media-minmax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-3.0.0.tgz", + "integrity": "sha1-Z1JWA3pD70C8Twdgv9BtTcadSNI=", + "dev": true, + "requires": { + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "postcss-merge-idents": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", + "dev": true, + "requires": { + "has": "1.0.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-merge-longhand": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", + "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-merge-rules": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", + "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-api": "1.6.1", + "postcss": "5.2.18", + "postcss-selector-parser": "2.2.3", + "vendors": "1.0.1" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, + "requires": { + "caniuse-db": "1.0.30000744", + "electron-to-chromium": "1.3.24" + } + } + } + }, + "postcss-message-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=", + "dev": true + }, + "postcss-minify-font-values": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-minify-gradients": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-minify-params": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0", + "uniqs": "2.0.0" + } + }, + "postcss-minify-selectors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "has": "1.0.1", + "postcss": "5.2.18", + "postcss-selector-parser": "2.2.3" + } + }, + "postcss-nesting": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-4.2.1.tgz", + "integrity": "sha512-IkyWXICwagCnlaviRexi7qOdwPw3+xVVjgFfGsxmztvRVaNxAlrypOIKqDE5mxY+BVxnId1rnUKBRQoNE2VDaA==", + "dev": true, + "requires": { + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-normalize-charset": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-normalize-url": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", + "dev": true, + "requires": { + "is-absolute-url": "2.1.0", + "normalize-url": "1.9.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-ordered-values": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", + "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-pseudo-class-any-link": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-4.0.0.tgz", + "integrity": "sha1-kVKgYT00UHIFE+iJKFS65C0O5o4=", + "dev": true, + "requires": { + "postcss": "6.0.13", + "postcss-selector-parser": "2.2.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-pseudoelements": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-pseudoelements/-/postcss-pseudoelements-5.0.0.tgz", + "integrity": "sha1-7vGU6NUkZFylIKlJ6V5RjoEkAss=", + "dev": true, + "requires": { + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-reduce-idents": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-reduce-initial": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-reduce-transforms": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", + "dev": true, + "requires": { + "has": "1.0.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-replace-overflow-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-2.0.0.tgz", + "integrity": "sha1-eU22+qVPjbEAhUOSqTr0V2i04ls=", + "dev": true, + "requires": { + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-reporter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-5.0.0.tgz", + "integrity": "sha512-rBkDbaHAu5uywbCR2XE8a25tats3xSOsGNx6mppK6Q9kSFGKc/FyAzfci+fWM2l+K402p1D0pNcfDGxeje5IKg==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "lodash": "4.17.4", + "log-symbols": "2.1.0", + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "log-symbols": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.1.0.tgz", + "integrity": "sha512-zLeLrzMA1A2vRF1e/0Mo+LNINzi6jzBylHj5WqvQ/WK/5WCZt8si9SyN4p9llr/HRYvVR1AoXHRHl4WTHyQAzQ==", + "dev": true, + "requires": { + "chalk": "2.1.0" + } + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "dev": true + }, + "postcss-scss": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-1.0.2.tgz", + "integrity": "sha1-/0XPM1S4ee6JpOtoaA9GrJuxT5Q=", + "dev": true, + "requires": { + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-selector-matches": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-3.0.1.tgz", + "integrity": "sha1-5WNAEeE5UIgYYbvdWMLQER/8lqs=", + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-selector-not": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-3.0.1.tgz", + "integrity": "sha1-Lk2y8JZTNsAefOx9tsYN/3ZzNdk=", + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "postcss": "6.0.13" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, + "requires": { + "flatten": "1.0.2", + "indexes-of": "1.0.1", + "uniq": "1.0.1" + } + }, + "postcss-sorting": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-2.1.0.tgz", + "integrity": "sha1-MrHpr6kTuyJaatB21QPY+YO7SoI=", + "dev": true, + "requires": { + "lodash": "4.17.4", + "postcss": "5.2.18" + } + }, + "postcss-svgo": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "dev": true, + "requires": { + "is-svg": "2.1.0", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0", + "svgo": "0.7.2" + } + }, + "postcss-unique-selectors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "postcss": "5.2.18", + "uniqs": "2.0.0" + } + }, + "postcss-url": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.0.tgz", + "integrity": "sha512-VBP6uf6iL3AZra23nkPkOEkS/5azj1xf/toRrjfkolfFEgg9Gyzg9UhJZeIsz12EGKZTNVeGbPa2XtaZm/iZvg==", + "dev": true, + "requires": { + "mime": "1.4.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "postcss": "6.0.14", + "xxhashjs": "0.2.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", + "dev": true + }, + "postcss-zindex": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", + "dev": true, + "requires": { + "has": "1.0.1", + "postcss": "5.2.18", + "uniqs": "2.0.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true + }, + "private": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", + "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + }, + "ps-tree": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz", + "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=", + "dev": true, + "requires": { + "event-stream": "3.3.4" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "q": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", + "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", + "dev": true + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "strict-uri-encode": "1.1.0" + } + }, + "qunit-reporter-junit": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/qunit-reporter-junit/-/qunit-reporter-junit-1.1.1.tgz", + "integrity": "sha1-7rYiZFeJaZPnlaEZQPGK9q+lebQ=", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "rc": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", + "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", + "dev": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "read-file-stdin": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/read-file-stdin/-/read-file-stdin-0.2.1.tgz", + "integrity": "sha1-JezP86FTtoCa+ssj7hU4fbng7mE=", + "dev": true, + "requires": { + "gather-stream": "1.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.3", + "set-immediate-shim": "1.0.1" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "reduce-css-calc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "math-expression-evaluator": "1.2.17", + "reduce-function-call": "1.0.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + } + } + }, + "reduce-function-call": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", + "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "dev": true, + "requires": { + "balanced-match": "0.4.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + } + } + }, + "regenerate": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", + "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==", + "dev": true + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "private": "0.1.7" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "1.3.3", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + }, + "registry-auth-token": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", + "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", + "dev": true, + "requires": { + "rc": "1.2.2", + "safe-buffer": "5.1.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "1.2.2" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "request": { + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "dev": true, + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + } + }, + "request-progress": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", + "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", + "dev": true, + "requires": { + "throttleit": "1.0.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", + "dev": true + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "resolve": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", + "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "rgb": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/rgb/-/rgb-0.1.0.tgz", + "integrity": "sha1-vieykej+/+rBvZlylyG/pA/AN7U=", + "dev": true + }, + "rgb-hex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rgb-hex/-/rgb-hex-2.1.0.tgz", + "integrity": "sha1-x3PF/iJoolV42SU5qCp6XOU77aY=", + "dev": true + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "rollup": { + "version": "0.53.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.53.3.tgz", + "integrity": "sha512-MADFV0jpoh1QDB6U0U6YamGihGetxHEYgwTcGsc7map6JFIydPEfGNshK+ozxv1RKeUOQKn1vRb85IAcdjL22Q==", + "dev": true + }, + "rollup-plugin-babel": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-3.0.3.tgz", + "integrity": "sha512-5kzM/Rr4jQSRPLc2eN5NuD+CI/6AAy7S1O18Ogu4U3nq1Q42VJn0C9EMtqnvxtfwf1XrezOtdA9ro1VZI5B0mA==", + "dev": true, + "requires": { + "rollup-pluginutils": "1.5.2" + } + }, + "rollup-pluginutils": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz", + "integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=", + "dev": true, + "requires": { + "estree-walker": "0.2.1", + "minimatch": "3.0.4" + } + }, + "rollup-watch": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/rollup-watch/-/rollup-watch-4.3.1.tgz", + "integrity": "sha512-6yjnIwfjpSrqA8IafyIu7fsEyeImNR4aDjA1bQ7KWeVuiA+Clfsx8+PGQkyABWIQzmauQ//tIJ5wAxLXsXs8qQ==", + "dev": true, + "requires": { + "chokidar": "1.7.0", + "require-relative": "0.8.7", + "rollup-pluginutils": "2.0.1" + }, + "dependencies": { + "estree-walker": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.3.1.tgz", + "integrity": "sha1-5rGlHPcpJSTnI3wxLl/mZgwc4ao=", + "dev": true + }, + "rollup-pluginutils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz", + "integrity": "sha1-fslbNXP2VDpGpkYb2afFRFJdD8A=", + "dev": true, + "requires": { + "estree-walker": "0.3.1", + "micromatch": "2.3.11" + } + } + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "4.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "5.4.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "dev": true, + "requires": { + "array-filter": "0.0.1", + "array-map": "0.0.0", + "array-reduce": "0.0.0", + "jsonify": "0.0.0" + } + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "requires": { + "is-arrayish": "0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.1.tgz", + "integrity": "sha1-wt/DhquqDD4zxI2z/ocFnmkGXv0=", + "dev": true + } + } + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0" + } + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "dev": true, + "requires": { + "hoek": "4.2.0" + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "requires": { + "is-plain-obj": "1.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "specificity": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.3.2.tgz", + "integrity": "sha512-Nc/QN/A425Qog7j9aHmwOrlwX2e7pNI47ciwxwy4jOlvbbMHkNNJchit+FX+UjF3IAdiaaV5BKeWuDUnws6G1A==", + "dev": true + }, + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "dev": true, + "requires": { + "through": "2.3.8" + } + }, + "split2": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", + "integrity": "sha1-At2smtwD7Au3jBKC7Aecpuha6QA=", + "dev": true, + "requires": { + "through2": "0.6.5" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "dev": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + } + }, + "stdin": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/stdin/-/stdin-0.0.1.tgz", + "integrity": "sha1-0wQZgarsPf28d6GzjWNy449ftx4=", + "dev": true + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "dev": true, + "requires": { + "duplexer": "0.1.1" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "string.prototype.padend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", + "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.9.0", + "function-bind": "1.1.1" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "stylefmt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/stylefmt/-/stylefmt-6.0.0.tgz", + "integrity": "sha1-yFHpwteLiplQL3S6PYY7MBY+7JM=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "css-color-list": "0.0.1", + "diff": "3.4.0", + "editorconfig": "0.13.3", + "globby": "6.1.0", + "minimist": "1.2.0", + "postcss": "6.0.13", + "postcss-scss": "1.0.2", + "postcss-sorting": "2.1.0", + "postcss-value-parser": "3.3.0", + "stdin": "0.0.1", + "stylelint": "7.13.0", + "stylelint-order": "0.4.4" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "postcss": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "source-map": "0.6.1", + "supports-color": "4.4.0" + }, + "dependencies": { + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "stylehacks": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-2.3.2.tgz", + "integrity": "sha1-ZMg+BDimjJ7fRJ6MVSp9mrYAmws=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "chalk": "1.1.3", + "log-symbols": "1.0.2", + "minimist": "1.2.0", + "plur": "2.1.2", + "postcss": "5.2.18", + "postcss-reporter": "1.4.1", + "postcss-selector-parser": "2.2.3", + "read-file-stdin": "0.2.1", + "text-table": "0.2.0", + "write-file-stdout": "0.0.2" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, + "requires": { + "caniuse-db": "1.0.30000744", + "electron-to-chromium": "1.3.24" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "postcss-reporter": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-1.4.1.tgz", + "integrity": "sha1-wTbwpbFhkV83ndN2XGEHX357mvI=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "lodash": "4.17.4", + "log-symbols": "1.0.2", + "postcss": "5.2.18" + } + } + } + }, + "stylelint": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-7.13.0.tgz", + "integrity": "sha1-ER+Xttpy53XICADWu29fhpmXeF0=", + "dev": true, + "requires": { + "autoprefixer": "6.7.7", + "balanced-match": "0.4.2", + "chalk": "2.1.0", + "colorguard": "1.2.0", + "cosmiconfig": "2.2.2", + "debug": "2.6.9", + "doiuse": "2.6.0", + "execall": "1.0.0", + "file-entry-cache": "2.0.0", + "get-stdin": "5.0.1", + "globby": "6.1.0", + "globjoin": "0.1.4", + "html-tags": "2.0.0", + "ignore": "3.3.5", + "imurmurhash": "0.1.4", + "known-css-properties": "0.2.0", + "lodash": "4.17.4", + "log-symbols": "1.0.2", + "mathml-tag-names": "2.0.1", + "meow": "3.7.0", + "micromatch": "2.3.11", + "normalize-selector": "0.2.0", + "pify": "2.3.0", + "postcss": "5.2.18", + "postcss-less": "0.14.0", + "postcss-media-query-parser": "0.2.3", + "postcss-reporter": "3.0.0", + "postcss-resolve-nested-selector": "0.1.1", + "postcss-scss": "0.4.1", + "postcss-selector-parser": "2.2.3", + "postcss-value-parser": "3.3.0", + "resolve-from": "3.0.0", + "specificity": "0.3.2", + "string-width": "2.1.1", + "style-search": "0.1.0", + "stylehacks": "2.3.2", + "sugarss": "0.2.0", + "svg-tags": "1.0.0", + "table": "4.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss-reporter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-3.0.0.tgz", + "integrity": "sha1-CeoPN6RExWk4eGBuCbAY6+/3z48=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "lodash": "4.17.4", + "log-symbols": "1.0.2", + "postcss": "5.2.18" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "postcss-scss": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-0.4.1.tgz", + "integrity": "sha1-rXcbgfD3L19IRdCKpg+TVXZT1Uw=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "stylelint-order": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-0.4.4.tgz", + "integrity": "sha1-2338oFQbUGIBDH4uIedFeR/AiKw=", + "dev": true, + "requires": { + "lodash": "4.17.4", + "postcss": "5.2.18", + "stylelint": "7.13.0" + } + }, + "sugarss": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-0.2.0.tgz", + "integrity": "sha1-rDQjdWMyfG/4l7ZHQr9q7BkK054=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "svgo": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", + "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "dev": true, + "requires": { + "coa": "1.0.4", + "colors": "1.1.2", + "csso": "2.3.2", + "js-yaml": "3.7.0", + "mkdirp": "0.5.1", + "sax": "1.2.4", + "whet.extend": "0.9.9" + } + }, + "synesthesia": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/synesthesia/-/synesthesia-1.0.1.tgz", + "integrity": "sha1-XvlepUjA1cbm+btLDQcx3/hkp3c=", + "dev": true, + "requires": { + "css-color-names": "0.0.3" + }, + "dependencies": { + "css-color-names": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.3.tgz", + "integrity": "sha1-3gzvFvTYqoIioyDVttfpu62nufY=", + "dev": true + } + } + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "5.2.3", + "ajv-keywords": "2.1.0", + "chalk": "2.1.0", + "lodash": "4.17.4", + "slice-ansi": "1.0.0", + "string-width": "2.1.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "0.7.0" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "dev": true, + "requires": { + "punycode": "1.4.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.4.tgz", + "integrity": "sha512-hfIwuAQI5dlXP30UtdmWoYF9k+ypVqBXIdmd6ZKBiaNHHvA8ty7ZloMe3+7S5AEKVkxHbjByl4DfRHQ7QpZquw==", + "dev": true, + "requires": { + "commander": "2.12.2", + "source-map": "0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqid": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz", + "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=", + "dev": true, + "requires": { + "macaddress": "0.2.8" + } + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "1.0.0" + } + }, + "units-css": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/units-css/-/units-css-0.4.0.tgz", + "integrity": "sha1-1iKGU6UZg9fBb/KPi53Dsf/tOgc=", + "dev": true, + "requires": { + "isnumeric": "0.2.0", + "viewport-dimensions": "0.2.0" + } + }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", + "dev": true + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "update-notifier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.3.0.tgz", + "integrity": "sha1-TognpruRUUCrCTVZ1wFOPruDdFE=", + "dev": true, + "requires": { + "boxen": "1.2.2", + "chalk": "2.3.0", + "configstore": "3.1.1", + "import-lazy": "2.1.0", + "is-installed-globally": "0.1.0", + "is-npm": "1.0.0", + "latest-version": "3.1.0", + "semver-diff": "2.1.0", + "xdg-basedir": "3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "1.0.4" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "vendors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz", + "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + } + }, + "viewport-dimensions": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/viewport-dimensions/-/viewport-dimensions-0.2.0.tgz", + "integrity": "sha1-3nQHR9tTh/0XJfUXXpG6x2r982w=", + "dev": true + }, + "whet.extend": { + "version": "0.9.9", + "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", + "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=", + "dev": true + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "widest-line": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", + "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", + "dev": true, + "requires": { + "string-width": "1.0.2" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "write-file-atomic": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "signal-exit": "3.0.2" + } + }, + "write-file-stdout": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/write-file-stdout/-/write-file-stdout-0.0.2.tgz", + "integrity": "sha1-wlLXx8WxtAKJdjDjRTx7/mkNnKE=", + "dev": true + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "xxhashjs": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.1.tgz", + "integrity": "sha1-m76b6JYUKXbfo0wGGy0GjEPTDeA=", + "dev": true, + "requires": { + "cuint": "0.2.2" + } + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "requires": { + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "1.0.1" + } + } + } +} diff --git a/library/cropperjs/package.json b/library/cropperjs/package.json new file mode 100644 index 000000000..f94100981 --- /dev/null +++ b/library/cropperjs/package.json @@ -0,0 +1,76 @@ +{ + "name": "cropperjs", + "description": "JavaScript image cropper.", + "version": "1.2.2", + "main": "dist/cropper.common.js", + "module": "dist/cropper.esm.js", + "browser": "dist/cropper.js", + "style": "dist/cropper.css", + "repository": "fengyuanchen/cropperjs", + "homepage": "https://fengyuanchen.github.io/cropperjs", + "license": "MIT", + "author": { + "name": "Chen Fengyuan", + "url": "http://chenfengyuan.com" + }, + "files": [ + "src", + "dist" + ], + "keywords": [ + "image", + "crop", + "cropping", + "move", + "zoom", + "rotate", + "scale", + "cropper", + "cropperjs", + "cropper.js", + "html", + "css", + "javascript", + "front-end", + "web", + "development" + ], + "scripts": { + "build": "npm run build:css && npm run build:js", + "build:css": "postcss src/css/cropper.css -o dist/cropper.css --no-map", + "build:js": "rollup -c", + "clear": "del-cli dist", + "compress": "npm run compress:css && npm run compress:js", + "compress:css": "postcss dist/cropper.css -u cssnano -o dist/cropper.min.css --no-map", + "compress:js": "uglifyjs dist/cropper.js -o dist/cropper.min.js -c -m --comments /^!/", + "copy": "cpy dist/cropper.css docs/css", + "lint": "eslint src/js --fix", + "release": "npm run clear && npm run lint && npm run build && npm run compress && npm run copy && npm test", + "start": "npm-run-all --parallel watch:*", + "test": "node-qunit-phantomjs test/index.html --timeout 10", + "watch:css": "postcss src/css/cropper.css -o docs/css/cropper.css -m -w", + "watch:js": "rollup -c -m -w" + }, + "devDependencies": { + "babel-core": "^6.26.0", + "babel-plugin-external-helpers": "^6.22.0", + "babel-preset-env": "^1.6.1", + "cpy-cli": "^1.0.1", + "cssnano": "^3.10.0", + "del-cli": "^1.1.0", + "eslint": "^4.14.0", + "eslint-config-airbnb-base": "^12.1.0", + "eslint-plugin-import": "^2.8.0", + "node-qunit-phantomjs": "^2.0.0", + "npm-run-all": "^4.1.2", + "postcss-cli": "^4.1.1", + "postcss-cssnext": "^3.0.2", + "postcss-header": "^1.0.0", + "postcss-url": "^7.3.0", + "rollup": "^0.53.3", + "rollup-plugin-babel": "^3.0.3", + "rollup-watch": "^4.3.1", + "stylefmt": "^6.0.0", + "uglify-js": "^3.3.4" + } +} diff --git a/library/cropperjs/postcss.config.js b/library/cropperjs/postcss.config.js new file mode 100644 index 000000000..af7ec6024 --- /dev/null +++ b/library/cropperjs/postcss.config.js @@ -0,0 +1,14 @@ +const rollupConfig = require('./rollup.config'); + +module.exports = { + plugins: { + 'postcss-cssnext': {}, + 'postcss-url': { + url: 'inline', + }, + 'postcss-header': { + header: rollupConfig.banner, + }, + stylefmt: {}, + }, +}; diff --git a/library/cropperjs/rollup.config.js b/library/cropperjs/rollup.config.js new file mode 100644 index 000000000..b792a79a7 --- /dev/null +++ b/library/cropperjs/rollup.config.js @@ -0,0 +1,50 @@ +const babel = require('rollup-plugin-babel'); +const pkg = require('./package'); + +const now = new Date(); +const banner = `/*! + * Cropper.js v${pkg.version} + * https://github.com/${pkg.repository} + * + * Copyright (c) 2015-${now.getFullYear()} ${pkg.author.name} + * Released under the ${pkg.license} license + * + * Date: ${now.toISOString()} + */ +`; + +module.exports = { + // Export banner for PostCSS + banner, + input: 'src/js/cropper.js', + output: [ + { + banner, + file: 'dist/cropper.js', + format: 'umd', + name: 'Cropper', + }, + { + banner, + file: 'dist/cropper.common.js', + format: 'cjs', + }, + { + banner, + file: 'dist/cropper.esm.js', + format: 'es', + }, + { + banner, + file: 'docs/js/cropper.js', + format: 'umd', + name: 'Cropper', + }, + ], + plugins: [ + babel({ + exclude: 'node_modules/**', + plugins: ['external-helpers'], + }), + ], +}; diff --git a/library/cropperjs/src/css/cropper.css b/library/cropperjs/src/css/cropper.css new file mode 100644 index 000000000..d09c4f182 --- /dev/null +++ b/library/cropperjs/src/css/cropper.css @@ -0,0 +1,290 @@ +:root { + --blue: #39f; +} + +.cropper-container { + direction: ltr; + font-size: 0; + line-height: 0; + position: relative; + touch-action: none; + user-select: none; + + & img { + /* Avoid margin top issue (Occur only when margin-top <= -height) */ + display: block; + height: 100%; + image-orientation: 0deg; + max-height: none !important; + max-width: none !important; + min-height: 0 !important; + min-width: 0 !important; + width: 100%; + } +} + +.cropper-wrap-box, +.cropper-canvas, +.cropper-drag-box, +.cropper-crop-box, +.cropper-modal { + bottom: 0; + left: 0; + position: absolute; + right: 0; + top: 0; +} + +.cropper-wrap-box, +.cropper-canvas { + overflow: hidden; +} + +.cropper-drag-box { + background-color: #fff; + opacity: 0; +} + +.cropper-modal { + background-color: #000; + opacity: .5; +} + +.cropper-view-box { + display: block; + height: 100%; + outline-color: color(var(--blue) alpha(75%)); + outline: 1px solid var(--blue); + overflow: hidden; + width: 100%; +} + +.cropper-dashed { + border: 0 dashed #eee; + display: block; + opacity: .5; + position: absolute; + + &.dashed-h { + border-bottom-width: 1px; + border-top-width: 1px; + height: calc(100 / 3)%; + left: 0; + top: calc(100 / 3)%; + width: 100%; + } + + &.dashed-v { + border-left-width: 1px; + border-right-width: 1px; + height: 100%; + left: calc(100 / 3)%; + top: 0; + width: calc(100 / 3)%; + } +} + +.cropper-center { + display: block; + height: 0; + left: 50%; + opacity: .75; + position: absolute; + top: 50%; + width: 0; + + &:before, + &:after { + background-color: #eee; + content: ' '; + display: block; + position: absolute; + } + + &:before { + height: 1px; + left: -3px; + top: 0; + width: 7px; + } + + &:after { + height: 7px; + left: 0; + top: -3px; + width: 1px; + } +} + +.cropper-face, +.cropper-line, +.cropper-point { + display: block; + height: 100%; + opacity: .1; + position: absolute; + width: 100%; +} + +.cropper-face { + background-color: #fff; + left: 0; + top: 0; +} + +.cropper-line { + background-color: var(--blue); + + &.line-e { + cursor: ew-resize; + right: -3px; + top: 0; + width: 5px; + } + + &.line-n { + cursor: ns-resize; + height: 5px; + left: 0; + top: -3px; + } + + &.line-w { + cursor: ew-resize; + left: -3px; + top: 0; + width: 5px; + } + + &.line-s { + bottom: -3px; + cursor: ns-resize; + height: 5px; + left: 0; + } +} + +.cropper-point { + background-color: var(--blue); + height: 5px; + opacity: .75; + width: 5px; + + &.point-e { + cursor: ew-resize; + margin-top: -3px; + right: -3px; + top: 50%; + } + + &.point-n { + cursor: ns-resize; + left: 50%; + margin-left: -3px; + top: -3px; + } + + &.point-w { + cursor: ew-resize; + left: -3px; + margin-top: -3px; + top: 50%; + } + + &.point-s { + bottom: -3px; + cursor: s-resize; + left: 50%; + margin-left: -3px; + } + + &.point-ne { + cursor: nesw-resize; + right: -3px; + top: -3px; + } + + &.point-nw { + cursor: nwse-resize; + left: -3px; + top: -3px; + } + + &.point-sw { + bottom: -3px; + cursor: nesw-resize; + left: -3px; + } + + &.point-se { + bottom: -3px; + cursor: nwse-resize; + height: 20px; + opacity: 1; + right: -3px; + width: 20px; + + @media (min-width: 768px) { + height: 15px; + width: 15px; + } + + @media (min-width: 992px) { + height: 10px; + width: 10px; + } + + @media (min-width: 1200px) { + height: 5px; + opacity: .75; + width: 5px; + } + } + + &.point-se:before { + background-color: var(--blue); + bottom: -50%; + content: ' '; + display: block; + height: 200%; + opacity: 0; + position: absolute; + right: -50%; + width: 200%; + } +} + +.cropper-invisible { + opacity: 0; +} + +.cropper-bg { + background-image: url('../images/bg.png'); +} + +.cropper-hide { + display: block; + height: 0; + position: absolute; + width: 0; +} + +.cropper-hidden { + display: none !important; +} + +.cropper-move { + cursor: move; +} + +.cropper-crop { + cursor: crosshair; +} + +.cropper-disabled .cropper-drag-box, +.cropper-disabled .cropper-face, +.cropper-disabled .cropper-line, +.cropper-disabled .cropper-point { + cursor: not-allowed; +} + diff --git a/library/cropperjs/src/images/bg.png b/library/cropperjs/src/images/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..3c7056b1940609526bd3091a82fb3b5af37a16cd GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;bFq_W2nPqp?T7vkfLyi!pAgqG zXU_cp|NnBYXcbP0 Hl+XkKKtwUY literal 0 HcmV?d00001 diff --git a/library/cropperjs/src/js/change.js b/library/cropperjs/src/js/change.js new file mode 100644 index 000000000..014222ef0 --- /dev/null +++ b/library/cropperjs/src/js/change.js @@ -0,0 +1,471 @@ +import { + ACTION_ALL, + ACTION_CROP, + ACTION_EAST, + ACTION_MOVE, + ACTION_NORTH, + ACTION_NORTH_EAST, + ACTION_NORTH_WEST, + ACTION_SOUTH, + ACTION_SOUTH_EAST, + ACTION_SOUTH_WEST, + ACTION_WEST, + ACTION_ZOOM, + CLASS_HIDDEN, +} from './constants'; +import { + each, + getMaxZoomRatio, + getOffset, + removeClass, +} from './utilities'; + +export default { + change(e) { + const { + options, + canvasData, + containerData, + cropBoxData, + pointers, + } = this; + let { action } = this; + let { aspectRatio } = options; + let { + left, + top, + width, + height, + } = cropBoxData; + const right = left + width; + const bottom = top + height; + let minLeft = 0; + let minTop = 0; + let maxWidth = containerData.width; + let maxHeight = containerData.height; + let renderable = true; + let offset; + + // Locking aspect ratio in "free mode" by holding shift key + if (!aspectRatio && e.shiftKey) { + aspectRatio = width && height ? width / height : 1; + } + + if (this.limited) { + ({ minLeft, minTop } = cropBoxData); + maxWidth = minLeft + Math.min( + containerData.width, + canvasData.width, + canvasData.left + canvasData.width, + ); + maxHeight = minTop + Math.min( + containerData.height, + canvasData.height, + canvasData.top + canvasData.height, + ); + } + + const pointer = pointers[Object.keys(pointers)[0]]; + const range = { + x: pointer.endX - pointer.startX, + y: pointer.endY - pointer.startY, + }; + const check = (side) => { + switch (side) { + case ACTION_EAST: + if (right + range.x > maxWidth) { + range.x = maxWidth - right; + } + + break; + + case ACTION_WEST: + if (left + range.x < minLeft) { + range.x = minLeft - left; + } + + break; + + case ACTION_NORTH: + if (top + range.y < minTop) { + range.y = minTop - top; + } + + break; + + case ACTION_SOUTH: + if (bottom + range.y > maxHeight) { + range.y = maxHeight - bottom; + } + + break; + + default: + } + }; + + switch (action) { + // Move crop box + case ACTION_ALL: + left += range.x; + top += range.y; + break; + + // Resize crop box + case ACTION_EAST: + if (range.x >= 0 && (right >= maxWidth || (aspectRatio && + (top <= minTop || bottom >= maxHeight)))) { + renderable = false; + break; + } + + check(ACTION_EAST); + width += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top -= (range.x / aspectRatio) / 2; + } + + if (width < 0) { + action = ACTION_WEST; + width = 0; + } + + break; + + case ACTION_NORTH: + if (range.y <= 0 && (top <= minTop || (aspectRatio && + (left <= minLeft || right >= maxWidth)))) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left += (range.y * aspectRatio) / 2; + } + + if (height < 0) { + action = ACTION_SOUTH; + height = 0; + } + + break; + + case ACTION_WEST: + if (range.x <= 0 && (left <= minLeft || (aspectRatio && + (top <= minTop || bottom >= maxHeight)))) { + renderable = false; + break; + } + + check(ACTION_WEST); + width -= range.x; + left += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top += (range.x / aspectRatio) / 2; + } + + if (width < 0) { + action = ACTION_EAST; + width = 0; + } + + break; + + case ACTION_SOUTH: + if (range.y >= 0 && (bottom >= maxHeight || (aspectRatio && + (left <= minLeft || right >= maxWidth)))) { + renderable = false; + break; + } + + check(ACTION_SOUTH); + height += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left -= (range.y * aspectRatio) / 2; + } + + if (height < 0) { + action = ACTION_NORTH; + height = 0; + } + + break; + + case ACTION_NORTH_EAST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || right >= maxWidth)) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + width = height * aspectRatio; + } else { + check(ACTION_NORTH); + check(ACTION_EAST); + + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + } + + break; + + case ACTION_NORTH_WEST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || left <= minLeft)) { + renderable = false; + break; + } + + check(ACTION_NORTH); + height -= range.y; + top += range.y; + width = height * aspectRatio; + left += range.y * aspectRatio; + } else { + check(ACTION_NORTH); + check(ACTION_WEST); + + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_WEST: + if (aspectRatio) { + if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) { + renderable = false; + break; + } + + check(ACTION_WEST); + width -= range.x; + left += range.x; + height = width / aspectRatio; + } else { + check(ACTION_SOUTH); + check(ACTION_WEST); + + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_EAST: + if (aspectRatio) { + if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) { + renderable = false; + break; + } + + check(ACTION_EAST); + width += range.x; + height = width / aspectRatio; + } else { + check(ACTION_SOUTH); + check(ACTION_EAST); + + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + } + + break; + + // Move canvas + case ACTION_MOVE: + this.move(range.x, range.y); + renderable = false; + break; + + // Zoom canvas + case ACTION_ZOOM: + this.zoom(getMaxZoomRatio(pointers), e); + renderable = false; + break; + + // Create crop box + case ACTION_CROP: + if (!range.x || !range.y) { + renderable = false; + break; + } + + offset = getOffset(this.cropper); + left = pointer.startX - offset.left; + top = pointer.startY - offset.top; + width = cropBoxData.minWidth; + height = cropBoxData.minHeight; + + if (range.x > 0) { + action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST; + } else if (range.x < 0) { + left -= width; + action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST; + } + + if (range.y < 0) { + top -= height; + } + + // Show the crop box if is hidden + if (!this.cropped) { + removeClass(this.cropBox, CLASS_HIDDEN); + this.cropped = true; + + if (this.limited) { + this.limitCropBox(true, true); + } + } + + break; + + default: + } + + if (renderable) { + cropBoxData.width = width; + cropBoxData.height = height; + cropBoxData.left = left; + cropBoxData.top = top; + this.action = action; + this.renderCropBox(); + } + + // Override + each(pointers, (p) => { + p.startX = p.endX; + p.startY = p.endY; + }); + }, +}; diff --git a/library/cropperjs/src/js/constants.js b/library/cropperjs/src/js/constants.js new file mode 100644 index 000000000..c675d4d1c --- /dev/null +++ b/library/cropperjs/src/js/constants.js @@ -0,0 +1,56 @@ +export const WINDOW = typeof window !== 'undefined' ? window : {}; +export const NAMESPACE = 'cropper'; + +// Actions +export const ACTION_ALL = 'all'; +export const ACTION_CROP = 'crop'; +export const ACTION_MOVE = 'move'; +export const ACTION_ZOOM = 'zoom'; +export const ACTION_EAST = 'e'; +export const ACTION_WEST = 'w'; +export const ACTION_SOUTH = 's'; +export const ACTION_NORTH = 'n'; +export const ACTION_NORTH_EAST = 'ne'; +export const ACTION_NORTH_WEST = 'nw'; +export const ACTION_SOUTH_EAST = 'se'; +export const ACTION_SOUTH_WEST = 'sw'; + +// Classes +export const CLASS_CROP = `${NAMESPACE}-crop`; +export const CLASS_DISABLED = `${NAMESPACE}-disabled`; +export const CLASS_HIDDEN = `${NAMESPACE}-hidden`; +export const CLASS_HIDE = `${NAMESPACE}-hide`; +export const CLASS_INVISIBLE = `${NAMESPACE}-invisible`; +export const CLASS_MODAL = `${NAMESPACE}-modal`; +export const CLASS_MOVE = `${NAMESPACE}-move`; + +// Data keys +export const DATA_ACTION = 'action'; +export const DATA_PREVIEW = 'preview'; + +// Drag modes +export const DRAG_MODE_CROP = 'crop'; +export const DRAG_MODE_MOVE = 'move'; +export const DRAG_MODE_NONE = 'none'; + +// Events +export const EVENT_CROP = 'crop'; +export const EVENT_CROP_END = 'cropend'; +export const EVENT_CROP_MOVE = 'cropmove'; +export const EVENT_CROP_START = 'cropstart'; +export const EVENT_DBLCLICK = 'dblclick'; +export const EVENT_ERROR = 'error'; +export const EVENT_LOAD = 'load'; +export const EVENT_POINTER_DOWN = WINDOW.PointerEvent ? 'pointerdown' : 'touchstart mousedown'; +export const EVENT_POINTER_MOVE = WINDOW.PointerEvent ? 'pointermove' : 'touchmove mousemove'; +export const EVENT_POINTER_UP = WINDOW.PointerEvent ? 'pointerup pointercancel' : 'touchend touchcancel mouseup'; +export const EVENT_READY = 'ready'; +export const EVENT_RESIZE = 'resize'; +export const EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll'; +export const EVENT_ZOOM = 'zoom'; + +// RegExps +export const REGEXP_ACTIONS = /^(?:e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/; +export const REGEXP_DATA_URL = /^data:/; +export const REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/; +export const REGEXP_TAG_NAME = /^(?:img|canvas)$/i; diff --git a/library/cropperjs/src/js/cropper.js b/library/cropperjs/src/js/cropper.js new file mode 100644 index 000000000..97f3511df --- /dev/null +++ b/library/cropperjs/src/js/cropper.js @@ -0,0 +1,421 @@ +import DEFAULTS from './defaults'; +import TEMPLATE from './template'; +import render from './render'; +import preview from './preview'; +import events from './events'; +import handlers from './handlers'; +import change from './change'; +import methods from './methods'; +import { + ACTION_ALL, + CLASS_HIDDEN, + CLASS_HIDE, + CLASS_INVISIBLE, + CLASS_MODAL, + CLASS_MOVE, + DATA_ACTION, + EVENT_CROP, + EVENT_ERROR, + EVENT_LOAD, + EVENT_READY, + NAMESPACE, + REGEXP_DATA_URL, + REGEXP_DATA_URL_JPEG, + REGEXP_TAG_NAME, + WINDOW, +} from './constants'; +import { + addClass, + addListener, + addTimestamp, + arrayBufferToDataURL, + dataURLToArrayBuffer, + dispatchEvent, + extend, + getData, + getImageNaturalSizes, + getOrientation, + isCrossOriginURL, + isFunction, + isPlainObject, + parseOrientation, + proxy, + removeClass, + removeListener, + setData, +} from './utilities'; + +const AnotherCropper = WINDOW.Cropper; + +class Cropper { + /** + * Create a new Cropper. + * @param {Element} element - The target element for cropping. + * @param {Object} [options={}] - The configuration options. + */ + constructor(element, options = {}) { + if (!element || !REGEXP_TAG_NAME.test(element.tagName)) { + throw new Error('The first argument is required and must be an or element.'); + } + + this.element = element; + this.options = extend({}, DEFAULTS, isPlainObject(options) && options); + this.complete = false; + this.cropped = false; + this.disabled = false; + this.isImg = false; + this.limited = false; + this.loaded = false; + this.ready = false; + this.replaced = false; + this.wheeling = false; + this.originalUrl = ''; + this.canvasData = null; + this.cropBoxData = null; + this.previews = null; + this.pointers = {}; + this.init(); + } + + init() { + const { element } = this; + const tagName = element.tagName.toLowerCase(); + let url; + + if (getData(element, NAMESPACE)) { + return; + } + + setData(element, NAMESPACE, this); + + if (tagName === 'img') { + this.isImg = true; + + // e.g.: "img/picture.jpg" + url = element.getAttribute('src') || ''; + this.originalUrl = url; + + // Stop when it's a blank image + if (!url) { + return; + } + + // e.g.: "http://example.com/img/picture.jpg" + url = element.src; + } else if (tagName === 'canvas' && window.HTMLCanvasElement) { + url = element.toDataURL(); + } + + this.load(url); + } + + load(url) { + if (!url) { + return; + } + + this.url = url; + this.imageData = {}; + + const { element, options } = this; + + if (!options.checkOrientation || !window.ArrayBuffer) { + this.clone(); + return; + } + + // XMLHttpRequest disallows to open a Data URL in some browsers like IE11 and Safari + if (REGEXP_DATA_URL.test(url)) { + if (REGEXP_DATA_URL_JPEG.test(url)) { + this.read(dataURLToArrayBuffer(url)); + } else { + this.clone(); + } + + return; + } + + const xhr = new XMLHttpRequest(); + + xhr.onerror = () => { + this.clone(); + }; + + xhr.onload = () => { + this.read(xhr.response); + }; + + // Bust cache when there is a "crossOrigin" property + if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) { + url = addTimestamp(url); + } + + xhr.open('get', url); + xhr.responseType = 'arraybuffer'; + xhr.withCredentials = element.crossOrigin === 'use-credentials'; + xhr.send(); + } + + read(arrayBuffer) { + const { options, imageData } = this; + const orientation = getOrientation(arrayBuffer); + let rotate = 0; + let scaleX = 1; + let scaleY = 1; + + if (orientation > 1) { + this.url = arrayBufferToDataURL(arrayBuffer, 'image/jpeg'); + ({ rotate, scaleX, scaleY } = parseOrientation(orientation)); + } + + if (options.rotatable) { + imageData.rotate = rotate; + } + + if (options.scalable) { + imageData.scaleX = scaleX; + imageData.scaleY = scaleY; + } + + this.clone(); + } + + clone() { + const { element, url } = this; + let crossOrigin; + let crossOriginUrl; + + if (this.options.checkCrossOrigin && isCrossOriginURL(url)) { + ({ crossOrigin } = element); + + if (crossOrigin) { + crossOriginUrl = url; + } else { + crossOrigin = 'anonymous'; + + // Bust cache when there is not a "crossOrigin" property + crossOriginUrl = addTimestamp(url); + } + } + + this.crossOrigin = crossOrigin; + this.crossOriginUrl = crossOriginUrl; + + const image = document.createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = crossOriginUrl || url; + + const start = proxy(this.start, this); + const stop = proxy(this.stop, this); + + this.image = image; + this.onStart = start; + this.onStop = stop; + + if (this.isImg) { + if (element.complete) { + this.start(); + } else { + addListener(element, EVENT_LOAD, start); + } + } else { + addListener(image, EVENT_LOAD, start); + addListener(image, EVENT_ERROR, stop); + addClass(image, CLASS_HIDE); + element.parentNode.insertBefore(image, element.nextSibling); + } + } + + start(event) { + const image = this.isImg ? this.element : this.image; + + if (event) { + removeListener(image, EVENT_LOAD, this.onStart); + removeListener(image, EVENT_ERROR, this.onStop); + } + + getImageNaturalSizes(image, (naturalWidth, naturalHeight) => { + extend(this.imageData, { + naturalWidth, + naturalHeight, + aspectRatio: naturalWidth / naturalHeight, + }); + this.loaded = true; + this.build(); + }); + } + + stop() { + const { image } = this; + + removeListener(image, EVENT_LOAD, this.onStart); + removeListener(image, EVENT_ERROR, this.onStop); + image.parentNode.removeChild(image); + this.image = null; + } + + build() { + if (!this.loaded) { + return; + } + + // Unbuild first when replace + if (this.ready) { + this.unbuild(); + } + + const { element, options, image } = this; + + // Create cropper elements + const container = element.parentNode; + const template = document.createElement('div'); + + template.innerHTML = TEMPLATE; + + const cropper = template.querySelector(`.${NAMESPACE}-container`); + const canvas = cropper.querySelector(`.${NAMESPACE}-canvas`); + const dragBox = cropper.querySelector(`.${NAMESPACE}-drag-box`); + const cropBox = cropper.querySelector(`.${NAMESPACE}-crop-box`); + const face = cropBox.querySelector(`.${NAMESPACE}-face`); + + this.container = container; + this.cropper = cropper; + this.canvas = canvas; + this.dragBox = dragBox; + this.cropBox = cropBox; + this.viewBox = cropper.querySelector(`.${NAMESPACE}-view-box`); + this.face = face; + + canvas.appendChild(image); + + // Hide the original image + addClass(element, CLASS_HIDDEN); + + // Inserts the cropper after to the current image + container.insertBefore(cropper, element.nextSibling); + + // Show the image if is hidden + if (!this.isImg) { + removeClass(image, CLASS_HIDE); + } + + this.initPreview(); + this.bind(); + + options.aspectRatio = Math.max(0, options.aspectRatio) || NaN; + options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0; + + this.cropped = options.autoCrop; + + if (options.autoCrop) { + if (options.modal) { + addClass(dragBox, CLASS_MODAL); + } + } else { + addClass(cropBox, CLASS_HIDDEN); + } + + if (!options.guides) { + addClass(cropBox.getElementsByClassName(`${NAMESPACE}-dashed`), CLASS_HIDDEN); + } + + if (!options.center) { + addClass(cropBox.getElementsByClassName(`${NAMESPACE}-center`), CLASS_HIDDEN); + } + + if (options.background) { + addClass(cropper, `${NAMESPACE}-bg`); + } + + if (!options.highlight) { + addClass(face, CLASS_INVISIBLE); + } + + if (options.cropBoxMovable) { + addClass(face, CLASS_MOVE); + setData(face, DATA_ACTION, ACTION_ALL); + } + + if (!options.cropBoxResizable) { + addClass(cropBox.getElementsByClassName(`${NAMESPACE}-line`), CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(`${NAMESPACE}-point`), CLASS_HIDDEN); + } + + this.setDragMode(options.dragMode); + this.render(); + this.ready = true; + this.setData(options.data); + + // Call the "ready" option asynchronously to keep "image.cropper" is defined + this.completing = setTimeout(() => { + if (isFunction(options.ready)) { + addListener(element, EVENT_READY, options.ready, { + once: true, + }); + } + + dispatchEvent(element, EVENT_READY); + dispatchEvent(element, EVENT_CROP, this.getData()); + + this.complete = true; + }, 0); + } + + unbuild() { + if (!this.ready) { + return; + } + + if (!this.complete) { + clearTimeout(this.completing); + } + + this.ready = false; + this.complete = false; + this.initialImageData = null; + + // Clear `initialCanvasData` is necessary when replace + this.initialCanvasData = null; + this.initialCropBoxData = null; + this.containerData = null; + this.canvasData = null; + + // Clear `cropBoxData` is necessary when replace + this.cropBoxData = null; + this.unbind(); + this.resetPreview(); + this.previews = null; + this.viewBox = null; + this.cropBox = null; + this.dragBox = null; + this.canvas = null; + this.container = null; + this.cropper.parentNode.removeChild(this.cropper); + this.cropper = null; + } + + /** + * Get the no conflict cropper class. + * @returns {Cropper} The cropper class. + */ + static noConflict() { + window.Cropper = AnotherCropper; + return Cropper; + } + + /** + * Change the default options. + * @param {Object} options - The new default options. + */ + static setDefaults(options) { + extend(DEFAULTS, isPlainObject(options) && options); + } +} + +extend(Cropper.prototype, render, preview, events, handlers, change, methods); + +export default Cropper; diff --git a/library/cropperjs/src/js/defaults.js b/library/cropperjs/src/js/defaults.js new file mode 100644 index 000000000..aa469e73a --- /dev/null +++ b/library/cropperjs/src/js/defaults.js @@ -0,0 +1,99 @@ +import { + DRAG_MODE_CROP, +} from './constants'; + +export default { + // Define the view mode of the cropper + viewMode: 0, // 0, 1, 2, 3 + + // Define the dragging mode of the cropper + dragMode: DRAG_MODE_CROP, // 'crop', 'move' or 'none' + + // Define the aspect ratio of the crop box + aspectRatio: NaN, + + // An object with the previous cropping result data + data: null, + + // A selector for adding extra containers to preview + preview: '', + + // Re-render the cropper when resize the window + responsive: true, + + // Restore the cropped area after resize the window + restore: true, + + // Check if the current image is a cross-origin image + checkCrossOrigin: true, + + // Check the current image's Exif Orientation information + checkOrientation: true, + + // Show the black modal + modal: true, + + // Show the dashed lines for guiding + guides: true, + + // Show the center indicator for guiding + center: true, + + // Show the white modal to highlight the crop box + highlight: true, + + // Show the grid background + background: true, + + // Enable to crop the image automatically when initialize + autoCrop: true, + + // Define the percentage of automatic cropping area when initializes + autoCropArea: 0.8, + + // Enable to move the image + movable: true, + + // Enable to rotate the image + rotatable: true, + + // Enable to scale the image + scalable: true, + + // Enable to zoom the image + zoomable: true, + + // Enable to zoom the image by dragging touch + zoomOnTouch: true, + + // Enable to zoom the image by wheeling mouse + zoomOnWheel: true, + + // Define zoom ratio when zoom the image by wheeling mouse + wheelZoomRatio: 0.1, + + // Enable to move the crop box + cropBoxMovable: true, + + // Enable to resize the crop box + cropBoxResizable: true, + + // Toggle drag mode between "crop" and "move" when click twice on the cropper + toggleDragModeOnDblclick: true, + + // Size limitation + minCanvasWidth: 0, + minCanvasHeight: 0, + minCropBoxWidth: 0, + minCropBoxHeight: 0, + minContainerWidth: 200, + minContainerHeight: 100, + + // Shortcuts of events + ready: null, + cropstart: null, + cropmove: null, + cropend: null, + crop: null, + zoom: null, +}; diff --git a/library/cropperjs/src/js/events.js b/library/cropperjs/src/js/events.js new file mode 100644 index 000000000..3753db022 --- /dev/null +++ b/library/cropperjs/src/js/events.js @@ -0,0 +1,111 @@ +import { + EVENT_CROP, + EVENT_CROP_END, + EVENT_CROP_MOVE, + EVENT_CROP_START, + EVENT_DBLCLICK, + EVENT_POINTER_DOWN, + EVENT_POINTER_MOVE, + EVENT_POINTER_UP, + EVENT_RESIZE, + EVENT_WHEEL, + EVENT_ZOOM, +} from './constants'; +import { + addListener, + isFunction, + proxy, + removeListener, +} from './utilities'; + +export default { + bind() { + const { element, options, cropper } = this; + + if (isFunction(options.cropstart)) { + addListener(element, EVENT_CROP_START, options.cropstart); + } + + if (isFunction(options.cropmove)) { + addListener(element, EVENT_CROP_MOVE, options.cropmove); + } + + if (isFunction(options.cropend)) { + addListener(element, EVENT_CROP_END, options.cropend); + } + + if (isFunction(options.crop)) { + addListener(element, EVENT_CROP, options.crop); + } + + if (isFunction(options.zoom)) { + addListener(element, EVENT_ZOOM, options.zoom); + } + + addListener(cropper, EVENT_POINTER_DOWN, (this.onCropStart = proxy(this.cropStart, this))); + + if (options.zoomable && options.zoomOnWheel) { + addListener(cropper, EVENT_WHEEL, (this.onWheel = proxy(this.wheel, this))); + } + + if (options.toggleDragModeOnDblclick) { + addListener(cropper, EVENT_DBLCLICK, (this.onDblclick = proxy(this.dblclick, this))); + } + + addListener( + element.ownerDocument, + EVENT_POINTER_MOVE, + (this.onCropMove = proxy(this.cropMove, this)), + ); + addListener( + element.ownerDocument, + EVENT_POINTER_UP, + (this.onCropEnd = proxy(this.cropEnd, this)), + ); + + if (options.responsive) { + addListener(window, EVENT_RESIZE, (this.onResize = proxy(this.resize, this))); + } + }, + + unbind() { + const { element, options, cropper } = this; + + if (isFunction(options.cropstart)) { + removeListener(element, EVENT_CROP_START, options.cropstart); + } + + if (isFunction(options.cropmove)) { + removeListener(element, EVENT_CROP_MOVE, options.cropmove); + } + + if (isFunction(options.cropend)) { + removeListener(element, EVENT_CROP_END, options.cropend); + } + + if (isFunction(options.crop)) { + removeListener(element, EVENT_CROP, options.crop); + } + + if (isFunction(options.zoom)) { + removeListener(element, EVENT_ZOOM, options.zoom); + } + + removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart); + + if (options.zoomable && options.zoomOnWheel) { + removeListener(cropper, EVENT_WHEEL, this.onWheel); + } + + if (options.toggleDragModeOnDblclick) { + removeListener(cropper, EVENT_DBLCLICK, this.onDblclick); + } + + removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove); + removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd); + + if (options.responsive) { + removeListener(window, EVENT_RESIZE, this.onResize); + } + }, +}; diff --git a/library/cropperjs/src/js/handlers.js b/library/cropperjs/src/js/handlers.js new file mode 100644 index 000000000..7b7b2469a --- /dev/null +++ b/library/cropperjs/src/js/handlers.js @@ -0,0 +1,212 @@ +import { + ACTION_CROP, + ACTION_ZOOM, + CLASS_CROP, + CLASS_MODAL, + DATA_ACTION, + DRAG_MODE_CROP, + DRAG_MODE_MOVE, + DRAG_MODE_NONE, + EVENT_CROP_END, + EVENT_CROP_MOVE, + EVENT_CROP_START, + REGEXP_ACTIONS, +} from './constants'; +import { + addClass, + dispatchEvent, + each, + extend, + getData, + getPointer, + hasClass, + toggleClass, +} from './utilities'; + +export default { + resize() { + const { options, container, containerData } = this; + const minContainerWidth = Number(options.minContainerWidth) || 200; + const minContainerHeight = Number(options.minContainerHeight) || 100; + + if (this.disabled || containerData.width <= minContainerWidth || + containerData.height <= minContainerHeight) { + return; + } + + const ratio = container.offsetWidth / containerData.width; + + // Resize when width changed or height changed + if (ratio !== 1 || container.offsetHeight !== containerData.height) { + let canvasData; + let cropBoxData; + + if (options.restore) { + canvasData = this.getCanvasData(); + cropBoxData = this.getCropBoxData(); + } + + this.render(); + + if (options.restore) { + this.setCanvasData(each(canvasData, (n, i) => { + canvasData[i] = n * ratio; + })); + this.setCropBoxData(each(cropBoxData, (n, i) => { + cropBoxData[i] = n * ratio; + })); + } + } + }, + + dblclick() { + if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) { + return; + } + + this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); + }, + + wheel(e) { + const ratio = Number(this.options.wheelZoomRatio) || 0.1; + let delta = 1; + + if (this.disabled) { + return; + } + + e.preventDefault(); + + // Limit wheel speed to prevent zoom too fast (#21) + if (this.wheeling) { + return; + } + + this.wheeling = true; + + setTimeout(() => { + this.wheeling = false; + }, 50); + + if (e.deltaY) { + delta = e.deltaY > 0 ? 1 : -1; + } else if (e.wheelDelta) { + delta = -e.wheelDelta / 120; + } else if (e.detail) { + delta = e.detail > 0 ? 1 : -1; + } + + this.zoom(-delta * ratio, e); + }, + + cropStart(e) { + if (this.disabled) { + return; + } + + const { options, pointers } = this; + let action; + + if (e.changedTouches) { + // Handle touch event + each(e.changedTouches, (touch) => { + pointers[touch.identifier] = getPointer(touch); + }); + } else { + // Handle mouse event and pointer event + pointers[e.pointerId || 0] = getPointer(e); + } + + if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { + action = ACTION_ZOOM; + } else { + action = getData(e.target, DATA_ACTION); + } + + if (!REGEXP_ACTIONS.test(action)) { + return; + } + + if (dispatchEvent(this.element, EVENT_CROP_START, { + originalEvent: e, + action, + }) === false) { + return; + } + + e.preventDefault(); + + this.action = action; + this.cropping = false; + + if (action === ACTION_CROP) { + this.cropping = true; + addClass(this.dragBox, CLASS_MODAL); + } + }, + + cropMove(e) { + const { action } = this; + + if (this.disabled || !action) { + return; + } + + const { pointers } = this; + + e.preventDefault(); + + if (dispatchEvent(this.element, EVENT_CROP_MOVE, { + originalEvent: e, + action, + }) === false) { + return; + } + + if (e.changedTouches) { + each(e.changedTouches, (touch) => { + extend(pointers[touch.identifier], getPointer(touch, true)); + }); + } else { + extend(pointers[e.pointerId || 0], getPointer(e, true)); + } + + this.change(e); + }, + + cropEnd(e) { + if (this.disabled) { + return; + } + + const { action, pointers } = this; + + if (e.changedTouches) { + each(e.changedTouches, (touch) => { + delete pointers[touch.identifier]; + }); + } else { + delete pointers[e.pointerId || 0]; + } + + if (!action) { + return; + } + + e.preventDefault(); + + if (!Object.keys(pointers).length) { + this.action = ''; + } + + if (this.cropping) { + this.cropping = false; + toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal); + } + + dispatchEvent(this.element, EVENT_CROP_END, { + originalEvent: e, + action, + }); + }, +}; diff --git a/library/cropperjs/src/js/methods.js b/library/cropperjs/src/js/methods.js new file mode 100644 index 000000000..3627d2bd1 --- /dev/null +++ b/library/cropperjs/src/js/methods.js @@ -0,0 +1,842 @@ +import { + CLASS_CROP, + CLASS_DISABLED, + CLASS_HIDDEN, + CLASS_MODAL, + CLASS_MOVE, + DATA_ACTION, + DRAG_MODE_CROP, + DRAG_MODE_MOVE, + DRAG_MODE_NONE, + EVENT_LOAD, + EVENT_ZOOM, + NAMESPACE, +} from './constants'; +import { + addClass, + dispatchEvent, + each, + extend, + getAdjustedSizes, + getOffset, + getPointersCenter, + getSourceCanvas, + isFunction, + isNumber, + isPlainObject, + isUndefined, + normalizeDecimalNumber, + removeClass, + removeData, + removeListener, + setData, + toggleClass, +} from './utilities'; + +export default { + // Show the crop box manually + crop() { + if (this.ready && !this.disabled) { + if (!this.cropped) { + this.cropped = true; + this.limitCropBox(true, true); + + if (this.options.modal) { + addClass(this.dragBox, CLASS_MODAL); + } + + removeClass(this.cropBox, CLASS_HIDDEN); + } + + this.setCropBoxData(this.initialCropBoxData); + } + + return this; + }, + + // Reset the image and crop box to their initial states + reset() { + if (this.ready && !this.disabled) { + this.imageData = extend({}, this.initialImageData); + this.canvasData = extend({}, this.initialCanvasData); + this.cropBoxData = extend({}, this.initialCropBoxData); + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + } + + return this; + }, + + // Clear the crop box + clear() { + if (this.cropped && !this.disabled) { + extend(this.cropBoxData, { + left: 0, + top: 0, + width: 0, + height: 0, + }); + + this.cropped = false; + this.renderCropBox(); + this.limitCanvas(true, true); + + // Render canvas after crop box rendered + this.renderCanvas(); + removeClass(this.dragBox, CLASS_MODAL); + addClass(this.cropBox, CLASS_HIDDEN); + } + + return this; + }, + + /** + * Replace the image's src and rebuild the cropper + * @param {string} url - The new URL. + * @param {boolean} [onlyColorChanged] - Indicate if the new image only changed color. + * @returns {Object} this + */ + replace(url, onlyColorChanged = false) { + if (!this.disabled && url) { + if (this.isImg) { + this.element.src = url; + } + + if (onlyColorChanged) { + this.url = url; + this.image.src = url; + + if (this.ready) { + this.image2.src = url; + + each(this.previews, (element) => { + element.getElementsByTagName('img')[0].src = url; + }); + } + } else { + if (this.isImg) { + this.replaced = true; + } + + // Clear previous data + this.options.data = null; + this.load(url); + } + } + + return this; + }, + + // Enable (unfreeze) the cropper + enable() { + if (this.ready) { + this.disabled = false; + removeClass(this.cropper, CLASS_DISABLED); + } + + return this; + }, + + // Disable (freeze) the cropper + disable() { + if (this.ready) { + this.disabled = true; + addClass(this.cropper, CLASS_DISABLED); + } + + return this; + }, + + // Destroy the cropper and remove the instance from the image + destroy() { + const { element, image } = this; + + if (this.loaded) { + if (this.isImg && this.replaced) { + element.src = this.originalUrl; + } + + this.unbuild(); + removeClass(element, CLASS_HIDDEN); + } else if (this.isImg) { + removeListener(element, EVENT_LOAD, this.onStart); + } else if (image) { + image.parentNode.removeChild(image); + } + + removeData(element, NAMESPACE); + + return this; + }, + + /** + * Move the canvas with relative offsets + * @param {number} offsetX - The relative offset distance on the x-axis. + * @param {number} offsetY - The relative offset distance on the y-axis. + * @returns {Object} this + */ + move(offsetX, offsetY) { + const { left, top } = this.canvasData; + + return this.moveTo( + isUndefined(offsetX) ? offsetX : (left + Number(offsetX)), + isUndefined(offsetY) ? offsetY : (top + Number(offsetY)), + ); + }, + + /** + * Move the canvas to an absolute point + * @param {number} x - The x-axis coordinate. + * @param {number} [y=x] - The y-axis coordinate. + * @returns {Object} this + */ + moveTo(x, y = x) { + const { canvasData } = this; + let changed = false; + + x = Number(x); + y = Number(y); + + if (this.ready && !this.disabled && this.options.movable) { + if (isNumber(x)) { + canvasData.left = x; + changed = true; + } + + if (isNumber(y)) { + canvasData.top = y; + changed = true; + } + + if (changed) { + this.renderCanvas(true); + } + } + + return this; + }, + + /** + * Zoom the canvas with a relative ratio + * @param {number} ratio - The target ratio. + * @param {Event} _originalEvent - The original event if any. + * @returns {Object} this + */ + zoom(ratio, _originalEvent) { + const { canvasData } = this; + + ratio = Number(ratio); + + if (ratio < 0) { + ratio = 1 / (1 - ratio); + } else { + ratio = 1 + ratio; + } + + return this.zoomTo((canvasData.width * ratio) / canvasData.naturalWidth, null, _originalEvent); + }, + + /** + * Zoom the canvas to an absolute ratio + * @param {number} ratio - The target ratio. + * @param {Object} pivot - The zoom pivot point coordinate. + * @param {Event} _originalEvent - The original event if any. + * @returns {Object} this + */ + zoomTo(ratio, pivot, _originalEvent) { + const { options, canvasData } = this; + const { + width, + height, + naturalWidth, + naturalHeight, + } = canvasData; + + ratio = Number(ratio); + + if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) { + const newWidth = naturalWidth * ratio; + const newHeight = naturalHeight * ratio; + + if (dispatchEvent(this.element, EVENT_ZOOM, { + originalEvent: _originalEvent, + oldRatio: width / naturalWidth, + ratio: newWidth / naturalWidth, + }) === false) { + return this; + } + + if (_originalEvent) { + const { pointers } = this; + const offset = getOffset(this.cropper); + const center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : { + pageX: _originalEvent.pageX, + pageY: _originalEvent.pageY, + }; + + // Zoom from the triggering point of the event + canvasData.left -= (newWidth - width) * ( + ((center.pageX - offset.left) - canvasData.left) / width + ); + canvasData.top -= (newHeight - height) * ( + ((center.pageY - offset.top) - canvasData.top) / height + ); + } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) { + canvasData.left -= (newWidth - width) * ( + (pivot.x - canvasData.left) / width + ); + canvasData.top -= (newHeight - height) * ( + (pivot.y - canvasData.top) / height + ); + } else { + // Zoom from the center of the canvas + canvasData.left -= (newWidth - width) / 2; + canvasData.top -= (newHeight - height) / 2; + } + + canvasData.width = newWidth; + canvasData.height = newHeight; + this.renderCanvas(true); + } + + return this; + }, + + /** + * Rotate the canvas with a relative degree + * @param {number} degree - The rotate degree. + * @returns {Object} this + */ + rotate(degree) { + return this.rotateTo((this.imageData.rotate || 0) + Number(degree)); + }, + + /** + * Rotate the canvas to an absolute degree + * @param {number} degree - The rotate degree. + * @returns {Object} this + */ + rotateTo(degree) { + degree = Number(degree); + + if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) { + this.imageData.rotate = degree % 360; + this.renderCanvas(true, true); + } + + return this; + }, + + /** + * Scale the image on the x-axis. + * @param {number} scaleX - The scale ratio on the x-axis. + * @returns {Object} this + */ + scaleX(scaleX) { + const { scaleY } = this.imageData; + + return this.scale(scaleX, isNumber(scaleY) ? scaleY : 1); + }, + + /** + * Scale the image on the y-axis. + * @param {number} scaleY - The scale ratio on the y-axis. + * @returns {Object} this + */ + scaleY(scaleY) { + const { scaleX } = this.imageData; + + return this.scale(isNumber(scaleX) ? scaleX : 1, scaleY); + }, + + /** + * Scale the image + * @param {number} scaleX - The scale ratio on the x-axis. + * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis. + * @returns {Object} this + */ + scale(scaleX, scaleY = scaleX) { + const { imageData } = this; + let transformed = false; + + scaleX = Number(scaleX); + scaleY = Number(scaleY); + + if (this.ready && !this.disabled && this.options.scalable) { + if (isNumber(scaleX)) { + imageData.scaleX = scaleX; + transformed = true; + } + + if (isNumber(scaleY)) { + imageData.scaleY = scaleY; + transformed = true; + } + + if (transformed) { + this.renderCanvas(true, true); + } + } + + return this; + }, + + /** + * Get the cropped area position and size data (base on the original image) + * @param {boolean} [rounded=false] - Indicate if round the data values or not. + * @returns {Object} The result cropped data. + */ + getData(rounded = false) { + const { + options, + imageData, + canvasData, + cropBoxData, + } = this; + let data; + + if (this.ready && this.cropped) { + data = { + x: cropBoxData.left - canvasData.left, + y: cropBoxData.top - canvasData.top, + width: cropBoxData.width, + height: cropBoxData.height, + }; + + const ratio = imageData.width / imageData.naturalWidth; + + each(data, (n, i) => { + n /= ratio; + data[i] = rounded ? Math.round(n) : n; + }); + } else { + data = { + x: 0, + y: 0, + width: 0, + height: 0, + }; + } + + if (options.rotatable) { + data.rotate = imageData.rotate || 0; + } + + if (options.scalable) { + data.scaleX = imageData.scaleX || 1; + data.scaleY = imageData.scaleY || 1; + } + + return data; + }, + + /** + * Set the cropped area position and size with new data + * @param {Object} data - The new data. + * @returns {Object} this + */ + setData(data) { + const { options, imageData, canvasData } = this; + const cropBoxData = {}; + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && !this.disabled && isPlainObject(data)) { + let transformed = false; + + if (options.rotatable) { + if (isNumber(data.rotate) && data.rotate !== imageData.rotate) { + imageData.rotate = data.rotate; + transformed = true; + } + } + + if (options.scalable) { + if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) { + imageData.scaleX = data.scaleX; + transformed = true; + } + + if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) { + imageData.scaleY = data.scaleY; + transformed = true; + } + } + + if (transformed) { + this.renderCanvas(true, true); + } + + const ratio = imageData.width / imageData.naturalWidth; + + if (isNumber(data.x)) { + cropBoxData.left = (data.x * ratio) + canvasData.left; + } + + if (isNumber(data.y)) { + cropBoxData.top = (data.y * ratio) + canvasData.top; + } + + if (isNumber(data.width)) { + cropBoxData.width = data.width * ratio; + } + + if (isNumber(data.height)) { + cropBoxData.height = data.height * ratio; + } + + this.setCropBoxData(cropBoxData); + } + + return this; + }, + + /** + * Get the container size data. + * @returns {Object} The result container data. + */ + getContainerData() { + return this.ready ? extend({}, this.containerData) : {}; + }, + + /** + * Get the image position and size data. + * @returns {Object} The result image data. + */ + getImageData() { + return this.loaded ? extend({}, this.imageData) : {}; + }, + + /** + * Get the canvas position and size data. + * @returns {Object} The result canvas data. + */ + getCanvasData() { + const { canvasData } = this; + const data = {}; + + if (this.ready) { + each([ + 'left', + 'top', + 'width', + 'height', + 'naturalWidth', + 'naturalHeight', + ], (n) => { + data[n] = canvasData[n]; + }); + } + + return data; + }, + + /** + * Set the canvas position and size with new data. + * @param {Object} data - The new canvas data. + * @returns {Object} this + */ + setCanvasData(data) { + const { canvasData } = this; + const { aspectRatio } = canvasData; + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && !this.disabled && isPlainObject(data)) { + if (isNumber(data.left)) { + canvasData.left = data.left; + } + + if (isNumber(data.top)) { + canvasData.top = data.top; + } + + if (isNumber(data.width)) { + canvasData.width = data.width; + canvasData.height = data.width / aspectRatio; + } else if (isNumber(data.height)) { + canvasData.height = data.height; + canvasData.width = data.height * aspectRatio; + } + + this.renderCanvas(true); + } + + return this; + }, + + /** + * Get the crop box position and size data. + * @returns {Object} The result crop box data. + */ + getCropBoxData() { + const { cropBoxData } = this; + let data; + + if (this.ready && this.cropped) { + data = { + left: cropBoxData.left, + top: cropBoxData.top, + width: cropBoxData.width, + height: cropBoxData.height, + }; + } + + return data || {}; + }, + + /** + * Set the crop box position and size with new data. + * @param {Object} data - The new crop box data. + * @returns {Object} this + */ + setCropBoxData(data) { + const { cropBoxData } = this; + const { aspectRatio } = this.options; + let widthChanged; + let heightChanged; + + if (isFunction(data)) { + data = data.call(this.element); + } + + if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) { + if (isNumber(data.left)) { + cropBoxData.left = data.left; + } + + if (isNumber(data.top)) { + cropBoxData.top = data.top; + } + + if (isNumber(data.width) && data.width !== cropBoxData.width) { + widthChanged = true; + cropBoxData.width = data.width; + } + + if (isNumber(data.height) && data.height !== cropBoxData.height) { + heightChanged = true; + cropBoxData.height = data.height; + } + + if (aspectRatio) { + if (widthChanged) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else if (heightChanged) { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + this.renderCropBox(); + } + + return this; + }, + + /** + * Get a canvas drawn the cropped image. + * @param {Object} [options={}] - The config options. + * @returns {HTMLCanvasElement} - The result canvas. + */ + getCroppedCanvas(options = {}) { + if (!this.ready || !window.HTMLCanvasElement) { + return null; + } + + const { canvasData } = this; + const source = getSourceCanvas(this.image, this.imageData, canvasData, options); + + // Returns the source canvas if it is not cropped. + if (!this.cropped) { + return source; + } + + let { + x: initialX, + y: initialY, + width: initialWidth, + height: initialHeight, + } = this.getData(); + const ratio = source.width / Math.floor(canvasData.naturalWidth); + + if (ratio !== 1) { + initialX *= ratio; + initialY *= ratio; + initialWidth *= ratio; + initialHeight *= ratio; + } + + const aspectRatio = initialWidth / initialHeight; + const maxSizes = getAdjustedSizes({ + aspectRatio, + width: options.maxWidth || Infinity, + height: options.maxHeight || Infinity, + }); + const minSizes = getAdjustedSizes({ + aspectRatio, + width: options.minWidth || 0, + height: options.minHeight || 0, + }, 'cover'); + let { + width, + height, + } = getAdjustedSizes({ + aspectRatio, + width: options.width || (ratio !== 1 ? source.width : initialWidth), + height: options.height || (ratio !== 1 ? source.height : initialHeight), + }); + + width = Math.min(maxSizes.width, Math.max(minSizes.width, width)); + height = Math.min(maxSizes.height, Math.max(minSizes.height, height)); + + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + + canvas.width = normalizeDecimalNumber(width); + canvas.height = normalizeDecimalNumber(height); + + context.fillStyle = options.fillColor || 'transparent'; + context.fillRect(0, 0, width, height); + + const { imageSmoothingEnabled = true, imageSmoothingQuality } = options; + + context.imageSmoothingEnabled = imageSmoothingEnabled; + + if (imageSmoothingQuality) { + context.imageSmoothingQuality = imageSmoothingQuality; + } + + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage + const sourceWidth = source.width; + const sourceHeight = source.height; + + // Source canvas parameters + let srcX = initialX; + let srcY = initialY; + let srcWidth; + let srcHeight; + + // Destination canvas parameters + let dstX; + let dstY; + let dstWidth; + let dstHeight; + + if (srcX <= -initialWidth || srcX > sourceWidth) { + srcX = 0; + srcWidth = 0; + dstX = 0; + dstWidth = 0; + } else if (srcX <= 0) { + dstX = -srcX; + srcX = 0; + srcWidth = Math.min(sourceWidth, initialWidth + srcX); + dstWidth = srcWidth; + } else if (srcX <= sourceWidth) { + dstX = 0; + srcWidth = Math.min(initialWidth, sourceWidth - srcX); + dstWidth = srcWidth; + } + + if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) { + srcY = 0; + srcHeight = 0; + dstY = 0; + dstHeight = 0; + } else if (srcY <= 0) { + dstY = -srcY; + srcY = 0; + srcHeight = Math.min(sourceHeight, initialHeight + srcY); + dstHeight = srcHeight; + } else if (srcY <= sourceHeight) { + dstY = 0; + srcHeight = Math.min(initialHeight, sourceHeight - srcY); + dstHeight = srcHeight; + } + + // All the numerical parameters should be integer for `drawImage` + // https://github.com/fengyuanchen/cropper/issues/476 + const params = [ + srcX, + srcY, + srcWidth, + srcHeight, + ]; + + // Avoid "IndexSizeError" + if (dstWidth > 0 && dstHeight > 0) { + const scale = width / initialWidth; + + params.push( + dstX * scale, + dstY * scale, + dstWidth * scale, + dstHeight * scale, + ); + } + + context.drawImage(source, ...params.map(param => Math.floor(normalizeDecimalNumber(param)))); + + return canvas; + }, + + /** + * Change the aspect ratio of the crop box. + * @param {number} aspectRatio - The new aspect ratio. + * @returns {Object} this + */ + setAspectRatio(aspectRatio) { + const { options } = this; + + if (!this.disabled && !isUndefined(aspectRatio)) { + // 0 -> NaN + options.aspectRatio = Math.max(0, aspectRatio) || NaN; + + if (this.ready) { + this.initCropBox(); + + if (this.cropped) { + this.renderCropBox(); + } + } + } + + return this; + }, + + /** + * Change the drag mode. + * @param {string} mode - The new drag mode. + * @returns {Object} this + */ + setDragMode(mode) { + const { options, dragBox, face } = this; + + if (this.loaded && !this.disabled) { + const croppable = mode === DRAG_MODE_CROP; + const movable = options.movable && mode === DRAG_MODE_MOVE; + + mode = (croppable || movable) ? mode : DRAG_MODE_NONE; + + setData(dragBox, DATA_ACTION, mode); + toggleClass(dragBox, CLASS_CROP, croppable); + toggleClass(dragBox, CLASS_MOVE, movable); + + if (!options.cropBoxMovable) { + // Sync drag mode to crop box when it is not movable + setData(face, DATA_ACTION, mode); + toggleClass(face, CLASS_CROP, croppable); + toggleClass(face, CLASS_MOVE, movable); + } + } + + return this; + }, +}; diff --git a/library/cropperjs/src/js/preview.js b/library/cropperjs/src/js/preview.js new file mode 100644 index 000000000..c47d03f4b --- /dev/null +++ b/library/cropperjs/src/js/preview.js @@ -0,0 +1,142 @@ +import { + DATA_PREVIEW, +} from './constants'; +import { + each, + empty, + extend, + getData, + getTransforms, + removeData, + setData, + setStyle, +} from './utilities'; + +export default { + initPreview() { + const { crossOrigin } = this; + const { preview } = this.options; + const url = crossOrigin ? this.crossOriginUrl : this.url; + const image = document.createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = url; + this.viewBox.appendChild(image); + this.image2 = image; + + if (!preview) { + return; + } + + const previews = preview.querySelector ? [preview] : document.querySelectorAll(preview); + + this.previews = previews; + + each(previews, (element) => { + const img = document.createElement('img'); + + // Save the original size for recover + setData(element, DATA_PREVIEW, { + width: element.offsetWidth, + height: element.offsetHeight, + html: element.innerHTML, + }); + + if (crossOrigin) { + img.crossOrigin = crossOrigin; + } + + img.src = url; + + /** + * Override img element styles + * Add `display:block` to avoid margin top issue + * Add `height:auto` to override `height` attribute on IE8 + * (Occur only when margin-top <= -height) + */ + img.style.cssText = ( + 'display:block;' + + 'width:100%;' + + 'height:auto;' + + 'min-width:0!important;' + + 'min-height:0!important;' + + 'max-width:none!important;' + + 'max-height:none!important;' + + 'image-orientation:0deg!important;"' + ); + + empty(element); + element.appendChild(img); + }); + }, + + resetPreview() { + each(this.previews, (element) => { + const data = getData(element, DATA_PREVIEW); + + setStyle(element, { + width: data.width, + height: data.height, + }); + + element.innerHTML = data.html; + removeData(element, DATA_PREVIEW); + }); + }, + + preview() { + const { imageData, canvasData, cropBoxData } = this; + const { width: cropBoxWidth, height: cropBoxHeight } = cropBoxData; + const { width, height } = imageData; + const left = cropBoxData.left - canvasData.left - imageData.left; + const top = cropBoxData.top - canvasData.top - imageData.top; + + if (!this.cropped || this.disabled) { + return; + } + + setStyle(this.image2, extend({ + width, + height, + }, getTransforms(extend({ + translateX: -left, + translateY: -top, + }, imageData)))); + + each(this.previews, (element) => { + const data = getData(element, DATA_PREVIEW); + const originalWidth = data.width; + const originalHeight = data.height; + let newWidth = originalWidth; + let newHeight = originalHeight; + let ratio = 1; + + if (cropBoxWidth) { + ratio = originalWidth / cropBoxWidth; + newHeight = cropBoxHeight * ratio; + } + + if (cropBoxHeight && newHeight > originalHeight) { + ratio = originalHeight / cropBoxHeight; + newWidth = cropBoxWidth * ratio; + newHeight = originalHeight; + } + + setStyle(element, { + width: newWidth, + height: newHeight, + }); + + setStyle(element.getElementsByTagName('img')[0], extend({ + width: width * ratio, + height: height * ratio, + }, getTransforms(extend({ + translateX: -left * ratio, + translateY: -top * ratio, + }, imageData)))); + }); + }, +}; diff --git a/library/cropperjs/src/js/render.js b/library/cropperjs/src/js/render.js new file mode 100644 index 000000000..09085ce41 --- /dev/null +++ b/library/cropperjs/src/js/render.js @@ -0,0 +1,495 @@ +import { + ACTION_ALL, + ACTION_MOVE, + CLASS_HIDDEN, + DATA_ACTION, + EVENT_CROP, +} from './constants'; +import { + addClass, + dispatchEvent, + extend, + getAdjustedSizes, + getRotatedSizes, + getTransforms, + removeClass, + setData, + setStyle, +} from './utilities'; + +export default { + render() { + this.initContainer(); + this.initCanvas(); + this.initCropBox(); + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + }, + + initContainer() { + const { + element, + options, + container, + cropper, + } = this; + + addClass(cropper, CLASS_HIDDEN); + removeClass(element, CLASS_HIDDEN); + + const containerData = { + width: Math.max( + container.offsetWidth, + Number(options.minContainerWidth) || 200, + ), + height: Math.max( + container.offsetHeight, + Number(options.minContainerHeight) || 100, + ), + }; + + this.containerData = containerData; + + setStyle(cropper, { + width: containerData.width, + height: containerData.height, + }); + + addClass(element, CLASS_HIDDEN); + removeClass(cropper, CLASS_HIDDEN); + }, + + // Canvas (image wrapper) + initCanvas() { + const { containerData, imageData } = this; + const { viewMode } = this.options; + const rotated = Math.abs(imageData.rotate) % 180 === 90; + const naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth; + const naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight; + const aspectRatio = naturalWidth / naturalHeight; + let canvasWidth = containerData.width; + let canvasHeight = containerData.height; + + if (containerData.height * aspectRatio > containerData.width) { + if (viewMode === 3) { + canvasWidth = containerData.height * aspectRatio; + } else { + canvasHeight = containerData.width / aspectRatio; + } + } else if (viewMode === 3) { + canvasHeight = containerData.width / aspectRatio; + } else { + canvasWidth = containerData.height * aspectRatio; + } + + const canvasData = { + aspectRatio, + naturalWidth, + naturalHeight, + width: canvasWidth, + height: canvasHeight, + }; + + canvasData.left = (containerData.width - canvasWidth) / 2; + canvasData.top = (containerData.height - canvasHeight) / 2; + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; + + this.canvasData = canvasData; + this.limited = (viewMode === 1 || viewMode === 2); + this.limitCanvas(true, true); + this.initialImageData = extend({}, imageData); + this.initialCanvasData = extend({}, canvasData); + }, + + limitCanvas(sizeLimited, positionLimited) { + const { + options, + containerData, + canvasData, + cropBoxData, + } = this; + const { viewMode } = options; + const { aspectRatio } = canvasData; + const cropped = this.cropped && cropBoxData; + + if (sizeLimited) { + let minCanvasWidth = Number(options.minCanvasWidth) || 0; + let minCanvasHeight = Number(options.minCanvasHeight) || 0; + + if (viewMode > 1) { + minCanvasWidth = Math.max(minCanvasWidth, containerData.width); + minCanvasHeight = Math.max(minCanvasHeight, containerData.height); + + if (viewMode === 3) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } else if (viewMode > 0) { + if (minCanvasWidth) { + minCanvasWidth = Math.max( + minCanvasWidth, + cropped ? cropBoxData.width : 0, + ); + } else if (minCanvasHeight) { + minCanvasHeight = Math.max( + minCanvasHeight, + cropped ? cropBoxData.height : 0, + ); + } else if (cropped) { + minCanvasWidth = cropBoxData.width; + minCanvasHeight = cropBoxData.height; + + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } + + ({ width: minCanvasWidth, height: minCanvasHeight } = getAdjustedSizes({ + aspectRatio, + width: minCanvasWidth, + height: minCanvasHeight, + }, 'cover')); + + canvasData.minWidth = minCanvasWidth; + canvasData.minHeight = minCanvasHeight; + canvasData.maxWidth = Infinity; + canvasData.maxHeight = Infinity; + } + + if (positionLimited) { + if (viewMode) { + const newCanvasLeft = containerData.width - canvasData.width; + const newCanvasTop = containerData.height - canvasData.height; + + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxLeft = Math.max(0, newCanvasLeft); + canvasData.maxTop = Math.max(0, newCanvasTop); + + if (cropped && this.limited) { + canvasData.minLeft = Math.min( + cropBoxData.left, + cropBoxData.left + (cropBoxData.width - canvasData.width), + ); + canvasData.minTop = Math.min( + cropBoxData.top, + cropBoxData.top + (cropBoxData.height - canvasData.height), + ); + canvasData.maxLeft = cropBoxData.left; + canvasData.maxTop = cropBoxData.top; + + if (viewMode === 2) { + if (canvasData.width >= containerData.width) { + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.maxLeft = Math.max(0, newCanvasLeft); + } + + if (canvasData.height >= containerData.height) { + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxTop = Math.max(0, newCanvasTop); + } + } + } + } else { + canvasData.minLeft = -canvasData.width; + canvasData.minTop = -canvasData.height; + canvasData.maxLeft = containerData.width; + canvasData.maxTop = containerData.height; + } + } + }, + + renderCanvas(changed, transformed) { + const { canvasData, imageData } = this; + + if (transformed) { + const { width: naturalWidth, height: naturalHeight } = getRotatedSizes({ + width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1), + height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1), + degree: imageData.rotate || 0, + }); + const width = canvasData.width * (naturalWidth / canvasData.naturalWidth); + const height = canvasData.height * (naturalHeight / canvasData.naturalHeight); + + canvasData.left -= (width - canvasData.width) / 2; + canvasData.top -= (height - canvasData.height) / 2; + canvasData.width = width; + canvasData.height = height; + canvasData.aspectRatio = naturalWidth / naturalHeight; + canvasData.naturalWidth = naturalWidth; + canvasData.naturalHeight = naturalHeight; + this.limitCanvas(true, false); + } + + if (canvasData.width > canvasData.maxWidth || + canvasData.width < canvasData.minWidth) { + canvasData.left = canvasData.oldLeft; + } + + if (canvasData.height > canvasData.maxHeight || + canvasData.height < canvasData.minHeight) { + canvasData.top = canvasData.oldTop; + } + + canvasData.width = Math.min( + Math.max(canvasData.width, canvasData.minWidth), + canvasData.maxWidth, + ); + canvasData.height = Math.min( + Math.max(canvasData.height, canvasData.minHeight), + canvasData.maxHeight, + ); + + this.limitCanvas(false, true); + + canvasData.left = Math.min( + Math.max(canvasData.left, canvasData.minLeft), + canvasData.maxLeft, + ); + canvasData.top = Math.min( + Math.max(canvasData.top, canvasData.minTop), + canvasData.maxTop, + ); + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; + + setStyle(this.canvas, extend({ + width: canvasData.width, + height: canvasData.height, + }, getTransforms({ + translateX: canvasData.left, + translateY: canvasData.top, + }))); + + this.renderImage(changed); + + if (this.cropped && this.limited) { + this.limitCropBox(true, true); + } + }, + + renderImage(changed) { + const { canvasData, imageData } = this; + const width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth); + const height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight); + + extend(imageData, { + width, + height, + left: (canvasData.width - width) / 2, + top: (canvasData.height - height) / 2, + }); + setStyle(this.image, extend({ + width: imageData.width, + height: imageData.height, + }, getTransforms(extend({ + translateX: imageData.left, + translateY: imageData.top, + }, imageData)))); + + if (changed) { + this.output(); + } + }, + + initCropBox() { + const { options, canvasData } = this; + const { aspectRatio } = options; + const autoCropArea = Number(options.autoCropArea) || 0.8; + const cropBoxData = { + width: canvasData.width, + height: canvasData.height, + }; + + if (aspectRatio) { + if (canvasData.height * aspectRatio > canvasData.width) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + this.cropBoxData = cropBoxData; + this.limitCropBox(true, true); + + // Initialize auto crop area + cropBoxData.width = Math.min( + Math.max(cropBoxData.width, cropBoxData.minWidth), + cropBoxData.maxWidth, + ); + cropBoxData.height = Math.min( + Math.max(cropBoxData.height, cropBoxData.minHeight), + cropBoxData.maxHeight, + ); + + // The width/height of auto crop area must large than "minWidth/Height" + cropBoxData.width = Math.max( + cropBoxData.minWidth, + cropBoxData.width * autoCropArea, + ); + cropBoxData.height = Math.max( + cropBoxData.minHeight, + cropBoxData.height * autoCropArea, + ); + cropBoxData.left = ( + canvasData.left + ((canvasData.width - cropBoxData.width) / 2) + ); + cropBoxData.top = ( + canvasData.top + ((canvasData.height - cropBoxData.height) / 2) + ); + cropBoxData.oldLeft = cropBoxData.left; + cropBoxData.oldTop = cropBoxData.top; + + this.initialCropBoxData = extend({}, cropBoxData); + }, + + limitCropBox(sizeLimited, positionLimited) { + const { + options, + containerData, + canvasData, + cropBoxData, + limited, + } = this; + const { aspectRatio } = options; + + if (sizeLimited) { + let minCropBoxWidth = Number(options.minCropBoxWidth) || 0; + let minCropBoxHeight = Number(options.minCropBoxHeight) || 0; + let maxCropBoxWidth = Math.min( + containerData.width, + limited ? canvasData.width : containerData.width, + ); + let maxCropBoxHeight = Math.min( + containerData.height, + limited ? canvasData.height : containerData.height, + ); + + // The min/maxCropBoxWidth/Height must be less than container's width/height + minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width); + minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height); + + if (aspectRatio) { + if (minCropBoxWidth && minCropBoxHeight) { + if (minCropBoxHeight * aspectRatio > minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + } else if (minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else if (minCropBoxHeight) { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + + if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) { + maxCropBoxHeight = maxCropBoxWidth / aspectRatio; + } else { + maxCropBoxWidth = maxCropBoxHeight * aspectRatio; + } + } + + // The minWidth/Height must be less than maxWidth/Height + cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); + cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); + cropBoxData.maxWidth = maxCropBoxWidth; + cropBoxData.maxHeight = maxCropBoxHeight; + } + + if (positionLimited) { + if (limited) { + cropBoxData.minLeft = Math.max(0, canvasData.left); + cropBoxData.minTop = Math.max(0, canvasData.top); + cropBoxData.maxLeft = Math.min( + containerData.width, + canvasData.left + canvasData.width, + ) - cropBoxData.width; + cropBoxData.maxTop = Math.min( + containerData.height, + canvasData.top + canvasData.height, + ) - cropBoxData.height; + } else { + cropBoxData.minLeft = 0; + cropBoxData.minTop = 0; + cropBoxData.maxLeft = containerData.width - cropBoxData.width; + cropBoxData.maxTop = containerData.height - cropBoxData.height; + } + } + }, + + renderCropBox() { + const { options, containerData, cropBoxData } = this; + + if (cropBoxData.width > cropBoxData.maxWidth || + cropBoxData.width < cropBoxData.minWidth) { + cropBoxData.left = cropBoxData.oldLeft; + } + + if (cropBoxData.height > cropBoxData.maxHeight || + cropBoxData.height < cropBoxData.minHeight) { + cropBoxData.top = cropBoxData.oldTop; + } + + cropBoxData.width = Math.min( + Math.max(cropBoxData.width, cropBoxData.minWidth), + cropBoxData.maxWidth, + ); + cropBoxData.height = Math.min( + Math.max(cropBoxData.height, cropBoxData.minHeight), + cropBoxData.maxHeight, + ); + + this.limitCropBox(false, true); + + cropBoxData.left = Math.min( + Math.max(cropBoxData.left, cropBoxData.minLeft), + cropBoxData.maxLeft, + ); + cropBoxData.top = Math.min( + Math.max(cropBoxData.top, cropBoxData.minTop), + cropBoxData.maxTop, + ); + cropBoxData.oldLeft = cropBoxData.left; + cropBoxData.oldTop = cropBoxData.top; + + if (options.movable && options.cropBoxMovable) { + // Turn to move the canvas when the crop box is equal to the container + setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && + cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL); + } + + setStyle(this.cropBox, extend({ + width: cropBoxData.width, + height: cropBoxData.height, + }, getTransforms({ + translateX: cropBoxData.left, + translateY: cropBoxData.top, + }))); + + if (this.cropped && this.limited) { + this.limitCanvas(true, true); + } + + if (!this.disabled) { + this.output(); + } + }, + + output() { + this.preview(); + + if (this.complete) { + dispatchEvent(this.element, EVENT_CROP, this.getData()); + } + }, +}; diff --git a/library/cropperjs/src/js/template.js b/library/cropperjs/src/js/template.js new file mode 100644 index 000000000..589b46a78 --- /dev/null +++ b/library/cropperjs/src/js/template.js @@ -0,0 +1,27 @@ +export default ( + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
' + + '
' +); diff --git a/library/cropperjs/src/js/utilities.js b/library/cropperjs/src/js/utilities.js new file mode 100644 index 000000000..50b586a76 --- /dev/null +++ b/library/cropperjs/src/js/utilities.js @@ -0,0 +1,985 @@ +import { + WINDOW, +} from './constants'; + +/** + * Check if the given value is not a number. + */ +export const isNaN = Number.isNaN || WINDOW.isNaN; + +/** + * Check if the given value is a number. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a number, else `false`. + */ +export function isNumber(value) { + return typeof value === 'number' && !isNaN(value); +} + +/** + * Check if the given value is undefined. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is undefined, else `false`. + */ +export function isUndefined(value) { + return typeof value === 'undefined'; +} + +/** + * Check if the given value is an object. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is an object, else `false`. + */ +export function isObject(value) { + return typeof value === 'object' && value !== null; +} + +const { hasOwnProperty } = Object.prototype; + +/** + * Check if the given value is a plain object. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a plain object, else `false`. + */ +export function isPlainObject(value) { + if (!isObject(value)) { + return false; + } + + try { + const { constructor } = value; + const { prototype } = constructor; + + return constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf'); + } catch (e) { + return false; + } +} + +/** + * Check if the given value is a function. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a function, else `false`. + */ +export function isFunction(value) { + return typeof value === 'function'; +} + +/** + * Iterate the given data. + * @param {*} data - The data to iterate. + * @param {Function} callback - The process function for each element. + * @returns {*} The original data. + */ +export function each(data, callback) { + if (data && isFunction(callback)) { + if (Array.isArray(data) || isNumber(data.length)/* array-like */) { + const { length } = data; + let i; + + for (i = 0; i < length; i += 1) { + if (callback.call(data, data[i], i, data) === false) { + break; + } + } + } else if (isObject(data)) { + Object.keys(data).forEach((key) => { + callback.call(data, data[key], key, data); + }); + } + } + + return data; +} + +/** + * Extend the given object. + * @param {*} obj - The object to be extended. + * @param {*} args - The rest objects which will be merged to the first object. + * @returns {Object} The extended object. + */ +export function extend(obj, ...args) { + if (isObject(obj) && args.length > 0) { + if (Object.assign) { + return Object.assign(obj, ...args); + } + + args.forEach((arg) => { + if (isObject(arg)) { + Object.keys(arg).forEach((key) => { + obj[key] = arg[key]; + }); + } + }); + } + + return obj; +} + +/** + * Takes a function and returns a new one that will always have a particular context. + * @param {Function} fn - The target function. + * @param {Object} context - The new context for the function. + * @returns {boolean} The new function. + */ +export function proxy(fn, context, ...args) { + return (...args2) => fn.apply(context, args.concat(args2)); +} + +const REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/i; + +/** + * Normalize decimal number. + * Check out {@link http://0.30000000000000004.com/ } + * @param {number} value - The value to normalize. + * @param {number} [times=100000000000] - The times for normalizing. + * @returns {number} Returns the normalized number. + */ +export function normalizeDecimalNumber(value, times = 100000000000) { + return REGEXP_DECIMALS.test(value) ? (Math.round(value * times) / times) : value; +} + +const REGEXP_SUFFIX = /^(?:width|height|left|top|marginLeft|marginTop)$/; + +/** + * Apply styles to the given element. + * @param {Element} element - The target element. + * @param {Object} styles - The styles for applying. + */ +export function setStyle(element, styles) { + const { style } = element; + + each(styles, (value, property) => { + if (REGEXP_SUFFIX.test(property) && isNumber(value)) { + value += 'px'; + } + + style[property] = value; + }); +} + +/** + * Check if the given element has a special class. + * @param {Element} element - The element to check. + * @param {string} value - The class to search. + * @returns {boolean} Returns `true` if the special class was found. + */ +export function hasClass(element, value) { + return element.classList ? + element.classList.contains(value) : + element.className.indexOf(value) > -1; +} + +/** + * Add classes to the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be added. + */ +export function addClass(element, value) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, (elem) => { + addClass(elem, value); + }); + return; + } + + if (element.classList) { + element.classList.add(value); + return; + } + + const className = element.className.trim(); + + if (!className) { + element.className = value; + } else if (className.indexOf(value) < 0) { + element.className = `${className} ${value}`; + } +} + +/** + * Remove classes from the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be removed. + */ +export function removeClass(element, value) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, (elem) => { + removeClass(elem, value); + }); + return; + } + + if (element.classList) { + element.classList.remove(value); + return; + } + + if (element.className.indexOf(value) >= 0) { + element.className = element.className.replace(value, ''); + } +} + +/** + * Add or remove classes from the given element. + * @param {Element} element - The target element. + * @param {string} value - The classes to be toggled. + * @param {boolean} added - Add only. + */ +export function toggleClass(element, value, added) { + if (!value) { + return; + } + + if (isNumber(element.length)) { + each(element, (elem) => { + toggleClass(elem, value, added); + }); + return; + } + + // IE10-11 doesn't support the second parameter of `classList.toggle` + if (added) { + addClass(element, value); + } else { + removeClass(element, value); + } +} + +const REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g; + +/** + * Hyphenate the given value. + * @param {string} value - The value to hyphenate. + * @returns {string} The hyphenated value. + */ +export function hyphenate(value) { + return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase(); +} + +/** + * Get data from the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to get. + * @returns {string} The data value. + */ +export function getData(element, name) { + if (isObject(element[name])) { + return element[name]; + } else if (element.dataset) { + return element.dataset[name]; + } + + return element.getAttribute(`data-${hyphenate(name)}`); +} + +/** + * Set data to the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to set. + * @param {string} data - The data value. + */ +export function setData(element, name, data) { + if (isObject(data)) { + element[name] = data; + } else if (element.dataset) { + element.dataset[name] = data; + } else { + element.setAttribute(`data-${hyphenate(name)}`, data); + } +} + +/** + * Remove data from the given element. + * @param {Element} element - The target element. + * @param {string} name - The data key to remove. + */ +export function removeData(element, name) { + if (isObject(element[name])) { + try { + delete element[name]; + } catch (e) { + element[name] = null; + } + } else if (element.dataset) { + // #128 Safari not allows to delete dataset property + try { + delete element.dataset[name]; + } catch (e) { + element.dataset[name] = null; + } + } else { + element.removeAttribute(`data-${hyphenate(name)}`); + } +} + +const REGEXP_SPACES = /\s\s*/; + +/** + * Remove event listener from the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Function} listener - The event listener. + * @param {Object} options - The event options. + */ +export function removeListener(element, type, listener, options = {}) { + if (!isFunction(listener)) { + return; + } + + const types = type.trim().split(REGEXP_SPACES); + + if (types.length > 1) { + each(types, (t) => { + removeListener(element, t, listener, options); + }); + return; + } + + if (element.removeEventListener) { + element.removeEventListener(type, listener, options); + } else if (element.detachEvent) { + element.detachEvent(`on${type}`, listener); + } +} + +/** + * Add event listener to the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Function} listener - The event listener. + * @param {Object} options - The event options. + */ +export function addListener(element, type, listener, options = {}) { + if (!isFunction(listener)) { + return; + } + + const types = type.trim().split(REGEXP_SPACES); + + if (types.length > 1) { + each(types, (t) => { + addListener(element, t, listener, options); + }); + return; + } + + if (options.once) { + const originalListener = listener; + + listener = (...args) => { + removeListener(element, type, listener, options); + return originalListener.apply(element, args); + }; + } + + if (element.addEventListener) { + element.addEventListener(type, listener, options); + } else if (element.attachEvent) { + element.attachEvent(`on${type}`, listener); + } +} + +/** + * Dispatch event on the target element. + * @param {Element} element - The event target. + * @param {string} type - The event type(s). + * @param {Object} data - The additional event data. + * @returns {boolean} Indicate if the event is default prevented or not. + */ +export function dispatchEvent(element, type, data) { + if (element.dispatchEvent) { + let event; + + // Event and CustomEvent on IE9-11 are global objects, not constructors + if (isFunction(Event) && isFunction(CustomEvent)) { + if (isUndefined(data)) { + event = new Event(type, { + bubbles: true, + cancelable: true, + }); + } else { + event = new CustomEvent(type, { + detail: data, + bubbles: true, + cancelable: true, + }); + } + } else if (isUndefined(data)) { + event = document.createEvent('Event'); + event.initEvent(type, true, true); + } else { + event = document.createEvent('CustomEvent'); + event.initCustomEvent(type, true, true, data); + } + + // IE9+ + return element.dispatchEvent(event); + } else if (element.fireEvent) { + // IE6-10 (native events only) + return element.fireEvent(`on${type}`); + } + + return true; +} + +/** + * Get the offset base on the document. + * @param {Element} element - The target element. + * @returns {Object} The offset data. + */ +export function getOffset(element) { + const doc = document.documentElement; + const box = element.getBoundingClientRect(); + + return { + left: box.left + ( + (window.scrollX || (doc && doc.scrollLeft) || 0) - ((doc && doc.clientLeft) || 0) + ), + top: box.top + ( + (window.scrollY || (doc && doc.scrollTop) || 0) - ((doc && doc.clientTop) || 0) + ), + }; +} + +/** + * Empty an element. + * @param {Element} element - The element to empty. + */ +export function empty(element) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } +} + +const { location } = WINDOW; +const REGEXP_ORIGINS = /^(https?:)\/\/([^:/?#]+):?(\d*)/i; + +/** + * Check if the given URL is a cross origin URL. + * @param {string} url - The target URL. + * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`. + */ +export function isCrossOriginURL(url) { + const parts = url.match(REGEXP_ORIGINS); + + return parts && ( + parts[1] !== location.protocol || + parts[2] !== location.hostname || + parts[3] !== location.port + ); +} + +/** + * Add timestamp to the given URL. + * @param {string} url - The target URL. + * @returns {string} The result URL. + */ +export function addTimestamp(url) { + const timestamp = `timestamp=${(new Date()).getTime()}`; + + return (url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp); +} + +/** + * Get transforms base on the given object. + * @param {Object} obj - The target object. + * @returns {string} A string contains transform values. + */ +export function getTransforms({ + rotate, + scaleX, + scaleY, + translateX, + translateY, +}) { + const values = []; + + if (isNumber(translateX) && translateX !== 0) { + values.push(`translateX(${translateX}px)`); + } + + if (isNumber(translateY) && translateY !== 0) { + values.push(`translateY(${translateY}px)`); + } + + // Rotate should come first before scale to match orientation transform + if (isNumber(rotate) && rotate !== 0) { + values.push(`rotate(${rotate}deg)`); + } + + if (isNumber(scaleX) && scaleX !== 1) { + values.push(`scaleX(${scaleX})`); + } + + if (isNumber(scaleY) && scaleY !== 1) { + values.push(`scaleY(${scaleY})`); + } + + const transform = values.length ? values.join(' ') : 'none'; + + return { + WebkitTransform: transform, + msTransform: transform, + transform, + }; +} + +const { navigator } = WINDOW; +const IS_SAFARI_OR_UIWEBVIEW = navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent); + +/** + * Get an image's natural sizes. + * @param {string} image - The target image. + * @param {Function} callback - The callback function. + */ +export function getImageNaturalSizes(image, callback) { + // Modern browsers (except Safari) + if (image.naturalWidth && !IS_SAFARI_OR_UIWEBVIEW) { + callback(image.naturalWidth, image.naturalHeight); + return; + } + + const newImage = document.createElement('img'); + const body = document.body || document.documentElement; + + newImage.onload = () => { + callback(newImage.width, newImage.height); + + if (!IS_SAFARI_OR_UIWEBVIEW) { + body.removeChild(newImage); + } + }; + + newImage.src = image.src; + + // iOS Safari will convert the image automatically + // with its orientation once append it into DOM (#279) + if (!IS_SAFARI_OR_UIWEBVIEW) { + newImage.style.cssText = ( + 'left:0;' + + 'max-height:none!important;' + + 'max-width:none!important;' + + 'min-height:0!important;' + + 'min-width:0!important;' + + 'opacity:0;' + + 'position:absolute;' + + 'top:0;' + + 'z-index:-1;' + ); + body.appendChild(newImage); + } +} + +/** + * Get the max ratio of a group of pointers. + * @param {string} pointers - The target pointers. + * @returns {number} The result ratio. + */ +export function getMaxZoomRatio(pointers) { + const pointers2 = extend({}, pointers); + const ratios = []; + + each(pointers, (pointer, pointerId) => { + delete pointers2[pointerId]; + + each(pointers2, (pointer2) => { + const x1 = Math.abs(pointer.startX - pointer2.startX); + const y1 = Math.abs(pointer.startY - pointer2.startY); + const x2 = Math.abs(pointer.endX - pointer2.endX); + const y2 = Math.abs(pointer.endY - pointer2.endY); + const z1 = Math.sqrt((x1 * x1) + (y1 * y1)); + const z2 = Math.sqrt((x2 * x2) + (y2 * y2)); + const ratio = (z2 - z1) / z1; + + ratios.push(ratio); + }); + }); + + ratios.sort((a, b) => Math.abs(a) < Math.abs(b)); + + return ratios[0]; +} + +/** + * Get a pointer from an event object. + * @param {Object} event - The target event object. + * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not. + * @returns {Object} The result pointer contains start and/or end point coordinates. + */ +export function getPointer({ pageX, pageY }, endOnly) { + const end = { + endX: pageX, + endY: pageY, + }; + + if (endOnly) { + return end; + } + + return extend({ + startX: pageX, + startY: pageY, + }, end); +} + +/** + * Get the center point coordinate of a group of pointers. + * @param {Object} pointers - The target pointers. + * @returns {Object} The center point coordinate. + */ +export function getPointersCenter(pointers) { + let pageX = 0; + let pageY = 0; + let count = 0; + + each(pointers, ({ startX, startY }) => { + pageX += startX; + pageY += startY; + count += 1; + }); + + pageX /= count; + pageY /= count; + + return { + pageX, + pageY, + }; +} + +/** + * Check if the given value is a finite number. + */ +export const isFinite = Number.isFinite || WINDOW.isFinite; + +/** + * Get the max sizes in a rectangle under the given aspect ratio. + * @param {Object} data - The original sizes. + * @param {string} [type='contain'] - The adjust type. + * @returns {Object} The result sizes. + */ +export function getAdjustedSizes( + { + aspectRatio, + height, + width, + }, + type = 'contain', // or 'cover' +) { + const isValidNumber = value => isFinite(value) && value > 0; + + if (isValidNumber(width) && isValidNumber(height)) { + const adjustedWidth = height * aspectRatio; + + if ((type === 'contain' && adjustedWidth > width) || (type === 'cover' && adjustedWidth < width)) { + height = width / aspectRatio; + } else { + width = height * aspectRatio; + } + } else if (isValidNumber(width)) { + height = width / aspectRatio; + } else if (isValidNumber(height)) { + width = height * aspectRatio; + } + + return { + width, + height, + }; +} + +/** + * Get the new sizes of a rectangle after rotated. + * @param {Object} data - The original sizes. + * @returns {Object} The result sizes. + */ +export function getRotatedSizes({ width, height, degree }) { + degree = Math.abs(degree) % 180; + + if (degree === 90) { + return { + width: height, + height: width, + }; + } + + const arc = ((degree % 90) * Math.PI) / 180; + const sinArc = Math.sin(arc); + const cosArc = Math.cos(arc); + const newWidth = (width * cosArc) + (height * sinArc); + const newHeight = (width * sinArc) + (height * cosArc); + + return degree > 90 ? { + width: newHeight, + height: newWidth, + } : { + width: newWidth, + height: newHeight, + }; +} + +/** + * Get a canvas which drew the given image. + * @param {HTMLImageElement} image - The image for drawing. + * @param {Object} imageData - The image data. + * @param {Object} canvasData - The canvas data. + * @param {Object} options - The options. + * @returns {HTMLCanvasElement} The result canvas. + */ +export function getSourceCanvas( + image, + { + rotate = 0, + scaleX = 1, + scaleY = 1, + }, + { + aspectRatio, + naturalWidth, + naturalHeight, + }, + { + fillColor = 'transparent', + imageSmoothingEnabled = true, + imageSmoothingQuality = 'low', + maxWidth = Infinity, + maxHeight = Infinity, + minWidth = 0, + minHeight = 0, + }, +) { + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + const maxSizes = getAdjustedSizes({ + aspectRatio, + width: maxWidth, + height: maxHeight, + }); + const minSizes = getAdjustedSizes({ + aspectRatio, + width: minWidth, + height: minHeight, + }, 'cover'); + const width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth)); + const height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight)); + const params = [ + -width / 2, + -height / 2, + width, + height, + ]; + + canvas.width = normalizeDecimalNumber(width); + canvas.height = normalizeDecimalNumber(height); + context.fillStyle = fillColor; + context.fillRect(0, 0, width, height); + context.save(); + context.translate(width / 2, height / 2); + context.rotate((rotate * Math.PI) / 180); + context.scale(scaleX, scaleY); + context.imageSmoothingEnabled = imageSmoothingEnabled; + context.imageSmoothingQuality = imageSmoothingQuality; + context.drawImage(image, ...params.map(param => Math.floor(normalizeDecimalNumber(param)))); + context.restore(); + return canvas; +} + +const { fromCharCode } = String; + +/** + * Get string from char code in data view. + * @param {DataView} dataView - The data view for read. + * @param {number} start - The start index. + * @param {number} length - The read length. + * @returns {string} The read result. + */ +export function getStringFromCharCode(dataView, start, length) { + let str = ''; + let i; + + length += start; + + for (i = start; i < length; i += 1) { + str += fromCharCode(dataView.getUint8(i)); + } + + return str; +} + +const REGEXP_DATA_URL_HEAD = /^data:.*,/; + +/** + * Transform Data URL to array buffer. + * @param {string} dataURL - The Data URL to transform. + * @returns {ArrayBuffer} The result array buffer. + */ +export function dataURLToArrayBuffer(dataURL) { + const base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, ''); + const binary = atob(base64); + const arrayBuffer = new ArrayBuffer(binary.length); + const uint8 = new Uint8Array(arrayBuffer); + + each(uint8, (value, i) => { + uint8[i] = binary.charCodeAt(i); + }); + + return arrayBuffer; +} + +/** + * Transform array buffer to Data URL. + * @param {ArrayBuffer} arrayBuffer - The array buffer to transform. + * @param {string} mimeType - The mime type of the Data URL. + * @returns {string} The result Data URL. + */ +export function arrayBufferToDataURL(arrayBuffer, mimeType) { + const uint8 = new Uint8Array(arrayBuffer); + let data = ''; + + // TypedArray.prototype.forEach is not supported in some browsers. + each(uint8, (value) => { + data += fromCharCode(value); + }); + + return `data:${mimeType};base64,${btoa(data)}`; +} + +/** + * Get orientation value from given array buffer. + * @param {ArrayBuffer} arrayBuffer - The array buffer to read. + * @returns {number} The read orientation value. + */ +export function getOrientation(arrayBuffer) { + const dataView = new DataView(arrayBuffer); + let orientation; + let littleEndian; + let app1Start; + let ifdStart; + + // Only handle JPEG image (start by 0xFFD8) + if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) { + const length = dataView.byteLength; + let offset = 2; + + while (offset < length) { + if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) { + app1Start = offset; + break; + } + + offset += 1; + } + } + + if (app1Start) { + const exifIDCode = app1Start + 4; + const tiffOffset = app1Start + 10; + + if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') { + const endianness = dataView.getUint16(tiffOffset); + + littleEndian = endianness === 0x4949; + + if (littleEndian || endianness === 0x4D4D /* bigEndian */) { + if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) { + const firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian); + + if (firstIFDOffset >= 0x00000008) { + ifdStart = tiffOffset + firstIFDOffset; + } + } + } + } + } + + if (ifdStart) { + const length = dataView.getUint16(ifdStart, littleEndian); + let offset; + let i; + + for (i = 0; i < length; i += 1) { + offset = ifdStart + (i * 12) + 2; + + if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) { + // 8 is the offset of the current tag's value + offset += 8; + + // Get the original orientation value + orientation = dataView.getUint16(offset, littleEndian); + + // Override the orientation with its default value + dataView.setUint16(offset, 1, littleEndian); + break; + } + } + } + + return orientation; +} + +/** + * Parse Exif Orientation value. + * @param {number} orientation - The orientation to parse. + * @returns {Object} The parsed result. + */ +export function parseOrientation(orientation) { + let rotate = 0; + let scaleX = 1; + let scaleY = 1; + + switch (orientation) { + // Flip horizontal + case 2: + scaleX = -1; + break; + + // Rotate left 180° + case 3: + rotate = -180; + break; + + // Flip vertical + case 4: + scaleY = -1; + break; + + // Flip vertical and rotate right 90° + case 5: + rotate = 90; + scaleY = -1; + break; + + // Rotate right 90° + case 6: + rotate = 90; + break; + + // Flip horizontal and rotate right 90° + case 7: + rotate = 90; + scaleX = -1; + break; + + // Rotate left 90° + case 8: + rotate = -90; + break; + + default: + } + + return { + rotate, + scaleX, + scaleY, + }; +} diff --git a/library/cropperjs/test/css/main.css b/library/cropperjs/test/css/main.css new file mode 100644 index 000000000..6a86d123c --- /dev/null +++ b/library/cropperjs/test/css/main.css @@ -0,0 +1,9 @@ +.container { + max-width: 640px; + max-height: 360px; + margin: 20px auto; +} + +.container > img { + max-width: 100%; +} diff --git a/library/cropperjs/test/events/crop.js b/library/cropperjs/test/events/crop.js new file mode 100644 index 000000000..1f769cf60 --- /dev/null +++ b/library/cropperjs/test/events/crop.js @@ -0,0 +1,21 @@ +QUnit.test('events#crop', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(7); + + image.addEventListener('crop', function (e) { + assert.ok(util.isNumber(e.detail.x)); + assert.ok(util.isNumber(e.detail.y)); + assert.ok(util.isNumber(e.detail.width)); + assert.ok(util.isNumber(e.detail.height)); + assert.ok(util.isNumber(e.detail.rotate)); + assert.ok(util.isNumber(e.detail.scaleX)); + assert.ok(util.isNumber(e.detail.scaleY)); + + done(); + }); + + return new Cropper(image); +}); diff --git a/library/cropperjs/test/events/cropend.js b/library/cropperjs/test/events/cropend.js new file mode 100644 index 000000000..1f18fb435 --- /dev/null +++ b/library/cropperjs/test/events/cropend.js @@ -0,0 +1,24 @@ +QUnit.test('events#cropend', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + image.addEventListener('ready', function () { + var PointerEvent = window.PointerEvent; + var cropper = this.cropper; + + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup'); + + done(); + }); + + image.addEventListener('cropend', function (e) { + assert.strictEqual(e.detail.action, 'crop'); + }); + + return new Cropper(image); +}); diff --git a/library/cropperjs/test/events/cropmove.js b/library/cropperjs/test/events/cropmove.js new file mode 100644 index 000000000..c695b7fdd --- /dev/null +++ b/library/cropperjs/test/events/cropmove.js @@ -0,0 +1,24 @@ +QUnit.test('events#cropmove', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + image.addEventListener('ready', function () { + var PointerEvent = window.PointerEvent; + var cropper = this.cropper; + + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup'); + + done(); + }); + + image.addEventListener('cropmove', function (e) { + assert.strictEqual(e.detail.action, 'crop'); + }); + + return new Cropper(image); +}); diff --git a/library/cropperjs/test/events/cropstart.js b/library/cropperjs/test/events/cropstart.js new file mode 100644 index 000000000..7d9b597a0 --- /dev/null +++ b/library/cropperjs/test/events/cropstart.js @@ -0,0 +1,56 @@ +QUnit.test('events#cropstart', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + image.addEventListener('ready', function () { + var PointerEvent = window.PointerEvent; + var cropper = this.cropper; + + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup'); + + done(); + }); + + image.addEventListener('cropstart', function (e) { + assert.strictEqual(e.detail.action, 'crop'); + }); + + return new Cropper(image); +}); + +QUnit.test('events#cropstart: default prevented', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(0); + + image.addEventListener('ready', function () { + var PointerEvent = window.PointerEvent; + var cropper = this.cropper; + + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup'); + + done(); + }); + + image.addEventListener('cropstart', function (e) { + e.preventDefault(); + }); + + image.addEventListener('cropmove', function () { + assert.ok(false); + }); + + image.addEventListener('cropend', function () { + assert.ok(false); + }); + + return new Cropper(image); +}); diff --git a/library/cropperjs/test/events/ready.js b/library/cropperjs/test/events/ready.js new file mode 100644 index 000000000..fbec2ff0c --- /dev/null +++ b/library/cropperjs/test/events/ready.js @@ -0,0 +1,15 @@ +QUnit.test('events#ready', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + image.addEventListener('ready', function () { + assert.ok(true); + + done(); + }); + + return new Cropper(image); +}); diff --git a/library/cropperjs/test/events/zoom.js b/library/cropperjs/test/events/zoom.js new file mode 100644 index 000000000..99fda34b5 --- /dev/null +++ b/library/cropperjs/test/events/zoom.js @@ -0,0 +1,46 @@ +QUnit.test('events#zoom', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(3); + + image.addEventListener('ready', function () { + var cropper = this.cropper; + + cropper.zoom(0.1); + + done(); + }); + + image.addEventListener('zoom', function (e) { + assert.ok(e.detail.ratio > 0); + assert.ok(e.detail.oldRatio > 0); + assert.ok(e.detail.ratio > e.detail.oldRatio); + }); + + return new Cropper(image); +}); + +QUnit.test('events#zoom: default prevented', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + image.addEventListener('ready', function () { + var cropper = this.cropper; + var canvasData = cropper.getCanvasData(); + + assert.deepEqual(cropper.zoom(0.1).getCanvasData(), canvasData); + + done(); + }); + + image.addEventListener('zoom', function (e) { + e.preventDefault(); + }); + + return new Cropper(image); +}); diff --git a/library/cropperjs/test/index.html b/library/cropperjs/test/index.html new file mode 100644 index 000000000..bdcaf6b21 --- /dev/null +++ b/library/cropperjs/test/index.html @@ -0,0 +1,90 @@ + + + + + + + Cropper.js + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/cropperjs/test/js/main.js b/library/cropperjs/test/js/main.js new file mode 100644 index 000000000..79fda799f --- /dev/null +++ b/library/cropperjs/test/js/main.js @@ -0,0 +1,74 @@ +window.Util = { + isNumber: function (n) { + return typeof n === 'number' && !isNaN(n); + }, + isFunction: function (fn) { + return typeof fn === 'function'; + }, + hasClass: function (element, className) { + return element.classList.contains(className); + }, + getByClass: function (element, className) { + return element.getElementsByClassName ? + element.getElementsByClassName(className) : + element.querySelectorAll('.' + className); + }, + createImage: function (attrs) { + var container = document.createElement('div'); + var image = new Image(); + var attr; + + if (typeof attrs !== 'object') { + attrs = {}; + } + + if (!attrs.src) { + attrs.src = '../docs/images/picture.jpg'; + } + + for (attr in attrs) { + if (attrs.hasOwnProperty(attr)) { + image[attr] = attrs[attr]; + } + } + + container.className = 'container'; + container.appendChild(image); + document.body.appendChild(container); + + return image; + }, + dispatchEvent: function (element, type, data) { + var event; + + if (element.dispatchEvent) { + // Event and CustomEvent on IE9-11 are global objects, not constructors + if (typeof Event === 'function' && typeof CustomEvent === 'function') { + if (!data) { + event = new Event(type, { + bubbles: true, + cancelable: true + }); + } else { + event = new CustomEvent(type, { + detail: data, + bubbles: true, + cancelable: true + }); + } + } else if (!data) { + event = document.createEvent('Event'); + event.initEvent(type, true, true); + } else { + event = document.createEvent('CustomEvent'); + event.initCustomEvent(type, true, true, data); + } + + // IE9+ + return element.dispatchEvent(event); + } else if (element.fireEvent) { + // IE6-10 (native events only) + return element.fireEvent('on' + type); + } + } +}; diff --git a/library/cropperjs/test/methods/clear.js b/library/cropperjs/test/methods/clear.js new file mode 100644 index 000000000..6510ebad2 --- /dev/null +++ b/library/cropperjs/test/methods/clear.js @@ -0,0 +1,29 @@ +QUnit.test('methods#clear', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(4); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + + cropper.clear(); + assert.notOk(cropper.cropped); + assert.deepEqual(cropper.getData(), { + x: 0, + y: 0, + width: 0, + height: 0, + rotate: 0, + scaleX: 1, + scaleY: 1 + }); + assert.deepEqual(cropper.getCropBoxData(), {}); + assert.ok(util.hasClass(cropper.cropBox, 'cropper-hidden')); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/crop.js b/library/cropperjs/test/methods/crop.js new file mode 100644 index 000000000..e4ae679f1 --- /dev/null +++ b/library/cropperjs/test/methods/crop.js @@ -0,0 +1,24 @@ +QUnit.test('methods#crop', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(4); + + return new Cropper(image, { + autoCrop: false, + + ready: function () { + var cropper = this.cropper; + + assert.notOk(cropper.cropped); + assert.ok(util.hasClass(cropper.cropBox, 'cropper-hidden')); + + cropper.crop(); + assert.ok(cropper.cropped); + assert.notOk(util.hasClass(cropper.cropBox, 'cropper-hidden')); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/destroy.js b/library/cropperjs/test/methods/destroy.js new file mode 100644 index 000000000..cb65e0696 --- /dev/null +++ b/library/cropperjs/test/methods/destroy.js @@ -0,0 +1,22 @@ +QUnit.test('methods#destroy', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(4); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + + assert.ok(typeof cropper === 'object'); + assert.ok(util.hasClass(image, 'cropper-hidden')); + + cropper.destroy(); + assert.ok(typeof this.cropper === 'undefined'); + assert.notOk(util.hasClass(image, 'cropper-hidden')); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/disable.js b/library/cropperjs/test/methods/disable.js new file mode 100644 index 000000000..c87f7aa91 --- /dev/null +++ b/library/cropperjs/test/methods/disable.js @@ -0,0 +1,60 @@ +QUnit.test('methods#disable', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(11); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var options = cropper.options; + var cropBoxData; + var canvasData; + var imageData; + var action; + + cropper.disable(); + assert.ok(cropper.disabled); + assert.ok(util.hasClass(cropper.cropper, 'cropper-disabled')); + + cropBoxData = cropper.getCropBoxData(); + cropper.clear(); + assert.deepEqual(cropper.getCropBoxData(), cropBoxData); + + imageData = cropper.getImageData(); + cropper.move(10, 10); + assert.deepEqual(cropper.getImageData(), imageData); + + cropper.zoom(0.5); + assert.strictEqual(cropper.getImageData().ratio, imageData.ratio); + + cropper.rotate(15); + assert.strictEqual(cropper.getImageData().rotate, imageData.rotate); + + cropper.scale(-1); + assert.strictEqual(cropper.getImageData().scaleX, imageData.scaleX); + + canvasData = cropper.getCanvasData(); + cropper.setCanvasData({ + width: canvasData.width - 160 + }); + assert.deepEqual(cropper.getCanvasData(), canvasData); + + cropBoxData = cropper.getCropBoxData(); + cropper.setCropBoxData({ + height: cropBoxData.height - 90 + }); + assert.deepEqual(cropper.getCropBoxData(), cropBoxData); + + cropper.setAspectRatio(0.618); + assert.ok(isNaN(options.aspectRatio)); + + action = cropper.dragBox.dataset.action; + cropper.setDragMode('none'); + assert.strictEqual(cropper.dragBox.dataset.action, action); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/enable.js b/library/cropperjs/test/methods/enable.js new file mode 100644 index 000000000..ebd5b9529 --- /dev/null +++ b/library/cropperjs/test/methods/enable.js @@ -0,0 +1,23 @@ +QUnit.test('methods#enable', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(4); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + + cropper.disable(); + assert.ok(cropper.disabled); + assert.ok(util.hasClass(cropper.cropper, 'cropper-disabled')); + + cropper.enable(); + assert.notOk(cropper.disabled); + assert.notOk(util.hasClass(cropper.cropper, 'cropper-disabled')); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/getCanvasData.js b/library/cropperjs/test/methods/getCanvasData.js new file mode 100644 index 000000000..60d96af4e --- /dev/null +++ b/library/cropperjs/test/methods/getCanvasData.js @@ -0,0 +1,23 @@ +QUnit.test('methods#getCanvasData', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(6); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.getCanvasData(); + + assert.ok(util.isNumber(canvasData.left)); + assert.ok(util.isNumber(canvasData.top)); + assert.ok(util.isNumber(canvasData.width)); + assert.ok(util.isNumber(canvasData.height)); + assert.ok(util.isNumber(canvasData.naturalWidth)); + assert.ok(util.isNumber(canvasData.naturalHeight)); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/getContainerData.js b/library/cropperjs/test/methods/getContainerData.js new file mode 100644 index 000000000..094421ba0 --- /dev/null +++ b/library/cropperjs/test/methods/getContainerData.js @@ -0,0 +1,19 @@ +QUnit.test('methods#getContainerData', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var containerData = cropper.getContainerData(); + + assert.ok(util.isNumber(containerData.width)); + assert.ok(util.isNumber(containerData.height)); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/getCropBoxData.js b/library/cropperjs/test/methods/getCropBoxData.js new file mode 100644 index 000000000..844c7953e --- /dev/null +++ b/library/cropperjs/test/methods/getCropBoxData.js @@ -0,0 +1,21 @@ +QUnit.test('methods#getCropBoxData', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(4); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var cropBoxData = cropper.getCropBoxData(); + + assert.ok(util.isNumber(cropBoxData.left)); + assert.ok(util.isNumber(cropBoxData.top)); + assert.ok(util.isNumber(cropBoxData.width)); + assert.ok(util.isNumber(cropBoxData.height)); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/getCroppedCanvas.js b/library/cropperjs/test/methods/getCroppedCanvas.js new file mode 100644 index 000000000..4117497a5 --- /dev/null +++ b/library/cropperjs/test/methods/getCroppedCanvas.js @@ -0,0 +1,33 @@ +QUnit.test('methods#getCroppedCanvas', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(7); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var canvas = cropper.getCroppedCanvas({ + width: 160, + height: 90 + }); + var pixelData; + + assert.ok(canvas instanceof HTMLCanvasElement); + assert.strictEqual(canvas.width, 160); + assert.strictEqual(canvas.height, 90); + + canvas = cropper.rotate(90).getCroppedCanvas({ + fillColor: '#010101' + }); + pixelData = canvas.getContext('2d').getImageData(0, 0, 1, 1).data; + assert.strictEqual(pixelData[0], 1, 'red is 1'); + assert.strictEqual(pixelData[1], 1, 'green is 1'); + assert.strictEqual(pixelData[2], 1, 'blue is 1'); + assert.strictEqual(pixelData[3], 255, 'color is opaque'); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/getData.js b/library/cropperjs/test/methods/getData.js new file mode 100644 index 000000000..9c519eb7f --- /dev/null +++ b/library/cropperjs/test/methods/getData.js @@ -0,0 +1,46 @@ +QUnit.test('methods#getData', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(7); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var data = cropper.getData(); + + assert.ok(util.isNumber(data.x)); + assert.ok(util.isNumber(data.y)); + assert.ok(util.isNumber(data.width)); + assert.ok(util.isNumber(data.height)); + assert.ok(util.isNumber(data.rotate)); + assert.ok(util.isNumber(data.scaleX)); + assert.ok(util.isNumber(data.scaleY)); + + done(); + } + }); +}); + +QUnit.test('methods#getData: rounded', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(4); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var data = cropper.getData(true); + + assert.ok(data.x % 1 === 0); + assert.ok(data.y % 1 === 0); + assert.ok(data.width % 1 === 0); + assert.ok(data.height % 1 === 0); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/getImageData.js b/library/cropperjs/test/methods/getImageData.js new file mode 100644 index 000000000..bd6e1941d --- /dev/null +++ b/library/cropperjs/test/methods/getImageData.js @@ -0,0 +1,31 @@ +QUnit.test('methods#getImageData', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(10); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var imageData = cropper.getImageData(); + + assert.ok(util.isNumber(imageData.naturalWidth)); + assert.ok(util.isNumber(imageData.naturalHeight)); + assert.ok(util.isNumber(imageData.aspectRatio)); + assert.ok(util.isNumber(imageData.left)); + assert.ok(util.isNumber(imageData.top)); + assert.ok(util.isNumber(imageData.width)); + assert.ok(util.isNumber(imageData.height)); + + imageData = cropper.rotateTo(45).getImageData(); + assert.strictEqual(imageData.rotate, 45); + + imageData = cropper.scale(-1, -1).getImageData(); + assert.strictEqual(imageData.scaleX, -1); + assert.strictEqual(imageData.scaleY, -1); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/move.js b/library/cropperjs/test/methods/move.js new file mode 100644 index 000000000..c2ead8412 --- /dev/null +++ b/library/cropperjs/test/methods/move.js @@ -0,0 +1,20 @@ +QUnit.test('methods#move', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.getCanvasData(); + var changedCanvasData = cropper.move(1, 1).getCanvasData(); + + assert.strictEqual(changedCanvasData.left, canvasData.left + 1); + assert.strictEqual(changedCanvasData.top, canvasData.top + 1); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/moveTo.js b/library/cropperjs/test/methods/moveTo.js new file mode 100644 index 000000000..e8bf0eebd --- /dev/null +++ b/library/cropperjs/test/methods/moveTo.js @@ -0,0 +1,19 @@ +QUnit.test('methods#moveTo', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.moveTo(0, 0).getCanvasData(); + + assert.strictEqual(canvasData.left, 0); + assert.strictEqual(canvasData.top, 0); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/replace.js b/library/cropperjs/test/methods/replace.js new file mode 100644 index 000000000..3fc8fe0b6 --- /dev/null +++ b/library/cropperjs/test/methods/replace.js @@ -0,0 +1,23 @@ +QUnit.test('methods#replace', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + + cropper.options.ready = function () { + assert.notOk(cropper.cropped); + cropper.crop(); + assert.ok(cropper.cropped); + done(); + }; + + cropper.options.autoCrop = false; + cropper.replace('../docs/images/picture-2.jpg'); + } + }); +}); diff --git a/library/cropperjs/test/methods/reset.js b/library/cropperjs/test/methods/reset.js new file mode 100644 index 000000000..3e047394c --- /dev/null +++ b/library/cropperjs/test/methods/reset.js @@ -0,0 +1,35 @@ +QUnit.test('methods#reset', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(4); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.getCanvasData(); + var cropBoxData = cropper.getCropBoxData(); + + cropper.setCanvasData({ + top: canvasData.top + 10, + width: canvasData.width - 10 + }); + + assert.notDeepEqual(cropper.getCanvasData(), canvasData); + + cropper.setCropBoxData({ + left: cropBoxData.left + 10, + height: cropBoxData.height - 10 + }); + + assert.notDeepEqual(cropper.getCropBoxData(), cropBoxData); + + cropper.reset(); + assert.deepEqual(cropper.getCanvasData(), canvasData); + assert.deepEqual(cropper.getCropBoxData(), cropBoxData); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/rotate.js b/library/cropperjs/test/methods/rotate.js new file mode 100644 index 000000000..749096f0b --- /dev/null +++ b/library/cropperjs/test/methods/rotate.js @@ -0,0 +1,19 @@ +QUnit.test('methods#rotate', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(3); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + + assert.strictEqual(cropper.rotate(360).getImageData().rotate, 0); + assert.strictEqual(cropper.rotate(90).getImageData().rotate, 90); + assert.strictEqual(cropper.rotate(-180).getImageData().rotate, -90); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/rotateTo.js b/library/cropperjs/test/methods/rotateTo.js new file mode 100644 index 000000000..323431e76 --- /dev/null +++ b/library/cropperjs/test/methods/rotateTo.js @@ -0,0 +1,20 @@ +QUnit.test('methods#rotateTo', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(4); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + + assert.strictEqual(cropper.rotateTo(360).getImageData().rotate, 0); + assert.strictEqual(cropper.rotateTo(90).getImageData().rotate, 90); + assert.strictEqual(cropper.rotateTo(0).getImageData().rotate, 0); + assert.strictEqual(cropper.rotateTo(-180).getImageData().rotate, -180); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/scale.js b/library/cropperjs/test/methods/scale.js new file mode 100644 index 000000000..be1caa589 --- /dev/null +++ b/library/cropperjs/test/methods/scale.js @@ -0,0 +1,19 @@ +QUnit.test('methods#scale', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var imageData = cropper.scale(-1, -1).getImageData(); + + assert.strictEqual(imageData.scaleX, -1); + assert.strictEqual(imageData.scaleY, -1); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/scaleX.js b/library/cropperjs/test/methods/scaleX.js new file mode 100644 index 000000000..c799df58d --- /dev/null +++ b/library/cropperjs/test/methods/scaleX.js @@ -0,0 +1,18 @@ +QUnit.test('methods#scaleX', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var imageData = cropper.scaleX(-1).getImageData(); + + assert.strictEqual(imageData.scaleX, -1); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/scaleY.js b/library/cropperjs/test/methods/scaleY.js new file mode 100644 index 000000000..026b93a1f --- /dev/null +++ b/library/cropperjs/test/methods/scaleY.js @@ -0,0 +1,18 @@ +QUnit.test('methods#scaleY', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var imageData = cropper.scaleY(-1).getImageData(); + + assert.strictEqual(imageData.scaleY, -1); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/setAspectRatio.js b/library/cropperjs/test/methods/setAspectRatio.js new file mode 100644 index 000000000..ddf46798d --- /dev/null +++ b/library/cropperjs/test/methods/setAspectRatio.js @@ -0,0 +1,20 @@ +QUnit.test('methods#setAspectRatio', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var options = cropper.options; + + assert.ok(isNaN(options.aspectRatio)); + cropper.setAspectRatio(1); + assert.strictEqual(options.aspectRatio, 1); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/setCanvasData.js b/library/cropperjs/test/methods/setCanvasData.js new file mode 100644 index 000000000..e8f6511dc --- /dev/null +++ b/library/cropperjs/test/methods/setCanvasData.js @@ -0,0 +1,34 @@ +QUnit.test('methods#setCanvasData', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(6); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.getCanvasData(); + var changedCanvasData = cropper.setCanvasData({ + left: 16, + top: 9 + }).getCanvasData(); + + assert.notStrictEqual(changedCanvasData.left, canvasData.left); + assert.notStrictEqual(changedCanvasData.top, canvasData.top); + assert.strictEqual(changedCanvasData.width, canvasData.width); + assert.strictEqual(changedCanvasData.height, canvasData.height); + + canvasData = cropper.getCanvasData(); + changedCanvasData = cropper.setCanvasData({ + width: 320, + height: 180 + }).getCanvasData(); + + assert.notStrictEqual(changedCanvasData.width, canvasData.width); + assert.notStrictEqual(changedCanvasData.height, canvasData.height); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/setCropBoxData.js b/library/cropperjs/test/methods/setCropBoxData.js new file mode 100644 index 000000000..e78767cfc --- /dev/null +++ b/library/cropperjs/test/methods/setCropBoxData.js @@ -0,0 +1,36 @@ +QUnit.test('methods#setCropBoxData', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(8); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var cropBoxData = cropper.getCropBoxData(); + var changedCropBoxData = cropper.setCropBoxData({ + left: 16, + top: 9 + }).getCropBoxData(); + + assert.notStrictEqual(changedCropBoxData.left, cropBoxData.left); + assert.notStrictEqual(changedCropBoxData.top, cropBoxData.top); + assert.strictEqual(changedCropBoxData.width, cropBoxData.width); + assert.strictEqual(changedCropBoxData.height, cropBoxData.height); + + cropBoxData = cropper.getCropBoxData(); + changedCropBoxData = cropper.setCropBoxData({ + width: 320, + height: 180 + }).getCropBoxData(); + + assert.strictEqual(changedCropBoxData.left, cropBoxData.left); + assert.strictEqual(changedCropBoxData.top, cropBoxData.top); + assert.notStrictEqual(changedCropBoxData.width, cropBoxData.width); + assert.notStrictEqual(changedCropBoxData.height, cropBoxData.height); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/setData.js b/library/cropperjs/test/methods/setData.js new file mode 100644 index 000000000..4e1360f09 --- /dev/null +++ b/library/cropperjs/test/methods/setData.js @@ -0,0 +1,36 @@ +QUnit.test('methods#setData', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(8); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var data = cropper.getData(); + var changedData = cropper.setData({ + x: 16, + y: 9 + }).getData(); + + assert.notStrictEqual(changedData.x, data.x); + assert.notStrictEqual(changedData.y, data.y); + assert.strictEqual(changedData.width, data.width); + assert.strictEqual(changedData.height, data.height); + + data = cropper.getData(); + changedData = cropper.setData({ + width: 320, + height: 180 + }).getData(); + + assert.strictEqual(changedData.x, data.x); + assert.strictEqual(changedData.y, data.y); + assert.notStrictEqual(changedData.width, data.width); + assert.notStrictEqual(changedData.height, data.height); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/setDragMode.js b/library/cropperjs/test/methods/setDragMode.js new file mode 100644 index 000000000..1b611af9b --- /dev/null +++ b/library/cropperjs/test/methods/setDragMode.js @@ -0,0 +1,27 @@ +QUnit.test('methods#setDragMode', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(4); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var dragBox = cropper.dragBox; + + assert.strictEqual(dragBox.dataset.action, 'crop'); + + cropper.setDragMode('move'); + assert.strictEqual(dragBox.dataset.action, 'move'); + + cropper.setDragMode('crop'); + assert.strictEqual(dragBox.dataset.action, 'crop'); + + cropper.setDragMode('none'); + assert.strictEqual(dragBox.dataset.action, 'none'); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/zoom.js b/library/cropperjs/test/methods/zoom.js new file mode 100644 index 000000000..70a1a763a --- /dev/null +++ b/library/cropperjs/test/methods/zoom.js @@ -0,0 +1,20 @@ +QUnit.test('methods#zoom', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.getCanvasData(); + var changedCanvasData = cropper.zoom(0.1).getCanvasData(); + + assert.ok(changedCanvasData.width > canvasData.width); + assert.ok(changedCanvasData.height > canvasData.height); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/methods/zoomTo.js b/library/cropperjs/test/methods/zoomTo.js new file mode 100644 index 000000000..dd9e81760 --- /dev/null +++ b/library/cropperjs/test/methods/zoomTo.js @@ -0,0 +1,21 @@ +QUnit.test('methods#zoomTo', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(3); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var imageData = cropper.zoomTo(1).getImageData(); + var canvasData = cropper.getCanvasData(); + + assert.strictEqual(imageData.width, imageData.naturalWidth); + assert.strictEqual(canvasData.width, canvasData.naturalWidth); + assert.strictEqual(canvasData.naturalWidth, imageData.naturalWidth); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/aspectRatio.js b/library/cropperjs/test/options/aspectRatio.js new file mode 100644 index 000000000..d7ba89401 --- /dev/null +++ b/library/cropperjs/test/options/aspectRatio.js @@ -0,0 +1,39 @@ +QUnit.test('options#aspectRatio: NaN', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + // aspectRatio: NaN, + + ready: function () { + var cropper = this.cropper; + + assert.ok(isNaN(cropper.options.aspectRatio)); + + done(); + } + }); +}); + +QUnit.test('options#aspectRatio: 1', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + aspectRatio: 1, + + ready: function () { + var cropper = this.cropper; + + assert.strictEqual(cropper.options.aspectRatio, 1); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/autoCrop.js b/library/cropperjs/test/options/autoCrop.js new file mode 100644 index 000000000..f010966eb --- /dev/null +++ b/library/cropperjs/test/options/autoCrop.js @@ -0,0 +1,39 @@ +QUnit.test('options#autoCrop: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + // autoCrop: true, + + ready: function () { + var cropper = this.cropper; + + assert.ok(cropper.cropped); + + done(); + } + }); +}); + +QUnit.test('options#autoCrop: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + autoCrop: false, + + ready: function () { + var cropper = this.cropper; + + assert.notOk(cropper.cropped); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/background.js b/library/cropperjs/test/options/background.js new file mode 100644 index 000000000..21dbb8b12 --- /dev/null +++ b/library/cropperjs/test/options/background.js @@ -0,0 +1,40 @@ +QUnit.test('options#background: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + // background: true, + + ready: function () { + var cropper = this.cropper; + + assert.ok(util.hasClass(cropper.cropper, 'cropper-bg')); + + done(); + } + }); +}); + +QUnit.test('options#background: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + background: false, + + ready: function () { + var cropper = this.cropper; + + assert.notOk(util.hasClass(cropper.cropper, 'cropper-bg')); + + done(); + } + }); + +}); diff --git a/library/cropperjs/test/options/center.js b/library/cropperjs/test/options/center.js new file mode 100644 index 000000000..5d45eb021 --- /dev/null +++ b/library/cropperjs/test/options/center.js @@ -0,0 +1,41 @@ +QUnit.test('options#center: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + // center: true, + + ready: function () { + var cropper = this.cropper; + var center = util.getByClass(cropper.cropBox, 'cropper-center'); + + assert.notOk(util.hasClass(center[0], 'cropper-hidden')); + + done(); + } + }); +}); + +QUnit.test('options#center: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + center: false, + + ready: function () { + var cropper = this.cropper; + var center = util.getByClass(cropper.cropBox, 'cropper-center'); + + assert.ok(util.hasClass(center[0], 'cropper-hidden')); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/checkCrossOrigin.js b/library/cropperjs/test/options/checkCrossOrigin.js new file mode 100644 index 000000000..86fde8f6f --- /dev/null +++ b/library/cropperjs/test/options/checkCrossOrigin.js @@ -0,0 +1,67 @@ +QUnit.test('options#checkCrossOrigin: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage({ + src: 'https://fengyuanchen.github.io/cropperjs/images/picture.jpg' + }); + + assert.expect(2); + + return new Cropper(image, { + // checkCrossOrigin: true, + + ready: function () { + var cropper = this.cropper; + + assert.strictEqual(cropper.image.crossOrigin, 'anonymous'); + assert.ok(cropper.image.src.indexOf('timestamp') >= 0); + + done(); + } + }); +}); + +QUnit.test('options#checkCrossOrigin: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage({ + src: 'https://fengyuanchen.github.io/cropperjs/images/picture.jpg' + }); + + assert.expect(2); + + return new Cropper(image, { + checkCrossOrigin: false, + + ready: function () { + var cropper = this.cropper; + + assert.notStrictEqual(cropper.image.crossOrigin, 'anonymous'); + assert.ok(cropper.image.src.indexOf('timestamp') < 0); + + done(); + } + }); +}); + +QUnit.test('options#checkCrossOrigin: exists crossOrigin attribute', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage({ + src: 'https://fengyuanchen.github.io/cropperjs/images/picture.jpg', + crossOrigin: 'anonymous' + }); + + assert.expect(2); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + + assert.strictEqual(cropper.image.crossOrigin, 'anonymous'); + assert.ok(cropper.image.src.indexOf('timestamp') < 0); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/checkOrientation.js b/library/cropperjs/test/options/checkOrientation.js new file mode 100644 index 000000000..0fe548404 --- /dev/null +++ b/library/cropperjs/test/options/checkOrientation.js @@ -0,0 +1,43 @@ +QUnit.test('options#checkOrientation: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage({ + src: '../docs/images/picture-3.jpg' + }); + + assert.expect(1); + + return new Cropper(image, { + // checkOrientation: true, + + ready: function () { + var cropper = this.cropper; + + assert.notStrictEqual(cropper.getData().rotate, 0); + + done(); + } + }); +}); + +QUnit.test('options#checkOrientation: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage({ + src: '../docs/images/picture-3.jpg' + }); + + assert.expect(1); + + return new Cropper(image, { + checkOrientation: false, + + ready: function () { + var cropper = this.cropper; + + assert.strictEqual(cropper.getData().rotate, 0); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/crop.js b/library/cropperjs/test/options/crop.js new file mode 100644 index 000000000..a4b48585e --- /dev/null +++ b/library/cropperjs/test/options/crop.js @@ -0,0 +1,21 @@ +QUnit.test('options#crop', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(7); + + return new Cropper(image, { + crop: function (e) { + assert.ok(util.isNumber(e.detail.x)); + assert.ok(util.isNumber(e.detail.y)); + assert.ok(util.isNumber(e.detail.width)); + assert.ok(util.isNumber(e.detail.height)); + assert.ok(util.isNumber(e.detail.rotate)); + assert.ok(util.isNumber(e.detail.scaleX)); + assert.ok(util.isNumber(e.detail.scaleY)); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/cropBoxMovable.js b/library/cropperjs/test/options/cropBoxMovable.js new file mode 100644 index 000000000..d5d3e1d7d --- /dev/null +++ b/library/cropperjs/test/options/cropBoxMovable.js @@ -0,0 +1,41 @@ +QUnit.test('options#cropBoxMovable: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + // cropBoxMovable: true, + + ready: function () { + var cropper = this.cropper; + var face = util.getByClass(cropper.cropBox, 'cropper-face'); + + assert.strictEqual(face[0].dataset.action, 'all'); + + done(); + } + }); +}); + +QUnit.test('options#cropBoxMovable: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + cropBoxMovable: false, + + ready: function () { + var cropper = this.cropper; + var face = util.getByClass(cropper.cropBox, 'cropper-face'); + + assert.strictEqual(face[0].dataset.action, cropper.options.dragMode); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/cropBoxResizable.js b/library/cropperjs/test/options/cropBoxResizable.js new file mode 100644 index 000000000..37093642b --- /dev/null +++ b/library/cropperjs/test/options/cropBoxResizable.js @@ -0,0 +1,65 @@ +QUnit.test('options#cropBoxResizable: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(12); + + return new Cropper(image, { + // cropBoxResizable: true, + + ready: function () { + var cropper = this.cropper; + var line = util.getByClass(cropper.cropBox, 'cropper-line'); + var point = util.getByClass(cropper.cropBox, 'cropper-point'); + + assert.notOk(util.hasClass(line[0], 'cropper-hidden')); + assert.notOk(util.hasClass(line[1], 'cropper-hidden')); + assert.notOk(util.hasClass(line[2], 'cropper-hidden')); + assert.notOk(util.hasClass(line[3], 'cropper-hidden')); + assert.notOk(util.hasClass(point[0], 'cropper-hidden')); + assert.notOk(util.hasClass(point[1], 'cropper-hidden')); + assert.notOk(util.hasClass(point[2], 'cropper-hidden')); + assert.notOk(util.hasClass(point[3], 'cropper-hidden')); + assert.notOk(util.hasClass(point[4], 'cropper-hidden')); + assert.notOk(util.hasClass(point[5], 'cropper-hidden')); + assert.notOk(util.hasClass(point[6], 'cropper-hidden')); + assert.notOk(util.hasClass(point[7], 'cropper-hidden')); + + done(); + } + }); +}); + +QUnit.test('options#cropBoxResizable: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(12); + + return new Cropper(image, { + cropBoxResizable: false, + + ready: function () { + var cropper = this.cropper; + var line = util.getByClass(cropper.cropBox, 'cropper-line'); + var point = util.getByClass(cropper.cropBox, 'cropper-point'); + + assert.ok(util.hasClass(line[0], 'cropper-hidden')); + assert.ok(util.hasClass(line[1], 'cropper-hidden')); + assert.ok(util.hasClass(line[2], 'cropper-hidden')); + assert.ok(util.hasClass(line[3], 'cropper-hidden')); + assert.ok(util.hasClass(point[0], 'cropper-hidden')); + assert.ok(util.hasClass(point[1], 'cropper-hidden')); + assert.ok(util.hasClass(point[2], 'cropper-hidden')); + assert.ok(util.hasClass(point[3], 'cropper-hidden')); + assert.ok(util.hasClass(point[4], 'cropper-hidden')); + assert.ok(util.hasClass(point[5], 'cropper-hidden')); + assert.ok(util.hasClass(point[6], 'cropper-hidden')); + assert.ok(util.hasClass(point[7], 'cropper-hidden')); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/cropend.js b/library/cropperjs/test/options/cropend.js new file mode 100644 index 000000000..abfe815c0 --- /dev/null +++ b/library/cropperjs/test/options/cropend.js @@ -0,0 +1,24 @@ +QUnit.test('options#cropend', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + ready: function () { + var PointerEvent = window.PointerEvent; + var cropper = this.cropper; + + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup'); + + done(); + }, + + cropend: function (e) { + assert.strictEqual(e.detail.action, 'crop'); + } + }); +}); diff --git a/library/cropperjs/test/options/cropmove.js b/library/cropperjs/test/options/cropmove.js new file mode 100644 index 000000000..fa20f4011 --- /dev/null +++ b/library/cropperjs/test/options/cropmove.js @@ -0,0 +1,24 @@ +QUnit.test('options#cropmove', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + ready: function () { + var PointerEvent = window.PointerEvent; + var cropper = this.cropper; + + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup'); + + done(); + }, + + cropmove: function (e) { + assert.strictEqual(e.detail.action, 'crop'); + } + }); +}); diff --git a/library/cropperjs/test/options/cropstart.js b/library/cropperjs/test/options/cropstart.js new file mode 100644 index 000000000..f547269cd --- /dev/null +++ b/library/cropperjs/test/options/cropstart.js @@ -0,0 +1,56 @@ +QUnit.test('options#cropstart', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + ready: function () { + var PointerEvent = window.PointerEvent; + var cropper = this.cropper; + + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup'); + + done(); + }, + + cropstart: function (e) { + assert.strictEqual(e.detail.action, 'crop'); + } + }); +}); + +QUnit.test('options#cropstart: default prevented', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(0); + + return new Cropper(image, { + ready: function () { + var PointerEvent = window.PointerEvent; + var cropper = this.cropper; + + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove'); + util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup'); + + done(); + }, + + cropstart: function (e) { + e.preventDefault(); + }, + + cropmove: function () { + assert.ok(false); + }, + + cropend: function () { + assert.ok(false); + } + }); +}); diff --git a/library/cropperjs/test/options/data.js b/library/cropperjs/test/options/data.js new file mode 100644 index 000000000..e9da6a4dd --- /dev/null +++ b/library/cropperjs/test/options/data.js @@ -0,0 +1,35 @@ +QUnit.test('options#data', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + var initialData = { + x: 360, + y: 450, + width: 640, + height: 360, + rotate: 45, + scaleX: -1, + scaleY: -1 + }; + + assert.expect(7); + + return new Cropper(image, { + data: initialData, + + ready: function () { + var cropper = this.cropper; + var data = cropper.getData(true); + + assert.strictEqual(data.x, initialData.x); + assert.strictEqual(data.y, initialData.y); + assert.strictEqual(data.width, initialData.width); + assert.strictEqual(data.height, initialData.height); + assert.strictEqual(data.rotate, initialData.rotate); + assert.strictEqual(data.scaleX, initialData.scaleX); + assert.strictEqual(data.scaleY, initialData.scaleY); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/dragMode.js b/library/cropperjs/test/options/dragMode.js new file mode 100644 index 000000000..57f31ff13 --- /dev/null +++ b/library/cropperjs/test/options/dragMode.js @@ -0,0 +1,60 @@ +QUnit.test('options#dragMode: crop', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + // dragMode: 'crop', + + ready: function () { + var cropper = this.cropper; + + assert.strictEqual(cropper.dragBox.dataset.action, 'crop'); + + done(); + } + }); +}); + +QUnit.test('options#dragMode: move', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + dragMode: 'move', + + ready: function () { + var cropper = this.cropper; + + assert.strictEqual(cropper.dragBox.dataset.action, 'move'); + + done(); + } + }); +}); + + +QUnit.test('options#dragMode: none', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + dragMode: 'none', + + ready: function () { + var cropper = this.cropper; + + assert.strictEqual(cropper.dragBox.dataset.action, 'none'); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/guides.js b/library/cropperjs/test/options/guides.js new file mode 100644 index 000000000..298c3ad3a --- /dev/null +++ b/library/cropperjs/test/options/guides.js @@ -0,0 +1,43 @@ +QUnit.test('options#guides: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + // guides: true, + + ready: function () { + var cropper = this.cropper; + var dashed = util.getByClass(cropper.cropBox, 'cropper-dashed'); + + assert.notOk(util.hasClass(dashed[0], 'cropper-hidden')); + assert.notOk(util.hasClass(dashed[1], 'cropper-hidden')); + + done(); + } + }); +}); + +QUnit.test('options#guides: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + guides: false, + + ready: function () { + var cropper = this.cropper; + var dashed = util.getByClass(cropper.cropBox, 'cropper-dashed'); + + assert.ok(util.hasClass(dashed[0], 'cropper-hidden')); + assert.ok(util.hasClass(dashed[1], 'cropper-hidden')); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/highlight.js b/library/cropperjs/test/options/highlight.js new file mode 100644 index 000000000..a1db4687f --- /dev/null +++ b/library/cropperjs/test/options/highlight.js @@ -0,0 +1,41 @@ +QUnit.test('options#highlight: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + // highlight: true, + + ready: function () { + var cropper = this.cropper; + var face = util.getByClass(cropper.cropBox, 'cropper-face'); + + assert.notOk(util.hasClass(face[0], 'cropper-invisible')); + + done(); + } + }); +}); + +QUnit.test('options#highlight: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + highlight: false, + + ready: function () { + var cropper = this.cropper; + var face = util.getByClass(cropper.cropBox, 'cropper-face'); + + assert.ok(util.hasClass(face[0], 'cropper-invisible')); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/minCanvasHeight.js b/library/cropperjs/test/options/minCanvasHeight.js new file mode 100644 index 000000000..c9745a9b1 --- /dev/null +++ b/library/cropperjs/test/options/minCanvasHeight.js @@ -0,0 +1,23 @@ +QUnit.test('options#minCanvasHeight', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + var minCanvasHeight = 270; + + assert.expect(1); + + return new Cropper(image, { + minCanvasHeight: minCanvasHeight, + + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.setCanvasData({ + height: 180 + }).getCanvasData(); + + assert.strictEqual(Math.round(canvasData.height), minCanvasHeight); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/minCanvasWidth.js b/library/cropperjs/test/options/minCanvasWidth.js new file mode 100644 index 000000000..61601e4f9 --- /dev/null +++ b/library/cropperjs/test/options/minCanvasWidth.js @@ -0,0 +1,23 @@ +QUnit.test('options#minCanvasWidth', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + var minCanvasWidth = 480; + + assert.expect(1); + + return new Cropper(image, { + minCanvasWidth: minCanvasWidth, + + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.setCanvasData({ + width: 320 + }).getCanvasData(); + + assert.strictEqual(Math.round(canvasData.width), minCanvasWidth); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/minContainerHeight.js b/library/cropperjs/test/options/minContainerHeight.js new file mode 100644 index 000000000..85d7a70ef --- /dev/null +++ b/library/cropperjs/test/options/minContainerHeight.js @@ -0,0 +1,21 @@ +QUnit.test('options#minContainerHeight', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + var minContainerHeight = 361; + + assert.expect(1); + + return new Cropper(image, { + minContainerHeight: minContainerHeight, + + ready: function () { + var cropper = this.cropper; + var containerData = cropper.getContainerData(); + + assert.strictEqual(Math.round(containerData.height), minContainerHeight); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/minContainerWidth.js b/library/cropperjs/test/options/minContainerWidth.js new file mode 100644 index 000000000..2119cc96e --- /dev/null +++ b/library/cropperjs/test/options/minContainerWidth.js @@ -0,0 +1,21 @@ +QUnit.test('options#minContainerWidth', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + var minContainerWidth = 641; + + assert.expect(1); + + return new Cropper(image, { + minContainerWidth: minContainerWidth, + + ready: function () { + var cropper = this.cropper; + var containerData = cropper.getContainerData(); + + assert.strictEqual(Math.round(containerData.width), minContainerWidth); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/minCropBoxHeight.js b/library/cropperjs/test/options/minCropBoxHeight.js new file mode 100644 index 000000000..ccf50aefe --- /dev/null +++ b/library/cropperjs/test/options/minCropBoxHeight.js @@ -0,0 +1,23 @@ +QUnit.test('options#minCropBoxHeight', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + var minCropBoxHeight = 150; + + assert.expect(1); + + return new Cropper(image, { + minCropBoxHeight: minCropBoxHeight, + + ready: function () { + var cropper = this.cropper; + var cropBoxData = cropper.setCropBoxData({ + height: 100 + }).getCropBoxData(); + + assert.strictEqual(Math.round(cropBoxData.height), minCropBoxHeight); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/minCropBoxWidth.js b/library/cropperjs/test/options/minCropBoxWidth.js new file mode 100644 index 000000000..acde5c366 --- /dev/null +++ b/library/cropperjs/test/options/minCropBoxWidth.js @@ -0,0 +1,23 @@ +QUnit.test('options#minCropBoxWidth', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + var minCropBoxWidth = 300; + + assert.expect(1); + + return new Cropper(image, { + minCropBoxWidth: minCropBoxWidth, + + ready: function () { + var cropper = this.cropper; + var cropBoxData = cropper.setCropBoxData({ + width: 200 + }).getCropBoxData(); + + assert.strictEqual(Math.round(cropBoxData.width), minCropBoxWidth); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/modal.js b/library/cropperjs/test/options/modal.js new file mode 100644 index 000000000..7284cb264 --- /dev/null +++ b/library/cropperjs/test/options/modal.js @@ -0,0 +1,39 @@ +QUnit.test('options#modal: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + // modal: true, + + ready: function () { + var cropper = this.cropper; + + assert.ok(util.hasClass(cropper.dragBox, 'cropper-modal')); + + done(); + } + }); +}); + +QUnit.test('options#modal: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + modal: false, + + ready: function () { + var cropper = this.cropper; + + assert.notOk(util.hasClass(cropper.dragBox, 'cropper-modal')); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/movable.js b/library/cropperjs/test/options/movable.js new file mode 100644 index 000000000..0e2c53506 --- /dev/null +++ b/library/cropperjs/test/options/movable.js @@ -0,0 +1,45 @@ +QUnit.test('options#movable: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + // movable: true, + + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.getCanvasData(); + var changedCanvasData = cropper.move(10, 10).getCanvasData(); + + assert.strictEqual(changedCanvasData.left, canvasData.left + 10); + assert.strictEqual(changedCanvasData.top, canvasData.top + 10); + + done(); + } + }); +}); + +QUnit.test('options#movable: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + movable: false, + + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.getCanvasData(); + var changedCanvasData = cropper.move(10, 10).getCanvasData(); + + assert.strictEqual(changedCanvasData.left, canvasData.left); + assert.strictEqual(changedCanvasData.top, canvasData.top); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/ready.js b/library/cropperjs/test/options/ready.js new file mode 100644 index 000000000..e09e8369c --- /dev/null +++ b/library/cropperjs/test/options/ready.js @@ -0,0 +1,15 @@ +QUnit.test('options#ready', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + ready: function () { + assert.ok(true); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/rotatable.js b/library/cropperjs/test/options/rotatable.js new file mode 100644 index 000000000..992e9362f --- /dev/null +++ b/library/cropperjs/test/options/rotatable.js @@ -0,0 +1,39 @@ +QUnit.test('options#rotatable: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + // rotatable: true, + + ready: function () { + var cropper = this.cropper; + + assert.strictEqual(cropper.rotate(90).getImageData().rotate, 90); + + done(); + } + }); +}); + +QUnit.test('options#rotatable: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + rotatable: false, + + ready: function () { + var cropper = this.cropper; + + assert.strictEqual(cropper.rotate(90).getImageData().rotate, undefined); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/scalable.js b/library/cropperjs/test/options/scalable.js new file mode 100644 index 000000000..c523eaf63 --- /dev/null +++ b/library/cropperjs/test/options/scalable.js @@ -0,0 +1,43 @@ +QUnit.test('options#scalable: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + // scalable: true, + + ready: function () { + var cropper = this.cropper; + var imageData = cropper.scale(-1, -1).getImageData(); + + assert.strictEqual(imageData.scaleX, -1); + assert.strictEqual(imageData.scaleY, -1); + + done(); + } + }); +}); + +QUnit.test('options#scalable: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + scalable: false, + + ready: function () { + var cropper = this.cropper; + var imageData = cropper.scale(-1, -1).getImageData(); + + assert.strictEqual(imageData.scaleX, undefined); + assert.strictEqual(imageData.scaleY, undefined); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/toggleDragModeOnDblclick.js b/library/cropperjs/test/options/toggleDragModeOnDblclick.js new file mode 100644 index 000000000..df64327b2 --- /dev/null +++ b/library/cropperjs/test/options/toggleDragModeOnDblclick.js @@ -0,0 +1,45 @@ +QUnit.test('options#toggleDragModeOnDblclick: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + // toggleDragModeOnDblclick: true, + + ready: function () { + var cropper = this.cropper; + var dragBox = cropper.dragBox; + + util.dispatchEvent(dragBox, 'dblclick'); + assert.ok(util.hasClass(dragBox, 'cropper-move')); + assert.strictEqual(dragBox.dataset.action, 'move'); + + done(); + } + }); +}); + +QUnit.test('options#toggleDragModeOnDblclick: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + toggleDragModeOnDblclick: false, + + ready: function () { + var cropper = this.cropper; + var dragBox = cropper.dragBox; + + util.dispatchEvent(dragBox, 'dblclick'); + assert.ok(util.hasClass(dragBox, 'cropper-crop')); + assert.strictEqual(dragBox.dataset.action, 'crop'); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/viewMode.js b/library/cropperjs/test/options/viewMode.js new file mode 100644 index 000000000..e39ec5fc1 --- /dev/null +++ b/library/cropperjs/test/options/viewMode.js @@ -0,0 +1,100 @@ +QUnit.test('options#viewMode: 0', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(4); + + return new Cropper(image, { + // viewMode: 0, + + ready: function () { + var cropper = this.cropper; + var canvasData = { + left: 100, + top: 100, + width: 160, + height: 90 + }; + var changedCanvasData = cropper.setCanvasData(canvasData).getCanvasData(); + + assert.strictEqual(changedCanvasData.left, canvasData.left); + assert.strictEqual(changedCanvasData.top, canvasData.top); + assert.strictEqual(changedCanvasData.width, canvasData.width); + assert.strictEqual(changedCanvasData.height, canvasData.height); + + done(); + } + }); +}); + +QUnit.test('options#viewMode: 1', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + viewMode: 1, + + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.zoom(-0.5).getCanvasData(); // Zoom out + var cropBoxData = cropper.getCropBoxData(); + + assert.ok(canvasData.width >= cropBoxData.width); + assert.ok(canvasData.height >= cropBoxData.height); + + done(); + } + }); +}); + +QUnit.test('options#viewMode: 2', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + viewMode: 2, + + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.zoom(-0.5).getCanvasData(); // Zoom out + var containerData = cropper.getContainerData(); + + assert.ok(canvasData.width >= containerData.width || + canvasData.height >= containerData.height); + + done(); + } + }); +}); + +QUnit.test('options#viewMode: 3', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(4); + + return new Cropper(image, { + viewMode: 3, + + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.zoom(-0.5).getCanvasData(); // Zoom out + var containerData = cropper.getContainerData(); + + assert.ok(canvasData.left <= 0); + assert.ok(canvasData.top <= 0); + assert.ok(canvasData.width >= containerData.width); + assert.ok(canvasData.height >= containerData.height); + + done(); + } + }); +}); diff --git a/library/cropperjs/test/options/zoom.js b/library/cropperjs/test/options/zoom.js new file mode 100644 index 000000000..51ebc76ad --- /dev/null +++ b/library/cropperjs/test/options/zoom.js @@ -0,0 +1,46 @@ +QUnit.test('options#zoom', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(3); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + + cropper.zoom(0.1); + + done(); + }, + + zoom: function (e) { + assert.ok(e.detail.ratio > 0); + assert.ok(e.detail.oldRatio > 0); + assert.ok(e.detail.ratio > e.detail.oldRatio); + } + }); +}); + +QUnit.test('options#zoom: default prevented', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.getCanvasData(); + + assert.deepEqual(cropper.zoom(0.1).getCanvasData(), canvasData); + + done(); + }, + + zoom: function (e) { + e.preventDefault(); + } + }); +}); diff --git a/library/cropperjs/test/options/zoomOnWheel.js b/library/cropperjs/test/options/zoomOnWheel.js new file mode 100644 index 000000000..1a1bf6dce --- /dev/null +++ b/library/cropperjs/test/options/zoomOnWheel.js @@ -0,0 +1,47 @@ +QUnit.test('options#zoomOnWheel: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(1); + + return new Cropper(image, { + // zoomOnWheel: true, + + ready: function () { + var cropper = this.cropper; + + util.dispatchEvent(cropper.cropper, 'wheel'); + + done(); + }, + + zoom: function () { + assert.ok(true); + } + }); +}); + +QUnit.test('options#zoomOnWheel: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(0); + + return new Cropper(image, { + zoomOnWheel: false, + + ready: function () { + var cropper = this.cropper; + + util.dispatchEvent(cropper.cropper, 'wheel'); + + done(); + }, + + zoom: function () { + assert.ok(false); + } + }); +}); diff --git a/library/cropperjs/test/options/zoomable.js b/library/cropperjs/test/options/zoomable.js new file mode 100644 index 000000000..9f8ec6fce --- /dev/null +++ b/library/cropperjs/test/options/zoomable.js @@ -0,0 +1,51 @@ +QUnit.test('options#zoomable: true', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(3); + + return new Cropper(image, { + // zoomable: true, + + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.getCanvasData(); + var changedCanvasData = cropper.zoom(0.1).getCanvasData(); + + assert.ok(changedCanvasData.width > canvasData.width); + assert.ok(changedCanvasData.height > canvasData.height); + + done(); + }, + zoom: function () { + assert.ok(true); + } + }); +}); + +QUnit.test('options#zoomable: false', function (assert) { + var done = assert.async(); + var util = window.Util; + var image = util.createImage(); + + assert.expect(2); + + return new Cropper(image, { + zoomable: false, + + ready: function () { + var cropper = this.cropper; + var canvasData = cropper.getCanvasData(); + var changedCanvasData = cropper.zoom(0.1).getCanvasData(); + + assert.ok(changedCanvasData.width === canvasData.width); + assert.ok(changedCanvasData.height === canvasData.height); + + done(); + }, + zoom: function () { + assert.ok(false); + } + }); +});