diff --git a/CHANGELOG.md b/CHANGELOG.md index 2deaffbf..2d57d734 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,42 @@ # Changelog +## 4.0.0-alpha (Mar 1, 2018) + +- The core code of Cropper is replaced with [Cropper.js](https://github.com/fengyuanchen/cropperjs) now. +- Migration from Cropper 3.x: + - **Before:** + ```js + $().cropper({ + crop(event) { + console.log( + event.x, + event.y, + event.width, + event.height, + event.rotate, + event.scaleX, + event.scaleY, + ); + }, + }); + ``` + - **After:** + ```js + $().cropper({ + crop(event) { + console.log( + event.detail.x, + event.detail.y, + event.detail.width, + event.detail.height, + event.detail.rotate, + event.detail.scaleX, + event.detail.scaleY, + ); + }, + }); + ``` + ## 3.1.6 (Mar 1, 2018) - Fixed a bug of incorrect behavior of `viewMode: 2`. diff --git a/README.md b/README.md index a4adada2..c4f28338 100644 --- a/README.md +++ b/README.md @@ -2,40 +2,11 @@ [![Build Status](https://travis-ci.org/fengyuanchen/cropper.svg)](https://travis-ci.org/fengyuanchen/cropper) [![Downloads](https://img.shields.io/npm/dm/cropper.svg)](https://www.npmjs.com/package/cropper) [![Version](https://img.shields.io/npm/v/cropper.svg)](https://www.npmjs.com/package/cropper) -> A simple jQuery image cropping plugin. - -- [Website](https://fengyuanchen.github.io/cropper) -- [Cropper.js](https://github.com/fengyuanchen/cropperjs) - the non-jQuery version of Cropper (**recommended**). - -## 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 jQuery v1.9.1+ -- 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 +> A simple jQuery image cropping plugin. As of v4.0.0, the core code of Cropper is replaced with [Cropper.js](https://github.com/fengyuanchen/cropperjs). + +- [Demo](https://fengyuanchen.github.io/cropper) +- [Cropper.js](https://github.com/fengyuanchen/cropperjs) - JavaScript image cropper (**recommended**) +- [jquery-cropper](https://github.com/fengyuanchen/jquery-cropper) - A jQuery plugin wrapper for Cropper.js (**recommended** for jQuery users to use this instead of Cropper) ## Main @@ -88,875 +59,43 @@ img { ```js $('#image').cropper({ aspectRatio: 16 / 9, - crop: function(e) { + crop: function(event) { // Output the result data for cropping image. - console.log(e.x); - console.log(e.y); - console.log(e.width); - console.log(e.height); - console.log(e.rotate); - console.log(e.scaleX); - console.log(e.scaleY); + console.log(event.detail.x); + console.log(event.detail.y); + console.log(event.detail.width); + console.log(event.detail.height); + console.log(event.detail.rotate); + console.log(event.detail.scaleX); + console.log(event.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 (below 1024px) 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 `$().cropper(options)`. -If you want to change the global default options, You may use `$.fn.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. - -### preview - -- Type: `String` (**jQuery selector**) -- Default: `''` - -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 preview container with the same aspect ratio. -- If preview is not getting properly displayed, set `overflow:hidden` 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 (#120, #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". - -```js -$().cropper({ - ready: function () { - $().cropper('method', argument1, , argument2, ..., argumentN); - } -}); -``` - -### crop() - -Show the crop box manually. +See the available [options](https://github.com/fengyuanchen/cropperjs#options) of Cropper.js. ```js -$().cropper({ - autoCrop: false, - ready: function () { - // Do something here - // ... - - // And then - $(this).cropper('crop'); - } -}); +$().cropper(options); ``` -### 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) - -- **ratio**: - - Type: `Number` - -Zoom the canvas (image wrapper) to an absolute ratio. - -```js -$().cropper('zoomTo', 1); // 1:1 (canvasData.width === canvasData.naturalWidth) -``` - -### 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](http://caniuse.com/transforms2d) support (IE 9+). - -```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](http://caniuse.com/transforms2d) support (IE 9+). - -```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 of 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 pass it 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 of 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](http://caniuse.com/canvas) support (IE 9+). - - Rotated image: requires [CSS3 2D Transforms](http://caniuse.com/transforms2d) support (IE 9+). - - Cross-origin image: requires HTML5 [CORS settings attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) support (IE 11+). - -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. +## Methods -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). +See the available [methods](https://github.com/fengyuanchen/cropperjs#methods) of Cropper.js. ```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); - - $.ajax('/path/to/upload', { - method: "POST", - data: formData, - processData: false, - contentType: false, - success: function () { - console.log('Upload success'); - }, - error: function () { - console.log('Upload error'); - } - }); -}); +$().cropper('method', argument1, , argument2, ..., argumentN); ``` -### 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 a cropper instance has built completely. - -### cropstart - -- **event.originalEvent**: - - Type: `Event` - - Options: `mousedown`, `touchstart` and `pointerdown` - -- **event.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 -$().on('cropstart', function (e) { - console.log(e.type); // cropstart - console.log(e.namespace); // cropper - console.log(e.action); // ... - console.log(e.originalEvent.pageX); - - // Prevent to start cropping, moving, etc if necessary - if (e.action === 'crop') { - e.preventDefault(); - } -}); -``` - -### cropmove - -- **event.originalEvent**: - - Type: `Event` - - Options: `mousemove`, `touchmove` and `pointermove`. - -- **event.action**: the same as "cropstart". - -This event fires when the canvas (image wrapper) or the crop box is changing. - -### cropend - -- **event.originalEvent**: - - Type: `Event` - - Options: `mouseup`, `touchend`, `touchcancel`, `pointerup` and `pointercancel`. - -- **event.action**: the same as "cropstart". - -This event fires when the canvas (image wrapper) or the crop box stops to change. - -### crop - -- **event.x** -- **event.y** -- **event.width** -- **event.height** -- **event.rotate** -- **event.scaleX** -- **event.scaleY** - -> About these properties, see the [`getData`](#getdatarounded) method. - -This event fires when the canvas (image wrapper) or the crop box changed. - -### zoom - -- **event.originalEvent**: - - Type: `Event` - - Options: `wheel`, `touchmove`. - -- **event.oldRatio**: - - Type: `Number` - - The old (current) ratio of the canvas - -- **event.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). +See the available [events](https://github.com/fengyuanchen/cropperjs#events) of Cropper.js. ```js -$().on('zoom', function (e) { - - // Zoom in - if (e.ratio > e.oldRatio) { - - // Prevent zoom in - e.preventDefault(); - } - - // Zoom out - // ... -}); +$().on('event', handler); ``` -[⬆ back to top](#table-of-contents) - ## No conflict If you have to use other plugin with the same namespace, just call the `$.fn.cropper.noConflict` method to revert to it. @@ -972,14 +111,7 @@ If you have to use other plugin with the same namespace, just call the `$.fn.cro ## Browser support -- Chrome (latest) -- Firefox (latest) -- Safari (latest) -- Opera (latest) -- Edge (latest) -- Internet Explorer 9+ - -As a jQuery plugin, you also need to see the [jQuery Browser Support](http://jquery.com/browser-support/). +It is the same as the [browser support of Cropper.js](https://github.com/fengyuanchen/cropperjs#browser-support). As a jQuery plugin, you also need to see the [jQuery Browser Support](http://jquery.com/browser-support/). ## Contributing @@ -992,13 +124,3 @@ Maintained under the [Semantic Versioning guidelines](http://semver.org/). ## License [MIT](http://opensource.org/licenses/MIT) © [Chen Fengyuan](http://chenfengyuan.com) - -## Related projects - -- [ember-cli-image-cropper](https://github.com/mhretab/ember-cli-image-cropper) by @mhretab -- [Image Widget Crop](https://www.drupal.org/project/image_widget_crop) - the main Crop solution in Drupal 8 -- [meteor-cropper](https://github.com/jonblum/meteor-cropper) by @jonblum -- [ngCropper](https://github.com/koorgoo/ngCropper) by @koorgoo -- [redux-cropper](https://github.com/lapanoid/redux-cropper) by @lapanoid - -[⬆ back to top](#table-of-contents) diff --git a/dist/cropper.common.js b/dist/cropper.common.js index 2eccea4f..63a36e69 100644 --- a/dist/cropper.common.js +++ b/dist/cropper.common.js @@ -1,11 +1,11 @@ /*! - * Cropper v3.1.6 + * Cropper v4.0.0-alpha * https://github.com/fengyuanchen/cropper * * Copyright (c) 2014-2018 Chen Fengyuan * Released under the MIT license * - * Date: 2018-03-01T13:33:48.179Z + * Date: 2018-03-01T14:21:13.980Z */ 'use strict'; @@ -55,7 +55,6 @@ 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'; @@ -66,10 +65,10 @@ 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_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 REGEXP_TAG_NAME = /^(?:img|canvas)$/i; var DEFAULTS = { // Define the view mode of the cropper @@ -167,7 +166,13 @@ var DEFAULTS = { zoom: null }; -var TEMPLATE = '
' + '
' + '
' + '
' + '
' + '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
' + '
'; +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)) { @@ -203,15 +208,6 @@ var toConsumableArray = function (arr) { } }; -/** - * Check if the given value is a string. - * @param {*} value - The value to check. - * @returns {boolean} Returns `true` if the given value is a string, else `false`. - */ -function isString(value) { - return typeof value === 'string'; -} - /** * Check if the given value is not a number. */ @@ -236,39 +232,97 @@ function isUndefined(value) { } /** - * Takes a function and returns a new one that will always have a particular context. - * Custom proxy to avoid jQuery's guid. - * @param {Function} fn - The target function. - * @param {Object} context - The new context for the function. - * @returns {Function} The new function. + * 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 proxy(fn, context) { - for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { - args[_key - 2] = arguments[_key]; +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'; +} - return function () { - for (var _len2 = arguments.length, args2 = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args2[_key2] = arguments[_key2]; +/** + * Iterate the given data. + * @param {*} data - The data to iterate. + * @param {Function} callback - The process function for each element. + * @returns {*} The original data. + */ +function forEach(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 fn.apply(context, args.concat(args2)); - }; + return data; } /** - * Get the own enumerable properties of a given object. - * @param {Object} obj - The target object. - * @returns {Array} All the own enumerable properties of the given object. + * 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. */ -var objectKeys = Object.keys || function objectKeys(obj) { - var keys = []; +var assign = Object.assign || function assign(obj) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } - $.each(obj, function (key) { - keys.push(key); - }); + if (isObject(obj) && args.length > 0) { + args.forEach(function (arg) { + if (isObject(arg)) { + Object.keys(arg).forEach(function (key) { + obj[key] = arg[key]; + }); + } + }); + } - return keys; + return obj; }; var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/i; @@ -286,6 +340,271 @@ function normalizeDecimalNumber(value) { 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; + + + forEach(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)) { + forEach(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)) { + forEach(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)) { + forEach(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; + +/** + * Transform the given string from camelCase to kebab-case + * @param {string} value - The value to transform. + * @returns {string} The transformed 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] = undefined; + } + } else if (element.dataset) { + // #128 Safari not allows to delete dataset property + try { + delete element.dataset[name]; + } catch (e) { + element.dataset[name] = undefined; + } + } else { + element.removeAttribute('data-' + hyphenate(name)); + } +} + +var 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. + */ +function removeListener(element, type, listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + forEach(type.trim().split(REGEXP_SPACES), function (t) { + element.removeEventListener(t, listener, options); + }); +} + +/** + * 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 (options.once) { + var originalListener = _listener; + + _listener = function listener() { + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + removeListener(element, type, _listener, options); + return originalListener.apply(element, args); + }; + } + + forEach(type.trim().split(REGEXP_SPACES), function (t) { + element.addEventListener(t, _listener, options); + }); +} + +/** + * 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) { + var event = void 0; + + // Event and CustomEvent on IE9-11 are global objects, not constructors + if (isFunction(Event) && isFunction(CustomEvent)) { + event = new CustomEvent(type, { + detail: data, + bubbles: true, + cancelable: true + }); + } else { + event = document.createEvent('CustomEvent'); + event.initCustomEvent(type, true, true, data); + } + + return element.dispatchEvent(event); +} + +/** + * Get the offset base on the document. + * @param {Element} element - The target element. + * @returns {Object} The offset data. + */ +function getOffset(element) { + var box = element.getBoundingClientRect(); + + return { + left: box.left + (window.pageXOffset - document.documentElement.clientLeft), + top: box.top + (window.pageYOffset - document.documentElement.clientTop) + }; +} + var location = WINDOW.location; var REGEXP_ORIGINS = /^(https?:)\/\/([^:/?#]+):?(\d*)/i; @@ -313,11 +632,11 @@ function addTimestamp(url) { } /** - * Get transform values base on the given object. + * Get transforms base on the given object. * @param {Object} obj - The target object. * @returns {string} A string contains transform values. */ -function getTransformValues(_ref) { +function getTransforms(_ref) { var rotate = _ref.rotate, scaleX = _ref.scaleX, scaleY = _ref.scaleY, @@ -347,32 +666,13 @@ function getTransformValues(_ref) { values.push('scaleY(' + scaleY + ')'); } - return values.length ? values.join(' ') : 'none'; -} - -var navigator = WINDOW.navigator; + var transform = values.length ? values.join(' ') : 'none'; -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'); - - newImage.onload = function () { - callback(newImage.width, newImage.height); + return { + WebkitTransform: transform, + msTransform: transform, + transform: transform }; - - newImage.src = image.src; } /** @@ -381,13 +681,13 @@ function getImageNaturalSizes(image, callback) { * @returns {number} The result ratio. */ function getMaxZoomRatio(pointers) { - var pointers2 = $.extend({}, pointers); + var pointers2 = assign({}, pointers); var ratios = []; - $.each(pointers, function (pointerId, pointer) { + forEach(pointers, function (pointer, pointerId) { delete pointers2[pointerId]; - $.each(pointers2, function (pointerId2, pointer2) { + forEach(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); @@ -422,11 +722,7 @@ function getPointer(_ref2, endOnly) { endY: pageY }; - if (endOnly) { - return end; - } - - return $.extend({ + return endOnly ? end : assign({ startX: pageX, startY: pageY }, end); @@ -442,7 +738,7 @@ function getPointersCenter(pointers) { var pageY = 0; var count = 0; - $.each(pointers, function (pointerId, _ref3) { + forEach(pointers, function (_ref3) { var startX = _ref3.startX, startY = _ref3.startY; @@ -595,7 +891,7 @@ function getSourceCanvas(image, _ref6, _ref7, _ref8) { context.scale(scaleX, scaleY); context.imageSmoothingEnabled = imageSmoothingEnabled; context.imageSmoothingQuality = imageSmoothingQuality; - context.drawImage.apply(context, [image].concat(toConsumableArray($.map(params, function (param) { + context.drawImage.apply(context, [image].concat(toConsumableArray(params.map(function (param) { return Math.floor(normalizeDecimalNumber(param)); })))); context.restore(); @@ -638,7 +934,7 @@ function dataURLToArrayBuffer(dataURL) { var arrayBuffer = new ArrayBuffer(binary.length); var uint8 = new Uint8Array(arrayBuffer); - $.each(uint8, function (i) { + forEach(uint8, function (value, i) { uint8[i] = binary.charCodeAt(i); }); @@ -656,7 +952,7 @@ function arrayBufferToDataURL(arrayBuffer, mimeType) { var data = ''; // TypedArray.prototype.forEach is not supported in some browsers. - $.each(uint8, function (i, value) { + forEach(uint8, function (value) { data += fromCharCode(value); }); @@ -806,51 +1102,58 @@ var render = { } }, initContainer: function initContainer() { - var $element = this.$element, + var element = this.element, options = this.options, - $container = this.$container, - $cropper = this.$cropper; + container = this.container, + cropper = this.cropper; - $cropper.addClass(CLASS_HIDDEN); - $element.removeClass(CLASS_HIDDEN); + 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; - $cropper.css(this.container = { - width: Math.max($container.width(), Number(options.minContainerWidth) || 200), - height: Math.max($container.height(), Number(options.minContainerHeight) || 100) + setStyle(cropper, { + width: containerData.width, + height: containerData.height }); - $element.addClass(CLASS_HIDDEN); - $cropper.removeClass(CLASS_HIDDEN); + addClass(element, CLASS_HIDDEN); + removeClass(cropper, CLASS_HIDDEN); }, // Canvas (image wrapper) initCanvas: function initCanvas() { - var container = this.container, - image = this.image; + var containerData = this.containerData, + imageData = this.imageData; var viewMode = this.options.viewMode; - var rotated = Math.abs(image.rotate) % 180 === 90; - var naturalWidth = rotated ? image.naturalHeight : image.naturalWidth; - var naturalHeight = rotated ? image.naturalWidth : image.naturalHeight; + 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 = container.width; - var canvasHeight = container.height; + var canvasWidth = containerData.width; + var canvasHeight = containerData.height; - if (container.height * aspectRatio > container.width) { + if (containerData.height * aspectRatio > containerData.width) { if (viewMode === 3) { - canvasWidth = container.height * aspectRatio; + canvasWidth = containerData.height * aspectRatio; } else { - canvasHeight = container.width / aspectRatio; + canvasHeight = containerData.width / aspectRatio; } } else if (viewMode === 3) { - canvasHeight = container.width / aspectRatio; + canvasHeight = containerData.width / aspectRatio; } else { - canvasWidth = container.height * aspectRatio; + canvasWidth = containerData.height * aspectRatio; } - var canvas = { + var canvasData = { aspectRatio: aspectRatio, naturalWidth: naturalWidth, naturalHeight: naturalHeight, @@ -858,50 +1161,50 @@ var render = { height: canvasHeight }; - canvas.left = (container.width - canvasWidth) / 2; - canvas.top = (container.height - canvasHeight) / 2; - canvas.oldLeft = canvas.left; - canvas.oldTop = canvas.top; + canvasData.left = (containerData.width - canvasWidth) / 2; + canvasData.top = (containerData.height - canvasHeight) / 2; + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; - this.canvas = canvas; + this.canvasData = canvasData; this.limited = viewMode === 1 || viewMode === 2; this.limitCanvas(true, true); - this.initialImage = $.extend({}, image); - this.initialCanvas = $.extend({}, canvas); + this.initialImageData = assign({}, imageData); + this.initialCanvasData = assign({}, canvasData); }, - limitCanvas: function limitCanvas(isSizeLimited, isPositionLimited) { + limitCanvas: function limitCanvas(sizeLimited, positionLimited) { var options = this.options, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox; + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; var viewMode = options.viewMode; - var aspectRatio = canvas.aspectRatio; + var aspectRatio = canvasData.aspectRatio; - var cropped = this.cropped && cropBox; + var cropped = this.cropped && cropBoxData; - if (isSizeLimited) { + if (sizeLimited) { var minCanvasWidth = Number(options.minCanvasWidth) || 0; var minCanvasHeight = Number(options.minCanvasHeight) || 0; - if (viewMode > 0) { - if (viewMode > 1) { - minCanvasWidth = Math.max(minCanvasWidth, container.width); - minCanvasHeight = Math.max(minCanvasHeight, container.height); + 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; - } + if (viewMode === 3) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; } - } else if (minCanvasWidth) { - minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBox.width : 0); + } + } else if (viewMode > 0) { + if (minCanvasWidth) { + minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0); } else if (minCanvasHeight) { - minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBox.height : 0); + minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0); } else if (cropped) { - minCanvasWidth = cropBox.width; - minCanvasHeight = cropBox.height; + minCanvasWidth = cropBoxData.width; + minCanvasHeight = cropBoxData.height; if (minCanvasHeight * aspectRatio > minCanvasWidth) { minCanvasWidth = minCanvasHeight * aspectRatio; @@ -921,101 +1224,100 @@ var render = { minCanvasHeight = _getAdjustedSizes.height; - canvas.minWidth = minCanvasWidth; - canvas.minHeight = minCanvasHeight; - canvas.maxWidth = Infinity; - canvas.maxHeight = Infinity; + canvasData.minWidth = minCanvasWidth; + canvasData.minHeight = minCanvasHeight; + canvasData.maxWidth = Infinity; + canvasData.maxHeight = Infinity; } - if (isPositionLimited) { - if (viewMode > 0) { - var newCanvasLeft = container.width - canvas.width; - var newCanvasTop = container.height - canvas.height; + if (positionLimited) { + if (viewMode) { + var newCanvasLeft = containerData.width - canvasData.width; + var newCanvasTop = containerData.height - canvasData.height; - canvas.minLeft = Math.min(0, newCanvasLeft); - canvas.minTop = Math.min(0, newCanvasTop); - canvas.maxLeft = Math.max(0, newCanvasLeft); - canvas.maxTop = Math.max(0, newCanvasTop); + 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) { - canvas.minLeft = Math.min(cropBox.left, cropBox.left + cropBox.width - canvas.width); - canvas.minTop = Math.min(cropBox.top, cropBox.top + cropBox.height - canvas.height); - canvas.maxLeft = cropBox.left; - canvas.maxTop = cropBox.top; + 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 (canvas.width >= container.width) { - canvas.minLeft = Math.min(0, newCanvasLeft); - canvas.maxLeft = Math.max(0, newCanvasLeft); + if (canvasData.width >= containerData.width) { + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.maxLeft = Math.max(0, newCanvasLeft); } - if (canvas.height >= container.height) { - canvas.minTop = Math.min(0, newCanvasTop); - canvas.maxTop = Math.max(0, newCanvasTop); + if (canvasData.height >= containerData.height) { + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxTop = Math.max(0, newCanvasTop); } } } } else { - canvas.minLeft = -canvas.width; - canvas.minTop = -canvas.height; - canvas.maxLeft = container.width; - canvas.maxTop = container.height; + canvasData.minLeft = -canvasData.width; + canvasData.minTop = -canvasData.height; + canvasData.maxLeft = containerData.width; + canvasData.maxTop = containerData.height; } } }, renderCanvas: function renderCanvas(changed, transformed) { - var canvas = this.canvas, - image = this.image; + var canvasData = this.canvasData, + imageData = this.imageData; if (transformed) { var _getRotatedSizes = getRotatedSizes({ - width: image.naturalWidth * Math.abs(image.scaleX || 1), - height: image.naturalHeight * Math.abs(image.scaleY || 1), - degree: image.rotate || 0 + 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 = canvas.width * (naturalWidth / canvas.naturalWidth); - var height = canvas.height * (naturalHeight / canvas.naturalHeight); + var width = canvasData.width * (naturalWidth / canvasData.naturalWidth); + var height = canvasData.height * (naturalHeight / canvasData.naturalHeight); - canvas.left -= (width - canvas.width) / 2; - canvas.top -= (height - canvas.height) / 2; - canvas.width = width; - canvas.height = height; - canvas.aspectRatio = naturalWidth / naturalHeight; - canvas.naturalWidth = naturalWidth; - canvas.naturalHeight = 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 (canvas.width > canvas.maxWidth || canvas.width < canvas.minWidth) { - canvas.left = canvas.oldLeft; + if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) { + canvasData.left = canvasData.oldLeft; } - if (canvas.height > canvas.maxHeight || canvas.height < canvas.minHeight) { - canvas.top = canvas.oldTop; + if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) { + canvasData.top = canvasData.oldTop; } - canvas.width = Math.min(Math.max(canvas.width, canvas.minWidth), canvas.maxWidth); - canvas.height = Math.min(Math.max(canvas.height, canvas.minHeight), canvas.maxHeight); + 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); - canvas.left = Math.min(Math.max(canvas.left, canvas.minLeft), canvas.maxLeft); - canvas.top = Math.min(Math.max(canvas.top, canvas.minTop), canvas.maxTop); - canvas.oldLeft = canvas.left; - canvas.oldTop = canvas.top; - - this.$canvas.css({ - width: canvas.width, - height: canvas.height, - transform: getTransformValues({ - translateX: canvas.left, - translateY: canvas.top - }) - }); + 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, assign({ + width: canvasData.width, + height: canvasData.height + }, getTransforms({ + translateX: canvasData.left, + translateY: canvasData.top + }))); this.renderImage(changed); @@ -1024,27 +1326,25 @@ var render = { } }, renderImage: function renderImage(changed) { - var canvas = this.canvas, - image = this.image; + var canvasData = this.canvasData, + imageData = this.imageData; - var width = image.naturalWidth * (canvas.width / canvas.naturalWidth); - var height = image.naturalHeight * (canvas.height / canvas.naturalHeight); + var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth); + var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight); - $.extend(image, { + assign(imageData, { width: width, height: height, - left: (canvas.width - width) / 2, - top: (canvas.height - height) / 2 - }); - - this.$clone.css({ - width: image.width, - height: image.height, - transform: getTransformValues($.extend({ - translateX: image.left, - translateY: image.top - }, image)) + left: (canvasData.width - width) / 2, + top: (canvasData.height - height) / 2 }); + setStyle(this.image, assign({ + width: imageData.width, + height: imageData.height + }, getTransforms(assign({ + translateX: imageData.left, + translateY: imageData.top + }, imageData)))); if (changed) { this.output(); @@ -1052,58 +1352,58 @@ var render = { }, initCropBox: function initCropBox() { var options = this.options, - canvas = this.canvas; + canvasData = this.canvasData; var aspectRatio = options.aspectRatio; var autoCropArea = Number(options.autoCropArea) || 0.8; - var cropBox = { - width: canvas.width, - height: canvas.height + var cropBoxData = { + width: canvasData.width, + height: canvasData.height }; if (aspectRatio) { - if (canvas.height * aspectRatio > canvas.width) { - cropBox.height = cropBox.width / aspectRatio; + if (canvasData.height * aspectRatio > canvasData.width) { + cropBoxData.height = cropBoxData.width / aspectRatio; } else { - cropBox.width = cropBox.height * aspectRatio; + cropBoxData.width = cropBoxData.height * aspectRatio; } } - this.cropBox = cropBox; + this.cropBoxData = cropBoxData; this.limitCropBox(true, true); // Initialize auto crop area - cropBox.width = Math.min(Math.max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); - cropBox.height = Math.min(Math.max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); - - // The width of auto crop area must large than "minWidth", and the height too. (#164) - cropBox.width = Math.max(cropBox.minWidth, cropBox.width * autoCropArea); - cropBox.height = Math.max(cropBox.minHeight, cropBox.height * autoCropArea); - cropBox.left = canvas.left + (canvas.width - cropBox.width) / 2; - cropBox.top = canvas.top + (canvas.height - cropBox.height) / 2; - cropBox.oldLeft = cropBox.left; - cropBox.oldTop = cropBox.top; - - this.initialCropBox = $.extend({}, cropBox); + 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 = assign({}, cropBoxData); }, - limitCropBox: function limitCropBox(isSizeLimited, isPositionLimited) { + limitCropBox: function limitCropBox(sizeLimited, positionLimited) { var options = this.options, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData, limited = this.limited; var aspectRatio = options.aspectRatio; - if (isSizeLimited) { + if (sizeLimited) { var minCropBoxWidth = Number(options.minCropBoxWidth) || 0; var minCropBoxHeight = Number(options.minCropBoxHeight) || 0; - var maxCropBoxWidth = Math.min(container.width, limited ? canvas.width : container.width); - var maxCropBoxHeight = Math.min(container.height, limited ? canvas.height : container.height); + 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, container.width); - minCropBoxHeight = Math.min(minCropBoxHeight, container.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) { @@ -1126,63 +1426,62 @@ var render = { } // The minWidth/Height must be less than maxWidth/Height - cropBox.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); - cropBox.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); - cropBox.maxWidth = maxCropBoxWidth; - cropBox.maxHeight = maxCropBoxHeight; + cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); + cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); + cropBoxData.maxWidth = maxCropBoxWidth; + cropBoxData.maxHeight = maxCropBoxHeight; } - if (isPositionLimited) { + if (positionLimited) { if (limited) { - cropBox.minLeft = Math.max(0, canvas.left); - cropBox.minTop = Math.max(0, canvas.top); - cropBox.maxLeft = Math.min(container.width, canvas.left + canvas.width) - cropBox.width; - cropBox.maxTop = Math.min(container.height, canvas.top + canvas.height) - cropBox.height; + 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 { - cropBox.minLeft = 0; - cropBox.minTop = 0; - cropBox.maxLeft = container.width - cropBox.width; - cropBox.maxTop = container.height - cropBox.height; + 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, - container = this.container, - cropBox = this.cropBox; + containerData = this.containerData, + cropBoxData = this.cropBoxData; - if (cropBox.width > cropBox.maxWidth || cropBox.width < cropBox.minWidth) { - cropBox.left = cropBox.oldLeft; + if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) { + cropBoxData.left = cropBoxData.oldLeft; } - if (cropBox.height > cropBox.maxHeight || cropBox.height < cropBox.minHeight) { - cropBox.top = cropBox.oldTop; + if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) { + cropBoxData.top = cropBoxData.oldTop; } - cropBox.width = Math.min(Math.max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); - cropBox.height = Math.min(Math.max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); + 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); - cropBox.left = Math.min(Math.max(cropBox.left, cropBox.minLeft), cropBox.maxLeft); - cropBox.top = Math.min(Math.max(cropBox.top, cropBox.minTop), cropBox.maxTop); - cropBox.oldLeft = cropBox.left; - cropBox.oldTop = cropBox.top; + 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 - this.$face.data(DATA_ACTION, cropBox.width >= container.width && cropBox.height >= container.height ? ACTION_MOVE : ACTION_ALL); + setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL); } - this.$cropBox.css({ - width: cropBox.width, - height: cropBox.height, - transform: getTransformValues({ - translateX: cropBox.left, - translateY: cropBox.top - }) - }); + setStyle(this.cropBox, assign({ + width: cropBoxData.width, + height: cropBoxData.height + }, getTransforms({ + translateX: cropBoxData.left, + translateY: cropBoxData.top + }))); if (this.cropped && this.limited) { this.limitCanvas(true, true); @@ -1194,16 +1493,14 @@ var render = { }, output: function output() { this.preview(); - - if (this.completed) { - this.trigger(EVENT_CROP, this.getData()); - } + 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'); @@ -1213,21 +1510,31 @@ var preview = { } image.src = url; + this.viewBox.appendChild(image); + this.viewBoxImage = image; - var $clone2 = $(image); + if (!preview) { + return; + } - this.$preview = $(this.options.preview); - this.$clone2 = $clone2; - this.$viewBox.html($clone2); - this.$preview.each(function (i, element) { - var $element = $(element); + var previews = preview; + + if (typeof preview === 'string') { + previews = this.element.ownerDocument.querySelectorAll(preview); + } else if (preview.querySelector) { + previews = [preview]; + } + + this.previews = previews; + + forEach(previews, function (el) { var img = document.createElement('img'); // Save the original size for recover - $element.data(DATA_PREVIEW, { - width: $element.width(), - height: $element.height(), - html: $element.html() + setData(el, DATA_PREVIEW, { + width: el.offsetWidth, + height: el.offsetHeight, + html: el.innerHTML }); if (crossOrigin) { @@ -1244,48 +1551,49 @@ var preview = { */ 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;"'; - $element.html(img); + el.innerHTML = ''; + el.appendChild(img); }); }, resetPreview: function resetPreview() { - this.$preview.each(function (i, element) { - var $element = $(element); - var data = $element.data(DATA_PREVIEW); + forEach(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); - $element.css({ + setStyle(element, { width: data.width, height: data.height - }).html(data.html).removeData(DATA_PREVIEW); + }); + + element.innerHTML = data.html; + removeData(element, DATA_PREVIEW); }); }, preview: function preview() { - var image = this.image, - canvas = this.canvas, - cropBox = this.cropBox; - var cropBoxWidth = cropBox.width, - cropBoxHeight = cropBox.height; - var width = image.width, - height = image.height; + 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 = cropBox.left - canvas.left - image.left; - var top = cropBox.top - canvas.top - image.top; + var left = cropBoxData.left - canvasData.left - imageData.left; + var top = cropBoxData.top - canvasData.top - imageData.top; if (!this.cropped || this.disabled) { return; } - this.$clone2.css({ + setStyle(this.viewBoxImage, assign({ width: width, - height: height, - transform: getTransformValues($.extend({ - translateX: -left, - translateY: -top - }, image)) - }); - - this.$preview.each(function (i, element) { - var $element = $(element); - var data = $element.data(DATA_PREVIEW); + height: height + }, getTransforms(assign({ + translateX: -left, + translateY: -top + }, imageData)))); + + forEach(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); var originalWidth = data.width; var originalHeight = data.height; var newWidth = originalWidth; @@ -1303,104 +1611,107 @@ var preview = { newHeight = originalHeight; } - $element.css({ + setStyle(element, { width: newWidth, height: newHeight - }).find('img').css({ - width: width * ratio, - height: height * ratio, - transform: getTransformValues($.extend({ - translateX: -left * ratio, - translateY: -top * ratio - }, image)) }); + + setStyle(element.getElementsByTagName('img')[0], assign({ + width: width * ratio, + height: height * ratio + }, getTransforms(assign({ + translateX: -left * ratio, + translateY: -top * ratio + }, imageData)))); }); } }; var events = { bind: function bind() { - var $element = this.$element, + var element = this.element, options = this.options, - $cropper = this.$cropper; + cropper = this.cropper; - if ($.isFunction(options.cropstart)) { - $element.on(EVENT_CROP_START, options.cropstart); + if (isFunction(options.cropstart)) { + addListener(element, EVENT_CROP_START, options.cropstart); } - if ($.isFunction(options.cropmove)) { - $element.on(EVENT_CROP_MOVE, options.cropmove); + if (isFunction(options.cropmove)) { + addListener(element, EVENT_CROP_MOVE, options.cropmove); } - if ($.isFunction(options.cropend)) { - $element.on(EVENT_CROP_END, options.cropend); + if (isFunction(options.cropend)) { + addListener(element, EVENT_CROP_END, options.cropend); } - if ($.isFunction(options.crop)) { - $element.on(EVENT_CROP, options.crop); + if (isFunction(options.crop)) { + addListener(element, EVENT_CROP, options.crop); } - if ($.isFunction(options.zoom)) { - $element.on(EVENT_ZOOM, options.zoom); + if (isFunction(options.zoom)) { + addListener(element, EVENT_ZOOM, options.zoom); } - $cropper.on(EVENT_POINTER_DOWN, proxy(this.cropStart, this)); + addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this)); if (options.zoomable && options.zoomOnWheel) { - $cropper.on(EVENT_WHEEL, proxy(this.wheel, this)); + addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this)); } if (options.toggleDragModeOnDblclick) { - $cropper.on(EVENT_DBLCLICK, proxy(this.dblclick, this)); + addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this)); } - $(this.element.ownerDocument).on(EVENT_POINTER_MOVE, this.onCropMove = proxy(this.cropMove, this)).on(EVENT_POINTER_UP, this.onCropEnd = proxy(this.cropEnd, this)); + addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this)); + addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this)); if (options.responsive) { - $(window).on(EVENT_RESIZE, this.onResize = proxy(this.resize, this)); + addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this)); } }, unbind: function unbind() { - var $element = this.$element, + var element = this.element, options = this.options, - $cropper = this.$cropper; + cropper = this.cropper; - if ($.isFunction(options.cropstart)) { - $element.off(EVENT_CROP_START, options.cropstart); + if (isFunction(options.cropstart)) { + removeListener(element, EVENT_CROP_START, options.cropstart); } - if ($.isFunction(options.cropmove)) { - $element.off(EVENT_CROP_MOVE, options.cropmove); + if (isFunction(options.cropmove)) { + removeListener(element, EVENT_CROP_MOVE, options.cropmove); } - if ($.isFunction(options.cropend)) { - $element.off(EVENT_CROP_END, options.cropend); + if (isFunction(options.cropend)) { + removeListener(element, EVENT_CROP_END, options.cropend); } - if ($.isFunction(options.crop)) { - $element.off(EVENT_CROP, options.crop); + if (isFunction(options.crop)) { + removeListener(element, EVENT_CROP, options.crop); } - if ($.isFunction(options.zoom)) { - $element.off(EVENT_ZOOM, options.zoom); + if (isFunction(options.zoom)) { + removeListener(element, EVENT_ZOOM, options.zoom); } - $cropper.off(EVENT_POINTER_DOWN, this.cropStart); + removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart); if (options.zoomable && options.zoomOnWheel) { - $cropper.off(EVENT_WHEEL, this.wheel); + removeListener(cropper, EVENT_WHEEL, this.onWheel); } if (options.toggleDragModeOnDblclick) { - $cropper.off(EVENT_DBLCLICK, this.dblclick); + removeListener(cropper, EVENT_DBLCLICK, this.onDblclick); } - $(this.element.ownerDocument).off(EVENT_POINTER_MOVE, this.onCropMove).off(EVENT_POINTER_UP, this.onCropEnd); + removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove); + removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd); if (options.responsive) { - $(window).off(EVENT_RESIZE, this.onResize); + removeListener(window, EVENT_RESIZE, this.onResize); } } }; @@ -1408,20 +1719,20 @@ var events = { var handlers = { resize: function resize() { var options = this.options, - $container = this.$container, - container = this.container; + container = this.container, + containerData = this.containerData; var minContainerWidth = Number(options.minContainerWidth) || 200; var minContainerHeight = Number(options.minContainerHeight) || 100; - if (this.disabled || container.width <= minContainerWidth || container.height <= minContainerHeight) { + if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) { return; } - var ratio = $container.width() / container.width; + var ratio = container.offsetWidth / containerData.width; // Resize when width changed or height changed - if (ratio !== 1 || $container.height() !== container.height) { + if (ratio !== 1 || container.offsetHeight !== containerData.height) { var canvasData = void 0; var cropBoxData = void 0; @@ -1433,10 +1744,10 @@ var handlers = { this.render(); if (options.restore) { - this.setCanvasData($.each(canvasData, function (i, n) { + this.setCanvasData(forEach(canvasData, function (n, i) { canvasData[i] = n * ratio; })); - this.setCropBoxData($.each(cropBoxData, function (i, n) { + this.setCropBoxData(forEach(cropBoxData, function (n, i) { cropBoxData[i] = n * ratio; })); } @@ -1447,21 +1758,21 @@ var handlers = { return; } - this.setDragMode(this.$dragBox.hasClass(CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); + this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); }, - wheel: function wheel(event) { + wheel: function wheel(e) { var _this = this; - var e = event.originalEvent || event; var ratio = Number(this.options.wheelZoomRatio) || 0.1; + var delta = 1; if (this.disabled) { return; } - event.preventDefault(); + e.preventDefault(); - // Limit wheel speed to prevent zoom too fast + // Limit wheel speed to prevent zoom too fast (#21) if (this.wheeling) { return; } @@ -1472,8 +1783,6 @@ var handlers = { _this.wheeling = false; }, 50); - var delta = 1; - if (e.deltaY) { delta = e.deltaY > 0 ? 1 : -1; } else if (e.wheelDelta) { @@ -1482,7 +1791,7 @@ var handlers = { delta = e.detail > 0 ? 1 : -1; } - this.zoom(-delta * ratio, event); + this.zoom(-delta * ratio, e); }, cropStart: function cropStart(e) { if (this.disabled) { @@ -1491,34 +1800,33 @@ var handlers = { var options = this.options, pointers = this.pointers; - var originalEvent = e.originalEvent; var action = void 0; - if (originalEvent && originalEvent.changedTouches) { + if (e.changedTouches) { // Handle touch event - $.each(originalEvent.changedTouches, function (i, touch) { + forEach(e.changedTouches, function (touch) { pointers[touch.identifier] = getPointer(touch); }); } else { // Handle mouse event and pointer event - pointers[originalEvent && originalEvent.pointerId || 0] = getPointer(originalEvent || e); + pointers[e.pointerId || 0] = getPointer(e); } - if (objectKeys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { + if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { action = ACTION_ZOOM; } else { - action = $(e.target).data(DATA_ACTION); + action = getData(e.target, DATA_ACTION); } if (!REGEXP_ACTIONS.test(action)) { return; } - if (this.trigger(EVENT_CROP_START, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_CROP_START, { + originalEvent: e, action: action - }).isDefaultPrevented()) { + }) === false) { return; } @@ -1529,7 +1837,7 @@ var handlers = { if (action === ACTION_CROP) { this.cropping = true; - this.$dragBox.addClass(CLASS_MODAL); + addClass(this.dragBox, CLASS_MODAL); } }, cropMove: function cropMove(e) { @@ -1541,24 +1849,23 @@ var handlers = { } var pointers = this.pointers; - var originalEvent = e.originalEvent; e.preventDefault(); - if (this.trigger(EVENT_CROP_MOVE, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_CROP_MOVE, { + originalEvent: e, action: action - }).isDefaultPrevented()) { + }) === false) { return; } - if (originalEvent && originalEvent.changedTouches) { - $.each(originalEvent.changedTouches, function (i, touch) { - $.extend(pointers[touch.identifier], getPointer(touch, true)); + if (e.changedTouches) { + forEach(e.changedTouches, function (touch) { + assign(pointers[touch.identifier], getPointer(touch, true)); }); } else { - $.extend(pointers[originalEvent && originalEvent.pointerId || 0], getPointer(originalEvent || e, true)); + assign(pointers[e.pointerId || 0], getPointer(e, true)); } this.change(e); @@ -1568,17 +1875,16 @@ var handlers = { return; } - var action = this.action; - var pointers = this.pointers; - var originalEvent = e.originalEvent; + var action = this.action, + pointers = this.pointers; - if (originalEvent && originalEvent.changedTouches) { - $.each(originalEvent.changedTouches, function (i, touch) { + if (e.changedTouches) { + forEach(e.changedTouches, function (touch) { delete pointers[touch.identifier]; }); } else { - delete pointers[originalEvent && originalEvent.pointerId || 0]; + delete pointers[e.pointerId || 0]; } if (!action) { @@ -1587,17 +1893,17 @@ var handlers = { e.preventDefault(); - if (!objectKeys(pointers).length) { + if (!Object.keys(pointers).length) { this.action = ''; } if (this.cropping) { this.cropping = false; - this.$dragBox.toggleClass(CLASS_MODAL, this.cropped && this.options.modal); + toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal); } - this.trigger(EVENT_CROP_END, { - originalEvent: originalEvent, + dispatchEvent(this.element, EVENT_CROP_END, { + originalEvent: e, action: action }); } @@ -1606,40 +1912,40 @@ var handlers = { var change = { change: function change(e) { var options = this.options, - pointers = this.pointers, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox; + canvasData = this.canvasData, + containerData = this.containerData, + cropBoxData = this.cropBoxData, + pointers = this.pointers; var action = this.action; var aspectRatio = options.aspectRatio; - var left = cropBox.left, - top = cropBox.top, - width = cropBox.width, - height = cropBox.height; + 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 = container.width; - var maxHeight = container.height; + 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 (#259) + // Locking aspect ratio in "free mode" by holding shift key if (!aspectRatio && e.shiftKey) { aspectRatio = width && height ? width / height : 1; } if (this.limited) { - minLeft = cropBox.minLeft; - minTop = cropBox.minTop; + minLeft = cropBoxData.minLeft; + minTop = cropBoxData.minTop; - maxWidth = minLeft + Math.min(container.width, canvas.width, canvas.left + canvas.width); - maxHeight = minTop + Math.min(container.height, canvas.height, canvas.top + canvas.height); + 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[objectKeys(pointers)[0]]; + var pointer = pointers[Object.keys(pointers)[0]]; var range = { x: pointer.endX - pointer.startX, y: pointer.endY - pointer.startY @@ -1980,7 +2286,7 @@ var change = { // Zoom canvas case ACTION_ZOOM: - this.zoom(getMaxZoomRatio(pointers), e.originalEvent); + this.zoom(getMaxZoomRatio(pointers), e); renderable = false; break; @@ -1991,11 +2297,11 @@ var change = { break; } - offset = this.$cropper.offset(); + offset = getOffset(this.cropper); left = pointer.startX - offset.left; top = pointer.startY - offset.top; - width = cropBox.minWidth; - height = cropBox.minHeight; + width = cropBoxData.minWidth; + height = cropBoxData.minHeight; if (range.x > 0) { action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST; @@ -2010,7 +2316,7 @@ var change = { // Show the crop box if is hidden if (!this.cropped) { - this.$cropBox.removeClass(CLASS_HIDDEN); + removeClass(this.cropBox, CLASS_HIDDEN); this.cropped = true; if (this.limited) { @@ -2024,16 +2330,16 @@ var change = { } if (renderable) { - cropBox.width = width; - cropBox.height = height; - cropBox.left = left; - cropBox.top = top; + cropBoxData.width = width; + cropBoxData.height = height; + cropBoxData.left = left; + cropBoxData.top = top; this.action = action; this.renderCropBox(); } // Override - $.each(pointers, function (i, p) { + forEach(pointers, function (p) { p.startX = p.endX; p.startY = p.endY; }); @@ -2043,149 +2349,162 @@ var change = { var methods = { // Show the crop box manually crop: function crop() { - if (!this.ready || this.disabled) { - return; - } - - if (!this.cropped) { + if (this.ready && !this.cropped && !this.disabled) { this.cropped = true; this.limitCropBox(true, true); if (this.options.modal) { - this.$dragBox.addClass(CLASS_MODAL); + addClass(this.dragBox, CLASS_MODAL); } - this.$cropBox.removeClass(CLASS_HIDDEN); + removeClass(this.cropBox, CLASS_HIDDEN); + this.setCropBoxData(this.initialCropBoxData); } - this.setCropBoxData(this.initialCropBox); + return this; }, // Reset the image and crop box to their initial states reset: function reset() { - if (!this.ready || this.disabled) { - return; - } + if (this.ready && !this.disabled) { + this.imageData = assign({}, this.initialImageData); + this.canvasData = assign({}, this.initialCanvasData); + this.cropBoxData = assign({}, this.initialCropBoxData); + this.renderCanvas(); - this.image = $.extend({}, this.initialImage); - this.canvas = $.extend({}, this.initialCanvas); - this.cropBox = $.extend({}, this.initialCropBox); - this.renderCanvas(); - - if (this.cropped) { - this.renderCropBox(); + if (this.cropped) { + this.renderCropBox(); + } } + + return this; }, // Clear the crop box clear: function clear() { - if (!this.cropped || this.disabled) { - return; - } + if (this.cropped && !this.disabled) { + assign(this.cropBoxData, { + left: 0, + top: 0, + width: 0, + height: 0 + }); - $.extend(this.cropBox, { - left: 0, - top: 0, - width: 0, - height: 0 - }); + this.cropped = false; + this.renderCropBox(); + this.limitCanvas(true, true); - 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); + } - // Render canvas after crop box rendered - this.renderCanvas(); - this.$dragBox.removeClass(CLASS_MODAL); - this.$cropBox.addClass(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. + * @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one. + * @returns {Cropper} this */ - replace: function replace(url, onlyColorChanged) { + replace: function replace(url) { + var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + if (!this.disabled && url) { if (this.isImg) { - this.$element.attr('src', url); + this.element.src = url; } - if (onlyColorChanged) { + if (hasSameSize) { this.url = url; - this.$clone.attr('src', url); + this.image.src = url; if (this.ready) { - this.$preview.find('img').add(this.$clone2).attr('src', url); + this.viewBoxImage.src = url; + + forEach(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.uncreate(); this.load(url); } } + + return this; }, // Enable (unfreeze) the cropper enable: function enable() { - if (this.ready) { + if (this.ready && this.disabled) { this.disabled = false; - this.$cropper.removeClass(CLASS_DISABLED); + removeClass(this.cropper, CLASS_DISABLED); } + + return this; }, // Disable (freeze) the cropper disable: function disable() { - if (this.ready) { + if (this.ready && !this.disabled) { this.disabled = true; - this.$cropper.addClass(CLASS_DISABLED); + addClass(this.cropper, CLASS_DISABLED); } + + return this; }, - // Destroy the cropper and remove the instance from the image + /** + * Destroy the cropper and remove the instance from the image + * @returns {Cropper} this + */ destroy: function destroy() { - var $element = this.$element; + var element = this.element; - if (this.loaded) { - if (this.isImg && this.replaced) { - $element.attr('src', this.originalUrl); - } + if (!getData(element, NAMESPACE)) { + return this; + } - this.unbuild(); - $element.removeClass(CLASS_HIDDEN); - } else if (this.isImg) { - $element.off(EVENT_LOAD, this.start); - } else if (this.$clone) { - this.$clone.remove(); + if (this.isImg && this.replaced) { + element.src = this.originalUrl; } - $element.removeData(NAMESPACE); + this.uncreate(); + 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. + * @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis. + * @returns {Cropper} this */ - move: function move(offsetX, offsetY) { - var _canvas = this.canvas, - left = _canvas.left, - top = _canvas.top; + move: function move(offsetX) { + var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX; + var _canvasData = this.canvasData, + left = _canvasData.left, + top = _canvasData.top; - this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); + return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); }, @@ -2193,28 +2512,25 @@ var methods = { * Move the canvas to an absolute point * @param {number} x - The x-axis coordinate. * @param {number} [y=x] - The y-axis coordinate. + * @returns {Cropper} this */ - moveTo: function moveTo(x, y) { - var canvas = this.canvas; + moveTo: function moveTo(x) { + var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + var canvasData = this.canvasData; var changed = false; - // If "y" is not present, its default value is "x" - if (isUndefined(y)) { - y = x; - } - x = Number(x); y = Number(y); if (this.ready && !this.disabled && this.options.movable) { if (isNumber(x)) { - canvas.left = x; + canvasData.left = x; changed = true; } if (isNumber(y)) { - canvas.top = y; + canvasData.top = y; changed = true; } @@ -2222,16 +2538,19 @@ var methods = { this.renderCanvas(true); } } + + return this; }, /** * Zoom the canvas with a relative ratio - * @param {Number} ratio - The target ratio. - * @param {Event} _event - The related event if any. + * @param {number} ratio - The target ratio. + * @param {Event} _originalEvent - The original event if any. + * @returns {Cropper} this */ - zoom: function zoom(ratio, _event) { - var canvas = this.canvas; + zoom: function zoom(ratio, _originalEvent) { + var canvasData = this.canvasData; ratio = Number(ratio); @@ -2242,23 +2561,24 @@ var methods = { ratio = 1 + ratio; } - this.zoomTo(canvas.width * ratio / canvas.naturalWidth, _event); + return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent); }, /** * Zoom the canvas to an absolute ratio * @param {number} ratio - The target ratio. - * @param {Event} _event - The related event if any. + * @param {Object} pivot - The zoom pivot point coordinate. + * @param {Event} _originalEvent - The original event if any. + * @returns {Cropper} this */ - zoomTo: function zoomTo(ratio, _event) { + zoomTo: function zoomTo(ratio, pivot, _originalEvent) { var options = this.options, - pointers = this.pointers, - canvas = this.canvas; - var width = canvas.width, - height = canvas.height, - naturalWidth = canvas.naturalWidth, - naturalHeight = canvas.naturalHeight; + canvasData = this.canvasData; + var width = canvasData.width, + height = canvasData.height, + naturalWidth = canvasData.naturalWidth, + naturalHeight = canvasData.naturalHeight; ratio = Number(ratio); @@ -2266,87 +2586,95 @@ var methods = { if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) { var newWidth = naturalWidth * ratio; var newHeight = naturalHeight * ratio; - var originalEvent = void 0; - - if (_event) { - originalEvent = _event.originalEvent; - } - if (this.trigger(EVENT_ZOOM, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_ZOOM, { + originalEvent: _originalEvent, oldRatio: width / naturalWidth, ratio: newWidth / naturalWidth - }).isDefaultPrevented()) { - return; + }) === false) { + return this; } - if (originalEvent) { - var offset = this.$cropper.offset(); - var center = pointers && objectKeys(pointers).length ? getPointersCenter(pointers) : { - pageX: _event.pageX || originalEvent.pageX || 0, - pageY: _event.pageY || originalEvent.pageY || 0 + 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 - canvas.left -= (newWidth - width) * ((center.pageX - offset.left - canvas.left) / width); - canvas.top -= (newHeight - height) * ((center.pageY - offset.top - canvas.top) / height); + 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 - canvas.left -= (newWidth - width) / 2; - canvas.top -= (newHeight - height) / 2; + canvasData.left -= (newWidth - width) / 2; + canvasData.top -= (newHeight - height) / 2; } - canvas.width = newWidth; - canvas.height = newHeight; + 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 {Cropper} this */ rotate: function rotate(degree) { - this.rotateTo((this.image.rotate || 0) + Number(degree)); + return this.rotateTo((this.imageData.rotate || 0) + Number(degree)); }, /** * Rotate the canvas to an absolute degree * @param {number} degree - The rotate degree. + * @returns {Cropper} this */ rotateTo: function rotateTo(degree) { degree = Number(degree); if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) { - this.image.rotate = degree % 360; + 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 {Cropper} this */ scaleX: function scaleX(_scaleX) { - var scaleY = this.image.scaleY; + var scaleY = this.imageData.scaleY; - this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1); + 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 {Cropper} this */ scaleY: function scaleY(_scaleY) { - var scaleX = this.image.scaleX; + var scaleX = this.imageData.scaleX; - this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); + return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); }, @@ -2354,10 +2682,11 @@ var methods = { * 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 {Cropper} this */ scale: function scale(scaleX) { var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX; - var image = this.image; + var imageData = this.imageData; var transformed = false; @@ -2366,12 +2695,12 @@ var methods = { if (this.ready && !this.disabled && this.options.scalable) { if (isNumber(scaleX)) { - image.scaleX = scaleX; + imageData.scaleX = scaleX; transformed = true; } if (isNumber(scaleY)) { - image.scaleY = scaleY; + imageData.scaleY = scaleY; transformed = true; } @@ -2379,6 +2708,8 @@ var methods = { this.renderCanvas(true, true); } } + + return this; }, @@ -2387,26 +2718,26 @@ var methods = { * @param {boolean} [rounded=false] - Indicate if round the data values or not. * @returns {Object} The result cropped data. */ - getData: function getData() { + getData: function getData$$1() { var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; var options = this.options, - image = this.image, - canvas = this.canvas, - cropBox = this.cropBox; + imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; var data = void 0; if (this.ready && this.cropped) { data = { - x: cropBox.left - canvas.left, - y: cropBox.top - canvas.top, - width: cropBox.width, - height: cropBox.height + x: cropBoxData.left - canvasData.left, + y: cropBoxData.top - canvasData.top, + width: cropBoxData.width, + height: cropBoxData.height }; - var ratio = image.width / image.naturalWidth; + var ratio = imageData.width / imageData.naturalWidth; - $.each(data, function (i, n) { + forEach(data, function (n, i) { n /= ratio; data[i] = rounded ? Math.round(n) : n; }); @@ -2420,12 +2751,12 @@ var methods = { } if (options.rotatable) { - data.rotate = image.rotate || 0; + data.rotate = imageData.rotate || 0; } if (options.scalable) { - data.scaleX = image.scaleX || 1; - data.scaleY = image.scaleY || 1; + data.scaleX = imageData.scaleX || 1; + data.scaleY = imageData.scaleY || 1; } return data; @@ -2435,36 +2766,33 @@ var methods = { /** * Set the cropped area position and size with new data * @param {Object} data - The new data. + * @returns {Cropper} this */ - setData: function setData(data) { + setData: function setData$$1(data) { var options = this.options, - image = this.image, - canvas = this.canvas; + imageData = this.imageData, + canvasData = this.canvasData; var cropBoxData = {}; - if ($.isFunction(data)) { - data = data.call(this.element); - } - - if (this.ready && !this.disabled && $.isPlainObject(data)) { + if (this.ready && !this.disabled && isPlainObject(data)) { var transformed = false; if (options.rotatable) { - if (isNumber(data.rotate) && data.rotate !== image.rotate) { - image.rotate = data.rotate; + if (isNumber(data.rotate) && data.rotate !== imageData.rotate) { + imageData.rotate = data.rotate; transformed = true; } } if (options.scalable) { - if (isNumber(data.scaleX) && data.scaleX !== image.scaleX) { - image.scaleX = data.scaleX; + if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) { + imageData.scaleX = data.scaleX; transformed = true; } - if (isNumber(data.scaleY) && data.scaleY !== image.scaleY) { - image.scaleY = data.scaleY; + if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) { + imageData.scaleY = data.scaleY; transformed = true; } } @@ -2473,14 +2801,14 @@ var methods = { this.renderCanvas(true, true); } - var ratio = image.width / image.naturalWidth; + var ratio = imageData.width / imageData.naturalWidth; if (isNumber(data.x)) { - cropBoxData.left = data.x * ratio + canvas.left; + cropBoxData.left = data.x * ratio + canvasData.left; } if (isNumber(data.y)) { - cropBoxData.top = data.y * ratio + canvas.top; + cropBoxData.top = data.y * ratio + canvasData.top; } if (isNumber(data.width)) { @@ -2493,6 +2821,8 @@ var methods = { this.setCropBoxData(cropBoxData); } + + return this; }, @@ -2501,7 +2831,7 @@ var methods = { * @returns {Object} The result container data. */ getContainerData: function getContainerData() { - return this.ready ? $.extend({}, this.container) : {}; + return this.ready ? assign({}, this.containerData) : {}; }, @@ -2510,7 +2840,7 @@ var methods = { * @returns {Object} The result image data. */ getImageData: function getImageData() { - return this.loaded ? $.extend({}, this.image) : {}; + return this.sized ? assign({}, this.imageData) : {}; }, @@ -2519,13 +2849,13 @@ var methods = { * @returns {Object} The result canvas data. */ getCanvasData: function getCanvasData() { - var canvas = this.canvas; + var canvasData = this.canvasData; var data = {}; if (this.ready) { - $.each(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (i, n) { - data[n] = canvas[n]; + forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) { + data[n] = canvasData[n]; }); } @@ -2536,35 +2866,34 @@ var methods = { /** * Set the canvas position and size with new data. * @param {Object} data - The new canvas data. + * @returns {Cropper} this */ setCanvasData: function setCanvasData(data) { - var canvas = this.canvas; - var aspectRatio = canvas.aspectRatio; + var canvasData = this.canvasData; + var aspectRatio = canvasData.aspectRatio; - if ($.isFunction(data)) { - data = data.call(this.$element); - } - - if (this.ready && !this.disabled && $.isPlainObject(data)) { + if (this.ready && !this.disabled && isPlainObject(data)) { if (isNumber(data.left)) { - canvas.left = data.left; + canvasData.left = data.left; } if (isNumber(data.top)) { - canvas.top = data.top; + canvasData.top = data.top; } if (isNumber(data.width)) { - canvas.width = data.width; - canvas.height = data.width / aspectRatio; + canvasData.width = data.width; + canvasData.height = data.width / aspectRatio; } else if (isNumber(data.height)) { - canvas.height = data.height; - canvas.width = data.height * aspectRatio; + canvasData.height = data.height; + canvasData.width = data.height * aspectRatio; } this.renderCanvas(true); } + + return this; }, @@ -2573,62 +2902,66 @@ var methods = { * @returns {Object} The result crop box data. */ getCropBoxData: function getCropBoxData() { - var cropBox = this.cropBox; + var cropBoxData = this.cropBoxData; + var data = void 0; - return this.ready && this.cropped ? { - left: cropBox.left, - top: cropBox.top, - width: cropBox.width, - height: cropBox.height - } : {}; + 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 {Cropper} this */ setCropBoxData: function setCropBoxData(data) { - var cropBox = this.cropBox; + 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 (this.ready && this.cropped && !this.disabled && isPlainObject(data)) { if (isNumber(data.left)) { - cropBox.left = data.left; + cropBoxData.left = data.left; } if (isNumber(data.top)) { - cropBox.top = data.top; + cropBoxData.top = data.top; } - if (isNumber(data.width) && data.width !== cropBox.width) { + if (isNumber(data.width) && data.width !== cropBoxData.width) { widthChanged = true; - cropBox.width = data.width; + cropBoxData.width = data.width; } - if (isNumber(data.height) && data.height !== cropBox.height) { + if (isNumber(data.height) && data.height !== cropBoxData.height) { heightChanged = true; - cropBox.height = data.height; + cropBoxData.height = data.height; } if (aspectRatio) { if (widthChanged) { - cropBox.height = cropBox.width / aspectRatio; + cropBoxData.height = cropBoxData.width / aspectRatio; } else if (heightChanged) { - cropBox.width = cropBox.height * aspectRatio; + cropBoxData.width = cropBoxData.height * aspectRatio; } } this.renderCropBox(); } + + return this; }, @@ -2644,9 +2977,9 @@ var methods = { return null; } - var canvasData = this.canvas; + var canvasData = this.canvasData; - var source = getSourceCanvas(this.$clone[0], this.image, canvasData, options); + var source = getSourceCanvas(this.image, this.imageData, canvasData, options); // Returns the source canvas if it is not cropped. if (!this.cropped) { @@ -2696,6 +3029,7 @@ var methods = { canvas.width = normalizeDecimalNumber(width); canvas.height = normalizeDecimalNumber(height); + context.fillStyle = options.fillColor || 'transparent'; context.fillRect(0, 0, width, height); @@ -2769,9 +3103,10 @@ var methods = { params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale); } - context.drawImage.apply(context, [source].concat(toConsumableArray($.map(params, function (param) { + context.drawImage.apply(context, [source].concat(toConsumableArray(params.map(function (param) { return Math.floor(normalizeDecimalNumber(param)); })))); + return canvas; }, @@ -2779,6 +3114,7 @@ var methods = { /** * Change the aspect ratio of the crop box. * @param {number} aspectRatio - The new aspect ratio. + * @returns {Cropper} this */ setAspectRatio: function setAspectRatio(aspectRatio) { var options = this.options; @@ -2796,34 +3132,47 @@ var methods = { } } } + + return this; }, /** * Change the drag mode. * @param {string} mode - The new drag mode. + * @returns {Cropper} this */ setDragMode: function setDragMode(mode) { - var options = this.options; + var options = this.options, + dragBox = this.dragBox, + face = this.face; + - var croppable = void 0; - var movable = void 0; + if (this.ready && !this.disabled) { + var croppable = mode === DRAG_MODE_CROP; + var movable = options.movable && mode === DRAG_MODE_MOVE; - if (this.loaded && !this.disabled) { - croppable = mode === DRAG_MODE_CROP; - movable = options.movable && mode === DRAG_MODE_MOVE; mode = croppable || movable ? mode : DRAG_MODE_NONE; - this.$dragBox.data(DATA_ACTION, mode).toggleClass(CLASS_CROP, croppable).toggleClass(CLASS_MOVE, movable); + options.dragMode = mode; + 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(#300) - this.$face.data(DATA_ACTION, mode).toggleClass(CLASS_CROP, croppable).toggleClass(CLASS_MOVE, movable); + // 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. @@ -2839,36 +3188,37 @@ var Cropper = function () { } this.element = element; - this.$element = $(element); - this.options = $.extend({}, DEFAULTS, $.isPlainObject(options) && options); - this.completed = false; + this.options = assign({}, DEFAULTS, isPlainObject(options) && options); this.cropped = false; this.disabled = false; - this.isImg = false; - this.limited = false; - this.loaded = false; + this.pointers = {}; this.ready = false; + this.reloading = false; this.replaced = false; - this.wheeling = false; - this.originalUrl = ''; - this.canvas = null; - this.cropBox = null; - this.pointers = {}; + this.sized = false; + this.sizing = false; this.init(); } createClass(Cropper, [{ key: 'init', value: function init() { - var $element = this.$element; + var element = this.element; + var tagName = element.tagName.toLowerCase(); var url = void 0; - if ($element.is('img')) { + if (getData(element, NAMESPACE)) { + return; + } + + setData(element, NAMESPACE, this); + + if (tagName === 'img') { this.isImg = true; - // Should use `$.fn.attr` here. e.g.: "img/picture.jpg" - url = $element.attr('src') || ''; + // e.g.: "img/picture.jpg" + url = element.getAttribute('src') || ''; this.originalUrl = url; // Stop when it's a blank image @@ -2876,26 +3226,14 @@ var Cropper = function () { return; } - // Should use `$.fn.prop` here. e.g.: "http://example.com/img/picture.jpg" - url = $element.prop('src'); - } else if ($element.is('canvas') && window.HTMLCanvasElement) { - url = $element[0].toDataURL(); + // e.g.: "http://example.com/img/picture.jpg" + url = element.src; + } else if (tagName === 'canvas' && window.HTMLCanvasElement) { + url = element.toDataURL(); } this.load(url); } - - // A shortcut for triggering custom events - - }, { - key: 'trigger', - value: function trigger(type, data) { - var e = $.Event(type, data); - - this.$element.trigger(e); - - return e; - } }, { key: 'load', value: function load(url) { @@ -2906,9 +3244,9 @@ var Cropper = function () { } this.url = url; - this.image = {}; + this.imageData = {}; - var $element = this.$element, + var element = this.element, options = this.options; @@ -2930,29 +3268,41 @@ var Cropper = function () { var xhr = new XMLHttpRequest(); + this.reloading = true; + this.xhr = xhr; + + var done = function done() { + _this.reloading = false; + _this.xhr = null; + }; + + xhr.ontimeout = done; + xhr.onabort = done; xhr.onerror = function () { + done(); _this.clone(); }; xhr.onload = function () { + done(); _this.read(xhr.response); }; // Bust cache when there is a "crossOrigin" property - if (options.checkCrossOrigin && isCrossOriginURL(url) && !$element.prop('crossOrigin')) { + if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) { url = addTimestamp(url); } xhr.open('get', url); xhr.responseType = 'arraybuffer'; - xhr.withCredentials = $element.prop('crossOrigin') === 'use-credentials'; + xhr.withCredentials = element.crossOrigin === 'use-credentials'; xhr.send(); } }, { key: 'read', value: function read(arrayBuffer) { var options = this.options, - image = this.image; + imageData = this.imageData; var orientation = getOrientation(arrayBuffer); var rotate = 0; @@ -2970,12 +3320,12 @@ var Cropper = function () { } if (options.rotatable) { - image.rotate = rotate; + imageData.rotate = rotate; } if (options.scalable) { - image.scaleX = scaleX; - image.scaleY = scaleY; + imageData.scaleX = scaleX; + imageData.scaleY = scaleY; } this.clone(); @@ -2983,22 +3333,22 @@ var Cropper = function () { }, { key: 'clone', value: function clone() { - var $element = this.$element, - options = this.options, + var element = this.element, url = this.url; - var crossOrigin = ''; + var crossOrigin = void 0; var crossOriginUrl = void 0; - if (options.checkCrossOrigin && isCrossOriginURL(url)) { - crossOrigin = $element.prop('crossOrigin'); + if (this.options.checkCrossOrigin && isCrossOriginURL(url)) { + crossOrigin = element.crossOrigin; + if (crossOrigin) { crossOriginUrl = url; } else { crossOrigin = 'anonymous'; - // Bust cache (#148) when there is not a "crossOrigin" property + // Bust cache when there is not a "crossOrigin" property crossOriginUrl = addTimestamp(url); } } @@ -3014,88 +3364,136 @@ var Cropper = function () { image.src = crossOriginUrl || url; - var $clone = $(image); + var start = this.start.bind(this); + var stop = this.stop.bind(this); - this.$clone = $clone; + this.image = image; + this.onStart = start; + this.onStop = stop; if (this.isImg) { - if (this.element.complete) { - this.start(); + if (element.complete) { + this.timeout = setTimeout(start, 0); } else { - $element.one(EVENT_LOAD, $.proxy(this.start, this)); + addListener(element, EVENT_LOAD, start, { + once: true + }); } } else { - $clone.one(EVENT_LOAD, $.proxy(this.start, this)).one(EVENT_ERROR, $.proxy(this.stop, this)).addClass(CLASS_HIDE).insertAfter($element); + image.onload = start; + image.onerror = stop; + addClass(image, CLASS_HIDE); + element.parentNode.insertBefore(image, element.nextSibling); } } }, { key: 'start', - value: function start() { + value: function start(event) { var _this2 = this; - var $clone = this.$clone; - - var $image = this.$element; + var image = this.isImg ? this.element : this.image; - if (!this.isImg) { - $clone.off(EVENT_ERROR, this.stop); - $image = $clone; + if (event) { + image.onload = null; + image.onerror = null; } - getImageNaturalSizes($image[0], function (naturalWidth, naturalHeight) { - $.extend(_this2.image, { + this.sizing = true; + + var IS_SAFARI = WINDOW.navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(WINDOW.navigator.userAgent); + var done = function done(naturalWidth, naturalHeight) { + assign(_this2.imageData, { naturalWidth: naturalWidth, naturalHeight: naturalHeight, aspectRatio: naturalWidth / naturalHeight }); - - _this2.loaded = true; + _this2.sizing = false; + _this2.sized = true; _this2.build(); - }); + }; + + // Modern browsers (except Safari) + if (image.naturalWidth && !IS_SAFARI) { + done(image.naturalWidth, image.naturalHeight); + return; + } + + var sizingImage = document.createElement('img'); + var body = document.body || document.documentElement; + + this.sizingImage = sizingImage; + + sizingImage.onload = function () { + done(sizingImage.width, sizingImage.height); + + if (!IS_SAFARI) { + body.removeChild(sizingImage); + } + }; + + sizingImage.src = image.src; + + // iOS Safari will convert the image automatically + // with its orientation once append it into DOM (#279) + if (!IS_SAFARI) { + sizingImage.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(sizingImage); + } } }, { key: 'stop', value: function stop() { - this.$clone.remove(); - this.$clone = null; + var image = this.image; + + + image.onload = null; + image.onerror = null; + image.parentNode.removeChild(image); + this.image = null; } }, { key: 'build', value: function build() { - var _this3 = this; - - if (!this.loaded) { + if (!this.sized || this.ready) { return; } - // Unbuild first when replace - if (this.ready) { - this.unbuild(); - } - - var $element = this.$element, + var element = this.element, options = this.options, - $clone = this.$clone; - - var $cropper = $(TEMPLATE); - var $cropBox = $cropper.find('.' + NAMESPACE + '-crop-box'); - var $face = $cropBox.find('.' + NAMESPACE + '-face'); + image = this.image; // Create cropper elements - this.$container = $element.parent(); - this.$cropper = $cropper; - this.$canvas = $cropper.find('.' + NAMESPACE + '-canvas').append($clone); - this.$dragBox = $cropper.find('.' + NAMESPACE + '-drag-box'); - this.$cropBox = $cropBox; - this.$viewBox = $cropper.find('.' + NAMESPACE + '-view-box'); - this.$face = $face; + + 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 - $element.addClass(CLASS_HIDDEN).after($cropper); + addClass(element, CLASS_HIDDEN); + + // Inserts the cropper after to the current image + container.insertBefore(cropper, element.nextSibling); - // Show the clone image if is hidden + // Show the image if is hidden if (!this.isImg) { - $clone.removeClass(CLASS_HIDE); + removeClass(image, CLASS_HIDE); } this.initPreview(); @@ -3104,55 +3502,51 @@ var Cropper = function () { 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) { - this.$dragBox.addClass(CLASS_MODAL); - } - } else { - $cropBox.addClass(CLASS_HIDDEN); - } + addClass(cropBox, CLASS_HIDDEN); if (!options.guides) { - $cropBox.find('.' + NAMESPACE + '-dashed').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-dashed'), CLASS_HIDDEN); } if (!options.center) { - $cropBox.find('.' + NAMESPACE + '-center').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-center'), CLASS_HIDDEN); } - if (options.cropBoxMovable) { - $face.addClass(CLASS_MOVE).data(DATA_ACTION, ACTION_ALL); + if (options.background) { + addClass(cropper, NAMESPACE + '-bg'); } if (!options.highlight) { - $face.addClass(CLASS_INVISIBLE); + addClass(face, CLASS_INVISIBLE); } - if (options.background) { - $cropper.addClass(NAMESPACE + '-bg'); + if (options.cropBoxMovable) { + addClass(face, CLASS_MOVE); + setData(face, DATA_ACTION, ACTION_ALL); } if (!options.cropBoxResizable) { - $cropBox.find('.' + NAMESPACE + '-line,.' + NAMESPACE + '-point').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-line'), CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-point'), CLASS_HIDDEN); } - this.setDragMode(options.dragMode); this.render(); this.ready = true; + this.setDragMode(options.dragMode); + + if (options.autoCrop) { + this.crop(); + } + this.setData(options.data); - // Trigger the ready event asynchronously to keep `data('cropper')` is defined - this.completing = setTimeout(function () { - if ($.isFunction(options.ready)) { - $element.one(EVENT_READY, options.ready); - } + if (isFunction(options.ready)) { + addListener(element, EVENT_READY, options.ready, { + once: true + }); + } - _this3.trigger(EVENT_READY); - _this3.trigger(EVENT_CROP, _this3.getData()); - _this3.completed = true; - }, 0); + dispatchEvent(element, EVENT_READY); } }, { key: 'unbuild', @@ -3161,35 +3555,49 @@ var Cropper = function () { return; } - if (!this.completed) { - clearTimeout(this.completing); - } - this.ready = false; - this.completed = false; - this.initialImage = null; - - // Clear `initialCanvas` is necessary when replace - this.initialCanvas = null; - this.initialCropBox = null; - this.container = null; - this.canvas = null; - - // Clear `cropBox` is necessary when replace - this.cropBox = null; this.unbind(); - this.resetPreview(); - this.$preview = null; + this.cropper.parentNode.removeChild(this.cropper); + removeClass(this.element, CLASS_HIDDEN); + } + }, { + key: 'uncreate', + value: function uncreate() { + var element = this.element; + + + if (this.ready) { + this.unbuild(); + this.ready = false; + this.cropped = false; + } else if (this.sizing) { + this.sizingImage.onload = null; + this.sizing = false; + this.sized = false; + } else if (this.reloading) { + this.xhr.abort(); + } else if (this.isImg) { + if (element.complete) { + clearTimeout(this.timeout); + } else { + removeListener(element, EVENT_LOAD, this.onStart); + } + } else if (this.image) { + this.stop(); + } + } - this.$viewBox = null; - this.$cropBox = null; - this.$dragBox = null; - this.$canvas = null; - this.$container = null; + /** + * Get the no conflict cropper class. + * @returns {Cropper} The cropper class. + */ - this.$cropper.remove(); - this.$cropper = null; + }], [{ + key: 'noConflict', + value: function noConflict() { + window.Cropper = AnotherCropper; + return Cropper; } /** @@ -3197,21 +3605,20 @@ var Cropper = function () { * @param {Object} options - The new default options. */ - }], [{ + }, { key: 'setDefaults', value: function setDefaults(options) { - $.extend(DEFAULTS, $.isPlainObject(options) && options); + assign(DEFAULTS, isPlainObject(options) && options); } }]); return Cropper; }(); -if ($.extend) { - $.extend(Cropper.prototype, render, preview, events, handlers, change, methods); -} +assign(Cropper.prototype, render, preview, events, handlers, change, methods); if ($.fn) { - var AnotherCropper = $.fn.cropper; + var AnotherCropper$1 = $.fn.cropper; + var NAMESPACE$1 = 'cropper'; $.fn.cropper = function jQueryCropper(option) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { @@ -3222,35 +3629,44 @@ if ($.fn) { this.each(function (i, element) { var $element = $(element); - var data = $element.data(NAMESPACE); + var isDestroy = option === 'destroy'; + var cropper = $element.data(NAMESPACE$1); - if (!data) { - if (/destroy/.test(option)) { + if (!cropper) { + if (isDestroy) { return; } var options = $.extend({}, $element.data(), $.isPlainObject(option) && option); - data = new Cropper(element, options); - $element.data(NAMESPACE, data); + cropper = new Cropper(element, options); + $element.data(NAMESPACE$1, cropper); } - if (isString(option)) { - var fn = data[option]; + if (typeof option === 'string') { + var fn = cropper[option]; if ($.isFunction(fn)) { - result = fn.apply(data, args); + result = fn.apply(cropper, args); + + if (result === cropper) { + result = undefined; + } + + if (isDestroy) { + $element.removeData(NAMESPACE$1); + } } } }); - return isUndefined(result) ? this : result; + return typeof result === 'undefined' ? this : result; }; $.fn.cropper.Constructor = Cropper; $.fn.cropper.setDefaults = Cropper.setDefaults; $.fn.cropper.noConflict = function noConflict() { - $.fn.cropper = AnotherCropper; + $.fn.cropper = AnotherCropper$1; return this; }; } diff --git a/dist/cropper.css b/dist/cropper.css index 45399716..29a7a56a 100644 --- a/dist/cropper.css +++ b/dist/cropper.css @@ -1,11 +1,11 @@ /*! - * Cropper v3.1.6 + * Cropper v4.0.0-alpha * https://github.com/fengyuanchen/cropper * * Copyright (c) 2014-2018 Chen Fengyuan * Released under the MIT license * - * Date: 2018-03-01T13:33:39.581Z + * Date: 2018-03-01T14:21:03.491Z */ .cropper-container { @@ -303,4 +303,3 @@ .cropper-disabled .cropper-point { cursor: not-allowed; } - diff --git a/dist/cropper.esm.js b/dist/cropper.esm.js index bccc7bc0..9e9af4c2 100644 --- a/dist/cropper.esm.js +++ b/dist/cropper.esm.js @@ -1,11 +1,11 @@ /*! - * Cropper v3.1.6 + * Cropper v4.0.0-alpha * https://github.com/fengyuanchen/cropper * * Copyright (c) 2014-2018 Chen Fengyuan * Released under the MIT license * - * Date: 2018-03-01T13:33:48.179Z + * Date: 2018-03-01T14:21:13.980Z */ import $ from 'jquery'; @@ -51,7 +51,6 @@ 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'; @@ -62,10 +61,10 @@ 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_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 REGEXP_TAG_NAME = /^(?:img|canvas)$/i; var DEFAULTS = { // Define the view mode of the cropper @@ -163,7 +162,13 @@ var DEFAULTS = { zoom: null }; -var TEMPLATE = '
' + '
' + '
' + '
' + '
' + '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
' + '
'; +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)) { @@ -199,15 +204,6 @@ var toConsumableArray = function (arr) { } }; -/** - * Check if the given value is a string. - * @param {*} value - The value to check. - * @returns {boolean} Returns `true` if the given value is a string, else `false`. - */ -function isString(value) { - return typeof value === 'string'; -} - /** * Check if the given value is not a number. */ @@ -232,39 +228,97 @@ function isUndefined(value) { } /** - * Takes a function and returns a new one that will always have a particular context. - * Custom proxy to avoid jQuery's guid. - * @param {Function} fn - The target function. - * @param {Object} context - The new context for the function. - * @returns {Function} The new function. + * 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 proxy(fn, context) { - for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { - args[_key - 2] = arguments[_key]; +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'; +} - return function () { - for (var _len2 = arguments.length, args2 = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args2[_key2] = arguments[_key2]; +/** + * Iterate the given data. + * @param {*} data - The data to iterate. + * @param {Function} callback - The process function for each element. + * @returns {*} The original data. + */ +function forEach(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 fn.apply(context, args.concat(args2)); - }; + return data; } /** - * Get the own enumerable properties of a given object. - * @param {Object} obj - The target object. - * @returns {Array} All the own enumerable properties of the given object. + * 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. */ -var objectKeys = Object.keys || function objectKeys(obj) { - var keys = []; +var assign = Object.assign || function assign(obj) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } - $.each(obj, function (key) { - keys.push(key); - }); + if (isObject(obj) && args.length > 0) { + args.forEach(function (arg) { + if (isObject(arg)) { + Object.keys(arg).forEach(function (key) { + obj[key] = arg[key]; + }); + } + }); + } - return keys; + return obj; }; var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/i; @@ -282,6 +336,271 @@ function normalizeDecimalNumber(value) { 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; + + + forEach(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)) { + forEach(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)) { + forEach(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)) { + forEach(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; + +/** + * Transform the given string from camelCase to kebab-case + * @param {string} value - The value to transform. + * @returns {string} The transformed 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] = undefined; + } + } else if (element.dataset) { + // #128 Safari not allows to delete dataset property + try { + delete element.dataset[name]; + } catch (e) { + element.dataset[name] = undefined; + } + } else { + element.removeAttribute('data-' + hyphenate(name)); + } +} + +var 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. + */ +function removeListener(element, type, listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + forEach(type.trim().split(REGEXP_SPACES), function (t) { + element.removeEventListener(t, listener, options); + }); +} + +/** + * 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 (options.once) { + var originalListener = _listener; + + _listener = function listener() { + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + removeListener(element, type, _listener, options); + return originalListener.apply(element, args); + }; + } + + forEach(type.trim().split(REGEXP_SPACES), function (t) { + element.addEventListener(t, _listener, options); + }); +} + +/** + * 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) { + var event = void 0; + + // Event and CustomEvent on IE9-11 are global objects, not constructors + if (isFunction(Event) && isFunction(CustomEvent)) { + event = new CustomEvent(type, { + detail: data, + bubbles: true, + cancelable: true + }); + } else { + event = document.createEvent('CustomEvent'); + event.initCustomEvent(type, true, true, data); + } + + return element.dispatchEvent(event); +} + +/** + * Get the offset base on the document. + * @param {Element} element - The target element. + * @returns {Object} The offset data. + */ +function getOffset(element) { + var box = element.getBoundingClientRect(); + + return { + left: box.left + (window.pageXOffset - document.documentElement.clientLeft), + top: box.top + (window.pageYOffset - document.documentElement.clientTop) + }; +} + var location = WINDOW.location; var REGEXP_ORIGINS = /^(https?:)\/\/([^:/?#]+):?(\d*)/i; @@ -309,11 +628,11 @@ function addTimestamp(url) { } /** - * Get transform values base on the given object. + * Get transforms base on the given object. * @param {Object} obj - The target object. * @returns {string} A string contains transform values. */ -function getTransformValues(_ref) { +function getTransforms(_ref) { var rotate = _ref.rotate, scaleX = _ref.scaleX, scaleY = _ref.scaleY, @@ -343,32 +662,13 @@ function getTransformValues(_ref) { values.push('scaleY(' + scaleY + ')'); } - return values.length ? values.join(' ') : 'none'; -} - -var navigator = WINDOW.navigator; + var transform = values.length ? values.join(' ') : 'none'; -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'); - - newImage.onload = function () { - callback(newImage.width, newImage.height); + return { + WebkitTransform: transform, + msTransform: transform, + transform: transform }; - - newImage.src = image.src; } /** @@ -377,13 +677,13 @@ function getImageNaturalSizes(image, callback) { * @returns {number} The result ratio. */ function getMaxZoomRatio(pointers) { - var pointers2 = $.extend({}, pointers); + var pointers2 = assign({}, pointers); var ratios = []; - $.each(pointers, function (pointerId, pointer) { + forEach(pointers, function (pointer, pointerId) { delete pointers2[pointerId]; - $.each(pointers2, function (pointerId2, pointer2) { + forEach(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); @@ -418,11 +718,7 @@ function getPointer(_ref2, endOnly) { endY: pageY }; - if (endOnly) { - return end; - } - - return $.extend({ + return endOnly ? end : assign({ startX: pageX, startY: pageY }, end); @@ -438,7 +734,7 @@ function getPointersCenter(pointers) { var pageY = 0; var count = 0; - $.each(pointers, function (pointerId, _ref3) { + forEach(pointers, function (_ref3) { var startX = _ref3.startX, startY = _ref3.startY; @@ -591,7 +887,7 @@ function getSourceCanvas(image, _ref6, _ref7, _ref8) { context.scale(scaleX, scaleY); context.imageSmoothingEnabled = imageSmoothingEnabled; context.imageSmoothingQuality = imageSmoothingQuality; - context.drawImage.apply(context, [image].concat(toConsumableArray($.map(params, function (param) { + context.drawImage.apply(context, [image].concat(toConsumableArray(params.map(function (param) { return Math.floor(normalizeDecimalNumber(param)); })))); context.restore(); @@ -634,7 +930,7 @@ function dataURLToArrayBuffer(dataURL) { var arrayBuffer = new ArrayBuffer(binary.length); var uint8 = new Uint8Array(arrayBuffer); - $.each(uint8, function (i) { + forEach(uint8, function (value, i) { uint8[i] = binary.charCodeAt(i); }); @@ -652,7 +948,7 @@ function arrayBufferToDataURL(arrayBuffer, mimeType) { var data = ''; // TypedArray.prototype.forEach is not supported in some browsers. - $.each(uint8, function (i, value) { + forEach(uint8, function (value) { data += fromCharCode(value); }); @@ -802,51 +1098,58 @@ var render = { } }, initContainer: function initContainer() { - var $element = this.$element, + var element = this.element, options = this.options, - $container = this.$container, - $cropper = this.$cropper; + container = this.container, + cropper = this.cropper; - $cropper.addClass(CLASS_HIDDEN); - $element.removeClass(CLASS_HIDDEN); + 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; - $cropper.css(this.container = { - width: Math.max($container.width(), Number(options.minContainerWidth) || 200), - height: Math.max($container.height(), Number(options.minContainerHeight) || 100) + setStyle(cropper, { + width: containerData.width, + height: containerData.height }); - $element.addClass(CLASS_HIDDEN); - $cropper.removeClass(CLASS_HIDDEN); + addClass(element, CLASS_HIDDEN); + removeClass(cropper, CLASS_HIDDEN); }, // Canvas (image wrapper) initCanvas: function initCanvas() { - var container = this.container, - image = this.image; + var containerData = this.containerData, + imageData = this.imageData; var viewMode = this.options.viewMode; - var rotated = Math.abs(image.rotate) % 180 === 90; - var naturalWidth = rotated ? image.naturalHeight : image.naturalWidth; - var naturalHeight = rotated ? image.naturalWidth : image.naturalHeight; + 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 = container.width; - var canvasHeight = container.height; + var canvasWidth = containerData.width; + var canvasHeight = containerData.height; - if (container.height * aspectRatio > container.width) { + if (containerData.height * aspectRatio > containerData.width) { if (viewMode === 3) { - canvasWidth = container.height * aspectRatio; + canvasWidth = containerData.height * aspectRatio; } else { - canvasHeight = container.width / aspectRatio; + canvasHeight = containerData.width / aspectRatio; } } else if (viewMode === 3) { - canvasHeight = container.width / aspectRatio; + canvasHeight = containerData.width / aspectRatio; } else { - canvasWidth = container.height * aspectRatio; + canvasWidth = containerData.height * aspectRatio; } - var canvas = { + var canvasData = { aspectRatio: aspectRatio, naturalWidth: naturalWidth, naturalHeight: naturalHeight, @@ -854,50 +1157,50 @@ var render = { height: canvasHeight }; - canvas.left = (container.width - canvasWidth) / 2; - canvas.top = (container.height - canvasHeight) / 2; - canvas.oldLeft = canvas.left; - canvas.oldTop = canvas.top; + canvasData.left = (containerData.width - canvasWidth) / 2; + canvasData.top = (containerData.height - canvasHeight) / 2; + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; - this.canvas = canvas; + this.canvasData = canvasData; this.limited = viewMode === 1 || viewMode === 2; this.limitCanvas(true, true); - this.initialImage = $.extend({}, image); - this.initialCanvas = $.extend({}, canvas); + this.initialImageData = assign({}, imageData); + this.initialCanvasData = assign({}, canvasData); }, - limitCanvas: function limitCanvas(isSizeLimited, isPositionLimited) { + limitCanvas: function limitCanvas(sizeLimited, positionLimited) { var options = this.options, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox; + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; var viewMode = options.viewMode; - var aspectRatio = canvas.aspectRatio; + var aspectRatio = canvasData.aspectRatio; - var cropped = this.cropped && cropBox; + var cropped = this.cropped && cropBoxData; - if (isSizeLimited) { + if (sizeLimited) { var minCanvasWidth = Number(options.minCanvasWidth) || 0; var minCanvasHeight = Number(options.minCanvasHeight) || 0; - if (viewMode > 0) { - if (viewMode > 1) { - minCanvasWidth = Math.max(minCanvasWidth, container.width); - minCanvasHeight = Math.max(minCanvasHeight, container.height); + 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; - } + if (viewMode === 3) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; } - } else if (minCanvasWidth) { - minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBox.width : 0); + } + } else if (viewMode > 0) { + if (minCanvasWidth) { + minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0); } else if (minCanvasHeight) { - minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBox.height : 0); + minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0); } else if (cropped) { - minCanvasWidth = cropBox.width; - minCanvasHeight = cropBox.height; + minCanvasWidth = cropBoxData.width; + minCanvasHeight = cropBoxData.height; if (minCanvasHeight * aspectRatio > minCanvasWidth) { minCanvasWidth = minCanvasHeight * aspectRatio; @@ -917,101 +1220,100 @@ var render = { minCanvasHeight = _getAdjustedSizes.height; - canvas.minWidth = minCanvasWidth; - canvas.minHeight = minCanvasHeight; - canvas.maxWidth = Infinity; - canvas.maxHeight = Infinity; + canvasData.minWidth = minCanvasWidth; + canvasData.minHeight = minCanvasHeight; + canvasData.maxWidth = Infinity; + canvasData.maxHeight = Infinity; } - if (isPositionLimited) { - if (viewMode > 0) { - var newCanvasLeft = container.width - canvas.width; - var newCanvasTop = container.height - canvas.height; + if (positionLimited) { + if (viewMode) { + var newCanvasLeft = containerData.width - canvasData.width; + var newCanvasTop = containerData.height - canvasData.height; - canvas.minLeft = Math.min(0, newCanvasLeft); - canvas.minTop = Math.min(0, newCanvasTop); - canvas.maxLeft = Math.max(0, newCanvasLeft); - canvas.maxTop = Math.max(0, newCanvasTop); + 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) { - canvas.minLeft = Math.min(cropBox.left, cropBox.left + cropBox.width - canvas.width); - canvas.minTop = Math.min(cropBox.top, cropBox.top + cropBox.height - canvas.height); - canvas.maxLeft = cropBox.left; - canvas.maxTop = cropBox.top; + 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 (canvas.width >= container.width) { - canvas.minLeft = Math.min(0, newCanvasLeft); - canvas.maxLeft = Math.max(0, newCanvasLeft); + if (canvasData.width >= containerData.width) { + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.maxLeft = Math.max(0, newCanvasLeft); } - if (canvas.height >= container.height) { - canvas.minTop = Math.min(0, newCanvasTop); - canvas.maxTop = Math.max(0, newCanvasTop); + if (canvasData.height >= containerData.height) { + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxTop = Math.max(0, newCanvasTop); } } } } else { - canvas.minLeft = -canvas.width; - canvas.minTop = -canvas.height; - canvas.maxLeft = container.width; - canvas.maxTop = container.height; + canvasData.minLeft = -canvasData.width; + canvasData.minTop = -canvasData.height; + canvasData.maxLeft = containerData.width; + canvasData.maxTop = containerData.height; } } }, renderCanvas: function renderCanvas(changed, transformed) { - var canvas = this.canvas, - image = this.image; + var canvasData = this.canvasData, + imageData = this.imageData; if (transformed) { var _getRotatedSizes = getRotatedSizes({ - width: image.naturalWidth * Math.abs(image.scaleX || 1), - height: image.naturalHeight * Math.abs(image.scaleY || 1), - degree: image.rotate || 0 + 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 = canvas.width * (naturalWidth / canvas.naturalWidth); - var height = canvas.height * (naturalHeight / canvas.naturalHeight); + var width = canvasData.width * (naturalWidth / canvasData.naturalWidth); + var height = canvasData.height * (naturalHeight / canvasData.naturalHeight); - canvas.left -= (width - canvas.width) / 2; - canvas.top -= (height - canvas.height) / 2; - canvas.width = width; - canvas.height = height; - canvas.aspectRatio = naturalWidth / naturalHeight; - canvas.naturalWidth = naturalWidth; - canvas.naturalHeight = 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 (canvas.width > canvas.maxWidth || canvas.width < canvas.minWidth) { - canvas.left = canvas.oldLeft; + if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) { + canvasData.left = canvasData.oldLeft; } - if (canvas.height > canvas.maxHeight || canvas.height < canvas.minHeight) { - canvas.top = canvas.oldTop; + if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) { + canvasData.top = canvasData.oldTop; } - canvas.width = Math.min(Math.max(canvas.width, canvas.minWidth), canvas.maxWidth); - canvas.height = Math.min(Math.max(canvas.height, canvas.minHeight), canvas.maxHeight); + 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); - canvas.left = Math.min(Math.max(canvas.left, canvas.minLeft), canvas.maxLeft); - canvas.top = Math.min(Math.max(canvas.top, canvas.minTop), canvas.maxTop); - canvas.oldLeft = canvas.left; - canvas.oldTop = canvas.top; - - this.$canvas.css({ - width: canvas.width, - height: canvas.height, - transform: getTransformValues({ - translateX: canvas.left, - translateY: canvas.top - }) - }); + 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, assign({ + width: canvasData.width, + height: canvasData.height + }, getTransforms({ + translateX: canvasData.left, + translateY: canvasData.top + }))); this.renderImage(changed); @@ -1020,27 +1322,25 @@ var render = { } }, renderImage: function renderImage(changed) { - var canvas = this.canvas, - image = this.image; + var canvasData = this.canvasData, + imageData = this.imageData; - var width = image.naturalWidth * (canvas.width / canvas.naturalWidth); - var height = image.naturalHeight * (canvas.height / canvas.naturalHeight); + var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth); + var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight); - $.extend(image, { + assign(imageData, { width: width, height: height, - left: (canvas.width - width) / 2, - top: (canvas.height - height) / 2 - }); - - this.$clone.css({ - width: image.width, - height: image.height, - transform: getTransformValues($.extend({ - translateX: image.left, - translateY: image.top - }, image)) + left: (canvasData.width - width) / 2, + top: (canvasData.height - height) / 2 }); + setStyle(this.image, assign({ + width: imageData.width, + height: imageData.height + }, getTransforms(assign({ + translateX: imageData.left, + translateY: imageData.top + }, imageData)))); if (changed) { this.output(); @@ -1048,58 +1348,58 @@ var render = { }, initCropBox: function initCropBox() { var options = this.options, - canvas = this.canvas; + canvasData = this.canvasData; var aspectRatio = options.aspectRatio; var autoCropArea = Number(options.autoCropArea) || 0.8; - var cropBox = { - width: canvas.width, - height: canvas.height + var cropBoxData = { + width: canvasData.width, + height: canvasData.height }; if (aspectRatio) { - if (canvas.height * aspectRatio > canvas.width) { - cropBox.height = cropBox.width / aspectRatio; + if (canvasData.height * aspectRatio > canvasData.width) { + cropBoxData.height = cropBoxData.width / aspectRatio; } else { - cropBox.width = cropBox.height * aspectRatio; + cropBoxData.width = cropBoxData.height * aspectRatio; } } - this.cropBox = cropBox; + this.cropBoxData = cropBoxData; this.limitCropBox(true, true); // Initialize auto crop area - cropBox.width = Math.min(Math.max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); - cropBox.height = Math.min(Math.max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); - - // The width of auto crop area must large than "minWidth", and the height too. (#164) - cropBox.width = Math.max(cropBox.minWidth, cropBox.width * autoCropArea); - cropBox.height = Math.max(cropBox.minHeight, cropBox.height * autoCropArea); - cropBox.left = canvas.left + (canvas.width - cropBox.width) / 2; - cropBox.top = canvas.top + (canvas.height - cropBox.height) / 2; - cropBox.oldLeft = cropBox.left; - cropBox.oldTop = cropBox.top; - - this.initialCropBox = $.extend({}, cropBox); + 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 = assign({}, cropBoxData); }, - limitCropBox: function limitCropBox(isSizeLimited, isPositionLimited) { + limitCropBox: function limitCropBox(sizeLimited, positionLimited) { var options = this.options, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData, limited = this.limited; var aspectRatio = options.aspectRatio; - if (isSizeLimited) { + if (sizeLimited) { var minCropBoxWidth = Number(options.minCropBoxWidth) || 0; var minCropBoxHeight = Number(options.minCropBoxHeight) || 0; - var maxCropBoxWidth = Math.min(container.width, limited ? canvas.width : container.width); - var maxCropBoxHeight = Math.min(container.height, limited ? canvas.height : container.height); + 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, container.width); - minCropBoxHeight = Math.min(minCropBoxHeight, container.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) { @@ -1122,63 +1422,62 @@ var render = { } // The minWidth/Height must be less than maxWidth/Height - cropBox.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); - cropBox.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); - cropBox.maxWidth = maxCropBoxWidth; - cropBox.maxHeight = maxCropBoxHeight; + cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); + cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); + cropBoxData.maxWidth = maxCropBoxWidth; + cropBoxData.maxHeight = maxCropBoxHeight; } - if (isPositionLimited) { + if (positionLimited) { if (limited) { - cropBox.minLeft = Math.max(0, canvas.left); - cropBox.minTop = Math.max(0, canvas.top); - cropBox.maxLeft = Math.min(container.width, canvas.left + canvas.width) - cropBox.width; - cropBox.maxTop = Math.min(container.height, canvas.top + canvas.height) - cropBox.height; + 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 { - cropBox.minLeft = 0; - cropBox.minTop = 0; - cropBox.maxLeft = container.width - cropBox.width; - cropBox.maxTop = container.height - cropBox.height; + 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, - container = this.container, - cropBox = this.cropBox; + containerData = this.containerData, + cropBoxData = this.cropBoxData; - if (cropBox.width > cropBox.maxWidth || cropBox.width < cropBox.minWidth) { - cropBox.left = cropBox.oldLeft; + if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) { + cropBoxData.left = cropBoxData.oldLeft; } - if (cropBox.height > cropBox.maxHeight || cropBox.height < cropBox.minHeight) { - cropBox.top = cropBox.oldTop; + if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) { + cropBoxData.top = cropBoxData.oldTop; } - cropBox.width = Math.min(Math.max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); - cropBox.height = Math.min(Math.max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); + 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); - cropBox.left = Math.min(Math.max(cropBox.left, cropBox.minLeft), cropBox.maxLeft); - cropBox.top = Math.min(Math.max(cropBox.top, cropBox.minTop), cropBox.maxTop); - cropBox.oldLeft = cropBox.left; - cropBox.oldTop = cropBox.top; + 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 - this.$face.data(DATA_ACTION, cropBox.width >= container.width && cropBox.height >= container.height ? ACTION_MOVE : ACTION_ALL); + setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL); } - this.$cropBox.css({ - width: cropBox.width, - height: cropBox.height, - transform: getTransformValues({ - translateX: cropBox.left, - translateY: cropBox.top - }) - }); + setStyle(this.cropBox, assign({ + width: cropBoxData.width, + height: cropBoxData.height + }, getTransforms({ + translateX: cropBoxData.left, + translateY: cropBoxData.top + }))); if (this.cropped && this.limited) { this.limitCanvas(true, true); @@ -1190,16 +1489,14 @@ var render = { }, output: function output() { this.preview(); - - if (this.completed) { - this.trigger(EVENT_CROP, this.getData()); - } + 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'); @@ -1209,21 +1506,31 @@ var preview = { } image.src = url; + this.viewBox.appendChild(image); + this.viewBoxImage = image; - var $clone2 = $(image); + if (!preview) { + return; + } - this.$preview = $(this.options.preview); - this.$clone2 = $clone2; - this.$viewBox.html($clone2); - this.$preview.each(function (i, element) { - var $element = $(element); + var previews = preview; + + if (typeof preview === 'string') { + previews = this.element.ownerDocument.querySelectorAll(preview); + } else if (preview.querySelector) { + previews = [preview]; + } + + this.previews = previews; + + forEach(previews, function (el) { var img = document.createElement('img'); // Save the original size for recover - $element.data(DATA_PREVIEW, { - width: $element.width(), - height: $element.height(), - html: $element.html() + setData(el, DATA_PREVIEW, { + width: el.offsetWidth, + height: el.offsetHeight, + html: el.innerHTML }); if (crossOrigin) { @@ -1240,48 +1547,49 @@ var preview = { */ 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;"'; - $element.html(img); + el.innerHTML = ''; + el.appendChild(img); }); }, resetPreview: function resetPreview() { - this.$preview.each(function (i, element) { - var $element = $(element); - var data = $element.data(DATA_PREVIEW); + forEach(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); - $element.css({ + setStyle(element, { width: data.width, height: data.height - }).html(data.html).removeData(DATA_PREVIEW); + }); + + element.innerHTML = data.html; + removeData(element, DATA_PREVIEW); }); }, preview: function preview() { - var image = this.image, - canvas = this.canvas, - cropBox = this.cropBox; - var cropBoxWidth = cropBox.width, - cropBoxHeight = cropBox.height; - var width = image.width, - height = image.height; + 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 = cropBox.left - canvas.left - image.left; - var top = cropBox.top - canvas.top - image.top; + var left = cropBoxData.left - canvasData.left - imageData.left; + var top = cropBoxData.top - canvasData.top - imageData.top; if (!this.cropped || this.disabled) { return; } - this.$clone2.css({ + setStyle(this.viewBoxImage, assign({ width: width, - height: height, - transform: getTransformValues($.extend({ - translateX: -left, - translateY: -top - }, image)) - }); - - this.$preview.each(function (i, element) { - var $element = $(element); - var data = $element.data(DATA_PREVIEW); + height: height + }, getTransforms(assign({ + translateX: -left, + translateY: -top + }, imageData)))); + + forEach(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); var originalWidth = data.width; var originalHeight = data.height; var newWidth = originalWidth; @@ -1299,104 +1607,107 @@ var preview = { newHeight = originalHeight; } - $element.css({ + setStyle(element, { width: newWidth, height: newHeight - }).find('img').css({ - width: width * ratio, - height: height * ratio, - transform: getTransformValues($.extend({ - translateX: -left * ratio, - translateY: -top * ratio - }, image)) }); + + setStyle(element.getElementsByTagName('img')[0], assign({ + width: width * ratio, + height: height * ratio + }, getTransforms(assign({ + translateX: -left * ratio, + translateY: -top * ratio + }, imageData)))); }); } }; var events = { bind: function bind() { - var $element = this.$element, + var element = this.element, options = this.options, - $cropper = this.$cropper; + cropper = this.cropper; - if ($.isFunction(options.cropstart)) { - $element.on(EVENT_CROP_START, options.cropstart); + if (isFunction(options.cropstart)) { + addListener(element, EVENT_CROP_START, options.cropstart); } - if ($.isFunction(options.cropmove)) { - $element.on(EVENT_CROP_MOVE, options.cropmove); + if (isFunction(options.cropmove)) { + addListener(element, EVENT_CROP_MOVE, options.cropmove); } - if ($.isFunction(options.cropend)) { - $element.on(EVENT_CROP_END, options.cropend); + if (isFunction(options.cropend)) { + addListener(element, EVENT_CROP_END, options.cropend); } - if ($.isFunction(options.crop)) { - $element.on(EVENT_CROP, options.crop); + if (isFunction(options.crop)) { + addListener(element, EVENT_CROP, options.crop); } - if ($.isFunction(options.zoom)) { - $element.on(EVENT_ZOOM, options.zoom); + if (isFunction(options.zoom)) { + addListener(element, EVENT_ZOOM, options.zoom); } - $cropper.on(EVENT_POINTER_DOWN, proxy(this.cropStart, this)); + addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this)); if (options.zoomable && options.zoomOnWheel) { - $cropper.on(EVENT_WHEEL, proxy(this.wheel, this)); + addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this)); } if (options.toggleDragModeOnDblclick) { - $cropper.on(EVENT_DBLCLICK, proxy(this.dblclick, this)); + addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this)); } - $(this.element.ownerDocument).on(EVENT_POINTER_MOVE, this.onCropMove = proxy(this.cropMove, this)).on(EVENT_POINTER_UP, this.onCropEnd = proxy(this.cropEnd, this)); + addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this)); + addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this)); if (options.responsive) { - $(window).on(EVENT_RESIZE, this.onResize = proxy(this.resize, this)); + addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this)); } }, unbind: function unbind() { - var $element = this.$element, + var element = this.element, options = this.options, - $cropper = this.$cropper; + cropper = this.cropper; - if ($.isFunction(options.cropstart)) { - $element.off(EVENT_CROP_START, options.cropstart); + if (isFunction(options.cropstart)) { + removeListener(element, EVENT_CROP_START, options.cropstart); } - if ($.isFunction(options.cropmove)) { - $element.off(EVENT_CROP_MOVE, options.cropmove); + if (isFunction(options.cropmove)) { + removeListener(element, EVENT_CROP_MOVE, options.cropmove); } - if ($.isFunction(options.cropend)) { - $element.off(EVENT_CROP_END, options.cropend); + if (isFunction(options.cropend)) { + removeListener(element, EVENT_CROP_END, options.cropend); } - if ($.isFunction(options.crop)) { - $element.off(EVENT_CROP, options.crop); + if (isFunction(options.crop)) { + removeListener(element, EVENT_CROP, options.crop); } - if ($.isFunction(options.zoom)) { - $element.off(EVENT_ZOOM, options.zoom); + if (isFunction(options.zoom)) { + removeListener(element, EVENT_ZOOM, options.zoom); } - $cropper.off(EVENT_POINTER_DOWN, this.cropStart); + removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart); if (options.zoomable && options.zoomOnWheel) { - $cropper.off(EVENT_WHEEL, this.wheel); + removeListener(cropper, EVENT_WHEEL, this.onWheel); } if (options.toggleDragModeOnDblclick) { - $cropper.off(EVENT_DBLCLICK, this.dblclick); + removeListener(cropper, EVENT_DBLCLICK, this.onDblclick); } - $(this.element.ownerDocument).off(EVENT_POINTER_MOVE, this.onCropMove).off(EVENT_POINTER_UP, this.onCropEnd); + removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove); + removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd); if (options.responsive) { - $(window).off(EVENT_RESIZE, this.onResize); + removeListener(window, EVENT_RESIZE, this.onResize); } } }; @@ -1404,20 +1715,20 @@ var events = { var handlers = { resize: function resize() { var options = this.options, - $container = this.$container, - container = this.container; + container = this.container, + containerData = this.containerData; var minContainerWidth = Number(options.minContainerWidth) || 200; var minContainerHeight = Number(options.minContainerHeight) || 100; - if (this.disabled || container.width <= minContainerWidth || container.height <= minContainerHeight) { + if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) { return; } - var ratio = $container.width() / container.width; + var ratio = container.offsetWidth / containerData.width; // Resize when width changed or height changed - if (ratio !== 1 || $container.height() !== container.height) { + if (ratio !== 1 || container.offsetHeight !== containerData.height) { var canvasData = void 0; var cropBoxData = void 0; @@ -1429,10 +1740,10 @@ var handlers = { this.render(); if (options.restore) { - this.setCanvasData($.each(canvasData, function (i, n) { + this.setCanvasData(forEach(canvasData, function (n, i) { canvasData[i] = n * ratio; })); - this.setCropBoxData($.each(cropBoxData, function (i, n) { + this.setCropBoxData(forEach(cropBoxData, function (n, i) { cropBoxData[i] = n * ratio; })); } @@ -1443,21 +1754,21 @@ var handlers = { return; } - this.setDragMode(this.$dragBox.hasClass(CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); + this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); }, - wheel: function wheel(event) { + wheel: function wheel(e) { var _this = this; - var e = event.originalEvent || event; var ratio = Number(this.options.wheelZoomRatio) || 0.1; + var delta = 1; if (this.disabled) { return; } - event.preventDefault(); + e.preventDefault(); - // Limit wheel speed to prevent zoom too fast + // Limit wheel speed to prevent zoom too fast (#21) if (this.wheeling) { return; } @@ -1468,8 +1779,6 @@ var handlers = { _this.wheeling = false; }, 50); - var delta = 1; - if (e.deltaY) { delta = e.deltaY > 0 ? 1 : -1; } else if (e.wheelDelta) { @@ -1478,7 +1787,7 @@ var handlers = { delta = e.detail > 0 ? 1 : -1; } - this.zoom(-delta * ratio, event); + this.zoom(-delta * ratio, e); }, cropStart: function cropStart(e) { if (this.disabled) { @@ -1487,34 +1796,33 @@ var handlers = { var options = this.options, pointers = this.pointers; - var originalEvent = e.originalEvent; var action = void 0; - if (originalEvent && originalEvent.changedTouches) { + if (e.changedTouches) { // Handle touch event - $.each(originalEvent.changedTouches, function (i, touch) { + forEach(e.changedTouches, function (touch) { pointers[touch.identifier] = getPointer(touch); }); } else { // Handle mouse event and pointer event - pointers[originalEvent && originalEvent.pointerId || 0] = getPointer(originalEvent || e); + pointers[e.pointerId || 0] = getPointer(e); } - if (objectKeys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { + if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { action = ACTION_ZOOM; } else { - action = $(e.target).data(DATA_ACTION); + action = getData(e.target, DATA_ACTION); } if (!REGEXP_ACTIONS.test(action)) { return; } - if (this.trigger(EVENT_CROP_START, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_CROP_START, { + originalEvent: e, action: action - }).isDefaultPrevented()) { + }) === false) { return; } @@ -1525,7 +1833,7 @@ var handlers = { if (action === ACTION_CROP) { this.cropping = true; - this.$dragBox.addClass(CLASS_MODAL); + addClass(this.dragBox, CLASS_MODAL); } }, cropMove: function cropMove(e) { @@ -1537,24 +1845,23 @@ var handlers = { } var pointers = this.pointers; - var originalEvent = e.originalEvent; e.preventDefault(); - if (this.trigger(EVENT_CROP_MOVE, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_CROP_MOVE, { + originalEvent: e, action: action - }).isDefaultPrevented()) { + }) === false) { return; } - if (originalEvent && originalEvent.changedTouches) { - $.each(originalEvent.changedTouches, function (i, touch) { - $.extend(pointers[touch.identifier], getPointer(touch, true)); + if (e.changedTouches) { + forEach(e.changedTouches, function (touch) { + assign(pointers[touch.identifier], getPointer(touch, true)); }); } else { - $.extend(pointers[originalEvent && originalEvent.pointerId || 0], getPointer(originalEvent || e, true)); + assign(pointers[e.pointerId || 0], getPointer(e, true)); } this.change(e); @@ -1564,17 +1871,16 @@ var handlers = { return; } - var action = this.action; - var pointers = this.pointers; - var originalEvent = e.originalEvent; + var action = this.action, + pointers = this.pointers; - if (originalEvent && originalEvent.changedTouches) { - $.each(originalEvent.changedTouches, function (i, touch) { + if (e.changedTouches) { + forEach(e.changedTouches, function (touch) { delete pointers[touch.identifier]; }); } else { - delete pointers[originalEvent && originalEvent.pointerId || 0]; + delete pointers[e.pointerId || 0]; } if (!action) { @@ -1583,17 +1889,17 @@ var handlers = { e.preventDefault(); - if (!objectKeys(pointers).length) { + if (!Object.keys(pointers).length) { this.action = ''; } if (this.cropping) { this.cropping = false; - this.$dragBox.toggleClass(CLASS_MODAL, this.cropped && this.options.modal); + toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal); } - this.trigger(EVENT_CROP_END, { - originalEvent: originalEvent, + dispatchEvent(this.element, EVENT_CROP_END, { + originalEvent: e, action: action }); } @@ -1602,40 +1908,40 @@ var handlers = { var change = { change: function change(e) { var options = this.options, - pointers = this.pointers, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox; + canvasData = this.canvasData, + containerData = this.containerData, + cropBoxData = this.cropBoxData, + pointers = this.pointers; var action = this.action; var aspectRatio = options.aspectRatio; - var left = cropBox.left, - top = cropBox.top, - width = cropBox.width, - height = cropBox.height; + 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 = container.width; - var maxHeight = container.height; + 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 (#259) + // Locking aspect ratio in "free mode" by holding shift key if (!aspectRatio && e.shiftKey) { aspectRatio = width && height ? width / height : 1; } if (this.limited) { - minLeft = cropBox.minLeft; - minTop = cropBox.minTop; + minLeft = cropBoxData.minLeft; + minTop = cropBoxData.minTop; - maxWidth = minLeft + Math.min(container.width, canvas.width, canvas.left + canvas.width); - maxHeight = minTop + Math.min(container.height, canvas.height, canvas.top + canvas.height); + 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[objectKeys(pointers)[0]]; + var pointer = pointers[Object.keys(pointers)[0]]; var range = { x: pointer.endX - pointer.startX, y: pointer.endY - pointer.startY @@ -1976,7 +2282,7 @@ var change = { // Zoom canvas case ACTION_ZOOM: - this.zoom(getMaxZoomRatio(pointers), e.originalEvent); + this.zoom(getMaxZoomRatio(pointers), e); renderable = false; break; @@ -1987,11 +2293,11 @@ var change = { break; } - offset = this.$cropper.offset(); + offset = getOffset(this.cropper); left = pointer.startX - offset.left; top = pointer.startY - offset.top; - width = cropBox.minWidth; - height = cropBox.minHeight; + width = cropBoxData.minWidth; + height = cropBoxData.minHeight; if (range.x > 0) { action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST; @@ -2006,7 +2312,7 @@ var change = { // Show the crop box if is hidden if (!this.cropped) { - this.$cropBox.removeClass(CLASS_HIDDEN); + removeClass(this.cropBox, CLASS_HIDDEN); this.cropped = true; if (this.limited) { @@ -2020,16 +2326,16 @@ var change = { } if (renderable) { - cropBox.width = width; - cropBox.height = height; - cropBox.left = left; - cropBox.top = top; + cropBoxData.width = width; + cropBoxData.height = height; + cropBoxData.left = left; + cropBoxData.top = top; this.action = action; this.renderCropBox(); } // Override - $.each(pointers, function (i, p) { + forEach(pointers, function (p) { p.startX = p.endX; p.startY = p.endY; }); @@ -2039,149 +2345,162 @@ var change = { var methods = { // Show the crop box manually crop: function crop() { - if (!this.ready || this.disabled) { - return; - } - - if (!this.cropped) { + if (this.ready && !this.cropped && !this.disabled) { this.cropped = true; this.limitCropBox(true, true); if (this.options.modal) { - this.$dragBox.addClass(CLASS_MODAL); + addClass(this.dragBox, CLASS_MODAL); } - this.$cropBox.removeClass(CLASS_HIDDEN); + removeClass(this.cropBox, CLASS_HIDDEN); + this.setCropBoxData(this.initialCropBoxData); } - this.setCropBoxData(this.initialCropBox); + return this; }, // Reset the image and crop box to their initial states reset: function reset() { - if (!this.ready || this.disabled) { - return; - } + if (this.ready && !this.disabled) { + this.imageData = assign({}, this.initialImageData); + this.canvasData = assign({}, this.initialCanvasData); + this.cropBoxData = assign({}, this.initialCropBoxData); + this.renderCanvas(); - this.image = $.extend({}, this.initialImage); - this.canvas = $.extend({}, this.initialCanvas); - this.cropBox = $.extend({}, this.initialCropBox); - this.renderCanvas(); - - if (this.cropped) { - this.renderCropBox(); + if (this.cropped) { + this.renderCropBox(); + } } + + return this; }, // Clear the crop box clear: function clear() { - if (!this.cropped || this.disabled) { - return; - } + if (this.cropped && !this.disabled) { + assign(this.cropBoxData, { + left: 0, + top: 0, + width: 0, + height: 0 + }); - $.extend(this.cropBox, { - left: 0, - top: 0, - width: 0, - height: 0 - }); + this.cropped = false; + this.renderCropBox(); + this.limitCanvas(true, true); - 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); + } - // Render canvas after crop box rendered - this.renderCanvas(); - this.$dragBox.removeClass(CLASS_MODAL); - this.$cropBox.addClass(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. + * @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one. + * @returns {Cropper} this */ - replace: function replace(url, onlyColorChanged) { + replace: function replace(url) { + var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + if (!this.disabled && url) { if (this.isImg) { - this.$element.attr('src', url); + this.element.src = url; } - if (onlyColorChanged) { + if (hasSameSize) { this.url = url; - this.$clone.attr('src', url); + this.image.src = url; if (this.ready) { - this.$preview.find('img').add(this.$clone2).attr('src', url); + this.viewBoxImage.src = url; + + forEach(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.uncreate(); this.load(url); } } + + return this; }, // Enable (unfreeze) the cropper enable: function enable() { - if (this.ready) { + if (this.ready && this.disabled) { this.disabled = false; - this.$cropper.removeClass(CLASS_DISABLED); + removeClass(this.cropper, CLASS_DISABLED); } + + return this; }, // Disable (freeze) the cropper disable: function disable() { - if (this.ready) { + if (this.ready && !this.disabled) { this.disabled = true; - this.$cropper.addClass(CLASS_DISABLED); + addClass(this.cropper, CLASS_DISABLED); } + + return this; }, - // Destroy the cropper and remove the instance from the image + /** + * Destroy the cropper and remove the instance from the image + * @returns {Cropper} this + */ destroy: function destroy() { - var $element = this.$element; + var element = this.element; - if (this.loaded) { - if (this.isImg && this.replaced) { - $element.attr('src', this.originalUrl); - } + if (!getData(element, NAMESPACE)) { + return this; + } - this.unbuild(); - $element.removeClass(CLASS_HIDDEN); - } else if (this.isImg) { - $element.off(EVENT_LOAD, this.start); - } else if (this.$clone) { - this.$clone.remove(); + if (this.isImg && this.replaced) { + element.src = this.originalUrl; } - $element.removeData(NAMESPACE); + this.uncreate(); + 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. + * @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis. + * @returns {Cropper} this */ - move: function move(offsetX, offsetY) { - var _canvas = this.canvas, - left = _canvas.left, - top = _canvas.top; + move: function move(offsetX) { + var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX; + var _canvasData = this.canvasData, + left = _canvasData.left, + top = _canvasData.top; - this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); + return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); }, @@ -2189,28 +2508,25 @@ var methods = { * Move the canvas to an absolute point * @param {number} x - The x-axis coordinate. * @param {number} [y=x] - The y-axis coordinate. + * @returns {Cropper} this */ - moveTo: function moveTo(x, y) { - var canvas = this.canvas; + moveTo: function moveTo(x) { + var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + var canvasData = this.canvasData; var changed = false; - // If "y" is not present, its default value is "x" - if (isUndefined(y)) { - y = x; - } - x = Number(x); y = Number(y); if (this.ready && !this.disabled && this.options.movable) { if (isNumber(x)) { - canvas.left = x; + canvasData.left = x; changed = true; } if (isNumber(y)) { - canvas.top = y; + canvasData.top = y; changed = true; } @@ -2218,16 +2534,19 @@ var methods = { this.renderCanvas(true); } } + + return this; }, /** * Zoom the canvas with a relative ratio - * @param {Number} ratio - The target ratio. - * @param {Event} _event - The related event if any. + * @param {number} ratio - The target ratio. + * @param {Event} _originalEvent - The original event if any. + * @returns {Cropper} this */ - zoom: function zoom(ratio, _event) { - var canvas = this.canvas; + zoom: function zoom(ratio, _originalEvent) { + var canvasData = this.canvasData; ratio = Number(ratio); @@ -2238,23 +2557,24 @@ var methods = { ratio = 1 + ratio; } - this.zoomTo(canvas.width * ratio / canvas.naturalWidth, _event); + return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent); }, /** * Zoom the canvas to an absolute ratio * @param {number} ratio - The target ratio. - * @param {Event} _event - The related event if any. + * @param {Object} pivot - The zoom pivot point coordinate. + * @param {Event} _originalEvent - The original event if any. + * @returns {Cropper} this */ - zoomTo: function zoomTo(ratio, _event) { + zoomTo: function zoomTo(ratio, pivot, _originalEvent) { var options = this.options, - pointers = this.pointers, - canvas = this.canvas; - var width = canvas.width, - height = canvas.height, - naturalWidth = canvas.naturalWidth, - naturalHeight = canvas.naturalHeight; + canvasData = this.canvasData; + var width = canvasData.width, + height = canvasData.height, + naturalWidth = canvasData.naturalWidth, + naturalHeight = canvasData.naturalHeight; ratio = Number(ratio); @@ -2262,87 +2582,95 @@ var methods = { if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) { var newWidth = naturalWidth * ratio; var newHeight = naturalHeight * ratio; - var originalEvent = void 0; - - if (_event) { - originalEvent = _event.originalEvent; - } - if (this.trigger(EVENT_ZOOM, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_ZOOM, { + originalEvent: _originalEvent, oldRatio: width / naturalWidth, ratio: newWidth / naturalWidth - }).isDefaultPrevented()) { - return; + }) === false) { + return this; } - if (originalEvent) { - var offset = this.$cropper.offset(); - var center = pointers && objectKeys(pointers).length ? getPointersCenter(pointers) : { - pageX: _event.pageX || originalEvent.pageX || 0, - pageY: _event.pageY || originalEvent.pageY || 0 + 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 - canvas.left -= (newWidth - width) * ((center.pageX - offset.left - canvas.left) / width); - canvas.top -= (newHeight - height) * ((center.pageY - offset.top - canvas.top) / height); + 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 - canvas.left -= (newWidth - width) / 2; - canvas.top -= (newHeight - height) / 2; + canvasData.left -= (newWidth - width) / 2; + canvasData.top -= (newHeight - height) / 2; } - canvas.width = newWidth; - canvas.height = newHeight; + 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 {Cropper} this */ rotate: function rotate(degree) { - this.rotateTo((this.image.rotate || 0) + Number(degree)); + return this.rotateTo((this.imageData.rotate || 0) + Number(degree)); }, /** * Rotate the canvas to an absolute degree * @param {number} degree - The rotate degree. + * @returns {Cropper} this */ rotateTo: function rotateTo(degree) { degree = Number(degree); if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) { - this.image.rotate = degree % 360; + 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 {Cropper} this */ scaleX: function scaleX(_scaleX) { - var scaleY = this.image.scaleY; + var scaleY = this.imageData.scaleY; - this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1); + 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 {Cropper} this */ scaleY: function scaleY(_scaleY) { - var scaleX = this.image.scaleX; + var scaleX = this.imageData.scaleX; - this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); + return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); }, @@ -2350,10 +2678,11 @@ var methods = { * 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 {Cropper} this */ scale: function scale(scaleX) { var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX; - var image = this.image; + var imageData = this.imageData; var transformed = false; @@ -2362,12 +2691,12 @@ var methods = { if (this.ready && !this.disabled && this.options.scalable) { if (isNumber(scaleX)) { - image.scaleX = scaleX; + imageData.scaleX = scaleX; transformed = true; } if (isNumber(scaleY)) { - image.scaleY = scaleY; + imageData.scaleY = scaleY; transformed = true; } @@ -2375,6 +2704,8 @@ var methods = { this.renderCanvas(true, true); } } + + return this; }, @@ -2383,26 +2714,26 @@ var methods = { * @param {boolean} [rounded=false] - Indicate if round the data values or not. * @returns {Object} The result cropped data. */ - getData: function getData() { + getData: function getData$$1() { var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; var options = this.options, - image = this.image, - canvas = this.canvas, - cropBox = this.cropBox; + imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; var data = void 0; if (this.ready && this.cropped) { data = { - x: cropBox.left - canvas.left, - y: cropBox.top - canvas.top, - width: cropBox.width, - height: cropBox.height + x: cropBoxData.left - canvasData.left, + y: cropBoxData.top - canvasData.top, + width: cropBoxData.width, + height: cropBoxData.height }; - var ratio = image.width / image.naturalWidth; + var ratio = imageData.width / imageData.naturalWidth; - $.each(data, function (i, n) { + forEach(data, function (n, i) { n /= ratio; data[i] = rounded ? Math.round(n) : n; }); @@ -2416,12 +2747,12 @@ var methods = { } if (options.rotatable) { - data.rotate = image.rotate || 0; + data.rotate = imageData.rotate || 0; } if (options.scalable) { - data.scaleX = image.scaleX || 1; - data.scaleY = image.scaleY || 1; + data.scaleX = imageData.scaleX || 1; + data.scaleY = imageData.scaleY || 1; } return data; @@ -2431,36 +2762,33 @@ var methods = { /** * Set the cropped area position and size with new data * @param {Object} data - The new data. + * @returns {Cropper} this */ - setData: function setData(data) { + setData: function setData$$1(data) { var options = this.options, - image = this.image, - canvas = this.canvas; + imageData = this.imageData, + canvasData = this.canvasData; var cropBoxData = {}; - if ($.isFunction(data)) { - data = data.call(this.element); - } - - if (this.ready && !this.disabled && $.isPlainObject(data)) { + if (this.ready && !this.disabled && isPlainObject(data)) { var transformed = false; if (options.rotatable) { - if (isNumber(data.rotate) && data.rotate !== image.rotate) { - image.rotate = data.rotate; + if (isNumber(data.rotate) && data.rotate !== imageData.rotate) { + imageData.rotate = data.rotate; transformed = true; } } if (options.scalable) { - if (isNumber(data.scaleX) && data.scaleX !== image.scaleX) { - image.scaleX = data.scaleX; + if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) { + imageData.scaleX = data.scaleX; transformed = true; } - if (isNumber(data.scaleY) && data.scaleY !== image.scaleY) { - image.scaleY = data.scaleY; + if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) { + imageData.scaleY = data.scaleY; transformed = true; } } @@ -2469,14 +2797,14 @@ var methods = { this.renderCanvas(true, true); } - var ratio = image.width / image.naturalWidth; + var ratio = imageData.width / imageData.naturalWidth; if (isNumber(data.x)) { - cropBoxData.left = data.x * ratio + canvas.left; + cropBoxData.left = data.x * ratio + canvasData.left; } if (isNumber(data.y)) { - cropBoxData.top = data.y * ratio + canvas.top; + cropBoxData.top = data.y * ratio + canvasData.top; } if (isNumber(data.width)) { @@ -2489,6 +2817,8 @@ var methods = { this.setCropBoxData(cropBoxData); } + + return this; }, @@ -2497,7 +2827,7 @@ var methods = { * @returns {Object} The result container data. */ getContainerData: function getContainerData() { - return this.ready ? $.extend({}, this.container) : {}; + return this.ready ? assign({}, this.containerData) : {}; }, @@ -2506,7 +2836,7 @@ var methods = { * @returns {Object} The result image data. */ getImageData: function getImageData() { - return this.loaded ? $.extend({}, this.image) : {}; + return this.sized ? assign({}, this.imageData) : {}; }, @@ -2515,13 +2845,13 @@ var methods = { * @returns {Object} The result canvas data. */ getCanvasData: function getCanvasData() { - var canvas = this.canvas; + var canvasData = this.canvasData; var data = {}; if (this.ready) { - $.each(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (i, n) { - data[n] = canvas[n]; + forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) { + data[n] = canvasData[n]; }); } @@ -2532,35 +2862,34 @@ var methods = { /** * Set the canvas position and size with new data. * @param {Object} data - The new canvas data. + * @returns {Cropper} this */ setCanvasData: function setCanvasData(data) { - var canvas = this.canvas; - var aspectRatio = canvas.aspectRatio; + var canvasData = this.canvasData; + var aspectRatio = canvasData.aspectRatio; - if ($.isFunction(data)) { - data = data.call(this.$element); - } - - if (this.ready && !this.disabled && $.isPlainObject(data)) { + if (this.ready && !this.disabled && isPlainObject(data)) { if (isNumber(data.left)) { - canvas.left = data.left; + canvasData.left = data.left; } if (isNumber(data.top)) { - canvas.top = data.top; + canvasData.top = data.top; } if (isNumber(data.width)) { - canvas.width = data.width; - canvas.height = data.width / aspectRatio; + canvasData.width = data.width; + canvasData.height = data.width / aspectRatio; } else if (isNumber(data.height)) { - canvas.height = data.height; - canvas.width = data.height * aspectRatio; + canvasData.height = data.height; + canvasData.width = data.height * aspectRatio; } this.renderCanvas(true); } + + return this; }, @@ -2569,62 +2898,66 @@ var methods = { * @returns {Object} The result crop box data. */ getCropBoxData: function getCropBoxData() { - var cropBox = this.cropBox; + var cropBoxData = this.cropBoxData; + var data = void 0; - return this.ready && this.cropped ? { - left: cropBox.left, - top: cropBox.top, - width: cropBox.width, - height: cropBox.height - } : {}; + 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 {Cropper} this */ setCropBoxData: function setCropBoxData(data) { - var cropBox = this.cropBox; + 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 (this.ready && this.cropped && !this.disabled && isPlainObject(data)) { if (isNumber(data.left)) { - cropBox.left = data.left; + cropBoxData.left = data.left; } if (isNumber(data.top)) { - cropBox.top = data.top; + cropBoxData.top = data.top; } - if (isNumber(data.width) && data.width !== cropBox.width) { + if (isNumber(data.width) && data.width !== cropBoxData.width) { widthChanged = true; - cropBox.width = data.width; + cropBoxData.width = data.width; } - if (isNumber(data.height) && data.height !== cropBox.height) { + if (isNumber(data.height) && data.height !== cropBoxData.height) { heightChanged = true; - cropBox.height = data.height; + cropBoxData.height = data.height; } if (aspectRatio) { if (widthChanged) { - cropBox.height = cropBox.width / aspectRatio; + cropBoxData.height = cropBoxData.width / aspectRatio; } else if (heightChanged) { - cropBox.width = cropBox.height * aspectRatio; + cropBoxData.width = cropBoxData.height * aspectRatio; } } this.renderCropBox(); } + + return this; }, @@ -2640,9 +2973,9 @@ var methods = { return null; } - var canvasData = this.canvas; + var canvasData = this.canvasData; - var source = getSourceCanvas(this.$clone[0], this.image, canvasData, options); + var source = getSourceCanvas(this.image, this.imageData, canvasData, options); // Returns the source canvas if it is not cropped. if (!this.cropped) { @@ -2692,6 +3025,7 @@ var methods = { canvas.width = normalizeDecimalNumber(width); canvas.height = normalizeDecimalNumber(height); + context.fillStyle = options.fillColor || 'transparent'; context.fillRect(0, 0, width, height); @@ -2765,9 +3099,10 @@ var methods = { params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale); } - context.drawImage.apply(context, [source].concat(toConsumableArray($.map(params, function (param) { + context.drawImage.apply(context, [source].concat(toConsumableArray(params.map(function (param) { return Math.floor(normalizeDecimalNumber(param)); })))); + return canvas; }, @@ -2775,6 +3110,7 @@ var methods = { /** * Change the aspect ratio of the crop box. * @param {number} aspectRatio - The new aspect ratio. + * @returns {Cropper} this */ setAspectRatio: function setAspectRatio(aspectRatio) { var options = this.options; @@ -2792,34 +3128,47 @@ var methods = { } } } + + return this; }, /** * Change the drag mode. * @param {string} mode - The new drag mode. + * @returns {Cropper} this */ setDragMode: function setDragMode(mode) { - var options = this.options; + var options = this.options, + dragBox = this.dragBox, + face = this.face; + - var croppable = void 0; - var movable = void 0; + if (this.ready && !this.disabled) { + var croppable = mode === DRAG_MODE_CROP; + var movable = options.movable && mode === DRAG_MODE_MOVE; - if (this.loaded && !this.disabled) { - croppable = mode === DRAG_MODE_CROP; - movable = options.movable && mode === DRAG_MODE_MOVE; mode = croppable || movable ? mode : DRAG_MODE_NONE; - this.$dragBox.data(DATA_ACTION, mode).toggleClass(CLASS_CROP, croppable).toggleClass(CLASS_MOVE, movable); + options.dragMode = mode; + 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(#300) - this.$face.data(DATA_ACTION, mode).toggleClass(CLASS_CROP, croppable).toggleClass(CLASS_MOVE, movable); + // 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. @@ -2835,36 +3184,37 @@ var Cropper = function () { } this.element = element; - this.$element = $(element); - this.options = $.extend({}, DEFAULTS, $.isPlainObject(options) && options); - this.completed = false; + this.options = assign({}, DEFAULTS, isPlainObject(options) && options); this.cropped = false; this.disabled = false; - this.isImg = false; - this.limited = false; - this.loaded = false; + this.pointers = {}; this.ready = false; + this.reloading = false; this.replaced = false; - this.wheeling = false; - this.originalUrl = ''; - this.canvas = null; - this.cropBox = null; - this.pointers = {}; + this.sized = false; + this.sizing = false; this.init(); } createClass(Cropper, [{ key: 'init', value: function init() { - var $element = this.$element; + var element = this.element; + var tagName = element.tagName.toLowerCase(); var url = void 0; - if ($element.is('img')) { + if (getData(element, NAMESPACE)) { + return; + } + + setData(element, NAMESPACE, this); + + if (tagName === 'img') { this.isImg = true; - // Should use `$.fn.attr` here. e.g.: "img/picture.jpg" - url = $element.attr('src') || ''; + // e.g.: "img/picture.jpg" + url = element.getAttribute('src') || ''; this.originalUrl = url; // Stop when it's a blank image @@ -2872,26 +3222,14 @@ var Cropper = function () { return; } - // Should use `$.fn.prop` here. e.g.: "http://example.com/img/picture.jpg" - url = $element.prop('src'); - } else if ($element.is('canvas') && window.HTMLCanvasElement) { - url = $element[0].toDataURL(); + // e.g.: "http://example.com/img/picture.jpg" + url = element.src; + } else if (tagName === 'canvas' && window.HTMLCanvasElement) { + url = element.toDataURL(); } this.load(url); } - - // A shortcut for triggering custom events - - }, { - key: 'trigger', - value: function trigger(type, data) { - var e = $.Event(type, data); - - this.$element.trigger(e); - - return e; - } }, { key: 'load', value: function load(url) { @@ -2902,9 +3240,9 @@ var Cropper = function () { } this.url = url; - this.image = {}; + this.imageData = {}; - var $element = this.$element, + var element = this.element, options = this.options; @@ -2926,29 +3264,41 @@ var Cropper = function () { var xhr = new XMLHttpRequest(); + this.reloading = true; + this.xhr = xhr; + + var done = function done() { + _this.reloading = false; + _this.xhr = null; + }; + + xhr.ontimeout = done; + xhr.onabort = done; xhr.onerror = function () { + done(); _this.clone(); }; xhr.onload = function () { + done(); _this.read(xhr.response); }; // Bust cache when there is a "crossOrigin" property - if (options.checkCrossOrigin && isCrossOriginURL(url) && !$element.prop('crossOrigin')) { + if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) { url = addTimestamp(url); } xhr.open('get', url); xhr.responseType = 'arraybuffer'; - xhr.withCredentials = $element.prop('crossOrigin') === 'use-credentials'; + xhr.withCredentials = element.crossOrigin === 'use-credentials'; xhr.send(); } }, { key: 'read', value: function read(arrayBuffer) { var options = this.options, - image = this.image; + imageData = this.imageData; var orientation = getOrientation(arrayBuffer); var rotate = 0; @@ -2966,12 +3316,12 @@ var Cropper = function () { } if (options.rotatable) { - image.rotate = rotate; + imageData.rotate = rotate; } if (options.scalable) { - image.scaleX = scaleX; - image.scaleY = scaleY; + imageData.scaleX = scaleX; + imageData.scaleY = scaleY; } this.clone(); @@ -2979,22 +3329,22 @@ var Cropper = function () { }, { key: 'clone', value: function clone() { - var $element = this.$element, - options = this.options, + var element = this.element, url = this.url; - var crossOrigin = ''; + var crossOrigin = void 0; var crossOriginUrl = void 0; - if (options.checkCrossOrigin && isCrossOriginURL(url)) { - crossOrigin = $element.prop('crossOrigin'); + if (this.options.checkCrossOrigin && isCrossOriginURL(url)) { + crossOrigin = element.crossOrigin; + if (crossOrigin) { crossOriginUrl = url; } else { crossOrigin = 'anonymous'; - // Bust cache (#148) when there is not a "crossOrigin" property + // Bust cache when there is not a "crossOrigin" property crossOriginUrl = addTimestamp(url); } } @@ -3010,88 +3360,136 @@ var Cropper = function () { image.src = crossOriginUrl || url; - var $clone = $(image); + var start = this.start.bind(this); + var stop = this.stop.bind(this); - this.$clone = $clone; + this.image = image; + this.onStart = start; + this.onStop = stop; if (this.isImg) { - if (this.element.complete) { - this.start(); + if (element.complete) { + this.timeout = setTimeout(start, 0); } else { - $element.one(EVENT_LOAD, $.proxy(this.start, this)); + addListener(element, EVENT_LOAD, start, { + once: true + }); } } else { - $clone.one(EVENT_LOAD, $.proxy(this.start, this)).one(EVENT_ERROR, $.proxy(this.stop, this)).addClass(CLASS_HIDE).insertAfter($element); + image.onload = start; + image.onerror = stop; + addClass(image, CLASS_HIDE); + element.parentNode.insertBefore(image, element.nextSibling); } } }, { key: 'start', - value: function start() { + value: function start(event) { var _this2 = this; - var $clone = this.$clone; - - var $image = this.$element; + var image = this.isImg ? this.element : this.image; - if (!this.isImg) { - $clone.off(EVENT_ERROR, this.stop); - $image = $clone; + if (event) { + image.onload = null; + image.onerror = null; } - getImageNaturalSizes($image[0], function (naturalWidth, naturalHeight) { - $.extend(_this2.image, { + this.sizing = true; + + var IS_SAFARI = WINDOW.navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(WINDOW.navigator.userAgent); + var done = function done(naturalWidth, naturalHeight) { + assign(_this2.imageData, { naturalWidth: naturalWidth, naturalHeight: naturalHeight, aspectRatio: naturalWidth / naturalHeight }); - - _this2.loaded = true; + _this2.sizing = false; + _this2.sized = true; _this2.build(); - }); + }; + + // Modern browsers (except Safari) + if (image.naturalWidth && !IS_SAFARI) { + done(image.naturalWidth, image.naturalHeight); + return; + } + + var sizingImage = document.createElement('img'); + var body = document.body || document.documentElement; + + this.sizingImage = sizingImage; + + sizingImage.onload = function () { + done(sizingImage.width, sizingImage.height); + + if (!IS_SAFARI) { + body.removeChild(sizingImage); + } + }; + + sizingImage.src = image.src; + + // iOS Safari will convert the image automatically + // with its orientation once append it into DOM (#279) + if (!IS_SAFARI) { + sizingImage.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(sizingImage); + } } }, { key: 'stop', value: function stop() { - this.$clone.remove(); - this.$clone = null; + var image = this.image; + + + image.onload = null; + image.onerror = null; + image.parentNode.removeChild(image); + this.image = null; } }, { key: 'build', value: function build() { - var _this3 = this; - - if (!this.loaded) { + if (!this.sized || this.ready) { return; } - // Unbuild first when replace - if (this.ready) { - this.unbuild(); - } - - var $element = this.$element, + var element = this.element, options = this.options, - $clone = this.$clone; - - var $cropper = $(TEMPLATE); - var $cropBox = $cropper.find('.' + NAMESPACE + '-crop-box'); - var $face = $cropBox.find('.' + NAMESPACE + '-face'); + image = this.image; // Create cropper elements - this.$container = $element.parent(); - this.$cropper = $cropper; - this.$canvas = $cropper.find('.' + NAMESPACE + '-canvas').append($clone); - this.$dragBox = $cropper.find('.' + NAMESPACE + '-drag-box'); - this.$cropBox = $cropBox; - this.$viewBox = $cropper.find('.' + NAMESPACE + '-view-box'); - this.$face = $face; + + 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 - $element.addClass(CLASS_HIDDEN).after($cropper); + addClass(element, CLASS_HIDDEN); + + // Inserts the cropper after to the current image + container.insertBefore(cropper, element.nextSibling); - // Show the clone image if is hidden + // Show the image if is hidden if (!this.isImg) { - $clone.removeClass(CLASS_HIDE); + removeClass(image, CLASS_HIDE); } this.initPreview(); @@ -3100,55 +3498,51 @@ var Cropper = function () { 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) { - this.$dragBox.addClass(CLASS_MODAL); - } - } else { - $cropBox.addClass(CLASS_HIDDEN); - } + addClass(cropBox, CLASS_HIDDEN); if (!options.guides) { - $cropBox.find('.' + NAMESPACE + '-dashed').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-dashed'), CLASS_HIDDEN); } if (!options.center) { - $cropBox.find('.' + NAMESPACE + '-center').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-center'), CLASS_HIDDEN); } - if (options.cropBoxMovable) { - $face.addClass(CLASS_MOVE).data(DATA_ACTION, ACTION_ALL); + if (options.background) { + addClass(cropper, NAMESPACE + '-bg'); } if (!options.highlight) { - $face.addClass(CLASS_INVISIBLE); + addClass(face, CLASS_INVISIBLE); } - if (options.background) { - $cropper.addClass(NAMESPACE + '-bg'); + if (options.cropBoxMovable) { + addClass(face, CLASS_MOVE); + setData(face, DATA_ACTION, ACTION_ALL); } if (!options.cropBoxResizable) { - $cropBox.find('.' + NAMESPACE + '-line,.' + NAMESPACE + '-point').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-line'), CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-point'), CLASS_HIDDEN); } - this.setDragMode(options.dragMode); this.render(); this.ready = true; + this.setDragMode(options.dragMode); + + if (options.autoCrop) { + this.crop(); + } + this.setData(options.data); - // Trigger the ready event asynchronously to keep `data('cropper')` is defined - this.completing = setTimeout(function () { - if ($.isFunction(options.ready)) { - $element.one(EVENT_READY, options.ready); - } + if (isFunction(options.ready)) { + addListener(element, EVENT_READY, options.ready, { + once: true + }); + } - _this3.trigger(EVENT_READY); - _this3.trigger(EVENT_CROP, _this3.getData()); - _this3.completed = true; - }, 0); + dispatchEvent(element, EVENT_READY); } }, { key: 'unbuild', @@ -3157,35 +3551,49 @@ var Cropper = function () { return; } - if (!this.completed) { - clearTimeout(this.completing); - } - this.ready = false; - this.completed = false; - this.initialImage = null; - - // Clear `initialCanvas` is necessary when replace - this.initialCanvas = null; - this.initialCropBox = null; - this.container = null; - this.canvas = null; - - // Clear `cropBox` is necessary when replace - this.cropBox = null; this.unbind(); - this.resetPreview(); - this.$preview = null; + this.cropper.parentNode.removeChild(this.cropper); + removeClass(this.element, CLASS_HIDDEN); + } + }, { + key: 'uncreate', + value: function uncreate() { + var element = this.element; + + + if (this.ready) { + this.unbuild(); + this.ready = false; + this.cropped = false; + } else if (this.sizing) { + this.sizingImage.onload = null; + this.sizing = false; + this.sized = false; + } else if (this.reloading) { + this.xhr.abort(); + } else if (this.isImg) { + if (element.complete) { + clearTimeout(this.timeout); + } else { + removeListener(element, EVENT_LOAD, this.onStart); + } + } else if (this.image) { + this.stop(); + } + } - this.$viewBox = null; - this.$cropBox = null; - this.$dragBox = null; - this.$canvas = null; - this.$container = null; + /** + * Get the no conflict cropper class. + * @returns {Cropper} The cropper class. + */ - this.$cropper.remove(); - this.$cropper = null; + }], [{ + key: 'noConflict', + value: function noConflict() { + window.Cropper = AnotherCropper; + return Cropper; } /** @@ -3193,21 +3601,20 @@ var Cropper = function () { * @param {Object} options - The new default options. */ - }], [{ + }, { key: 'setDefaults', value: function setDefaults(options) { - $.extend(DEFAULTS, $.isPlainObject(options) && options); + assign(DEFAULTS, isPlainObject(options) && options); } }]); return Cropper; }(); -if ($.extend) { - $.extend(Cropper.prototype, render, preview, events, handlers, change, methods); -} +assign(Cropper.prototype, render, preview, events, handlers, change, methods); if ($.fn) { - var AnotherCropper = $.fn.cropper; + var AnotherCropper$1 = $.fn.cropper; + var NAMESPACE$1 = 'cropper'; $.fn.cropper = function jQueryCropper(option) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { @@ -3218,35 +3625,44 @@ if ($.fn) { this.each(function (i, element) { var $element = $(element); - var data = $element.data(NAMESPACE); + var isDestroy = option === 'destroy'; + var cropper = $element.data(NAMESPACE$1); - if (!data) { - if (/destroy/.test(option)) { + if (!cropper) { + if (isDestroy) { return; } var options = $.extend({}, $element.data(), $.isPlainObject(option) && option); - data = new Cropper(element, options); - $element.data(NAMESPACE, data); + cropper = new Cropper(element, options); + $element.data(NAMESPACE$1, cropper); } - if (isString(option)) { - var fn = data[option]; + if (typeof option === 'string') { + var fn = cropper[option]; if ($.isFunction(fn)) { - result = fn.apply(data, args); + result = fn.apply(cropper, args); + + if (result === cropper) { + result = undefined; + } + + if (isDestroy) { + $element.removeData(NAMESPACE$1); + } } } }); - return isUndefined(result) ? this : result; + return typeof result === 'undefined' ? this : result; }; $.fn.cropper.Constructor = Cropper; $.fn.cropper.setDefaults = Cropper.setDefaults; $.fn.cropper.noConflict = function noConflict() { - $.fn.cropper = AnotherCropper; + $.fn.cropper = AnotherCropper$1; return this; }; } diff --git a/dist/cropper.js b/dist/cropper.js index 3757403d..c82e8516 100644 --- a/dist/cropper.js +++ b/dist/cropper.js @@ -1,11 +1,11 @@ /*! - * Cropper v3.1.6 + * Cropper v4.0.0-alpha * https://github.com/fengyuanchen/cropper * * Copyright (c) 2014-2018 Chen Fengyuan * Released under the MIT license * - * Date: 2018-03-01T13:33:48.179Z + * Date: 2018-03-01T14:21:13.980Z */ (function (global, factory) { @@ -57,7 +57,6 @@ 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'; @@ -68,10 +67,10 @@ 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_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 REGEXP_TAG_NAME = /^(?:img|canvas)$/i; var DEFAULTS = { // Define the view mode of the cropper @@ -169,7 +168,13 @@ var DEFAULTS = { zoom: null }; -var TEMPLATE = '
' + '
' + '
' + '
' + '
' + '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
' + '
'; +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)) { @@ -205,15 +210,6 @@ var toConsumableArray = function (arr) { } }; -/** - * Check if the given value is a string. - * @param {*} value - The value to check. - * @returns {boolean} Returns `true` if the given value is a string, else `false`. - */ -function isString(value) { - return typeof value === 'string'; -} - /** * Check if the given value is not a number. */ @@ -238,39 +234,97 @@ function isUndefined(value) { } /** - * Takes a function and returns a new one that will always have a particular context. - * Custom proxy to avoid jQuery's guid. - * @param {Function} fn - The target function. - * @param {Object} context - The new context for the function. - * @returns {Function} The new function. + * 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 proxy(fn, context) { - for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { - args[_key - 2] = arguments[_key]; +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'; +} - return function () { - for (var _len2 = arguments.length, args2 = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args2[_key2] = arguments[_key2]; +/** + * Iterate the given data. + * @param {*} data - The data to iterate. + * @param {Function} callback - The process function for each element. + * @returns {*} The original data. + */ +function forEach(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 fn.apply(context, args.concat(args2)); - }; + return data; } /** - * Get the own enumerable properties of a given object. - * @param {Object} obj - The target object. - * @returns {Array} All the own enumerable properties of the given object. + * 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. */ -var objectKeys = Object.keys || function objectKeys(obj) { - var keys = []; +var assign = Object.assign || function assign(obj) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } - $.each(obj, function (key) { - keys.push(key); - }); + if (isObject(obj) && args.length > 0) { + args.forEach(function (arg) { + if (isObject(arg)) { + Object.keys(arg).forEach(function (key) { + obj[key] = arg[key]; + }); + } + }); + } - return keys; + return obj; }; var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/i; @@ -288,6 +342,271 @@ function normalizeDecimalNumber(value) { 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; + + + forEach(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)) { + forEach(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)) { + forEach(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)) { + forEach(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; + +/** + * Transform the given string from camelCase to kebab-case + * @param {string} value - The value to transform. + * @returns {string} The transformed 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] = undefined; + } + } else if (element.dataset) { + // #128 Safari not allows to delete dataset property + try { + delete element.dataset[name]; + } catch (e) { + element.dataset[name] = undefined; + } + } else { + element.removeAttribute('data-' + hyphenate(name)); + } +} + +var 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. + */ +function removeListener(element, type, listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + forEach(type.trim().split(REGEXP_SPACES), function (t) { + element.removeEventListener(t, listener, options); + }); +} + +/** + * 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 (options.once) { + var originalListener = _listener; + + _listener = function listener() { + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + removeListener(element, type, _listener, options); + return originalListener.apply(element, args); + }; + } + + forEach(type.trim().split(REGEXP_SPACES), function (t) { + element.addEventListener(t, _listener, options); + }); +} + +/** + * 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) { + var event = void 0; + + // Event and CustomEvent on IE9-11 are global objects, not constructors + if (isFunction(Event) && isFunction(CustomEvent)) { + event = new CustomEvent(type, { + detail: data, + bubbles: true, + cancelable: true + }); + } else { + event = document.createEvent('CustomEvent'); + event.initCustomEvent(type, true, true, data); + } + + return element.dispatchEvent(event); +} + +/** + * Get the offset base on the document. + * @param {Element} element - The target element. + * @returns {Object} The offset data. + */ +function getOffset(element) { + var box = element.getBoundingClientRect(); + + return { + left: box.left + (window.pageXOffset - document.documentElement.clientLeft), + top: box.top + (window.pageYOffset - document.documentElement.clientTop) + }; +} + var location = WINDOW.location; var REGEXP_ORIGINS = /^(https?:)\/\/([^:/?#]+):?(\d*)/i; @@ -315,11 +634,11 @@ function addTimestamp(url) { } /** - * Get transform values base on the given object. + * Get transforms base on the given object. * @param {Object} obj - The target object. * @returns {string} A string contains transform values. */ -function getTransformValues(_ref) { +function getTransforms(_ref) { var rotate = _ref.rotate, scaleX = _ref.scaleX, scaleY = _ref.scaleY, @@ -349,32 +668,13 @@ function getTransformValues(_ref) { values.push('scaleY(' + scaleY + ')'); } - return values.length ? values.join(' ') : 'none'; -} - -var navigator = WINDOW.navigator; + var transform = values.length ? values.join(' ') : 'none'; -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'); - - newImage.onload = function () { - callback(newImage.width, newImage.height); + return { + WebkitTransform: transform, + msTransform: transform, + transform: transform }; - - newImage.src = image.src; } /** @@ -383,13 +683,13 @@ function getImageNaturalSizes(image, callback) { * @returns {number} The result ratio. */ function getMaxZoomRatio(pointers) { - var pointers2 = $.extend({}, pointers); + var pointers2 = assign({}, pointers); var ratios = []; - $.each(pointers, function (pointerId, pointer) { + forEach(pointers, function (pointer, pointerId) { delete pointers2[pointerId]; - $.each(pointers2, function (pointerId2, pointer2) { + forEach(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); @@ -424,11 +724,7 @@ function getPointer(_ref2, endOnly) { endY: pageY }; - if (endOnly) { - return end; - } - - return $.extend({ + return endOnly ? end : assign({ startX: pageX, startY: pageY }, end); @@ -444,7 +740,7 @@ function getPointersCenter(pointers) { var pageY = 0; var count = 0; - $.each(pointers, function (pointerId, _ref3) { + forEach(pointers, function (_ref3) { var startX = _ref3.startX, startY = _ref3.startY; @@ -597,7 +893,7 @@ function getSourceCanvas(image, _ref6, _ref7, _ref8) { context.scale(scaleX, scaleY); context.imageSmoothingEnabled = imageSmoothingEnabled; context.imageSmoothingQuality = imageSmoothingQuality; - context.drawImage.apply(context, [image].concat(toConsumableArray($.map(params, function (param) { + context.drawImage.apply(context, [image].concat(toConsumableArray(params.map(function (param) { return Math.floor(normalizeDecimalNumber(param)); })))); context.restore(); @@ -640,7 +936,7 @@ function dataURLToArrayBuffer(dataURL) { var arrayBuffer = new ArrayBuffer(binary.length); var uint8 = new Uint8Array(arrayBuffer); - $.each(uint8, function (i) { + forEach(uint8, function (value, i) { uint8[i] = binary.charCodeAt(i); }); @@ -658,7 +954,7 @@ function arrayBufferToDataURL(arrayBuffer, mimeType) { var data = ''; // TypedArray.prototype.forEach is not supported in some browsers. - $.each(uint8, function (i, value) { + forEach(uint8, function (value) { data += fromCharCode(value); }); @@ -808,51 +1104,58 @@ var render = { } }, initContainer: function initContainer() { - var $element = this.$element, + var element = this.element, options = this.options, - $container = this.$container, - $cropper = this.$cropper; + container = this.container, + cropper = this.cropper; - $cropper.addClass(CLASS_HIDDEN); - $element.removeClass(CLASS_HIDDEN); + 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; - $cropper.css(this.container = { - width: Math.max($container.width(), Number(options.minContainerWidth) || 200), - height: Math.max($container.height(), Number(options.minContainerHeight) || 100) + setStyle(cropper, { + width: containerData.width, + height: containerData.height }); - $element.addClass(CLASS_HIDDEN); - $cropper.removeClass(CLASS_HIDDEN); + addClass(element, CLASS_HIDDEN); + removeClass(cropper, CLASS_HIDDEN); }, // Canvas (image wrapper) initCanvas: function initCanvas() { - var container = this.container, - image = this.image; + var containerData = this.containerData, + imageData = this.imageData; var viewMode = this.options.viewMode; - var rotated = Math.abs(image.rotate) % 180 === 90; - var naturalWidth = rotated ? image.naturalHeight : image.naturalWidth; - var naturalHeight = rotated ? image.naturalWidth : image.naturalHeight; + 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 = container.width; - var canvasHeight = container.height; + var canvasWidth = containerData.width; + var canvasHeight = containerData.height; - if (container.height * aspectRatio > container.width) { + if (containerData.height * aspectRatio > containerData.width) { if (viewMode === 3) { - canvasWidth = container.height * aspectRatio; + canvasWidth = containerData.height * aspectRatio; } else { - canvasHeight = container.width / aspectRatio; + canvasHeight = containerData.width / aspectRatio; } } else if (viewMode === 3) { - canvasHeight = container.width / aspectRatio; + canvasHeight = containerData.width / aspectRatio; } else { - canvasWidth = container.height * aspectRatio; + canvasWidth = containerData.height * aspectRatio; } - var canvas = { + var canvasData = { aspectRatio: aspectRatio, naturalWidth: naturalWidth, naturalHeight: naturalHeight, @@ -860,50 +1163,50 @@ var render = { height: canvasHeight }; - canvas.left = (container.width - canvasWidth) / 2; - canvas.top = (container.height - canvasHeight) / 2; - canvas.oldLeft = canvas.left; - canvas.oldTop = canvas.top; + canvasData.left = (containerData.width - canvasWidth) / 2; + canvasData.top = (containerData.height - canvasHeight) / 2; + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; - this.canvas = canvas; + this.canvasData = canvasData; this.limited = viewMode === 1 || viewMode === 2; this.limitCanvas(true, true); - this.initialImage = $.extend({}, image); - this.initialCanvas = $.extend({}, canvas); + this.initialImageData = assign({}, imageData); + this.initialCanvasData = assign({}, canvasData); }, - limitCanvas: function limitCanvas(isSizeLimited, isPositionLimited) { + limitCanvas: function limitCanvas(sizeLimited, positionLimited) { var options = this.options, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox; + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; var viewMode = options.viewMode; - var aspectRatio = canvas.aspectRatio; + var aspectRatio = canvasData.aspectRatio; - var cropped = this.cropped && cropBox; + var cropped = this.cropped && cropBoxData; - if (isSizeLimited) { + if (sizeLimited) { var minCanvasWidth = Number(options.minCanvasWidth) || 0; var minCanvasHeight = Number(options.minCanvasHeight) || 0; - if (viewMode > 0) { - if (viewMode > 1) { - minCanvasWidth = Math.max(minCanvasWidth, container.width); - minCanvasHeight = Math.max(minCanvasHeight, container.height); + 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; - } + if (viewMode === 3) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; } - } else if (minCanvasWidth) { - minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBox.width : 0); + } + } else if (viewMode > 0) { + if (minCanvasWidth) { + minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0); } else if (minCanvasHeight) { - minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBox.height : 0); + minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0); } else if (cropped) { - minCanvasWidth = cropBox.width; - minCanvasHeight = cropBox.height; + minCanvasWidth = cropBoxData.width; + minCanvasHeight = cropBoxData.height; if (minCanvasHeight * aspectRatio > minCanvasWidth) { minCanvasWidth = minCanvasHeight * aspectRatio; @@ -923,101 +1226,100 @@ var render = { minCanvasHeight = _getAdjustedSizes.height; - canvas.minWidth = minCanvasWidth; - canvas.minHeight = minCanvasHeight; - canvas.maxWidth = Infinity; - canvas.maxHeight = Infinity; + canvasData.minWidth = minCanvasWidth; + canvasData.minHeight = minCanvasHeight; + canvasData.maxWidth = Infinity; + canvasData.maxHeight = Infinity; } - if (isPositionLimited) { - if (viewMode > 0) { - var newCanvasLeft = container.width - canvas.width; - var newCanvasTop = container.height - canvas.height; + if (positionLimited) { + if (viewMode) { + var newCanvasLeft = containerData.width - canvasData.width; + var newCanvasTop = containerData.height - canvasData.height; - canvas.minLeft = Math.min(0, newCanvasLeft); - canvas.minTop = Math.min(0, newCanvasTop); - canvas.maxLeft = Math.max(0, newCanvasLeft); - canvas.maxTop = Math.max(0, newCanvasTop); + 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) { - canvas.minLeft = Math.min(cropBox.left, cropBox.left + cropBox.width - canvas.width); - canvas.minTop = Math.min(cropBox.top, cropBox.top + cropBox.height - canvas.height); - canvas.maxLeft = cropBox.left; - canvas.maxTop = cropBox.top; + 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 (canvas.width >= container.width) { - canvas.minLeft = Math.min(0, newCanvasLeft); - canvas.maxLeft = Math.max(0, newCanvasLeft); + if (canvasData.width >= containerData.width) { + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.maxLeft = Math.max(0, newCanvasLeft); } - if (canvas.height >= container.height) { - canvas.minTop = Math.min(0, newCanvasTop); - canvas.maxTop = Math.max(0, newCanvasTop); + if (canvasData.height >= containerData.height) { + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxTop = Math.max(0, newCanvasTop); } } } } else { - canvas.minLeft = -canvas.width; - canvas.minTop = -canvas.height; - canvas.maxLeft = container.width; - canvas.maxTop = container.height; + canvasData.minLeft = -canvasData.width; + canvasData.minTop = -canvasData.height; + canvasData.maxLeft = containerData.width; + canvasData.maxTop = containerData.height; } } }, renderCanvas: function renderCanvas(changed, transformed) { - var canvas = this.canvas, - image = this.image; + var canvasData = this.canvasData, + imageData = this.imageData; if (transformed) { var _getRotatedSizes = getRotatedSizes({ - width: image.naturalWidth * Math.abs(image.scaleX || 1), - height: image.naturalHeight * Math.abs(image.scaleY || 1), - degree: image.rotate || 0 + 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 = canvas.width * (naturalWidth / canvas.naturalWidth); - var height = canvas.height * (naturalHeight / canvas.naturalHeight); + var width = canvasData.width * (naturalWidth / canvasData.naturalWidth); + var height = canvasData.height * (naturalHeight / canvasData.naturalHeight); - canvas.left -= (width - canvas.width) / 2; - canvas.top -= (height - canvas.height) / 2; - canvas.width = width; - canvas.height = height; - canvas.aspectRatio = naturalWidth / naturalHeight; - canvas.naturalWidth = naturalWidth; - canvas.naturalHeight = 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 (canvas.width > canvas.maxWidth || canvas.width < canvas.minWidth) { - canvas.left = canvas.oldLeft; + if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) { + canvasData.left = canvasData.oldLeft; } - if (canvas.height > canvas.maxHeight || canvas.height < canvas.minHeight) { - canvas.top = canvas.oldTop; + if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) { + canvasData.top = canvasData.oldTop; } - canvas.width = Math.min(Math.max(canvas.width, canvas.minWidth), canvas.maxWidth); - canvas.height = Math.min(Math.max(canvas.height, canvas.minHeight), canvas.maxHeight); + 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); - canvas.left = Math.min(Math.max(canvas.left, canvas.minLeft), canvas.maxLeft); - canvas.top = Math.min(Math.max(canvas.top, canvas.minTop), canvas.maxTop); - canvas.oldLeft = canvas.left; - canvas.oldTop = canvas.top; - - this.$canvas.css({ - width: canvas.width, - height: canvas.height, - transform: getTransformValues({ - translateX: canvas.left, - translateY: canvas.top - }) - }); + 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, assign({ + width: canvasData.width, + height: canvasData.height + }, getTransforms({ + translateX: canvasData.left, + translateY: canvasData.top + }))); this.renderImage(changed); @@ -1026,27 +1328,25 @@ var render = { } }, renderImage: function renderImage(changed) { - var canvas = this.canvas, - image = this.image; + var canvasData = this.canvasData, + imageData = this.imageData; - var width = image.naturalWidth * (canvas.width / canvas.naturalWidth); - var height = image.naturalHeight * (canvas.height / canvas.naturalHeight); + var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth); + var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight); - $.extend(image, { + assign(imageData, { width: width, height: height, - left: (canvas.width - width) / 2, - top: (canvas.height - height) / 2 - }); - - this.$clone.css({ - width: image.width, - height: image.height, - transform: getTransformValues($.extend({ - translateX: image.left, - translateY: image.top - }, image)) + left: (canvasData.width - width) / 2, + top: (canvasData.height - height) / 2 }); + setStyle(this.image, assign({ + width: imageData.width, + height: imageData.height + }, getTransforms(assign({ + translateX: imageData.left, + translateY: imageData.top + }, imageData)))); if (changed) { this.output(); @@ -1054,58 +1354,58 @@ var render = { }, initCropBox: function initCropBox() { var options = this.options, - canvas = this.canvas; + canvasData = this.canvasData; var aspectRatio = options.aspectRatio; var autoCropArea = Number(options.autoCropArea) || 0.8; - var cropBox = { - width: canvas.width, - height: canvas.height + var cropBoxData = { + width: canvasData.width, + height: canvasData.height }; if (aspectRatio) { - if (canvas.height * aspectRatio > canvas.width) { - cropBox.height = cropBox.width / aspectRatio; + if (canvasData.height * aspectRatio > canvasData.width) { + cropBoxData.height = cropBoxData.width / aspectRatio; } else { - cropBox.width = cropBox.height * aspectRatio; + cropBoxData.width = cropBoxData.height * aspectRatio; } } - this.cropBox = cropBox; + this.cropBoxData = cropBoxData; this.limitCropBox(true, true); // Initialize auto crop area - cropBox.width = Math.min(Math.max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); - cropBox.height = Math.min(Math.max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); - - // The width of auto crop area must large than "minWidth", and the height too. (#164) - cropBox.width = Math.max(cropBox.minWidth, cropBox.width * autoCropArea); - cropBox.height = Math.max(cropBox.minHeight, cropBox.height * autoCropArea); - cropBox.left = canvas.left + (canvas.width - cropBox.width) / 2; - cropBox.top = canvas.top + (canvas.height - cropBox.height) / 2; - cropBox.oldLeft = cropBox.left; - cropBox.oldTop = cropBox.top; - - this.initialCropBox = $.extend({}, cropBox); + 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 = assign({}, cropBoxData); }, - limitCropBox: function limitCropBox(isSizeLimited, isPositionLimited) { + limitCropBox: function limitCropBox(sizeLimited, positionLimited) { var options = this.options, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData, limited = this.limited; var aspectRatio = options.aspectRatio; - if (isSizeLimited) { + if (sizeLimited) { var minCropBoxWidth = Number(options.minCropBoxWidth) || 0; var minCropBoxHeight = Number(options.minCropBoxHeight) || 0; - var maxCropBoxWidth = Math.min(container.width, limited ? canvas.width : container.width); - var maxCropBoxHeight = Math.min(container.height, limited ? canvas.height : container.height); + 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, container.width); - minCropBoxHeight = Math.min(minCropBoxHeight, container.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) { @@ -1128,63 +1428,62 @@ var render = { } // The minWidth/Height must be less than maxWidth/Height - cropBox.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); - cropBox.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); - cropBox.maxWidth = maxCropBoxWidth; - cropBox.maxHeight = maxCropBoxHeight; + cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); + cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); + cropBoxData.maxWidth = maxCropBoxWidth; + cropBoxData.maxHeight = maxCropBoxHeight; } - if (isPositionLimited) { + if (positionLimited) { if (limited) { - cropBox.minLeft = Math.max(0, canvas.left); - cropBox.minTop = Math.max(0, canvas.top); - cropBox.maxLeft = Math.min(container.width, canvas.left + canvas.width) - cropBox.width; - cropBox.maxTop = Math.min(container.height, canvas.top + canvas.height) - cropBox.height; + 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 { - cropBox.minLeft = 0; - cropBox.minTop = 0; - cropBox.maxLeft = container.width - cropBox.width; - cropBox.maxTop = container.height - cropBox.height; + 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, - container = this.container, - cropBox = this.cropBox; + containerData = this.containerData, + cropBoxData = this.cropBoxData; - if (cropBox.width > cropBox.maxWidth || cropBox.width < cropBox.minWidth) { - cropBox.left = cropBox.oldLeft; + if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) { + cropBoxData.left = cropBoxData.oldLeft; } - if (cropBox.height > cropBox.maxHeight || cropBox.height < cropBox.minHeight) { - cropBox.top = cropBox.oldTop; + if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) { + cropBoxData.top = cropBoxData.oldTop; } - cropBox.width = Math.min(Math.max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); - cropBox.height = Math.min(Math.max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); + 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); - cropBox.left = Math.min(Math.max(cropBox.left, cropBox.minLeft), cropBox.maxLeft); - cropBox.top = Math.min(Math.max(cropBox.top, cropBox.minTop), cropBox.maxTop); - cropBox.oldLeft = cropBox.left; - cropBox.oldTop = cropBox.top; + 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 - this.$face.data(DATA_ACTION, cropBox.width >= container.width && cropBox.height >= container.height ? ACTION_MOVE : ACTION_ALL); + setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL); } - this.$cropBox.css({ - width: cropBox.width, - height: cropBox.height, - transform: getTransformValues({ - translateX: cropBox.left, - translateY: cropBox.top - }) - }); + setStyle(this.cropBox, assign({ + width: cropBoxData.width, + height: cropBoxData.height + }, getTransforms({ + translateX: cropBoxData.left, + translateY: cropBoxData.top + }))); if (this.cropped && this.limited) { this.limitCanvas(true, true); @@ -1196,16 +1495,14 @@ var render = { }, output: function output() { this.preview(); - - if (this.completed) { - this.trigger(EVENT_CROP, this.getData()); - } + 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'); @@ -1215,21 +1512,31 @@ var preview = { } image.src = url; + this.viewBox.appendChild(image); + this.viewBoxImage = image; - var $clone2 = $(image); + if (!preview) { + return; + } - this.$preview = $(this.options.preview); - this.$clone2 = $clone2; - this.$viewBox.html($clone2); - this.$preview.each(function (i, element) { - var $element = $(element); + var previews = preview; + + if (typeof preview === 'string') { + previews = this.element.ownerDocument.querySelectorAll(preview); + } else if (preview.querySelector) { + previews = [preview]; + } + + this.previews = previews; + + forEach(previews, function (el) { var img = document.createElement('img'); // Save the original size for recover - $element.data(DATA_PREVIEW, { - width: $element.width(), - height: $element.height(), - html: $element.html() + setData(el, DATA_PREVIEW, { + width: el.offsetWidth, + height: el.offsetHeight, + html: el.innerHTML }); if (crossOrigin) { @@ -1246,48 +1553,49 @@ var preview = { */ 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;"'; - $element.html(img); + el.innerHTML = ''; + el.appendChild(img); }); }, resetPreview: function resetPreview() { - this.$preview.each(function (i, element) { - var $element = $(element); - var data = $element.data(DATA_PREVIEW); + forEach(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); - $element.css({ + setStyle(element, { width: data.width, height: data.height - }).html(data.html).removeData(DATA_PREVIEW); + }); + + element.innerHTML = data.html; + removeData(element, DATA_PREVIEW); }); }, preview: function preview() { - var image = this.image, - canvas = this.canvas, - cropBox = this.cropBox; - var cropBoxWidth = cropBox.width, - cropBoxHeight = cropBox.height; - var width = image.width, - height = image.height; + 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 = cropBox.left - canvas.left - image.left; - var top = cropBox.top - canvas.top - image.top; + var left = cropBoxData.left - canvasData.left - imageData.left; + var top = cropBoxData.top - canvasData.top - imageData.top; if (!this.cropped || this.disabled) { return; } - this.$clone2.css({ + setStyle(this.viewBoxImage, assign({ width: width, - height: height, - transform: getTransformValues($.extend({ - translateX: -left, - translateY: -top - }, image)) - }); - - this.$preview.each(function (i, element) { - var $element = $(element); - var data = $element.data(DATA_PREVIEW); + height: height + }, getTransforms(assign({ + translateX: -left, + translateY: -top + }, imageData)))); + + forEach(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); var originalWidth = data.width; var originalHeight = data.height; var newWidth = originalWidth; @@ -1305,104 +1613,107 @@ var preview = { newHeight = originalHeight; } - $element.css({ + setStyle(element, { width: newWidth, height: newHeight - }).find('img').css({ - width: width * ratio, - height: height * ratio, - transform: getTransformValues($.extend({ - translateX: -left * ratio, - translateY: -top * ratio - }, image)) }); + + setStyle(element.getElementsByTagName('img')[0], assign({ + width: width * ratio, + height: height * ratio + }, getTransforms(assign({ + translateX: -left * ratio, + translateY: -top * ratio + }, imageData)))); }); } }; var events = { bind: function bind() { - var $element = this.$element, + var element = this.element, options = this.options, - $cropper = this.$cropper; + cropper = this.cropper; - if ($.isFunction(options.cropstart)) { - $element.on(EVENT_CROP_START, options.cropstart); + if (isFunction(options.cropstart)) { + addListener(element, EVENT_CROP_START, options.cropstart); } - if ($.isFunction(options.cropmove)) { - $element.on(EVENT_CROP_MOVE, options.cropmove); + if (isFunction(options.cropmove)) { + addListener(element, EVENT_CROP_MOVE, options.cropmove); } - if ($.isFunction(options.cropend)) { - $element.on(EVENT_CROP_END, options.cropend); + if (isFunction(options.cropend)) { + addListener(element, EVENT_CROP_END, options.cropend); } - if ($.isFunction(options.crop)) { - $element.on(EVENT_CROP, options.crop); + if (isFunction(options.crop)) { + addListener(element, EVENT_CROP, options.crop); } - if ($.isFunction(options.zoom)) { - $element.on(EVENT_ZOOM, options.zoom); + if (isFunction(options.zoom)) { + addListener(element, EVENT_ZOOM, options.zoom); } - $cropper.on(EVENT_POINTER_DOWN, proxy(this.cropStart, this)); + addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this)); if (options.zoomable && options.zoomOnWheel) { - $cropper.on(EVENT_WHEEL, proxy(this.wheel, this)); + addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this)); } if (options.toggleDragModeOnDblclick) { - $cropper.on(EVENT_DBLCLICK, proxy(this.dblclick, this)); + addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this)); } - $(this.element.ownerDocument).on(EVENT_POINTER_MOVE, this.onCropMove = proxy(this.cropMove, this)).on(EVENT_POINTER_UP, this.onCropEnd = proxy(this.cropEnd, this)); + addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this)); + addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this)); if (options.responsive) { - $(window).on(EVENT_RESIZE, this.onResize = proxy(this.resize, this)); + addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this)); } }, unbind: function unbind() { - var $element = this.$element, + var element = this.element, options = this.options, - $cropper = this.$cropper; + cropper = this.cropper; - if ($.isFunction(options.cropstart)) { - $element.off(EVENT_CROP_START, options.cropstart); + if (isFunction(options.cropstart)) { + removeListener(element, EVENT_CROP_START, options.cropstart); } - if ($.isFunction(options.cropmove)) { - $element.off(EVENT_CROP_MOVE, options.cropmove); + if (isFunction(options.cropmove)) { + removeListener(element, EVENT_CROP_MOVE, options.cropmove); } - if ($.isFunction(options.cropend)) { - $element.off(EVENT_CROP_END, options.cropend); + if (isFunction(options.cropend)) { + removeListener(element, EVENT_CROP_END, options.cropend); } - if ($.isFunction(options.crop)) { - $element.off(EVENT_CROP, options.crop); + if (isFunction(options.crop)) { + removeListener(element, EVENT_CROP, options.crop); } - if ($.isFunction(options.zoom)) { - $element.off(EVENT_ZOOM, options.zoom); + if (isFunction(options.zoom)) { + removeListener(element, EVENT_ZOOM, options.zoom); } - $cropper.off(EVENT_POINTER_DOWN, this.cropStart); + removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart); if (options.zoomable && options.zoomOnWheel) { - $cropper.off(EVENT_WHEEL, this.wheel); + removeListener(cropper, EVENT_WHEEL, this.onWheel); } if (options.toggleDragModeOnDblclick) { - $cropper.off(EVENT_DBLCLICK, this.dblclick); + removeListener(cropper, EVENT_DBLCLICK, this.onDblclick); } - $(this.element.ownerDocument).off(EVENT_POINTER_MOVE, this.onCropMove).off(EVENT_POINTER_UP, this.onCropEnd); + removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove); + removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd); if (options.responsive) { - $(window).off(EVENT_RESIZE, this.onResize); + removeListener(window, EVENT_RESIZE, this.onResize); } } }; @@ -1410,20 +1721,20 @@ var events = { var handlers = { resize: function resize() { var options = this.options, - $container = this.$container, - container = this.container; + container = this.container, + containerData = this.containerData; var minContainerWidth = Number(options.minContainerWidth) || 200; var minContainerHeight = Number(options.minContainerHeight) || 100; - if (this.disabled || container.width <= minContainerWidth || container.height <= minContainerHeight) { + if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) { return; } - var ratio = $container.width() / container.width; + var ratio = container.offsetWidth / containerData.width; // Resize when width changed or height changed - if (ratio !== 1 || $container.height() !== container.height) { + if (ratio !== 1 || container.offsetHeight !== containerData.height) { var canvasData = void 0; var cropBoxData = void 0; @@ -1435,10 +1746,10 @@ var handlers = { this.render(); if (options.restore) { - this.setCanvasData($.each(canvasData, function (i, n) { + this.setCanvasData(forEach(canvasData, function (n, i) { canvasData[i] = n * ratio; })); - this.setCropBoxData($.each(cropBoxData, function (i, n) { + this.setCropBoxData(forEach(cropBoxData, function (n, i) { cropBoxData[i] = n * ratio; })); } @@ -1449,21 +1760,21 @@ var handlers = { return; } - this.setDragMode(this.$dragBox.hasClass(CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); + this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); }, - wheel: function wheel(event) { + wheel: function wheel(e) { var _this = this; - var e = event.originalEvent || event; var ratio = Number(this.options.wheelZoomRatio) || 0.1; + var delta = 1; if (this.disabled) { return; } - event.preventDefault(); + e.preventDefault(); - // Limit wheel speed to prevent zoom too fast + // Limit wheel speed to prevent zoom too fast (#21) if (this.wheeling) { return; } @@ -1474,8 +1785,6 @@ var handlers = { _this.wheeling = false; }, 50); - var delta = 1; - if (e.deltaY) { delta = e.deltaY > 0 ? 1 : -1; } else if (e.wheelDelta) { @@ -1484,7 +1793,7 @@ var handlers = { delta = e.detail > 0 ? 1 : -1; } - this.zoom(-delta * ratio, event); + this.zoom(-delta * ratio, e); }, cropStart: function cropStart(e) { if (this.disabled) { @@ -1493,34 +1802,33 @@ var handlers = { var options = this.options, pointers = this.pointers; - var originalEvent = e.originalEvent; var action = void 0; - if (originalEvent && originalEvent.changedTouches) { + if (e.changedTouches) { // Handle touch event - $.each(originalEvent.changedTouches, function (i, touch) { + forEach(e.changedTouches, function (touch) { pointers[touch.identifier] = getPointer(touch); }); } else { // Handle mouse event and pointer event - pointers[originalEvent && originalEvent.pointerId || 0] = getPointer(originalEvent || e); + pointers[e.pointerId || 0] = getPointer(e); } - if (objectKeys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { + if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { action = ACTION_ZOOM; } else { - action = $(e.target).data(DATA_ACTION); + action = getData(e.target, DATA_ACTION); } if (!REGEXP_ACTIONS.test(action)) { return; } - if (this.trigger(EVENT_CROP_START, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_CROP_START, { + originalEvent: e, action: action - }).isDefaultPrevented()) { + }) === false) { return; } @@ -1531,7 +1839,7 @@ var handlers = { if (action === ACTION_CROP) { this.cropping = true; - this.$dragBox.addClass(CLASS_MODAL); + addClass(this.dragBox, CLASS_MODAL); } }, cropMove: function cropMove(e) { @@ -1543,24 +1851,23 @@ var handlers = { } var pointers = this.pointers; - var originalEvent = e.originalEvent; e.preventDefault(); - if (this.trigger(EVENT_CROP_MOVE, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_CROP_MOVE, { + originalEvent: e, action: action - }).isDefaultPrevented()) { + }) === false) { return; } - if (originalEvent && originalEvent.changedTouches) { - $.each(originalEvent.changedTouches, function (i, touch) { - $.extend(pointers[touch.identifier], getPointer(touch, true)); + if (e.changedTouches) { + forEach(e.changedTouches, function (touch) { + assign(pointers[touch.identifier], getPointer(touch, true)); }); } else { - $.extend(pointers[originalEvent && originalEvent.pointerId || 0], getPointer(originalEvent || e, true)); + assign(pointers[e.pointerId || 0], getPointer(e, true)); } this.change(e); @@ -1570,17 +1877,16 @@ var handlers = { return; } - var action = this.action; - var pointers = this.pointers; - var originalEvent = e.originalEvent; + var action = this.action, + pointers = this.pointers; - if (originalEvent && originalEvent.changedTouches) { - $.each(originalEvent.changedTouches, function (i, touch) { + if (e.changedTouches) { + forEach(e.changedTouches, function (touch) { delete pointers[touch.identifier]; }); } else { - delete pointers[originalEvent && originalEvent.pointerId || 0]; + delete pointers[e.pointerId || 0]; } if (!action) { @@ -1589,17 +1895,17 @@ var handlers = { e.preventDefault(); - if (!objectKeys(pointers).length) { + if (!Object.keys(pointers).length) { this.action = ''; } if (this.cropping) { this.cropping = false; - this.$dragBox.toggleClass(CLASS_MODAL, this.cropped && this.options.modal); + toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal); } - this.trigger(EVENT_CROP_END, { - originalEvent: originalEvent, + dispatchEvent(this.element, EVENT_CROP_END, { + originalEvent: e, action: action }); } @@ -1608,40 +1914,40 @@ var handlers = { var change = { change: function change(e) { var options = this.options, - pointers = this.pointers, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox; + canvasData = this.canvasData, + containerData = this.containerData, + cropBoxData = this.cropBoxData, + pointers = this.pointers; var action = this.action; var aspectRatio = options.aspectRatio; - var left = cropBox.left, - top = cropBox.top, - width = cropBox.width, - height = cropBox.height; + 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 = container.width; - var maxHeight = container.height; + 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 (#259) + // Locking aspect ratio in "free mode" by holding shift key if (!aspectRatio && e.shiftKey) { aspectRatio = width && height ? width / height : 1; } if (this.limited) { - minLeft = cropBox.minLeft; - minTop = cropBox.minTop; + minLeft = cropBoxData.minLeft; + minTop = cropBoxData.minTop; - maxWidth = minLeft + Math.min(container.width, canvas.width, canvas.left + canvas.width); - maxHeight = minTop + Math.min(container.height, canvas.height, canvas.top + canvas.height); + 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[objectKeys(pointers)[0]]; + var pointer = pointers[Object.keys(pointers)[0]]; var range = { x: pointer.endX - pointer.startX, y: pointer.endY - pointer.startY @@ -1982,7 +2288,7 @@ var change = { // Zoom canvas case ACTION_ZOOM: - this.zoom(getMaxZoomRatio(pointers), e.originalEvent); + this.zoom(getMaxZoomRatio(pointers), e); renderable = false; break; @@ -1993,11 +2299,11 @@ var change = { break; } - offset = this.$cropper.offset(); + offset = getOffset(this.cropper); left = pointer.startX - offset.left; top = pointer.startY - offset.top; - width = cropBox.minWidth; - height = cropBox.minHeight; + width = cropBoxData.minWidth; + height = cropBoxData.minHeight; if (range.x > 0) { action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST; @@ -2012,7 +2318,7 @@ var change = { // Show the crop box if is hidden if (!this.cropped) { - this.$cropBox.removeClass(CLASS_HIDDEN); + removeClass(this.cropBox, CLASS_HIDDEN); this.cropped = true; if (this.limited) { @@ -2026,16 +2332,16 @@ var change = { } if (renderable) { - cropBox.width = width; - cropBox.height = height; - cropBox.left = left; - cropBox.top = top; + cropBoxData.width = width; + cropBoxData.height = height; + cropBoxData.left = left; + cropBoxData.top = top; this.action = action; this.renderCropBox(); } // Override - $.each(pointers, function (i, p) { + forEach(pointers, function (p) { p.startX = p.endX; p.startY = p.endY; }); @@ -2045,149 +2351,162 @@ var change = { var methods = { // Show the crop box manually crop: function crop() { - if (!this.ready || this.disabled) { - return; - } - - if (!this.cropped) { + if (this.ready && !this.cropped && !this.disabled) { this.cropped = true; this.limitCropBox(true, true); if (this.options.modal) { - this.$dragBox.addClass(CLASS_MODAL); + addClass(this.dragBox, CLASS_MODAL); } - this.$cropBox.removeClass(CLASS_HIDDEN); + removeClass(this.cropBox, CLASS_HIDDEN); + this.setCropBoxData(this.initialCropBoxData); } - this.setCropBoxData(this.initialCropBox); + return this; }, // Reset the image and crop box to their initial states reset: function reset() { - if (!this.ready || this.disabled) { - return; - } + if (this.ready && !this.disabled) { + this.imageData = assign({}, this.initialImageData); + this.canvasData = assign({}, this.initialCanvasData); + this.cropBoxData = assign({}, this.initialCropBoxData); + this.renderCanvas(); - this.image = $.extend({}, this.initialImage); - this.canvas = $.extend({}, this.initialCanvas); - this.cropBox = $.extend({}, this.initialCropBox); - this.renderCanvas(); - - if (this.cropped) { - this.renderCropBox(); + if (this.cropped) { + this.renderCropBox(); + } } + + return this; }, // Clear the crop box clear: function clear() { - if (!this.cropped || this.disabled) { - return; - } + if (this.cropped && !this.disabled) { + assign(this.cropBoxData, { + left: 0, + top: 0, + width: 0, + height: 0 + }); - $.extend(this.cropBox, { - left: 0, - top: 0, - width: 0, - height: 0 - }); + this.cropped = false; + this.renderCropBox(); + this.limitCanvas(true, true); - 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); + } - // Render canvas after crop box rendered - this.renderCanvas(); - this.$dragBox.removeClass(CLASS_MODAL); - this.$cropBox.addClass(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. + * @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one. + * @returns {Cropper} this */ - replace: function replace(url, onlyColorChanged) { + replace: function replace(url) { + var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + if (!this.disabled && url) { if (this.isImg) { - this.$element.attr('src', url); + this.element.src = url; } - if (onlyColorChanged) { + if (hasSameSize) { this.url = url; - this.$clone.attr('src', url); + this.image.src = url; if (this.ready) { - this.$preview.find('img').add(this.$clone2).attr('src', url); + this.viewBoxImage.src = url; + + forEach(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.uncreate(); this.load(url); } } + + return this; }, // Enable (unfreeze) the cropper enable: function enable() { - if (this.ready) { + if (this.ready && this.disabled) { this.disabled = false; - this.$cropper.removeClass(CLASS_DISABLED); + removeClass(this.cropper, CLASS_DISABLED); } + + return this; }, // Disable (freeze) the cropper disable: function disable() { - if (this.ready) { + if (this.ready && !this.disabled) { this.disabled = true; - this.$cropper.addClass(CLASS_DISABLED); + addClass(this.cropper, CLASS_DISABLED); } + + return this; }, - // Destroy the cropper and remove the instance from the image + /** + * Destroy the cropper and remove the instance from the image + * @returns {Cropper} this + */ destroy: function destroy() { - var $element = this.$element; + var element = this.element; - if (this.loaded) { - if (this.isImg && this.replaced) { - $element.attr('src', this.originalUrl); - } + if (!getData(element, NAMESPACE)) { + return this; + } - this.unbuild(); - $element.removeClass(CLASS_HIDDEN); - } else if (this.isImg) { - $element.off(EVENT_LOAD, this.start); - } else if (this.$clone) { - this.$clone.remove(); + if (this.isImg && this.replaced) { + element.src = this.originalUrl; } - $element.removeData(NAMESPACE); + this.uncreate(); + 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. + * @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis. + * @returns {Cropper} this */ - move: function move(offsetX, offsetY) { - var _canvas = this.canvas, - left = _canvas.left, - top = _canvas.top; + move: function move(offsetX) { + var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX; + var _canvasData = this.canvasData, + left = _canvasData.left, + top = _canvasData.top; - this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); + return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); }, @@ -2195,28 +2514,25 @@ var methods = { * Move the canvas to an absolute point * @param {number} x - The x-axis coordinate. * @param {number} [y=x] - The y-axis coordinate. + * @returns {Cropper} this */ - moveTo: function moveTo(x, y) { - var canvas = this.canvas; + moveTo: function moveTo(x) { + var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + var canvasData = this.canvasData; var changed = false; - // If "y" is not present, its default value is "x" - if (isUndefined(y)) { - y = x; - } - x = Number(x); y = Number(y); if (this.ready && !this.disabled && this.options.movable) { if (isNumber(x)) { - canvas.left = x; + canvasData.left = x; changed = true; } if (isNumber(y)) { - canvas.top = y; + canvasData.top = y; changed = true; } @@ -2224,16 +2540,19 @@ var methods = { this.renderCanvas(true); } } + + return this; }, /** * Zoom the canvas with a relative ratio - * @param {Number} ratio - The target ratio. - * @param {Event} _event - The related event if any. + * @param {number} ratio - The target ratio. + * @param {Event} _originalEvent - The original event if any. + * @returns {Cropper} this */ - zoom: function zoom(ratio, _event) { - var canvas = this.canvas; + zoom: function zoom(ratio, _originalEvent) { + var canvasData = this.canvasData; ratio = Number(ratio); @@ -2244,23 +2563,24 @@ var methods = { ratio = 1 + ratio; } - this.zoomTo(canvas.width * ratio / canvas.naturalWidth, _event); + return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent); }, /** * Zoom the canvas to an absolute ratio * @param {number} ratio - The target ratio. - * @param {Event} _event - The related event if any. + * @param {Object} pivot - The zoom pivot point coordinate. + * @param {Event} _originalEvent - The original event if any. + * @returns {Cropper} this */ - zoomTo: function zoomTo(ratio, _event) { + zoomTo: function zoomTo(ratio, pivot, _originalEvent) { var options = this.options, - pointers = this.pointers, - canvas = this.canvas; - var width = canvas.width, - height = canvas.height, - naturalWidth = canvas.naturalWidth, - naturalHeight = canvas.naturalHeight; + canvasData = this.canvasData; + var width = canvasData.width, + height = canvasData.height, + naturalWidth = canvasData.naturalWidth, + naturalHeight = canvasData.naturalHeight; ratio = Number(ratio); @@ -2268,87 +2588,95 @@ var methods = { if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) { var newWidth = naturalWidth * ratio; var newHeight = naturalHeight * ratio; - var originalEvent = void 0; - - if (_event) { - originalEvent = _event.originalEvent; - } - if (this.trigger(EVENT_ZOOM, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_ZOOM, { + originalEvent: _originalEvent, oldRatio: width / naturalWidth, ratio: newWidth / naturalWidth - }).isDefaultPrevented()) { - return; + }) === false) { + return this; } - if (originalEvent) { - var offset = this.$cropper.offset(); - var center = pointers && objectKeys(pointers).length ? getPointersCenter(pointers) : { - pageX: _event.pageX || originalEvent.pageX || 0, - pageY: _event.pageY || originalEvent.pageY || 0 + 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 - canvas.left -= (newWidth - width) * ((center.pageX - offset.left - canvas.left) / width); - canvas.top -= (newHeight - height) * ((center.pageY - offset.top - canvas.top) / height); + 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 - canvas.left -= (newWidth - width) / 2; - canvas.top -= (newHeight - height) / 2; + canvasData.left -= (newWidth - width) / 2; + canvasData.top -= (newHeight - height) / 2; } - canvas.width = newWidth; - canvas.height = newHeight; + 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 {Cropper} this */ rotate: function rotate(degree) { - this.rotateTo((this.image.rotate || 0) + Number(degree)); + return this.rotateTo((this.imageData.rotate || 0) + Number(degree)); }, /** * Rotate the canvas to an absolute degree * @param {number} degree - The rotate degree. + * @returns {Cropper} this */ rotateTo: function rotateTo(degree) { degree = Number(degree); if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) { - this.image.rotate = degree % 360; + 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 {Cropper} this */ scaleX: function scaleX(_scaleX) { - var scaleY = this.image.scaleY; + var scaleY = this.imageData.scaleY; - this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1); + 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 {Cropper} this */ scaleY: function scaleY(_scaleY) { - var scaleX = this.image.scaleX; + var scaleX = this.imageData.scaleX; - this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); + return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); }, @@ -2356,10 +2684,11 @@ var methods = { * 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 {Cropper} this */ scale: function scale(scaleX) { var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX; - var image = this.image; + var imageData = this.imageData; var transformed = false; @@ -2368,12 +2697,12 @@ var methods = { if (this.ready && !this.disabled && this.options.scalable) { if (isNumber(scaleX)) { - image.scaleX = scaleX; + imageData.scaleX = scaleX; transformed = true; } if (isNumber(scaleY)) { - image.scaleY = scaleY; + imageData.scaleY = scaleY; transformed = true; } @@ -2381,6 +2710,8 @@ var methods = { this.renderCanvas(true, true); } } + + return this; }, @@ -2389,26 +2720,26 @@ var methods = { * @param {boolean} [rounded=false] - Indicate if round the data values or not. * @returns {Object} The result cropped data. */ - getData: function getData() { + getData: function getData$$1() { var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; var options = this.options, - image = this.image, - canvas = this.canvas, - cropBox = this.cropBox; + imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; var data = void 0; if (this.ready && this.cropped) { data = { - x: cropBox.left - canvas.left, - y: cropBox.top - canvas.top, - width: cropBox.width, - height: cropBox.height + x: cropBoxData.left - canvasData.left, + y: cropBoxData.top - canvasData.top, + width: cropBoxData.width, + height: cropBoxData.height }; - var ratio = image.width / image.naturalWidth; + var ratio = imageData.width / imageData.naturalWidth; - $.each(data, function (i, n) { + forEach(data, function (n, i) { n /= ratio; data[i] = rounded ? Math.round(n) : n; }); @@ -2422,12 +2753,12 @@ var methods = { } if (options.rotatable) { - data.rotate = image.rotate || 0; + data.rotate = imageData.rotate || 0; } if (options.scalable) { - data.scaleX = image.scaleX || 1; - data.scaleY = image.scaleY || 1; + data.scaleX = imageData.scaleX || 1; + data.scaleY = imageData.scaleY || 1; } return data; @@ -2437,36 +2768,33 @@ var methods = { /** * Set the cropped area position and size with new data * @param {Object} data - The new data. + * @returns {Cropper} this */ - setData: function setData(data) { + setData: function setData$$1(data) { var options = this.options, - image = this.image, - canvas = this.canvas; + imageData = this.imageData, + canvasData = this.canvasData; var cropBoxData = {}; - if ($.isFunction(data)) { - data = data.call(this.element); - } - - if (this.ready && !this.disabled && $.isPlainObject(data)) { + if (this.ready && !this.disabled && isPlainObject(data)) { var transformed = false; if (options.rotatable) { - if (isNumber(data.rotate) && data.rotate !== image.rotate) { - image.rotate = data.rotate; + if (isNumber(data.rotate) && data.rotate !== imageData.rotate) { + imageData.rotate = data.rotate; transformed = true; } } if (options.scalable) { - if (isNumber(data.scaleX) && data.scaleX !== image.scaleX) { - image.scaleX = data.scaleX; + if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) { + imageData.scaleX = data.scaleX; transformed = true; } - if (isNumber(data.scaleY) && data.scaleY !== image.scaleY) { - image.scaleY = data.scaleY; + if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) { + imageData.scaleY = data.scaleY; transformed = true; } } @@ -2475,14 +2803,14 @@ var methods = { this.renderCanvas(true, true); } - var ratio = image.width / image.naturalWidth; + var ratio = imageData.width / imageData.naturalWidth; if (isNumber(data.x)) { - cropBoxData.left = data.x * ratio + canvas.left; + cropBoxData.left = data.x * ratio + canvasData.left; } if (isNumber(data.y)) { - cropBoxData.top = data.y * ratio + canvas.top; + cropBoxData.top = data.y * ratio + canvasData.top; } if (isNumber(data.width)) { @@ -2495,6 +2823,8 @@ var methods = { this.setCropBoxData(cropBoxData); } + + return this; }, @@ -2503,7 +2833,7 @@ var methods = { * @returns {Object} The result container data. */ getContainerData: function getContainerData() { - return this.ready ? $.extend({}, this.container) : {}; + return this.ready ? assign({}, this.containerData) : {}; }, @@ -2512,7 +2842,7 @@ var methods = { * @returns {Object} The result image data. */ getImageData: function getImageData() { - return this.loaded ? $.extend({}, this.image) : {}; + return this.sized ? assign({}, this.imageData) : {}; }, @@ -2521,13 +2851,13 @@ var methods = { * @returns {Object} The result canvas data. */ getCanvasData: function getCanvasData() { - var canvas = this.canvas; + var canvasData = this.canvasData; var data = {}; if (this.ready) { - $.each(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (i, n) { - data[n] = canvas[n]; + forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) { + data[n] = canvasData[n]; }); } @@ -2538,35 +2868,34 @@ var methods = { /** * Set the canvas position and size with new data. * @param {Object} data - The new canvas data. + * @returns {Cropper} this */ setCanvasData: function setCanvasData(data) { - var canvas = this.canvas; - var aspectRatio = canvas.aspectRatio; + var canvasData = this.canvasData; + var aspectRatio = canvasData.aspectRatio; - if ($.isFunction(data)) { - data = data.call(this.$element); - } - - if (this.ready && !this.disabled && $.isPlainObject(data)) { + if (this.ready && !this.disabled && isPlainObject(data)) { if (isNumber(data.left)) { - canvas.left = data.left; + canvasData.left = data.left; } if (isNumber(data.top)) { - canvas.top = data.top; + canvasData.top = data.top; } if (isNumber(data.width)) { - canvas.width = data.width; - canvas.height = data.width / aspectRatio; + canvasData.width = data.width; + canvasData.height = data.width / aspectRatio; } else if (isNumber(data.height)) { - canvas.height = data.height; - canvas.width = data.height * aspectRatio; + canvasData.height = data.height; + canvasData.width = data.height * aspectRatio; } this.renderCanvas(true); } + + return this; }, @@ -2575,62 +2904,66 @@ var methods = { * @returns {Object} The result crop box data. */ getCropBoxData: function getCropBoxData() { - var cropBox = this.cropBox; + var cropBoxData = this.cropBoxData; + var data = void 0; - return this.ready && this.cropped ? { - left: cropBox.left, - top: cropBox.top, - width: cropBox.width, - height: cropBox.height - } : {}; + 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 {Cropper} this */ setCropBoxData: function setCropBoxData(data) { - var cropBox = this.cropBox; + 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 (this.ready && this.cropped && !this.disabled && isPlainObject(data)) { if (isNumber(data.left)) { - cropBox.left = data.left; + cropBoxData.left = data.left; } if (isNumber(data.top)) { - cropBox.top = data.top; + cropBoxData.top = data.top; } - if (isNumber(data.width) && data.width !== cropBox.width) { + if (isNumber(data.width) && data.width !== cropBoxData.width) { widthChanged = true; - cropBox.width = data.width; + cropBoxData.width = data.width; } - if (isNumber(data.height) && data.height !== cropBox.height) { + if (isNumber(data.height) && data.height !== cropBoxData.height) { heightChanged = true; - cropBox.height = data.height; + cropBoxData.height = data.height; } if (aspectRatio) { if (widthChanged) { - cropBox.height = cropBox.width / aspectRatio; + cropBoxData.height = cropBoxData.width / aspectRatio; } else if (heightChanged) { - cropBox.width = cropBox.height * aspectRatio; + cropBoxData.width = cropBoxData.height * aspectRatio; } } this.renderCropBox(); } + + return this; }, @@ -2646,9 +2979,9 @@ var methods = { return null; } - var canvasData = this.canvas; + var canvasData = this.canvasData; - var source = getSourceCanvas(this.$clone[0], this.image, canvasData, options); + var source = getSourceCanvas(this.image, this.imageData, canvasData, options); // Returns the source canvas if it is not cropped. if (!this.cropped) { @@ -2698,6 +3031,7 @@ var methods = { canvas.width = normalizeDecimalNumber(width); canvas.height = normalizeDecimalNumber(height); + context.fillStyle = options.fillColor || 'transparent'; context.fillRect(0, 0, width, height); @@ -2771,9 +3105,10 @@ var methods = { params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale); } - context.drawImage.apply(context, [source].concat(toConsumableArray($.map(params, function (param) { + context.drawImage.apply(context, [source].concat(toConsumableArray(params.map(function (param) { return Math.floor(normalizeDecimalNumber(param)); })))); + return canvas; }, @@ -2781,6 +3116,7 @@ var methods = { /** * Change the aspect ratio of the crop box. * @param {number} aspectRatio - The new aspect ratio. + * @returns {Cropper} this */ setAspectRatio: function setAspectRatio(aspectRatio) { var options = this.options; @@ -2798,34 +3134,47 @@ var methods = { } } } + + return this; }, /** * Change the drag mode. * @param {string} mode - The new drag mode. + * @returns {Cropper} this */ setDragMode: function setDragMode(mode) { - var options = this.options; + var options = this.options, + dragBox = this.dragBox, + face = this.face; + - var croppable = void 0; - var movable = void 0; + if (this.ready && !this.disabled) { + var croppable = mode === DRAG_MODE_CROP; + var movable = options.movable && mode === DRAG_MODE_MOVE; - if (this.loaded && !this.disabled) { - croppable = mode === DRAG_MODE_CROP; - movable = options.movable && mode === DRAG_MODE_MOVE; mode = croppable || movable ? mode : DRAG_MODE_NONE; - this.$dragBox.data(DATA_ACTION, mode).toggleClass(CLASS_CROP, croppable).toggleClass(CLASS_MOVE, movable); + options.dragMode = mode; + 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(#300) - this.$face.data(DATA_ACTION, mode).toggleClass(CLASS_CROP, croppable).toggleClass(CLASS_MOVE, movable); + // 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. @@ -2841,36 +3190,37 @@ var Cropper = function () { } this.element = element; - this.$element = $(element); - this.options = $.extend({}, DEFAULTS, $.isPlainObject(options) && options); - this.completed = false; + this.options = assign({}, DEFAULTS, isPlainObject(options) && options); this.cropped = false; this.disabled = false; - this.isImg = false; - this.limited = false; - this.loaded = false; + this.pointers = {}; this.ready = false; + this.reloading = false; this.replaced = false; - this.wheeling = false; - this.originalUrl = ''; - this.canvas = null; - this.cropBox = null; - this.pointers = {}; + this.sized = false; + this.sizing = false; this.init(); } createClass(Cropper, [{ key: 'init', value: function init() { - var $element = this.$element; + var element = this.element; + var tagName = element.tagName.toLowerCase(); var url = void 0; - if ($element.is('img')) { + if (getData(element, NAMESPACE)) { + return; + } + + setData(element, NAMESPACE, this); + + if (tagName === 'img') { this.isImg = true; - // Should use `$.fn.attr` here. e.g.: "img/picture.jpg" - url = $element.attr('src') || ''; + // e.g.: "img/picture.jpg" + url = element.getAttribute('src') || ''; this.originalUrl = url; // Stop when it's a blank image @@ -2878,26 +3228,14 @@ var Cropper = function () { return; } - // Should use `$.fn.prop` here. e.g.: "http://example.com/img/picture.jpg" - url = $element.prop('src'); - } else if ($element.is('canvas') && window.HTMLCanvasElement) { - url = $element[0].toDataURL(); + // e.g.: "http://example.com/img/picture.jpg" + url = element.src; + } else if (tagName === 'canvas' && window.HTMLCanvasElement) { + url = element.toDataURL(); } this.load(url); } - - // A shortcut for triggering custom events - - }, { - key: 'trigger', - value: function trigger(type, data) { - var e = $.Event(type, data); - - this.$element.trigger(e); - - return e; - } }, { key: 'load', value: function load(url) { @@ -2908,9 +3246,9 @@ var Cropper = function () { } this.url = url; - this.image = {}; + this.imageData = {}; - var $element = this.$element, + var element = this.element, options = this.options; @@ -2932,29 +3270,41 @@ var Cropper = function () { var xhr = new XMLHttpRequest(); + this.reloading = true; + this.xhr = xhr; + + var done = function done() { + _this.reloading = false; + _this.xhr = null; + }; + + xhr.ontimeout = done; + xhr.onabort = done; xhr.onerror = function () { + done(); _this.clone(); }; xhr.onload = function () { + done(); _this.read(xhr.response); }; // Bust cache when there is a "crossOrigin" property - if (options.checkCrossOrigin && isCrossOriginURL(url) && !$element.prop('crossOrigin')) { + if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) { url = addTimestamp(url); } xhr.open('get', url); xhr.responseType = 'arraybuffer'; - xhr.withCredentials = $element.prop('crossOrigin') === 'use-credentials'; + xhr.withCredentials = element.crossOrigin === 'use-credentials'; xhr.send(); } }, { key: 'read', value: function read(arrayBuffer) { var options = this.options, - image = this.image; + imageData = this.imageData; var orientation = getOrientation(arrayBuffer); var rotate = 0; @@ -2972,12 +3322,12 @@ var Cropper = function () { } if (options.rotatable) { - image.rotate = rotate; + imageData.rotate = rotate; } if (options.scalable) { - image.scaleX = scaleX; - image.scaleY = scaleY; + imageData.scaleX = scaleX; + imageData.scaleY = scaleY; } this.clone(); @@ -2985,22 +3335,22 @@ var Cropper = function () { }, { key: 'clone', value: function clone() { - var $element = this.$element, - options = this.options, + var element = this.element, url = this.url; - var crossOrigin = ''; + var crossOrigin = void 0; var crossOriginUrl = void 0; - if (options.checkCrossOrigin && isCrossOriginURL(url)) { - crossOrigin = $element.prop('crossOrigin'); + if (this.options.checkCrossOrigin && isCrossOriginURL(url)) { + crossOrigin = element.crossOrigin; + if (crossOrigin) { crossOriginUrl = url; } else { crossOrigin = 'anonymous'; - // Bust cache (#148) when there is not a "crossOrigin" property + // Bust cache when there is not a "crossOrigin" property crossOriginUrl = addTimestamp(url); } } @@ -3016,88 +3366,136 @@ var Cropper = function () { image.src = crossOriginUrl || url; - var $clone = $(image); + var start = this.start.bind(this); + var stop = this.stop.bind(this); - this.$clone = $clone; + this.image = image; + this.onStart = start; + this.onStop = stop; if (this.isImg) { - if (this.element.complete) { - this.start(); + if (element.complete) { + this.timeout = setTimeout(start, 0); } else { - $element.one(EVENT_LOAD, $.proxy(this.start, this)); + addListener(element, EVENT_LOAD, start, { + once: true + }); } } else { - $clone.one(EVENT_LOAD, $.proxy(this.start, this)).one(EVENT_ERROR, $.proxy(this.stop, this)).addClass(CLASS_HIDE).insertAfter($element); + image.onload = start; + image.onerror = stop; + addClass(image, CLASS_HIDE); + element.parentNode.insertBefore(image, element.nextSibling); } } }, { key: 'start', - value: function start() { + value: function start(event) { var _this2 = this; - var $clone = this.$clone; - - var $image = this.$element; + var image = this.isImg ? this.element : this.image; - if (!this.isImg) { - $clone.off(EVENT_ERROR, this.stop); - $image = $clone; + if (event) { + image.onload = null; + image.onerror = null; } - getImageNaturalSizes($image[0], function (naturalWidth, naturalHeight) { - $.extend(_this2.image, { + this.sizing = true; + + var IS_SAFARI = WINDOW.navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(WINDOW.navigator.userAgent); + var done = function done(naturalWidth, naturalHeight) { + assign(_this2.imageData, { naturalWidth: naturalWidth, naturalHeight: naturalHeight, aspectRatio: naturalWidth / naturalHeight }); - - _this2.loaded = true; + _this2.sizing = false; + _this2.sized = true; _this2.build(); - }); + }; + + // Modern browsers (except Safari) + if (image.naturalWidth && !IS_SAFARI) { + done(image.naturalWidth, image.naturalHeight); + return; + } + + var sizingImage = document.createElement('img'); + var body = document.body || document.documentElement; + + this.sizingImage = sizingImage; + + sizingImage.onload = function () { + done(sizingImage.width, sizingImage.height); + + if (!IS_SAFARI) { + body.removeChild(sizingImage); + } + }; + + sizingImage.src = image.src; + + // iOS Safari will convert the image automatically + // with its orientation once append it into DOM (#279) + if (!IS_SAFARI) { + sizingImage.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(sizingImage); + } } }, { key: 'stop', value: function stop() { - this.$clone.remove(); - this.$clone = null; + var image = this.image; + + + image.onload = null; + image.onerror = null; + image.parentNode.removeChild(image); + this.image = null; } }, { key: 'build', value: function build() { - var _this3 = this; - - if (!this.loaded) { + if (!this.sized || this.ready) { return; } - // Unbuild first when replace - if (this.ready) { - this.unbuild(); - } - - var $element = this.$element, + var element = this.element, options = this.options, - $clone = this.$clone; - - var $cropper = $(TEMPLATE); - var $cropBox = $cropper.find('.' + NAMESPACE + '-crop-box'); - var $face = $cropBox.find('.' + NAMESPACE + '-face'); + image = this.image; // Create cropper elements - this.$container = $element.parent(); - this.$cropper = $cropper; - this.$canvas = $cropper.find('.' + NAMESPACE + '-canvas').append($clone); - this.$dragBox = $cropper.find('.' + NAMESPACE + '-drag-box'); - this.$cropBox = $cropBox; - this.$viewBox = $cropper.find('.' + NAMESPACE + '-view-box'); - this.$face = $face; + + 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 - $element.addClass(CLASS_HIDDEN).after($cropper); + addClass(element, CLASS_HIDDEN); + + // Inserts the cropper after to the current image + container.insertBefore(cropper, element.nextSibling); - // Show the clone image if is hidden + // Show the image if is hidden if (!this.isImg) { - $clone.removeClass(CLASS_HIDE); + removeClass(image, CLASS_HIDE); } this.initPreview(); @@ -3106,55 +3504,51 @@ var Cropper = function () { 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) { - this.$dragBox.addClass(CLASS_MODAL); - } - } else { - $cropBox.addClass(CLASS_HIDDEN); - } + addClass(cropBox, CLASS_HIDDEN); if (!options.guides) { - $cropBox.find('.' + NAMESPACE + '-dashed').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-dashed'), CLASS_HIDDEN); } if (!options.center) { - $cropBox.find('.' + NAMESPACE + '-center').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-center'), CLASS_HIDDEN); } - if (options.cropBoxMovable) { - $face.addClass(CLASS_MOVE).data(DATA_ACTION, ACTION_ALL); + if (options.background) { + addClass(cropper, NAMESPACE + '-bg'); } if (!options.highlight) { - $face.addClass(CLASS_INVISIBLE); + addClass(face, CLASS_INVISIBLE); } - if (options.background) { - $cropper.addClass(NAMESPACE + '-bg'); + if (options.cropBoxMovable) { + addClass(face, CLASS_MOVE); + setData(face, DATA_ACTION, ACTION_ALL); } if (!options.cropBoxResizable) { - $cropBox.find('.' + NAMESPACE + '-line,.' + NAMESPACE + '-point').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-line'), CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-point'), CLASS_HIDDEN); } - this.setDragMode(options.dragMode); this.render(); this.ready = true; + this.setDragMode(options.dragMode); + + if (options.autoCrop) { + this.crop(); + } + this.setData(options.data); - // Trigger the ready event asynchronously to keep `data('cropper')` is defined - this.completing = setTimeout(function () { - if ($.isFunction(options.ready)) { - $element.one(EVENT_READY, options.ready); - } + if (isFunction(options.ready)) { + addListener(element, EVENT_READY, options.ready, { + once: true + }); + } - _this3.trigger(EVENT_READY); - _this3.trigger(EVENT_CROP, _this3.getData()); - _this3.completed = true; - }, 0); + dispatchEvent(element, EVENT_READY); } }, { key: 'unbuild', @@ -3163,35 +3557,49 @@ var Cropper = function () { return; } - if (!this.completed) { - clearTimeout(this.completing); - } - this.ready = false; - this.completed = false; - this.initialImage = null; - - // Clear `initialCanvas` is necessary when replace - this.initialCanvas = null; - this.initialCropBox = null; - this.container = null; - this.canvas = null; - - // Clear `cropBox` is necessary when replace - this.cropBox = null; this.unbind(); - this.resetPreview(); - this.$preview = null; + this.cropper.parentNode.removeChild(this.cropper); + removeClass(this.element, CLASS_HIDDEN); + } + }, { + key: 'uncreate', + value: function uncreate() { + var element = this.element; + + + if (this.ready) { + this.unbuild(); + this.ready = false; + this.cropped = false; + } else if (this.sizing) { + this.sizingImage.onload = null; + this.sizing = false; + this.sized = false; + } else if (this.reloading) { + this.xhr.abort(); + } else if (this.isImg) { + if (element.complete) { + clearTimeout(this.timeout); + } else { + removeListener(element, EVENT_LOAD, this.onStart); + } + } else if (this.image) { + this.stop(); + } + } - this.$viewBox = null; - this.$cropBox = null; - this.$dragBox = null; - this.$canvas = null; - this.$container = null; + /** + * Get the no conflict cropper class. + * @returns {Cropper} The cropper class. + */ - this.$cropper.remove(); - this.$cropper = null; + }], [{ + key: 'noConflict', + value: function noConflict() { + window.Cropper = AnotherCropper; + return Cropper; } /** @@ -3199,21 +3607,20 @@ var Cropper = function () { * @param {Object} options - The new default options. */ - }], [{ + }, { key: 'setDefaults', value: function setDefaults(options) { - $.extend(DEFAULTS, $.isPlainObject(options) && options); + assign(DEFAULTS, isPlainObject(options) && options); } }]); return Cropper; }(); -if ($.extend) { - $.extend(Cropper.prototype, render, preview, events, handlers, change, methods); -} +assign(Cropper.prototype, render, preview, events, handlers, change, methods); if ($.fn) { - var AnotherCropper = $.fn.cropper; + var AnotherCropper$1 = $.fn.cropper; + var NAMESPACE$1 = 'cropper'; $.fn.cropper = function jQueryCropper(option) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { @@ -3224,35 +3631,44 @@ if ($.fn) { this.each(function (i, element) { var $element = $(element); - var data = $element.data(NAMESPACE); + var isDestroy = option === 'destroy'; + var cropper = $element.data(NAMESPACE$1); - if (!data) { - if (/destroy/.test(option)) { + if (!cropper) { + if (isDestroy) { return; } var options = $.extend({}, $element.data(), $.isPlainObject(option) && option); - data = new Cropper(element, options); - $element.data(NAMESPACE, data); + cropper = new Cropper(element, options); + $element.data(NAMESPACE$1, cropper); } - if (isString(option)) { - var fn = data[option]; + if (typeof option === 'string') { + var fn = cropper[option]; if ($.isFunction(fn)) { - result = fn.apply(data, args); + result = fn.apply(cropper, args); + + if (result === cropper) { + result = undefined; + } + + if (isDestroy) { + $element.removeData(NAMESPACE$1); + } } } }); - return isUndefined(result) ? this : result; + return typeof result === 'undefined' ? this : result; }; $.fn.cropper.Constructor = Cropper; $.fn.cropper.setDefaults = Cropper.setDefaults; $.fn.cropper.noConflict = function noConflict() { - $.fn.cropper = AnotherCropper; + $.fn.cropper = AnotherCropper$1; return this; }; } diff --git a/dist/cropper.min.css b/dist/cropper.min.css index edb229b0..16c98962 100644 --- a/dist/cropper.min.css +++ b/dist/cropper.min.css @@ -1,9 +1,9 @@ /*! - * Cropper v3.1.6 + * Cropper v4.0.0-alpha * https://github.com/fengyuanchen/cropper * * Copyright (c) 2014-2018 Chen Fengyuan * Released under the MIT license * - * Date: 2018-03-01T13:33:39.581Z + * Date: 2018-03-01T14:21:03.491Z */.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/dist/cropper.min.js b/dist/cropper.min.js index eeb0d70d..13b78377 100644 --- a/dist/cropper.min.js +++ b/dist/cropper.min.js @@ -1,10 +1,10 @@ /*! - * Cropper v3.1.6 + * Cropper v4.0.0-alpha * https://github.com/fengyuanchen/cropper * * Copyright (c) 2014-2018 Chen Fengyuan * Released under the MIT license * - * Date: 2018-03-01T13:33:48.179Z + * Date: 2018-03-01T14:21:13.980Z */ -!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],i):i(t.jQuery)}(this,function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var i="undefined"!=typeof window?window:{},e="cropper",a="all",n="crop",h="move",o="zoom",s="e",r="w",d="s",c="n",l="ne",p="nw",g="se",m="sw",u=e+"-crop",f=e+"-disabled",v=e+"-hidden",w=e+"-hide",x=e+"-modal",b=e+"-move",y="action",C="preview",M="crop",$="move",B="none",k="crop",W="cropend",D="cropmove",T="cropstart",Y="dblclick",H="error",X="load",O=i.PointerEvent?"pointerdown":"touchstart mousedown",E=i.PointerEvent?"pointermove":"touchmove mousemove",N=i.PointerEvent?"pointerup pointercancel":"touchend touchcancel mouseup",R="ready",z="resize",L="wheel mousewheel DOMMouseScroll",P="zoom",I=/^(e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/,U=/^data:/,A=/^data:image\/jpeg;base64,/,F=/^(img|canvas)$/i,j={viewMode:0,dragMode:M,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},S=function(t,i){if(!(t instanceof i))throw new TypeError("Cannot call a class as a function")},q=function(){function t(t,i){for(var e=0;e2?e-2:0),n=2;n1&&void 0!==arguments[1]?arguments[1]:1e11;return _.test(t)?Math.round(t*i)/i:t}var it=i.location,et=/^(https?:)\/\/([^:/?#]+):?(\d*)/i;function at(t){var i=t.match(et);return i&&(i[1]!==it.protocol||i[2]!==it.hostname||i[3]!==it.port)}function nt(t){var i="timestamp="+(new Date).getTime();return t+(-1===t.indexOf("?")?"?":"&")+i}function ht(t){var i=t.rotate,e=t.scaleX,a=t.scaleY,n=t.translateX,h=t.translateY,o=[];return Z(n)&&0!==n&&o.push("translateX("+n+"px)"),Z(h)&&0!==h&&o.push("translateY("+h+"px)"),Z(i)&&0!==i&&o.push("rotate("+i+"deg)"),Z(e)&&1!==e&&o.push("scaleX("+e+")"),Z(a)&&1!==a&&o.push("scaleY("+a+")"),o.length?o.join(" "):"none"}var ot=i.navigator,st=ot&&/(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(ot.userAgent);function rt(i,e){var a=i.pageX,n=i.pageY,h={endX:a,endY:n};return e?h:t.extend({startX:a,startY:n},h)}var dt=Number.isFinite||i.isFinite;function ct(t){var i=t.aspectRatio,e=t.height,a=t.width,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"contain",h=function(t){return dt(t)&&t>0};if(h(a)&&h(e)){var o=e*i;"contain"===n&&o>a||"cover"===n&&o=8&&(h=r+c)}}}if(h){var l=i.getUint16(h,a),p=void 0,g=void 0;for(g=0;gi.width?3===a?r=i.height*s:d=i.width/s:3===a?d=i.width/s:r=i.height*s;var c={aspectRatio:s,naturalWidth:h,naturalHeight:o,width:r,height:d};c.left=(i.width-r)/2,c.top=(i.height-d)/2,c.oldLeft=c.left,c.oldTop=c.top,this.canvas=c,this.limited=1===a||2===a,this.limitCanvas(!0,!0),this.initialImage=t.extend({},e),this.initialCanvas=t.extend({},c)},limitCanvas:function(t,i){var e=this.options,a=this.container,n=this.canvas,h=this.cropBox,o=e.viewMode,s=n.aspectRatio,r=this.cropped&&h;if(t){var d=Number(e.minCanvasWidth)||0,c=Number(e.minCanvasHeight)||0;o>0&&(o>1?(d=Math.max(d,a.width),c=Math.max(c,a.height),3===o&&(c*s>d?d=c*s:c=d/s)):d?d=Math.max(d,r?h.width:0):c?c=Math.max(c,r?h.height:0):r&&(d=h.width,(c=h.height)*s>d?d=c*s:c=d/s));var l=ct({aspectRatio:s,width:d,height:c});d=l.width,c=l.height,n.minWidth=d,n.minHeight=c,n.maxWidth=1/0,n.maxHeight=1/0}if(i)if(o>0){var p=a.width-n.width,g=a.height-n.height;n.minLeft=Math.min(0,p),n.minTop=Math.min(0,g),n.maxLeft=Math.max(0,p),n.maxTop=Math.max(0,g),r&&this.limited&&(n.minLeft=Math.min(h.left,h.left+h.width-n.width),n.minTop=Math.min(h.top,h.top+h.height-n.height),n.maxLeft=h.left,n.maxTop=h.top,2===o&&(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,g),n.maxTop=Math.max(0,g))))}else n.minLeft=-n.width,n.minTop=-n.height,n.maxLeft=a.width,n.maxTop=a.height},renderCanvas:function(t,i){var e=this.canvas,a=this.image;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,h=Math.sin(n),o=Math.cos(n),s=i*o+e*h,r=i*h+e*o;return a>90?{width:r,height:s}:{width:s,height:r}}({width:a.naturalWidth*Math.abs(a.scaleX||1),height:a.naturalHeight*Math.abs(a.scaleY||1),degree:a.rotate||0}),h=n.width,o=n.height,s=e.width*(h/e.naturalWidth),r=e.height*(o/e.naturalHeight);e.left-=(s-e.width)/2,e.top-=(r-e.height)/2,e.width=s,e.height=r,e.aspectRatio=h/o,e.naturalWidth=h,e.naturalHeight=o,this.limitCanvas(!0,!1)}(e.width>e.maxWidth||e.widthe.maxHeight||e.heighte.width?h.height=h.width/a:h.width=h.height*a),this.cropBox=h,this.limitCropBox(!0,!0),h.width=Math.min(Math.max(h.width,h.minWidth),h.maxWidth),h.height=Math.min(Math.max(h.height,h.minHeight),h.maxHeight),h.width=Math.max(h.minWidth,h.width*n),h.height=Math.max(h.minHeight,h.height*n),h.left=e.left+(e.width-h.width)/2,h.top=e.top+(e.height-h.height)/2,h.oldLeft=h.left,h.oldTop=h.top,this.initialCropBox=t.extend({},h)},limitCropBox:function(t,i){var e=this.options,a=this.container,n=this.canvas,h=this.cropBox,o=this.limited,s=e.aspectRatio;if(t){var r=Number(e.minCropBoxWidth)||0,d=Number(e.minCropBoxHeight)||0,c=Math.min(a.width,o?n.width:a.width),l=Math.min(a.height,o?n.height:a.height);r=Math.min(r,a.width),d=Math.min(d,a.height),s&&(r&&d?d*s>r?d=r/s:r=d*s:r?d=r/s:d&&(r=d*s),l*s>c?l=c/s:c=l*s),h.minWidth=Math.min(r,c),h.minHeight=Math.min(d,l),h.maxWidth=c,h.maxHeight=l}i&&(o?(h.minLeft=Math.max(0,n.left),h.minTop=Math.max(0,n.top),h.maxLeft=Math.min(a.width,n.left+n.width)-h.width,h.maxTop=Math.min(a.height,n.top+n.height)-h.height):(h.minLeft=0,h.minTop=0,h.maxLeft=a.width-h.width,h.maxTop=a.height-h.height))},renderCropBox:function(){var t=this.options,i=this.container,e=this.cropBox;(e.width>e.maxWidth||e.widthe.maxHeight||e.height=i.width&&e.height>=i.height?h:a),this.$cropBox.css({width:e.width,height:e.height,transform:ht({translateX:e.left,translateY:e.top})}),this.cropped&&this.limited&&this.limitCanvas(!0,!0),this.disabled||this.output()},output:function(){this.preview(),this.completed&&this.trigger(k,this.getData())}},ut={initPreview:function(){var i=this.crossOrigin,e=i?this.crossOriginUrl:this.url,a=document.createElement("img");i&&(a.crossOrigin=i),a.src=e;var n=t(a);this.$preview=t(this.options.preview),this.$clone2=n,this.$viewBox.html(n),this.$preview.each(function(a,n){var h=t(n),o=document.createElement("img");h.data(C,{width:h.width(),height:h.height(),html:h.html()}),i&&(o.crossOrigin=i),o.src=e,o.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;"',h.html(o)})},resetPreview:function(){this.$preview.each(function(i,e){var a=t(e),n=a.data(C);a.css({width:n.width,height:n.height}).html(n.html).removeData(C)})},preview:function(){var i=this.image,e=this.canvas,a=this.cropBox,n=a.width,h=a.height,o=i.width,s=i.height,r=a.left-e.left-i.left,d=a.top-e.top-i.top;this.cropped&&!this.disabled&&(this.$clone2.css({width:o,height:s,transform:ht(t.extend({translateX:-r,translateY:-d},i))}),this.$preview.each(function(e,a){var c=t(a),l=c.data(C),p=l.width,g=l.height,m=p,u=g,f=1;n&&(u=h*(f=p/n)),h&&u>g&&(m=n*(f=g/h),u=g),c.css({width:m,height:u}).find("img").css({width:o*f,height:s*f,transform:ht(t.extend({translateX:-r*f,translateY:-d*f},i))})}))}},ft={bind:function(){var i=this.$element,e=this.options,a=this.$cropper;t.isFunction(e.cropstart)&&i.on(T,e.cropstart),t.isFunction(e.cropmove)&&i.on(D,e.cropmove),t.isFunction(e.cropend)&&i.on(W,e.cropend),t.isFunction(e.crop)&&i.on(k,e.crop),t.isFunction(e.zoom)&&i.on(P,e.zoom),a.on(O,G(this.cropStart,this)),e.zoomable&&e.zoomOnWheel&&a.on(L,G(this.wheel,this)),e.toggleDragModeOnDblclick&&a.on(Y,G(this.dblclick,this)),t(this.element.ownerDocument).on(E,this.onCropMove=G(this.cropMove,this)).on(N,this.onCropEnd=G(this.cropEnd,this)),e.responsive&&t(window).on(z,this.onResize=G(this.resize,this))},unbind:function(){var i=this.$element,e=this.options,a=this.$cropper;t.isFunction(e.cropstart)&&i.off(T,e.cropstart),t.isFunction(e.cropmove)&&i.off(D,e.cropmove),t.isFunction(e.cropend)&&i.off(W,e.cropend),t.isFunction(e.crop)&&i.off(k,e.crop),t.isFunction(e.zoom)&&i.off(P,e.zoom),a.off(O,this.cropStart),e.zoomable&&e.zoomOnWheel&&a.off(L,this.wheel),e.toggleDragModeOnDblclick&&a.off(Y,this.dblclick),t(this.element.ownerDocument).off(E,this.onCropMove).off(N,this.onCropEnd),e.responsive&&t(window).off(z,this.onResize)}},vt={resize:function(){var i=this.options,e=this.$container,a=this.container,n=Number(i.minContainerWidth)||200,h=Number(i.minContainerHeight)||100;if(!(this.disabled||a.width<=n||a.height<=h)){var o=e.width()/a.width;if(1!==o||e.height()!==a.height){var s=void 0,r=void 0;i.restore&&(s=this.getCanvasData(),r=this.getCropBoxData()),this.render(),i.restore&&(this.setCanvasData(t.each(s,function(t,i){s[t]=i*o})),this.setCropBoxData(t.each(r,function(t,i){r[t]=i*o})))}}},dblclick:function(){this.disabled||this.options.dragMode===B||this.setDragMode(this.$dragBox.hasClass(u)?$:M)},wheel:function(t){var i=this,e=t.originalEvent||t,a=Number(this.options.wheelZoomRatio)||.1;if(!this.disabled&&(t.preventDefault(),!this.wheeling)){this.wheeling=!0,setTimeout(function(){i.wheeling=!1},50);var n=1;e.deltaY?n=e.deltaY>0?1:-1:e.wheelDelta?n=-e.wheelDelta/120:e.detail&&(n=e.detail>0?1:-1),this.zoom(-n*a,t)}},cropStart:function(i){if(!this.disabled){var e=this.options,a=this.pointers,h=i.originalEvent,s=void 0;h&&h.changedTouches?t.each(h.changedTouches,function(t,i){a[i.identifier]=rt(i)}):a[h&&h.pointerId||0]=rt(h||i),s=J(a).length>1&&e.zoomable&&e.zoomOnTouch?o:t(i.target).data(y),I.test(s)&&(this.trigger(T,{originalEvent:h,action:s}).isDefaultPrevented()||(i.preventDefault(),this.action=s,this.cropping=!1,s===n&&(this.cropping=!0,this.$dragBox.addClass(x))))}},cropMove:function(i){var e=this.action;if(!this.disabled&&e){var a=this.pointers,n=i.originalEvent;i.preventDefault(),this.trigger(D,{originalEvent:n,action:e}).isDefaultPrevented()||(n&&n.changedTouches?t.each(n.changedTouches,function(i,e){t.extend(a[e.identifier],rt(e,!0))}):t.extend(a[n&&n.pointerId||0],rt(n||i,!0)),this.change(i))}},cropEnd:function(i){if(!this.disabled){var e=this.action,a=this.pointers,n=i.originalEvent;n&&n.changedTouches?t.each(n.changedTouches,function(t,i){delete a[i.identifier]}):delete a[n&&n.pointerId||0],e&&(i.preventDefault(),J(a).length||(this.action=""),this.cropping&&(this.cropping=!1,this.$dragBox.toggleClass(x,this.cropped&&this.options.modal)),this.trigger(W,{originalEvent:n,action:e}))}}},wt={change:function(i){var e=this.options,u=this.pointers,f=this.container,w=this.canvas,x=this.cropBox,b=this.action,y=e.aspectRatio,C=x.left,M=x.top,$=x.width,B=x.height,k=C+$,W=M+B,D=0,T=0,Y=f.width,H=f.height,X=!0,O=void 0;!y&&i.shiftKey&&(y=$&&B?$/B:1),this.limited&&(D=x.minLeft,T=x.minTop,Y=D+Math.min(f.width,w.width,w.left+w.width),H=T+Math.min(f.height,w.height,w.top+w.height));var E,N,R,z=u[J(u)[0]],L={x:z.endX-z.startX,y:z.endY-z.startY},P=function(t){switch(t){case s:k+L.x>Y&&(L.x=Y-k);break;case r:C+L.xH&&(L.y=H-W)}};switch(b){case a:C+=L.x,M+=L.y;break;case s:if(L.x>=0&&(k>=Y||y&&(M<=T||W>=H))){X=!1;break}P(s),$+=L.x,y&&(B=$/y,M-=L.x/y/2),$<0&&(b=r,$=0);break;case c:if(L.y<=0&&(M<=T||y&&(C<=D||k>=Y))){X=!1;break}P(c),B-=L.y,M+=L.y,y&&($=B*y,C+=L.y*y/2),B<0&&(b=d,B=0);break;case r:if(L.x<=0&&(C<=D||y&&(M<=T||W>=H))){X=!1;break}P(r),$-=L.x,C+=L.x,y&&(B=$/y,M+=L.x/y/2),$<0&&(b=s,$=0);break;case d:if(L.y>=0&&(W>=H||y&&(C<=D||k>=Y))){X=!1;break}P(d),B+=L.y,y&&($=B*y,C-=L.y*y/2),B<0&&(b=c,B=0);break;case l:if(y){if(L.y<=0&&(M<=T||k>=Y)){X=!1;break}P(c),B-=L.y,M+=L.y,$=B*y}else P(c),P(s),L.x>=0?kT&&(B-=L.y,M+=L.y):(B-=L.y,M+=L.y);$<0&&B<0?(b=m,B=0,$=0):$<0?(b=p,$=0):B<0&&(b=g,B=0);break;case p:if(y){if(L.y<=0&&(M<=T||C<=D)){X=!1;break}P(c),B-=L.y,M+=L.y,$=B*y,C+=L.y*y}else P(c),P(r),L.x<=0?C>D?($-=L.x,C+=L.x):L.y<=0&&M<=T&&(X=!1):($-=L.x,C+=L.x),L.y<=0?M>T&&(B-=L.y,M+=L.y):(B-=L.y,M+=L.y);$<0&&B<0?(b=g,B=0,$=0):$<0?(b=l,$=0):B<0&&(b=m,B=0);break;case m:if(y){if(L.x<=0&&(C<=D||W>=H)){X=!1;break}P(r),$-=L.x,C+=L.x,B=$/y}else P(d),P(r),L.x<=0?C>D?($-=L.x,C+=L.x):L.y>=0&&W>=H&&(X=!1):($-=L.x,C+=L.x),L.y>=0?W=0&&(k>=Y||W>=H)){X=!1;break}P(s),B=($+=L.x)/y}else P(d),P(s),L.x>=0?k=0&&W>=H&&(X=!1):$+=L.x,L.y>=0?W0?b=L.y>0?g:l:L.x<0&&(C-=$,b=L.y>0?m:p),L.y<0&&(M-=B),this.cropped||(this.$cropBox.removeClass(v),this.cropped=!0,this.limited&&this.limitCropBox(!0,!0))}X&&(x.width=$,x.height=B,x.left=C,x.top=M,this.action=b,this.renderCropBox()),t.each(u,function(t,i){i.startX=i.endX,i.startY=i.endY})}},xt={crop:function(){this.ready&&!this.disabled&&(this.cropped||(this.cropped=!0,this.limitCropBox(!0,!0),this.options.modal&&this.$dragBox.addClass(x),this.$cropBox.removeClass(v)),this.setCropBoxData(this.initialCropBox))},reset:function(){this.ready&&!this.disabled&&(this.image=t.extend({},this.initialImage),this.canvas=t.extend({},this.initialCanvas),this.cropBox=t.extend({},this.initialCropBox),this.renderCanvas(),this.cropped&&this.renderCropBox())},clear:function(){this.cropped&&!this.disabled&&(t.extend(this.cropBox,{left:0,top:0,width:0,height:0}),this.cropped=!1,this.renderCropBox(),this.limitCanvas(!0,!0),this.renderCanvas(),this.$dragBox.removeClass(x),this.$cropBox.addClass(v))},replace:function(t,i){!this.disabled&&t&&(this.isImg&&this.$element.attr("src",t),i?(this.url=t,this.$clone.attr("src",t),this.ready&&this.$preview.find("img").add(this.$clone2).attr("src",t)):(this.isImg&&(this.replaced=!0),this.options.data=null,this.load(t)))},enable:function(){this.ready&&(this.disabled=!1,this.$cropper.removeClass(f))},disable:function(){this.ready&&(this.disabled=!0,this.$cropper.addClass(f))},destroy:function(){var t=this.$element;this.loaded?(this.isImg&&this.replaced&&t.attr("src",this.originalUrl),this.unbuild(),t.removeClass(v)):this.isImg?t.off(X,this.start):this.$clone&&this.$clone.remove(),t.removeData(e)},move:function(t,i){var e=this.canvas,a=e.left,n=e.top;this.moveTo(V(t)?t:a+Number(t),V(i)?i:n+Number(i))},moveTo:function(t,i){var e=this.canvas,a=!1;V(i)&&(i=t),t=Number(t),i=Number(i),this.ready&&!this.disabled&&this.options.movable&&(Z(t)&&(e.left=t,a=!0),Z(i)&&(e.top=i,a=!0),a&&this.renderCanvas(!0))},zoom:function(t,i){var e=this.canvas;t=(t=Number(t))<0?1/(1-t):1+t,this.zoomTo(e.width*t/e.naturalWidth,i)},zoomTo:function(i,e){var a,n,h,o,s=this.options,r=this.pointers,d=this.canvas,c=d.width,l=d.height,p=d.naturalWidth,g=d.naturalHeight;if((i=Number(i))>=0&&this.ready&&!this.disabled&&s.zoomable){var m=p*i,u=g*i,f=void 0;if(e&&(f=e.originalEvent),this.trigger(P,{originalEvent:f,oldRatio:c/p,ratio:m/p}).isDefaultPrevented())return;if(f){var v=this.$cropper.offset(),w=r&&J(r).length?(a=r,n=0,h=0,o=0,t.each(a,function(t,i){var e=i.startX,a=i.startY;n+=e,h+=a,o+=1}),{pageX:n/=o,pageY:h/=o}):{pageX:e.pageX||f.pageX||0,pageY:e.pageY||f.pageY||0};d.left-=(m-c)*((w.pageX-v.left-d.left)/c),d.top-=(u-l)*((w.pageY-v.top-d.top)/l)}else d.left-=(m-c)/2,d.top-=(u-l)/2;d.width=m,d.height=u,this.renderCanvas(!0)}},rotate:function(t){this.rotateTo((this.image.rotate||0)+Number(t))},rotateTo:function(t){Z(t=Number(t))&&this.ready&&!this.disabled&&this.options.rotatable&&(this.image.rotate=t%360,this.renderCanvas(!0,!0))},scaleX:function(t){var i=this.image.scaleY;this.scale(t,Z(i)?i:1)},scaleY:function(t){var i=this.image.scaleX;this.scale(Z(i)?i:1,t)},scale:function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t,e=this.image,a=!1;t=Number(t),i=Number(i),this.ready&&!this.disabled&&this.options.scalable&&(Z(t)&&(e.scaleX=t,a=!0),Z(i)&&(e.scaleY=i,a=!0),a&&this.renderCanvas(!0,!0))},getData:function(){var i=arguments.length>0&&void 0!==arguments[0]&&arguments[0],e=this.options,a=this.image,n=this.canvas,h=this.cropBox,o=void 0;if(this.ready&&this.cropped){o={x:h.left-n.left,y:h.top-n.top,width:h.width,height:h.height};var s=a.width/a.naturalWidth;t.each(o,function(t,e){e/=s,o[t]=i?Math.round(e):e})}else o={x:0,y:0,width:0,height:0};return e.rotatable&&(o.rotate=a.rotate||0),e.scalable&&(o.scaleX=a.scaleX||1,o.scaleY=a.scaleY||1),o},setData:function(i){var e=this.options,a=this.image,n=this.canvas,h={};if(t.isFunction(i)&&(i=i.call(this.element)),this.ready&&!this.disabled&&t.isPlainObject(i)){var o=!1;e.rotatable&&Z(i.rotate)&&i.rotate!==a.rotate&&(a.rotate=i.rotate,o=!0),e.scalable&&(Z(i.scaleX)&&i.scaleX!==a.scaleX&&(a.scaleX=i.scaleX,o=!0),Z(i.scaleY)&&i.scaleY!==a.scaleY&&(a.scaleY=i.scaleY,o=!0)),o&&this.renderCanvas(!0,!0);var s=a.width/a.naturalWidth;Z(i.x)&&(h.left=i.x*s+n.left),Z(i.y)&&(h.top=i.y*s+n.top),Z(i.width)&&(h.width=i.width*s),Z(i.height)&&(h.height=i.height*s),this.setCropBoxData(h)}},getContainerData:function(){return this.ready?t.extend({},this.container):{}},getImageData:function(){return this.loaded?t.extend({},this.image):{}},getCanvasData:function(){var i=this.canvas,e={};return this.ready&&t.each(["left","top","width","height","naturalWidth","naturalHeight"],function(t,a){e[a]=i[a]}),e},setCanvasData:function(i){var e=this.canvas,a=e.aspectRatio;t.isFunction(i)&&(i=i.call(this.$element)),this.ready&&!this.disabled&&t.isPlainObject(i)&&(Z(i.left)&&(e.left=i.left),Z(i.top)&&(e.top=i.top),Z(i.width)?(e.width=i.width,e.height=i.width/a):Z(i.height)&&(e.height=i.height,e.width=i.height*a),this.renderCanvas(!0))},getCropBoxData:function(){var t=this.cropBox;return this.ready&&this.cropped?{left:t.left,top:t.top,width:t.width,height:t.height}:{}},setCropBoxData:function(i){var e=this.cropBox,a=this.options.aspectRatio,n=void 0,h=void 0;t.isFunction(i)&&(i=i.call(this.$element)),this.ready&&this.cropped&&!this.disabled&&t.isPlainObject(i)&&(Z(i.left)&&(e.left=i.left),Z(i.top)&&(e.top=i.top),Z(i.width)&&i.width!==e.width&&(n=!0,e.width=i.width),Z(i.height)&&i.height!==e.height&&(h=!0,e.height=i.height),a&&(n?e.height=e.width/a:h&&(e.width=e.height*a)),this.renderCropBox())},getCroppedCanvas:function(){var i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!this.ready||!window.HTMLCanvasElement)return null;var e,a,n,h,o,s,r,d,c,l,p,g,m,u,f,v,w,x,b,y,C,M,$,B,k,W,D,T,Y,H,X,O,E,N,R=this.canvas,z=(e=this.$clone[0],a=this.image,n=R,h=i,o=a.rotate,s=void 0===o?0:o,r=a.scaleX,d=void 0===r?1:r,c=a.scaleY,l=void 0===c?1:c,p=n.aspectRatio,g=n.naturalWidth,m=n.naturalHeight,u=h.fillColor,f=void 0===u?"transparent":u,v=h.imageSmoothingEnabled,w=void 0===v||v,x=h.imageSmoothingQuality,b=void 0===x?"low":x,y=h.maxWidth,C=void 0===y?1/0:y,M=h.maxHeight,$=void 0===M?1/0:M,B=h.minWidth,k=void 0===B?0:B,W=h.minHeight,D=void 0===W?0:W,T=document.createElement("canvas"),Y=T.getContext("2d"),H=ct({aspectRatio:p,width:C,height:$}),X=ct({aspectRatio:p,width:k,height:D},"cover"),O=Math.min(H.width,Math.max(X.width,g)),E=Math.min(H.height,Math.max(X.height,m)),N=[-O/2,-E/2,O,E],T.width=tt(O),T.height=tt(E),Y.fillStyle=f,Y.fillRect(0,0,O,E),Y.save(),Y.translate(O/2,E/2),Y.rotate(s*Math.PI/180),Y.scale(d,l),Y.imageSmoothingEnabled=w,Y.imageSmoothingQuality=b,Y.drawImage.apply(Y,[e].concat(Q(t.map(N,function(t){return Math.floor(tt(t))})))),Y.restore(),T);if(!this.cropped)return z;var L=this.getData(),P=L.x,I=L.y,U=L.width,A=L.height,F=z.width/Math.floor(R.naturalWidth);1!==F&&(P*=F,I*=F,U*=F,A*=F);var j=U/A,S=ct({aspectRatio:j,width:i.maxWidth||1/0,height:i.maxHeight||1/0}),q=ct({aspectRatio:j,width:i.minWidth||0,height:i.minHeight||0},"cover"),K=ct({aspectRatio:j,width:i.width||(1!==F?z.width:U),height:i.height||(1!==F?z.height:A)}),Z=K.width,V=K.height;Z=Math.min(S.width,Math.max(q.width,Z)),V=Math.min(S.height,Math.max(q.height,V));var G=document.createElement("canvas"),J=G.getContext("2d");G.width=tt(Z),G.height=tt(V),J.fillStyle=i.fillColor||"transparent",J.fillRect(0,0,Z,V);var _=i.imageSmoothingEnabled,it=void 0===_||_,et=i.imageSmoothingQuality;J.imageSmoothingEnabled=it,et&&(J.imageSmoothingQuality=et);var at=z.width,nt=z.height,ht=P,ot=I,st=void 0,rt=void 0,dt=void 0,lt=void 0,pt=void 0,gt=void 0;ht<=-U||ht>at?(ht=0,st=0,dt=0,pt=0):ht<=0?(dt=-ht,ht=0,pt=st=Math.min(at,U+ht)):ht<=at&&(dt=0,pt=st=Math.min(U,at-ht)),st<=0||ot<=-A||ot>nt?(ot=0,rt=0,lt=0,gt=0):ot<=0?(lt=-ot,ot=0,gt=rt=Math.min(nt,A+ot)):ot<=nt&&(lt=0,gt=rt=Math.min(A,nt-ot));var mt=[ht,ot,st,rt];if(pt>0&>>0){var ut=Z/U;mt.push(dt*ut,lt*ut,pt*ut,gt*ut)}return J.drawImage.apply(J,[z].concat(Q(t.map(mt,function(t){return Math.floor(tt(t))})))),G},setAspectRatio:function(t){var i=this.options;this.disabled||V(t)||(i.aspectRatio=Math.max(0,t)||NaN,this.ready&&(this.initCropBox(),this.cropped&&this.renderCropBox()))},setDragMode:function(t){var i=this.options,e=void 0,a=void 0;this.loaded&&!this.disabled&&(e=t===M,a=i.movable&&t===$,t=e||a?t:B,this.$dragBox.data(y,t).toggleClass(u,e).toggleClass(b,a),i.cropBoxMovable||this.$face.data(y,t).toggleClass(u,e).toggleClass(b,a))}},bt=function(){function i(e){var a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(S(this,i),!e||!F.test(e.tagName))throw new Error("The first argument is required and must be an or element.");this.element=e,this.$element=t(e),this.options=t.extend({},j,t.isPlainObject(a)&&a),this.completed=!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.canvas=null,this.cropBox=null,this.pointers={},this.init()}return q(i,[{key:"init",value:function(){var t=this.$element,i=void 0;if(t.is("img")){if(this.isImg=!0,i=t.attr("src")||"",this.originalUrl=i,!i)return;i=t.prop("src")}else t.is("canvas")&&window.HTMLCanvasElement&&(i=t[0].toDataURL());this.load(i)}},{key:"trigger",value:function(i,e){var a=t.Event(i,e);return this.$element.trigger(a),a}},{key:"load",value:function(i){var e=this;if(i){this.url=i,this.image={};var a=this.$element,n=this.options;if(n.checkOrientation&&window.ArrayBuffer)if(U.test(i))A.test(i)?this.read((h=i.replace(pt,""),o=atob(h),s=new ArrayBuffer(o.length),r=new Uint8Array(s),t.each(r,function(t){r[t]=o.charCodeAt(t)}),s)):this.clone();else{var h,o,s,r,d=new XMLHttpRequest;d.onerror=function(){e.clone()},d.onload=function(){e.read(d.response)},n.checkCrossOrigin&&at(i)&&!a.prop("crossOrigin")&&(i=nt(i)),d.open("get",i),d.responseType="arraybuffer",d.withCredentials="use-credentials"===a.prop("crossOrigin"),d.send()}else this.clone()}}},{key:"read",value:function(i){var e,a,n,h=this.options,o=this.image,s=gt(i),r=0,d=1,c=1;if(s>1){this.url=(e="image/jpeg",a=new Uint8Array(i),n="",t.each(a,function(t,i){n+=lt(i)}),"data:"+e+";base64,"+btoa(n));var l=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}}(s);r=l.rotate,d=l.scaleX,c=l.scaleY}h.rotatable&&(o.rotate=r),h.scalable&&(o.scaleX=d,o.scaleY=c),this.clone()}},{key:"clone",value:function(){var i=this.$element,e=this.options,a=this.url,n="",h=void 0;e.checkCrossOrigin&&at(a)&&((n=i.prop("crossOrigin"))?h=a:(n="anonymous",h=nt(a))),this.crossOrigin=n,this.crossOriginUrl=h;var o=document.createElement("img");n&&(o.crossOrigin=n),o.src=h||a;var s=t(o);this.$clone=s,this.isImg?this.element.complete?this.start():i.one(X,t.proxy(this.start,this)):s.one(X,t.proxy(this.start,this)).one(H,t.proxy(this.stop,this)).addClass(w).insertAfter(i)}},{key:"start",value:function(){var i=this,e=this.$clone,a=this.$element;this.isImg||(e.off(H,this.stop),a=e),function(t,i){if(!t.naturalWidth||st){var e=document.createElement("img");e.onload=function(){i(e.width,e.height)},e.src=t.src}else i(t.naturalWidth,t.naturalHeight)}(a[0],function(e,a){t.extend(i.image,{naturalWidth:e,naturalHeight:a,aspectRatio:e/a}),i.loaded=!0,i.build()})}},{key:"stop",value:function(){this.$clone.remove(),this.$clone=null}},{key:"build",value:function(){var i=this;if(this.loaded){this.ready&&this.unbuild();var n=this.$element,h=this.options,o=this.$clone,s=t('
'),r=s.find("."+e+"-crop-box"),d=r.find("."+e+"-face");this.$container=n.parent(),this.$cropper=s,this.$canvas=s.find("."+e+"-canvas").append(o),this.$dragBox=s.find("."+e+"-drag-box"),this.$cropBox=r,this.$viewBox=s.find("."+e+"-view-box"),this.$face=d,n.addClass(v).after(s),this.isImg||o.removeClass(w),this.initPreview(),this.bind(),h.aspectRatio=Math.max(0,h.aspectRatio)||NaN,h.viewMode=Math.max(0,Math.min(3,Math.round(h.viewMode)))||0,this.cropped=h.autoCrop,h.autoCrop?h.modal&&this.$dragBox.addClass(x):r.addClass(v),h.guides||r.find("."+e+"-dashed").addClass(v),h.center||r.find("."+e+"-center").addClass(v),h.cropBoxMovable&&d.addClass(b).data(y,a),h.highlight||d.addClass("cropper-invisible"),h.background&&s.addClass(e+"-bg"),h.cropBoxResizable||r.find("."+e+"-line,."+e+"-point").addClass(v),this.setDragMode(h.dragMode),this.render(),this.ready=!0,this.setData(h.data),this.completing=setTimeout(function(){t.isFunction(h.ready)&&n.one(R,h.ready),i.trigger(R),i.trigger(k,i.getData()),i.completed=!0},0)}}},{key:"unbuild",value:function(){this.ready&&(this.completed||clearTimeout(this.completing),this.ready=!1,this.completed=!1,this.initialImage=null,this.initialCanvas=null,this.initialCropBox=null,this.container=null,this.canvas=null,this.cropBox=null,this.unbind(),this.resetPreview(),this.$preview=null,this.$viewBox=null,this.$cropBox=null,this.$dragBox=null,this.$canvas=null,this.$container=null,this.$cropper.remove(),this.$cropper=null)}}],[{key:"setDefaults",value:function(i){t.extend(j,t.isPlainObject(i)&&i)}}]),i}();if(t.extend&&t.extend(bt.prototype,mt,ut,ft,vt,wt,xt),t.fn){var yt=t.fn.cropper;t.fn.cropper=function(i){for(var a=arguments.length,n=Array(a>1?a-1:0),h=1;h1?i-1:0),a=1;a0&&e.forEach(function(i){G(i)&&Object.keys(i).forEach(function(e){t[e]=i[e]})}),t},at=/\.\d*(?:0|9){12}\d*$/i;function nt(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1e11;return at.test(t)?Math.round(t*i)/i:t}var ot=/^(?:width|height|left|top|marginLeft|marginTop)$/;function ht(t,i){var e=t.style;it(i,function(t,i){ot.test(i)&&K(t)&&(t+="px"),e[i]=t})}function rt(t,i){if(i)if(K(t.length))it(t,function(t){rt(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 st(t,i){i&&(K(t.length)?it(t,function(t){st(t,i)}):t.classList?t.classList.remove(i):t.className.indexOf(i)>=0&&(t.className=t.className.replace(i,"")))}function ct(t,i,e){i&&(K(t.length)?it(t,function(t){ct(t,i,e)}):e?rt(t,i):st(t,i))}var dt=/([a-z\d])([A-Z])/g;function lt(t){return t.replace(dt,"$1-$2").toLowerCase()}function pt(t,i){return G(t[i])?t[i]:t.dataset?t.dataset[i]:t.getAttribute("data-"+lt(i))}function mt(t,i,e){G(e)?t[i]=e:t.dataset?t.dataset[i]=e:t.setAttribute("data-"+lt(i),e)}function ut(t,i){if(G(t[i]))try{delete t[i]}catch(e){t[i]=void 0}else if(t.dataset)try{delete t.dataset[i]}catch(e){t.dataset[i]=void 0}else t.removeAttribute("data-"+lt(i))}var gt=/\s\s*/;function ft(t,i,e){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};it(i.trim().split(gt),function(i){t.removeEventListener(i,e,a)})}function vt(t,i,e){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(a.once){var n=e;e=function(){for(var o=arguments.length,h=Array(o),r=0;r1&&void 0!==arguments[1]?arguments[1]:"contain",o=function(t){return kt(t)&&t>0};if(o(a)&&o(e)){var h=e*i;"contain"===n&&h>a||"cover"===n&&h=8&&(o=s+d)}}}if(o){var l=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=et({},i),this.initialCanvasData=et({},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,d=Number(e.minCanvasHeight)||0;h>1?(c=Math.max(c,a.width),d=Math.max(d,a.height),3===h&&(d*r>c?c=d*r:d=c/r)):h>0&&(c?c=Math.max(c,s?o.width:0):d?d=Math.max(d,s?o.height:0):s&&(c=o.width,(d=o.height)*r>c?c=d*r:d=c/r));var l=Tt({aspectRatio:r,width:c,height:d});c=l.width,d=l.height,n.minWidth=c,n.minHeight=d,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=et({},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,d=Math.min(a.width,h?n.width:a.width),l=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),l*r>d?l=d/r:d=l*r),o.minWidth=Math.min(s,d),o.minHeight=Math.min(c,l),o.maxWidth=d,o.maxHeight=l}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?o:a),ht(this.cropBox,et({width:e.width,height:e.height},Dt({translateX:e.left,translateY:e.top}))),this.cropped&&this.limited&&this.limitCanvas(!0,!0),this.disabled||this.output()},output:function(){this.preview(),wt(this.element,k,this.getData())}},zt={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.viewBoxImage=a,i){var n=i;"string"==typeof i?n=this.element.ownerDocument.querySelectorAll(i):i.querySelector&&(n=[i]),this.previews=n,it(n,function(i){var a=document.createElement("img");mt(i,M,{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;"',i.innerHTML="",i.appendChild(a)})}},resetPreview:function(){it(this.previews,function(t){var i=pt(t,M);ht(t,{width:i.width,height:i.height}),t.innerHTML=i.html,ut(t,M)})},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&&(ht(this.viewBoxImage,et({width:o,height:h},Dt(et({translateX:-r,translateY:-s},t)))),it(this.previews,function(i){var e=pt(i,M),c=e.width,d=e.height,l=c,p=d,m=1;a&&(p=n*(m=c/a)),n&&p>d&&(l=a*(m=d/n),p=d),ht(i,{width:l,height:p}),ht(i.getElementsByTagName("img")[0],et({width:o*m,height:h*m},Dt(et({translateX:-r*m,translateY:-s*m},t))))}))}},Lt={bind:function(){var t=this.element,i=this.options,e=this.cropper;tt(i.cropstart)&&vt(t,N,i.cropstart),tt(i.cropmove)&&vt(t,W,i.cropmove),tt(i.cropend)&&vt(t,T,i.cropend),tt(i.crop)&&vt(t,k,i.crop),tt(i.zoom)&&vt(t,S,i.zoom),vt(e,z,this.onCropStart=this.cropStart.bind(this)),i.zoomable&&i.zoomOnWheel&&vt(e,R,this.onWheel=this.wheel.bind(this)),i.toggleDragModeOnDblclick&&vt(e,H,this.onDblclick=this.dblclick.bind(this)),vt(t.ownerDocument,L,this.onCropMove=this.cropMove.bind(this)),vt(t.ownerDocument,Y,this.onCropEnd=this.cropEnd.bind(this)),i.responsive&&vt(window,X,this.onResize=this.resize.bind(this))},unbind:function(){var t=this.element,i=this.options,e=this.cropper;tt(i.cropstart)&&ft(t,N,i.cropstart),tt(i.cropmove)&&ft(t,W,i.cropmove),tt(i.cropend)&&ft(t,T,i.cropend),tt(i.crop)&&ft(t,k,i.crop),tt(i.zoom)&&ft(t,S,i.zoom),ft(e,z,this.onCropStart),i.zoomable&&i.zoomOnWheel&&ft(e,R,this.onWheel),i.toggleDragModeOnDblclick&&ft(e,H,this.onDblclick),ft(t.ownerDocument,L,this.onCropMove),ft(t.ownerDocument,Y,this.onCropEnd),i.responsive&&ft(window,X,this.onResize)}},Yt={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(it(h,function(t,i){h[i]=t*o})),this.setCropBoxData(it(r,function(t,i){r[i]=t*o})))}}},dblclick:function(){var t,i;this.disabled||this.options.dragMode===B||this.setDragMode((t=this.dragBox,i=g,(t.classList?t.classList.contains(i):t.className.indexOf(i)>-1)?D:C))},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?it(t.changedTouches,function(t){e[t.identifier]=Bt(t)}):e[t.pointerId||0]=Bt(t),a=Object.keys(e).length>1&&i.zoomable&&i.zoomOnTouch?h:pt(t.target,y),A.test(a)&&!1!==wt(this.element,N,{originalEvent:t,action:a})&&(t.preventDefault(),this.action=a,this.cropping=!1,a===n&&(this.cropping=!0,rt(this.dragBox,b)))}},cropMove:function(t){var i=this.action;if(!this.disabled&&i){var e=this.pointers;t.preventDefault(),!1!==wt(this.element,W,{originalEvent:t,action:i})&&(t.changedTouches?it(t.changedTouches,function(t){et(e[t.identifier],Bt(t,!0))}):et(e[t.pointerId||0],Bt(t,!0)),this.change(t))}},cropEnd:function(t){if(!this.disabled){var i=this.action,e=this.pointers;t.changedTouches?it(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,ct(this.dragBox,b,this.cropped&&this.options.modal)),wt(this.element,T,{originalEvent:t,action:i}))}}},Ot={change:function(t){var i=this.options,e=this.canvasData,g=this.containerData,f=this.cropBoxData,w=this.pointers,b=this.action,x=i.aspectRatio,y=f.left,M=f.top,C=f.width,D=f.height,B=y+C,k=M+D,T=0,W=0,N=g.width,H=g.height,E=!0,z=void 0;!x&&t.shiftKey&&(x=C&&D?C/D:1),this.limited&&(T=f.minLeft,W=f.minTop,N=T+Math.min(g.width,e.width,e.left+e.width),H=W+Math.min(g.height,e.height,e.top+e.height));var L,Y,O,X=w[Object.keys(w)[0]],R={x:X.endX-X.startX,y:X.endY-X.startY},S=function(t){switch(t){case r:B+R.x>N&&(R.x=N-B);break;case s:y+R.xH&&(R.y=H-k)}};switch(b){case a:y+=R.x,M+=R.y;break;case r:if(R.x>=0&&(B>=N||x&&(M<=W||k>=H))){E=!1;break}S(r),C+=R.x,x&&(D=C/x,M-=R.x/x/2),C<0&&(b=s,C=0);break;case d:if(R.y<=0&&(M<=W||x&&(y<=T||B>=N))){E=!1;break}S(d),D-=R.y,M+=R.y,x&&(C=D*x,y+=R.y*x/2),D<0&&(b=c,D=0);break;case s:if(R.x<=0&&(y<=T||x&&(M<=W||k>=H))){E=!1;break}S(s),C-=R.x,y+=R.x,x&&(D=C/x,M+=R.x/x/2),C<0&&(b=r,C=0);break;case c:if(R.y>=0&&(k>=H||x&&(y<=T||B>=N))){E=!1;break}S(c),D+=R.y,x&&(C=D*x,y-=R.y*x/2),D<0&&(b=d,D=0);break;case l:if(x){if(R.y<=0&&(M<=W||B>=N)){E=!1;break}S(d),D-=R.y,M+=R.y,C=D*x}else S(d),S(r),R.x>=0?BW&&(D-=R.y,M+=R.y):(D-=R.y,M+=R.y);C<0&&D<0?(b=u,D=0,C=0):C<0?(b=p,C=0):D<0&&(b=m,D=0);break;case p:if(x){if(R.y<=0&&(M<=W||y<=T)){E=!1;break}S(d),D-=R.y,M+=R.y,C=D*x,y+=R.y*x}else S(d),S(s),R.x<=0?y>T?(C-=R.x,y+=R.x):R.y<=0&&M<=W&&(E=!1):(C-=R.x,y+=R.x),R.y<=0?M>W&&(D-=R.y,M+=R.y):(D-=R.y,M+=R.y);C<0&&D<0?(b=m,D=0,C=0):C<0?(b=l,C=0):D<0&&(b=u,D=0);break;case u:if(x){if(R.x<=0&&(y<=T||k>=H)){E=!1;break}S(s),C-=R.x,y+=R.x,D=C/x}else S(c),S(s),R.x<=0?y>T?(C-=R.x,y+=R.x):R.y>=0&&k>=H&&(E=!1):(C-=R.x,y+=R.x),R.y>=0?k=0&&(B>=N||k>=H)){E=!1;break}S(r),D=(C+=R.x)/x}else S(c),S(r),R.x>=0?B=0&&k>=H&&(E=!1):C+=R.x,R.y>=0?k0?b=R.y>0?m:l:R.x<0&&(y-=C,b=R.y>0?u:p),R.y<0&&(M-=D),this.cropped||(st(this.cropBox,v),this.cropped=!0,this.limited&&this.limitCropBox(!0,!0))}E&&(f.width=C,f.height=D,f.left=y,f.top=M,this.action=b,this.renderCropBox()),it(w,function(t){t.startX=t.endX,t.startY=t.endY})}},Xt={crop:function(){return!this.ready||this.cropped||this.disabled||(this.cropped=!0,this.limitCropBox(!0,!0),this.options.modal&&rt(this.dragBox,b),st(this.cropBox,v),this.setCropBoxData(this.initialCropBoxData)),this},reset:function(){return this.ready&&!this.disabled&&(this.imageData=et({},this.initialImageData),this.canvasData=et({},this.initialCanvasData),this.cropBoxData=et({},this.initialCropBoxData),this.renderCanvas(),this.cropped&&this.renderCropBox()),this},clear:function(){return this.cropped&&!this.disabled&&(et(this.cropBoxData,{left:0,top:0,width:0,height:0}),this.cropped=!1,this.renderCropBox(),this.limitCanvas(!0,!0),this.renderCanvas(),st(this.dragBox,b),rt(this.cropBox,v)),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.viewBoxImage.src=t,it(this.previews,function(i){i.getElementsByTagName("img")[0].src=t}))):(this.isImg&&(this.replaced=!0),this.options.data=null,this.uncreate(),this.load(t))),this},enable:function(){return this.ready&&this.disabled&&(this.disabled=!1,st(this.cropper,f)),this},disable:function(){return this.ready&&!this.disabled&&(this.disabled=!0,rt(this.cropper,f)),this},destroy:function(){var t=this.element;return pt(t,e)?(this.isImg&&this.replaced&&(t.src=this.originalUrl),this.uncreate(),ut(t,e),this):this},move:function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t,e=this.canvasData,a=e.left,n=e.top;return this.moveTo(V(t)?t:a+Number(t),V(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&&(K(t)&&(e.left=t,a=!0),K(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,n,o,h=this.options,r=this.canvasData,s=r.width,c=r.height,d=r.naturalWidth,l=r.naturalHeight;if((t=Number(t))>=0&&this.ready&&!this.disabled&&h.zoomable){var p=d*t,m=l*t;if(!1===wt(this.element,S,{originalEvent:e,oldRatio:s/d,ratio:p/d}))return this;if(e){var u=this.pointers,g=bt(this.cropper),f=u&&Object.keys(u).length?(a=0,n=0,o=0,it(u,function(t){var i=t.startX,e=t.startY;a+=i,n+=e,o+=1}),{pageX:a/=o,pageY:n/=o}):{pageX:e.pageX,pageY:e.pageY};r.left-=(p-s)*((f.pageX-g.left-r.left)/s),r.top-=(m-c)*((f.pageY-g.top-r.top)/c)}else _(i)&&K(i.x)&&K(i.y)?(r.left-=(p-s)*((i.x-r.left)/s),r.top-=(m-c)*((i.y-r.top)/c)):(r.left-=(p-s)/2,r.top-=(m-c)/2);r.width=p,r.height=m,this.renderCanvas(!0)}return this},rotate:function(t){return this.rotateTo((this.imageData.rotate||0)+Number(t))},rotateTo:function(t){return K(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,K(i)?i:1)},scaleY:function(t){var i=this.imageData.scaleX;return this.scale(K(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&&(K(t)&&(e.scaleX=t,a=!0),K(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;it(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(this.ready&&!this.disabled&&_(t)){var o=!1;i.rotatable&&K(t.rotate)&&t.rotate!==e.rotate&&(e.rotate=t.rotate,o=!0),i.scalable&&(K(t.scaleX)&&t.scaleX!==e.scaleX&&(e.scaleX=t.scaleX,o=!0),K(t.scaleY)&&t.scaleY!==e.scaleY&&(e.scaleY=t.scaleY,o=!0)),o&&this.renderCanvas(!0,!0);var h=e.width/e.naturalWidth;K(t.x)&&(n.left=t.x*h+a.left),K(t.y)&&(n.top=t.y*h+a.top),K(t.width)&&(n.width=t.width*h),K(t.height)&&(n.height=t.height*h),this.setCropBoxData(n)}return this},getContainerData:function(){return this.ready?et({},this.containerData):{}},getImageData:function(){return this.sized?et({},this.imageData):{}},getCanvasData:function(){var t=this.canvasData,i={};return this.ready&&it(["left","top","width","height","naturalWidth","naturalHeight"],function(e){i[e]=t[e]}),i},setCanvasData:function(t){var i=this.canvasData,e=i.aspectRatio;return this.ready&&!this.disabled&&_(t)&&(K(t.left)&&(i.left=t.left),K(t.top)&&(i.top=t.top),K(t.width)?(i.width=t.width,i.height=t.width/e):K(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 this.ready&&this.cropped&&!this.disabled&&_(t)&&(K(t.left)&&(i.left=t.left),K(t.top)&&(i.top=t.top),K(t.width)&&t.width!==i.width&&(a=!0,i.width=t.width),K(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,e,a,n,o,h,r,s,c,d,l,p,m,u,g,f,v,w,b,x,y,M,C,D,B,k,T,W,N,H,E,z,L,Y,O=this.canvasData,X=(i=this.image,e=this.imageData,a=O,n=t,o=e.rotate,h=void 0===o?0:o,r=e.scaleX,s=void 0===r?1:r,c=e.scaleY,d=void 0===c?1:c,l=a.aspectRatio,p=a.naturalWidth,m=a.naturalHeight,u=n.fillColor,g=void 0===u?"transparent":u,f=n.imageSmoothingEnabled,v=void 0===f||f,w=n.imageSmoothingQuality,b=void 0===w?"low":w,x=n.maxWidth,y=void 0===x?1/0:x,M=n.maxHeight,C=void 0===M?1/0:M,D=n.minWidth,B=void 0===D?0:D,k=n.minHeight,T=void 0===k?0:k,W=document.createElement("canvas"),N=W.getContext("2d"),H=Tt({aspectRatio:l,width:y,height:C}),E=Tt({aspectRatio:l,width:B,height:T},"cover"),z=Math.min(H.width,Math.max(E.width,p)),L=Math.min(H.height,Math.max(E.height,m)),Y=[-z/2,-L/2,z,L],W.width=nt(z),W.height=nt(L),N.fillStyle=g,N.fillRect(0,0,z,L),N.save(),N.translate(z/2,L/2),N.rotate(h*Math.PI/180),N.scale(s,d),N.imageSmoothingEnabled=v,N.imageSmoothingQuality=b,N.drawImage.apply(N,[i].concat(F(Y.map(function(t){return Math.floor(nt(t))})))),N.restore(),W);if(!this.cropped)return X;var R=this.getData(),S=R.x,A=R.y,I=R.width,U=R.height,j=X.width/Math.floor(O.naturalWidth);1!==j&&(S*=j,A*=j,I*=j,U*=j);var P=I/U,q=Tt({aspectRatio:P,width:t.maxWidth||1/0,height:t.maxHeight||1/0}),$=Tt({aspectRatio:P,width:t.minWidth||0,height:t.minHeight||0},"cover"),Q=Tt({aspectRatio:P,width:t.width||(1!==j?X.width:I),height:t.height||(1!==j?X.height:U)}),Z=Q.width,K=Q.height;Z=Math.min(q.width,Math.max($.width,Z)),K=Math.min(q.height,Math.max($.height,K));var V=document.createElement("canvas"),G=V.getContext("2d");V.width=nt(Z),V.height=nt(K),G.fillStyle=t.fillColor||"transparent",G.fillRect(0,0,Z,K);var J=t.imageSmoothingEnabled,_=void 0===J||J,tt=t.imageSmoothingQuality;G.imageSmoothingEnabled=_,tt&&(G.imageSmoothingQuality=tt);var it=X.width,et=X.height,at=S,ot=A,ht=void 0,rt=void 0,st=void 0,ct=void 0,dt=void 0,lt=void 0;at<=-I||at>it?(at=0,ht=0,st=0,dt=0):at<=0?(st=-at,at=0,dt=ht=Math.min(it,I+at)):at<=it&&(st=0,dt=ht=Math.min(I,it-at)),ht<=0||ot<=-U||ot>et?(ot=0,rt=0,ct=0,lt=0):ot<=0?(ct=-ot,ot=0,lt=rt=Math.min(et,U+ot)):ot<=et&&(ct=0,lt=rt=Math.min(U,et-ot));var pt=[at,ot,ht,rt];if(dt>0&<>0){var mt=Z/I;pt.push(st*mt,ct*mt,dt*mt,lt*mt)}return G.drawImage.apply(G,[X].concat(F(pt.map(function(t){return Math.floor(nt(t))})))),V},setAspectRatio:function(t){var i=this.options;return this.disabled||V(t)||(i.aspectRatio=Math.max(0,t)||NaN,this.ready&&(this.initCropBox(),this.cropped&&this.renderCropBox())),this},setDragMode:function(t){var i=this.options,e=this.dragBox,a=this.face;if(this.ready&&!this.disabled){var n=t===C,o=i.movable&&t===D;t=n||o?t:B,i.dragMode=t,mt(e,y,t),ct(e,g,n),ct(e,x,o),i.cropBoxMovable||(mt(a,y,t),ct(a,g,n),ct(a,x,o))}return this}},Rt=i.Cropper,St=function(){function t(i){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if($(this,t),!i||!j.test(i.tagName))throw new Error("The first argument is required and must be an or element.");this.element=i,this.options=et({},P,_(e)&&e),this.cropped=!1,this.disabled=!1,this.pointers={},this.ready=!1,this.reloading=!1,this.replaced=!1,this.sized=!1,this.sizing=!1,this.init()}return Q(t,[{key:"init",value:function(){var t=this.element,i=t.tagName.toLowerCase(),a=void 0;if(!pt(t,e)){if(mt(t,e,this),"img"===i){if(this.isImg=!0,a=t.getAttribute("src")||"",this.originalUrl=a,!a)return;a=t.src}else"canvas"===i&&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(I.test(t))U.test(t)?this.read((n=t.replace(Nt,""),o=atob(n),h=new ArrayBuffer(o.length),it(r=new Uint8Array(h),function(t,i){r[i]=o.charCodeAt(i)}),h)):this.clone();else{var n,o,h,r,s=new XMLHttpRequest;this.reloading=!0,this.xhr=s;var c=function(){i.reloading=!1,i.xhr=null};s.ontimeout=c,s.onabort=c,s.onerror=function(){c(),i.clone()},s.onload=function(){c(),i.read(s.response)},a.checkCrossOrigin&&Mt(t)&&e.crossOrigin&&(t=Ct(t)),s.open("get",t),s.responseType="arraybuffer",s.withCredentials="use-credentials"===e.crossOrigin,s.send()}else this.clone()}}},{key:"read",value:function(t){var i,e,a,n=this.options,o=this.imageData,h=Ht(t),r=0,s=1,c=1;if(h>1){this.url=(i="image/jpeg",e=new Uint8Array(t),a="",it(e,function(t){a+=Wt(t)}),"data:"+i+";base64,"+btoa(a));var d=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}}(h);r=d.rotate,s=d.scaleX,c=d.scaleY}n.rotatable&&(o.rotate=r),n.scalable&&(o.scaleX=s,o.scaleY=c),this.clone()}},{key:"clone",value:function(){var t=this.element,i=this.url,e=void 0,a=void 0;this.options.checkCrossOrigin&&Mt(i)&&((e=t.crossOrigin)?a=i:(e="anonymous",a=Ct(i))),this.crossOrigin=e,this.crossOriginUrl=a;var n=document.createElement("img");e&&(n.crossOrigin=e),n.src=a||i;var o=this.start.bind(this),h=this.stop.bind(this);this.image=n,this.onStart=o,this.onStop=h,this.isImg?t.complete?this.timeout=setTimeout(o,0):vt(t,E,o,{once:!0}):(n.onload=o,n.onerror=h,rt(n,w),t.parentNode.insertBefore(n,t.nextSibling))}},{key:"start",value:function(t){var e=this,a=this.isImg?this.element:this.image;t&&(a.onload=null,a.onerror=null),this.sizing=!0;var n=i.navigator&&/(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(i.navigator.userAgent),o=function(t,i){et(e.imageData,{naturalWidth:t,naturalHeight:i,aspectRatio:t/i}),e.sizing=!1,e.sized=!0,e.build()};if(!a.naturalWidth||n){var h=document.createElement("img"),r=document.body||document.documentElement;this.sizingImage=h,h.onload=function(){o(h.width,h.height),n||r.removeChild(h)},h.src=a.src,n||(h.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;",r.appendChild(h))}else o(a.naturalWidth,a.naturalHeight)}},{key:"stop",value:function(){var t=this.image;t.onload=null,t.onerror=null,t.parentNode.removeChild(t),this.image=null}},{key:"build",value:function(){if(this.sized&&!this.ready){var t=this.element,i=this.options,n=this.image,o=t.parentNode,h=document.createElement("div");h.innerHTML='
';var r=h.querySelector("."+e+"-container"),s=r.querySelector("."+e+"-canvas"),c=r.querySelector("."+e+"-drag-box"),d=r.querySelector("."+e+"-crop-box"),l=d.querySelector("."+e+"-face");this.container=o,this.cropper=r,this.canvas=s,this.dragBox=c,this.cropBox=d,this.viewBox=r.querySelector("."+e+"-view-box"),this.face=l,s.appendChild(n),rt(t,v),o.insertBefore(r,t.nextSibling),this.isImg||st(n,w),this.initPreview(),this.bind(),i.aspectRatio=Math.max(0,i.aspectRatio)||NaN,i.viewMode=Math.max(0,Math.min(3,Math.round(i.viewMode)))||0,rt(d,v),i.guides||rt(d.getElementsByClassName(e+"-dashed"),v),i.center||rt(d.getElementsByClassName(e+"-center"),v),i.background&&rt(r,e+"-bg"),i.highlight||rt(l,"cropper-invisible"),i.cropBoxMovable&&(rt(l,x),mt(l,y,a)),i.cropBoxResizable||(rt(d.getElementsByClassName(e+"-line"),v),rt(d.getElementsByClassName(e+"-point"),v)),this.render(),this.ready=!0,this.setDragMode(i.dragMode),i.autoCrop&&this.crop(),this.setData(i.data),tt(i.ready)&&vt(t,O,i.ready,{once:!0}),wt(t,O)}}},{key:"unbuild",value:function(){this.ready&&(this.ready=!1,this.unbind(),this.resetPreview(),this.cropper.parentNode.removeChild(this.cropper),st(this.element,v))}},{key:"uncreate",value:function(){var t=this.element;this.ready?(this.unbuild(),this.ready=!1,this.cropped=!1):this.sizing?(this.sizingImage.onload=null,this.sizing=!1,this.sized=!1):this.reloading?this.xhr.abort():this.isImg?t.complete?clearTimeout(this.timeout):ft(t,E,this.onStart):this.image&&this.stop()}}],[{key:"noConflict",value:function(){return window.Cropper=Rt,t}},{key:"setDefaults",value:function(t){et(P,_(t)&&t)}}]),t}();if(et(St.prototype,Et,zt,Lt,Yt,Ot,Xt),t.fn){var At=t.fn.cropper,It="cropper";t.fn.cropper=function(i){for(var e=arguments.length,a=Array(e>1?e-1:0),n=1;n Cropper - @@ -50,7 +49,7 @@
-

Cropper v3.1.6

+

Cropper v4.0.0-alpha

A simple jQuery image cropping plugin.

@@ -64,6 +63,12 @@

Cropper v3.1.6

+
@@ -562,16 +567,16 @@

- + diff --git a/docs/js/cropper.js b/docs/js/cropper.js index 3757403d..c82e8516 100644 --- a/docs/js/cropper.js +++ b/docs/js/cropper.js @@ -1,11 +1,11 @@ /*! - * Cropper v3.1.6 + * Cropper v4.0.0-alpha * https://github.com/fengyuanchen/cropper * * Copyright (c) 2014-2018 Chen Fengyuan * Released under the MIT license * - * Date: 2018-03-01T13:33:48.179Z + * Date: 2018-03-01T14:21:13.980Z */ (function (global, factory) { @@ -57,7 +57,6 @@ 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'; @@ -68,10 +67,10 @@ 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_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 REGEXP_TAG_NAME = /^(?:img|canvas)$/i; var DEFAULTS = { // Define the view mode of the cropper @@ -169,7 +168,13 @@ var DEFAULTS = { zoom: null }; -var TEMPLATE = '
' + '
' + '
' + '
' + '
' + '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
' + '
'; +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)) { @@ -205,15 +210,6 @@ var toConsumableArray = function (arr) { } }; -/** - * Check if the given value is a string. - * @param {*} value - The value to check. - * @returns {boolean} Returns `true` if the given value is a string, else `false`. - */ -function isString(value) { - return typeof value === 'string'; -} - /** * Check if the given value is not a number. */ @@ -238,39 +234,97 @@ function isUndefined(value) { } /** - * Takes a function and returns a new one that will always have a particular context. - * Custom proxy to avoid jQuery's guid. - * @param {Function} fn - The target function. - * @param {Object} context - The new context for the function. - * @returns {Function} The new function. + * 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 proxy(fn, context) { - for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { - args[_key - 2] = arguments[_key]; +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'; +} - return function () { - for (var _len2 = arguments.length, args2 = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args2[_key2] = arguments[_key2]; +/** + * Iterate the given data. + * @param {*} data - The data to iterate. + * @param {Function} callback - The process function for each element. + * @returns {*} The original data. + */ +function forEach(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 fn.apply(context, args.concat(args2)); - }; + return data; } /** - * Get the own enumerable properties of a given object. - * @param {Object} obj - The target object. - * @returns {Array} All the own enumerable properties of the given object. + * 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. */ -var objectKeys = Object.keys || function objectKeys(obj) { - var keys = []; +var assign = Object.assign || function assign(obj) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } - $.each(obj, function (key) { - keys.push(key); - }); + if (isObject(obj) && args.length > 0) { + args.forEach(function (arg) { + if (isObject(arg)) { + Object.keys(arg).forEach(function (key) { + obj[key] = arg[key]; + }); + } + }); + } - return keys; + return obj; }; var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/i; @@ -288,6 +342,271 @@ function normalizeDecimalNumber(value) { 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; + + + forEach(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)) { + forEach(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)) { + forEach(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)) { + forEach(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; + +/** + * Transform the given string from camelCase to kebab-case + * @param {string} value - The value to transform. + * @returns {string} The transformed 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] = undefined; + } + } else if (element.dataset) { + // #128 Safari not allows to delete dataset property + try { + delete element.dataset[name]; + } catch (e) { + element.dataset[name] = undefined; + } + } else { + element.removeAttribute('data-' + hyphenate(name)); + } +} + +var 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. + */ +function removeListener(element, type, listener) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + forEach(type.trim().split(REGEXP_SPACES), function (t) { + element.removeEventListener(t, listener, options); + }); +} + +/** + * 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 (options.once) { + var originalListener = _listener; + + _listener = function listener() { + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + removeListener(element, type, _listener, options); + return originalListener.apply(element, args); + }; + } + + forEach(type.trim().split(REGEXP_SPACES), function (t) { + element.addEventListener(t, _listener, options); + }); +} + +/** + * 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) { + var event = void 0; + + // Event and CustomEvent on IE9-11 are global objects, not constructors + if (isFunction(Event) && isFunction(CustomEvent)) { + event = new CustomEvent(type, { + detail: data, + bubbles: true, + cancelable: true + }); + } else { + event = document.createEvent('CustomEvent'); + event.initCustomEvent(type, true, true, data); + } + + return element.dispatchEvent(event); +} + +/** + * Get the offset base on the document. + * @param {Element} element - The target element. + * @returns {Object} The offset data. + */ +function getOffset(element) { + var box = element.getBoundingClientRect(); + + return { + left: box.left + (window.pageXOffset - document.documentElement.clientLeft), + top: box.top + (window.pageYOffset - document.documentElement.clientTop) + }; +} + var location = WINDOW.location; var REGEXP_ORIGINS = /^(https?:)\/\/([^:/?#]+):?(\d*)/i; @@ -315,11 +634,11 @@ function addTimestamp(url) { } /** - * Get transform values base on the given object. + * Get transforms base on the given object. * @param {Object} obj - The target object. * @returns {string} A string contains transform values. */ -function getTransformValues(_ref) { +function getTransforms(_ref) { var rotate = _ref.rotate, scaleX = _ref.scaleX, scaleY = _ref.scaleY, @@ -349,32 +668,13 @@ function getTransformValues(_ref) { values.push('scaleY(' + scaleY + ')'); } - return values.length ? values.join(' ') : 'none'; -} - -var navigator = WINDOW.navigator; + var transform = values.length ? values.join(' ') : 'none'; -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'); - - newImage.onload = function () { - callback(newImage.width, newImage.height); + return { + WebkitTransform: transform, + msTransform: transform, + transform: transform }; - - newImage.src = image.src; } /** @@ -383,13 +683,13 @@ function getImageNaturalSizes(image, callback) { * @returns {number} The result ratio. */ function getMaxZoomRatio(pointers) { - var pointers2 = $.extend({}, pointers); + var pointers2 = assign({}, pointers); var ratios = []; - $.each(pointers, function (pointerId, pointer) { + forEach(pointers, function (pointer, pointerId) { delete pointers2[pointerId]; - $.each(pointers2, function (pointerId2, pointer2) { + forEach(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); @@ -424,11 +724,7 @@ function getPointer(_ref2, endOnly) { endY: pageY }; - if (endOnly) { - return end; - } - - return $.extend({ + return endOnly ? end : assign({ startX: pageX, startY: pageY }, end); @@ -444,7 +740,7 @@ function getPointersCenter(pointers) { var pageY = 0; var count = 0; - $.each(pointers, function (pointerId, _ref3) { + forEach(pointers, function (_ref3) { var startX = _ref3.startX, startY = _ref3.startY; @@ -597,7 +893,7 @@ function getSourceCanvas(image, _ref6, _ref7, _ref8) { context.scale(scaleX, scaleY); context.imageSmoothingEnabled = imageSmoothingEnabled; context.imageSmoothingQuality = imageSmoothingQuality; - context.drawImage.apply(context, [image].concat(toConsumableArray($.map(params, function (param) { + context.drawImage.apply(context, [image].concat(toConsumableArray(params.map(function (param) { return Math.floor(normalizeDecimalNumber(param)); })))); context.restore(); @@ -640,7 +936,7 @@ function dataURLToArrayBuffer(dataURL) { var arrayBuffer = new ArrayBuffer(binary.length); var uint8 = new Uint8Array(arrayBuffer); - $.each(uint8, function (i) { + forEach(uint8, function (value, i) { uint8[i] = binary.charCodeAt(i); }); @@ -658,7 +954,7 @@ function arrayBufferToDataURL(arrayBuffer, mimeType) { var data = ''; // TypedArray.prototype.forEach is not supported in some browsers. - $.each(uint8, function (i, value) { + forEach(uint8, function (value) { data += fromCharCode(value); }); @@ -808,51 +1104,58 @@ var render = { } }, initContainer: function initContainer() { - var $element = this.$element, + var element = this.element, options = this.options, - $container = this.$container, - $cropper = this.$cropper; + container = this.container, + cropper = this.cropper; - $cropper.addClass(CLASS_HIDDEN); - $element.removeClass(CLASS_HIDDEN); + 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; - $cropper.css(this.container = { - width: Math.max($container.width(), Number(options.minContainerWidth) || 200), - height: Math.max($container.height(), Number(options.minContainerHeight) || 100) + setStyle(cropper, { + width: containerData.width, + height: containerData.height }); - $element.addClass(CLASS_HIDDEN); - $cropper.removeClass(CLASS_HIDDEN); + addClass(element, CLASS_HIDDEN); + removeClass(cropper, CLASS_HIDDEN); }, // Canvas (image wrapper) initCanvas: function initCanvas() { - var container = this.container, - image = this.image; + var containerData = this.containerData, + imageData = this.imageData; var viewMode = this.options.viewMode; - var rotated = Math.abs(image.rotate) % 180 === 90; - var naturalWidth = rotated ? image.naturalHeight : image.naturalWidth; - var naturalHeight = rotated ? image.naturalWidth : image.naturalHeight; + 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 = container.width; - var canvasHeight = container.height; + var canvasWidth = containerData.width; + var canvasHeight = containerData.height; - if (container.height * aspectRatio > container.width) { + if (containerData.height * aspectRatio > containerData.width) { if (viewMode === 3) { - canvasWidth = container.height * aspectRatio; + canvasWidth = containerData.height * aspectRatio; } else { - canvasHeight = container.width / aspectRatio; + canvasHeight = containerData.width / aspectRatio; } } else if (viewMode === 3) { - canvasHeight = container.width / aspectRatio; + canvasHeight = containerData.width / aspectRatio; } else { - canvasWidth = container.height * aspectRatio; + canvasWidth = containerData.height * aspectRatio; } - var canvas = { + var canvasData = { aspectRatio: aspectRatio, naturalWidth: naturalWidth, naturalHeight: naturalHeight, @@ -860,50 +1163,50 @@ var render = { height: canvasHeight }; - canvas.left = (container.width - canvasWidth) / 2; - canvas.top = (container.height - canvasHeight) / 2; - canvas.oldLeft = canvas.left; - canvas.oldTop = canvas.top; + canvasData.left = (containerData.width - canvasWidth) / 2; + canvasData.top = (containerData.height - canvasHeight) / 2; + canvasData.oldLeft = canvasData.left; + canvasData.oldTop = canvasData.top; - this.canvas = canvas; + this.canvasData = canvasData; this.limited = viewMode === 1 || viewMode === 2; this.limitCanvas(true, true); - this.initialImage = $.extend({}, image); - this.initialCanvas = $.extend({}, canvas); + this.initialImageData = assign({}, imageData); + this.initialCanvasData = assign({}, canvasData); }, - limitCanvas: function limitCanvas(isSizeLimited, isPositionLimited) { + limitCanvas: function limitCanvas(sizeLimited, positionLimited) { var options = this.options, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox; + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; var viewMode = options.viewMode; - var aspectRatio = canvas.aspectRatio; + var aspectRatio = canvasData.aspectRatio; - var cropped = this.cropped && cropBox; + var cropped = this.cropped && cropBoxData; - if (isSizeLimited) { + if (sizeLimited) { var minCanvasWidth = Number(options.minCanvasWidth) || 0; var minCanvasHeight = Number(options.minCanvasHeight) || 0; - if (viewMode > 0) { - if (viewMode > 1) { - minCanvasWidth = Math.max(minCanvasWidth, container.width); - minCanvasHeight = Math.max(minCanvasHeight, container.height); + 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; - } + if (viewMode === 3) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; } - } else if (minCanvasWidth) { - minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBox.width : 0); + } + } else if (viewMode > 0) { + if (minCanvasWidth) { + minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0); } else if (minCanvasHeight) { - minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBox.height : 0); + minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0); } else if (cropped) { - minCanvasWidth = cropBox.width; - minCanvasHeight = cropBox.height; + minCanvasWidth = cropBoxData.width; + minCanvasHeight = cropBoxData.height; if (minCanvasHeight * aspectRatio > minCanvasWidth) { minCanvasWidth = minCanvasHeight * aspectRatio; @@ -923,101 +1226,100 @@ var render = { minCanvasHeight = _getAdjustedSizes.height; - canvas.minWidth = minCanvasWidth; - canvas.minHeight = minCanvasHeight; - canvas.maxWidth = Infinity; - canvas.maxHeight = Infinity; + canvasData.minWidth = minCanvasWidth; + canvasData.minHeight = minCanvasHeight; + canvasData.maxWidth = Infinity; + canvasData.maxHeight = Infinity; } - if (isPositionLimited) { - if (viewMode > 0) { - var newCanvasLeft = container.width - canvas.width; - var newCanvasTop = container.height - canvas.height; + if (positionLimited) { + if (viewMode) { + var newCanvasLeft = containerData.width - canvasData.width; + var newCanvasTop = containerData.height - canvasData.height; - canvas.minLeft = Math.min(0, newCanvasLeft); - canvas.minTop = Math.min(0, newCanvasTop); - canvas.maxLeft = Math.max(0, newCanvasLeft); - canvas.maxTop = Math.max(0, newCanvasTop); + 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) { - canvas.minLeft = Math.min(cropBox.left, cropBox.left + cropBox.width - canvas.width); - canvas.minTop = Math.min(cropBox.top, cropBox.top + cropBox.height - canvas.height); - canvas.maxLeft = cropBox.left; - canvas.maxTop = cropBox.top; + 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 (canvas.width >= container.width) { - canvas.minLeft = Math.min(0, newCanvasLeft); - canvas.maxLeft = Math.max(0, newCanvasLeft); + if (canvasData.width >= containerData.width) { + canvasData.minLeft = Math.min(0, newCanvasLeft); + canvasData.maxLeft = Math.max(0, newCanvasLeft); } - if (canvas.height >= container.height) { - canvas.minTop = Math.min(0, newCanvasTop); - canvas.maxTop = Math.max(0, newCanvasTop); + if (canvasData.height >= containerData.height) { + canvasData.minTop = Math.min(0, newCanvasTop); + canvasData.maxTop = Math.max(0, newCanvasTop); } } } } else { - canvas.minLeft = -canvas.width; - canvas.minTop = -canvas.height; - canvas.maxLeft = container.width; - canvas.maxTop = container.height; + canvasData.minLeft = -canvasData.width; + canvasData.minTop = -canvasData.height; + canvasData.maxLeft = containerData.width; + canvasData.maxTop = containerData.height; } } }, renderCanvas: function renderCanvas(changed, transformed) { - var canvas = this.canvas, - image = this.image; + var canvasData = this.canvasData, + imageData = this.imageData; if (transformed) { var _getRotatedSizes = getRotatedSizes({ - width: image.naturalWidth * Math.abs(image.scaleX || 1), - height: image.naturalHeight * Math.abs(image.scaleY || 1), - degree: image.rotate || 0 + 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 = canvas.width * (naturalWidth / canvas.naturalWidth); - var height = canvas.height * (naturalHeight / canvas.naturalHeight); + var width = canvasData.width * (naturalWidth / canvasData.naturalWidth); + var height = canvasData.height * (naturalHeight / canvasData.naturalHeight); - canvas.left -= (width - canvas.width) / 2; - canvas.top -= (height - canvas.height) / 2; - canvas.width = width; - canvas.height = height; - canvas.aspectRatio = naturalWidth / naturalHeight; - canvas.naturalWidth = naturalWidth; - canvas.naturalHeight = 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 (canvas.width > canvas.maxWidth || canvas.width < canvas.minWidth) { - canvas.left = canvas.oldLeft; + if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) { + canvasData.left = canvasData.oldLeft; } - if (canvas.height > canvas.maxHeight || canvas.height < canvas.minHeight) { - canvas.top = canvas.oldTop; + if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) { + canvasData.top = canvasData.oldTop; } - canvas.width = Math.min(Math.max(canvas.width, canvas.minWidth), canvas.maxWidth); - canvas.height = Math.min(Math.max(canvas.height, canvas.minHeight), canvas.maxHeight); + 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); - canvas.left = Math.min(Math.max(canvas.left, canvas.minLeft), canvas.maxLeft); - canvas.top = Math.min(Math.max(canvas.top, canvas.minTop), canvas.maxTop); - canvas.oldLeft = canvas.left; - canvas.oldTop = canvas.top; - - this.$canvas.css({ - width: canvas.width, - height: canvas.height, - transform: getTransformValues({ - translateX: canvas.left, - translateY: canvas.top - }) - }); + 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, assign({ + width: canvasData.width, + height: canvasData.height + }, getTransforms({ + translateX: canvasData.left, + translateY: canvasData.top + }))); this.renderImage(changed); @@ -1026,27 +1328,25 @@ var render = { } }, renderImage: function renderImage(changed) { - var canvas = this.canvas, - image = this.image; + var canvasData = this.canvasData, + imageData = this.imageData; - var width = image.naturalWidth * (canvas.width / canvas.naturalWidth); - var height = image.naturalHeight * (canvas.height / canvas.naturalHeight); + var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth); + var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight); - $.extend(image, { + assign(imageData, { width: width, height: height, - left: (canvas.width - width) / 2, - top: (canvas.height - height) / 2 - }); - - this.$clone.css({ - width: image.width, - height: image.height, - transform: getTransformValues($.extend({ - translateX: image.left, - translateY: image.top - }, image)) + left: (canvasData.width - width) / 2, + top: (canvasData.height - height) / 2 }); + setStyle(this.image, assign({ + width: imageData.width, + height: imageData.height + }, getTransforms(assign({ + translateX: imageData.left, + translateY: imageData.top + }, imageData)))); if (changed) { this.output(); @@ -1054,58 +1354,58 @@ var render = { }, initCropBox: function initCropBox() { var options = this.options, - canvas = this.canvas; + canvasData = this.canvasData; var aspectRatio = options.aspectRatio; var autoCropArea = Number(options.autoCropArea) || 0.8; - var cropBox = { - width: canvas.width, - height: canvas.height + var cropBoxData = { + width: canvasData.width, + height: canvasData.height }; if (aspectRatio) { - if (canvas.height * aspectRatio > canvas.width) { - cropBox.height = cropBox.width / aspectRatio; + if (canvasData.height * aspectRatio > canvasData.width) { + cropBoxData.height = cropBoxData.width / aspectRatio; } else { - cropBox.width = cropBox.height * aspectRatio; + cropBoxData.width = cropBoxData.height * aspectRatio; } } - this.cropBox = cropBox; + this.cropBoxData = cropBoxData; this.limitCropBox(true, true); // Initialize auto crop area - cropBox.width = Math.min(Math.max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); - cropBox.height = Math.min(Math.max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); - - // The width of auto crop area must large than "minWidth", and the height too. (#164) - cropBox.width = Math.max(cropBox.minWidth, cropBox.width * autoCropArea); - cropBox.height = Math.max(cropBox.minHeight, cropBox.height * autoCropArea); - cropBox.left = canvas.left + (canvas.width - cropBox.width) / 2; - cropBox.top = canvas.top + (canvas.height - cropBox.height) / 2; - cropBox.oldLeft = cropBox.left; - cropBox.oldTop = cropBox.top; - - this.initialCropBox = $.extend({}, cropBox); + 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 = assign({}, cropBoxData); }, - limitCropBox: function limitCropBox(isSizeLimited, isPositionLimited) { + limitCropBox: function limitCropBox(sizeLimited, positionLimited) { var options = this.options, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox, + containerData = this.containerData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData, limited = this.limited; var aspectRatio = options.aspectRatio; - if (isSizeLimited) { + if (sizeLimited) { var minCropBoxWidth = Number(options.minCropBoxWidth) || 0; var minCropBoxHeight = Number(options.minCropBoxHeight) || 0; - var maxCropBoxWidth = Math.min(container.width, limited ? canvas.width : container.width); - var maxCropBoxHeight = Math.min(container.height, limited ? canvas.height : container.height); + 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, container.width); - minCropBoxHeight = Math.min(minCropBoxHeight, container.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) { @@ -1128,63 +1428,62 @@ var render = { } // The minWidth/Height must be less than maxWidth/Height - cropBox.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); - cropBox.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); - cropBox.maxWidth = maxCropBoxWidth; - cropBox.maxHeight = maxCropBoxHeight; + cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); + cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); + cropBoxData.maxWidth = maxCropBoxWidth; + cropBoxData.maxHeight = maxCropBoxHeight; } - if (isPositionLimited) { + if (positionLimited) { if (limited) { - cropBox.minLeft = Math.max(0, canvas.left); - cropBox.minTop = Math.max(0, canvas.top); - cropBox.maxLeft = Math.min(container.width, canvas.left + canvas.width) - cropBox.width; - cropBox.maxTop = Math.min(container.height, canvas.top + canvas.height) - cropBox.height; + 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 { - cropBox.minLeft = 0; - cropBox.minTop = 0; - cropBox.maxLeft = container.width - cropBox.width; - cropBox.maxTop = container.height - cropBox.height; + 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, - container = this.container, - cropBox = this.cropBox; + containerData = this.containerData, + cropBoxData = this.cropBoxData; - if (cropBox.width > cropBox.maxWidth || cropBox.width < cropBox.minWidth) { - cropBox.left = cropBox.oldLeft; + if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) { + cropBoxData.left = cropBoxData.oldLeft; } - if (cropBox.height > cropBox.maxHeight || cropBox.height < cropBox.minHeight) { - cropBox.top = cropBox.oldTop; + if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) { + cropBoxData.top = cropBoxData.oldTop; } - cropBox.width = Math.min(Math.max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); - cropBox.height = Math.min(Math.max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); + 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); - cropBox.left = Math.min(Math.max(cropBox.left, cropBox.minLeft), cropBox.maxLeft); - cropBox.top = Math.min(Math.max(cropBox.top, cropBox.minTop), cropBox.maxTop); - cropBox.oldLeft = cropBox.left; - cropBox.oldTop = cropBox.top; + 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 - this.$face.data(DATA_ACTION, cropBox.width >= container.width && cropBox.height >= container.height ? ACTION_MOVE : ACTION_ALL); + setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL); } - this.$cropBox.css({ - width: cropBox.width, - height: cropBox.height, - transform: getTransformValues({ - translateX: cropBox.left, - translateY: cropBox.top - }) - }); + setStyle(this.cropBox, assign({ + width: cropBoxData.width, + height: cropBoxData.height + }, getTransforms({ + translateX: cropBoxData.left, + translateY: cropBoxData.top + }))); if (this.cropped && this.limited) { this.limitCanvas(true, true); @@ -1196,16 +1495,14 @@ var render = { }, output: function output() { this.preview(); - - if (this.completed) { - this.trigger(EVENT_CROP, this.getData()); - } + 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'); @@ -1215,21 +1512,31 @@ var preview = { } image.src = url; + this.viewBox.appendChild(image); + this.viewBoxImage = image; - var $clone2 = $(image); + if (!preview) { + return; + } - this.$preview = $(this.options.preview); - this.$clone2 = $clone2; - this.$viewBox.html($clone2); - this.$preview.each(function (i, element) { - var $element = $(element); + var previews = preview; + + if (typeof preview === 'string') { + previews = this.element.ownerDocument.querySelectorAll(preview); + } else if (preview.querySelector) { + previews = [preview]; + } + + this.previews = previews; + + forEach(previews, function (el) { var img = document.createElement('img'); // Save the original size for recover - $element.data(DATA_PREVIEW, { - width: $element.width(), - height: $element.height(), - html: $element.html() + setData(el, DATA_PREVIEW, { + width: el.offsetWidth, + height: el.offsetHeight, + html: el.innerHTML }); if (crossOrigin) { @@ -1246,48 +1553,49 @@ var preview = { */ 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;"'; - $element.html(img); + el.innerHTML = ''; + el.appendChild(img); }); }, resetPreview: function resetPreview() { - this.$preview.each(function (i, element) { - var $element = $(element); - var data = $element.data(DATA_PREVIEW); + forEach(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); - $element.css({ + setStyle(element, { width: data.width, height: data.height - }).html(data.html).removeData(DATA_PREVIEW); + }); + + element.innerHTML = data.html; + removeData(element, DATA_PREVIEW); }); }, preview: function preview() { - var image = this.image, - canvas = this.canvas, - cropBox = this.cropBox; - var cropBoxWidth = cropBox.width, - cropBoxHeight = cropBox.height; - var width = image.width, - height = image.height; + 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 = cropBox.left - canvas.left - image.left; - var top = cropBox.top - canvas.top - image.top; + var left = cropBoxData.left - canvasData.left - imageData.left; + var top = cropBoxData.top - canvasData.top - imageData.top; if (!this.cropped || this.disabled) { return; } - this.$clone2.css({ + setStyle(this.viewBoxImage, assign({ width: width, - height: height, - transform: getTransformValues($.extend({ - translateX: -left, - translateY: -top - }, image)) - }); - - this.$preview.each(function (i, element) { - var $element = $(element); - var data = $element.data(DATA_PREVIEW); + height: height + }, getTransforms(assign({ + translateX: -left, + translateY: -top + }, imageData)))); + + forEach(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); var originalWidth = data.width; var originalHeight = data.height; var newWidth = originalWidth; @@ -1305,104 +1613,107 @@ var preview = { newHeight = originalHeight; } - $element.css({ + setStyle(element, { width: newWidth, height: newHeight - }).find('img').css({ - width: width * ratio, - height: height * ratio, - transform: getTransformValues($.extend({ - translateX: -left * ratio, - translateY: -top * ratio - }, image)) }); + + setStyle(element.getElementsByTagName('img')[0], assign({ + width: width * ratio, + height: height * ratio + }, getTransforms(assign({ + translateX: -left * ratio, + translateY: -top * ratio + }, imageData)))); }); } }; var events = { bind: function bind() { - var $element = this.$element, + var element = this.element, options = this.options, - $cropper = this.$cropper; + cropper = this.cropper; - if ($.isFunction(options.cropstart)) { - $element.on(EVENT_CROP_START, options.cropstart); + if (isFunction(options.cropstart)) { + addListener(element, EVENT_CROP_START, options.cropstart); } - if ($.isFunction(options.cropmove)) { - $element.on(EVENT_CROP_MOVE, options.cropmove); + if (isFunction(options.cropmove)) { + addListener(element, EVENT_CROP_MOVE, options.cropmove); } - if ($.isFunction(options.cropend)) { - $element.on(EVENT_CROP_END, options.cropend); + if (isFunction(options.cropend)) { + addListener(element, EVENT_CROP_END, options.cropend); } - if ($.isFunction(options.crop)) { - $element.on(EVENT_CROP, options.crop); + if (isFunction(options.crop)) { + addListener(element, EVENT_CROP, options.crop); } - if ($.isFunction(options.zoom)) { - $element.on(EVENT_ZOOM, options.zoom); + if (isFunction(options.zoom)) { + addListener(element, EVENT_ZOOM, options.zoom); } - $cropper.on(EVENT_POINTER_DOWN, proxy(this.cropStart, this)); + addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this)); if (options.zoomable && options.zoomOnWheel) { - $cropper.on(EVENT_WHEEL, proxy(this.wheel, this)); + addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this)); } if (options.toggleDragModeOnDblclick) { - $cropper.on(EVENT_DBLCLICK, proxy(this.dblclick, this)); + addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this)); } - $(this.element.ownerDocument).on(EVENT_POINTER_MOVE, this.onCropMove = proxy(this.cropMove, this)).on(EVENT_POINTER_UP, this.onCropEnd = proxy(this.cropEnd, this)); + addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this)); + addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this)); if (options.responsive) { - $(window).on(EVENT_RESIZE, this.onResize = proxy(this.resize, this)); + addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this)); } }, unbind: function unbind() { - var $element = this.$element, + var element = this.element, options = this.options, - $cropper = this.$cropper; + cropper = this.cropper; - if ($.isFunction(options.cropstart)) { - $element.off(EVENT_CROP_START, options.cropstart); + if (isFunction(options.cropstart)) { + removeListener(element, EVENT_CROP_START, options.cropstart); } - if ($.isFunction(options.cropmove)) { - $element.off(EVENT_CROP_MOVE, options.cropmove); + if (isFunction(options.cropmove)) { + removeListener(element, EVENT_CROP_MOVE, options.cropmove); } - if ($.isFunction(options.cropend)) { - $element.off(EVENT_CROP_END, options.cropend); + if (isFunction(options.cropend)) { + removeListener(element, EVENT_CROP_END, options.cropend); } - if ($.isFunction(options.crop)) { - $element.off(EVENT_CROP, options.crop); + if (isFunction(options.crop)) { + removeListener(element, EVENT_CROP, options.crop); } - if ($.isFunction(options.zoom)) { - $element.off(EVENT_ZOOM, options.zoom); + if (isFunction(options.zoom)) { + removeListener(element, EVENT_ZOOM, options.zoom); } - $cropper.off(EVENT_POINTER_DOWN, this.cropStart); + removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart); if (options.zoomable && options.zoomOnWheel) { - $cropper.off(EVENT_WHEEL, this.wheel); + removeListener(cropper, EVENT_WHEEL, this.onWheel); } if (options.toggleDragModeOnDblclick) { - $cropper.off(EVENT_DBLCLICK, this.dblclick); + removeListener(cropper, EVENT_DBLCLICK, this.onDblclick); } - $(this.element.ownerDocument).off(EVENT_POINTER_MOVE, this.onCropMove).off(EVENT_POINTER_UP, this.onCropEnd); + removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove); + removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd); if (options.responsive) { - $(window).off(EVENT_RESIZE, this.onResize); + removeListener(window, EVENT_RESIZE, this.onResize); } } }; @@ -1410,20 +1721,20 @@ var events = { var handlers = { resize: function resize() { var options = this.options, - $container = this.$container, - container = this.container; + container = this.container, + containerData = this.containerData; var minContainerWidth = Number(options.minContainerWidth) || 200; var minContainerHeight = Number(options.minContainerHeight) || 100; - if (this.disabled || container.width <= minContainerWidth || container.height <= minContainerHeight) { + if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) { return; } - var ratio = $container.width() / container.width; + var ratio = container.offsetWidth / containerData.width; // Resize when width changed or height changed - if (ratio !== 1 || $container.height() !== container.height) { + if (ratio !== 1 || container.offsetHeight !== containerData.height) { var canvasData = void 0; var cropBoxData = void 0; @@ -1435,10 +1746,10 @@ var handlers = { this.render(); if (options.restore) { - this.setCanvasData($.each(canvasData, function (i, n) { + this.setCanvasData(forEach(canvasData, function (n, i) { canvasData[i] = n * ratio; })); - this.setCropBoxData($.each(cropBoxData, function (i, n) { + this.setCropBoxData(forEach(cropBoxData, function (n, i) { cropBoxData[i] = n * ratio; })); } @@ -1449,21 +1760,21 @@ var handlers = { return; } - this.setDragMode(this.$dragBox.hasClass(CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); + this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); }, - wheel: function wheel(event) { + wheel: function wheel(e) { var _this = this; - var e = event.originalEvent || event; var ratio = Number(this.options.wheelZoomRatio) || 0.1; + var delta = 1; if (this.disabled) { return; } - event.preventDefault(); + e.preventDefault(); - // Limit wheel speed to prevent zoom too fast + // Limit wheel speed to prevent zoom too fast (#21) if (this.wheeling) { return; } @@ -1474,8 +1785,6 @@ var handlers = { _this.wheeling = false; }, 50); - var delta = 1; - if (e.deltaY) { delta = e.deltaY > 0 ? 1 : -1; } else if (e.wheelDelta) { @@ -1484,7 +1793,7 @@ var handlers = { delta = e.detail > 0 ? 1 : -1; } - this.zoom(-delta * ratio, event); + this.zoom(-delta * ratio, e); }, cropStart: function cropStart(e) { if (this.disabled) { @@ -1493,34 +1802,33 @@ var handlers = { var options = this.options, pointers = this.pointers; - var originalEvent = e.originalEvent; var action = void 0; - if (originalEvent && originalEvent.changedTouches) { + if (e.changedTouches) { // Handle touch event - $.each(originalEvent.changedTouches, function (i, touch) { + forEach(e.changedTouches, function (touch) { pointers[touch.identifier] = getPointer(touch); }); } else { // Handle mouse event and pointer event - pointers[originalEvent && originalEvent.pointerId || 0] = getPointer(originalEvent || e); + pointers[e.pointerId || 0] = getPointer(e); } - if (objectKeys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { + if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { action = ACTION_ZOOM; } else { - action = $(e.target).data(DATA_ACTION); + action = getData(e.target, DATA_ACTION); } if (!REGEXP_ACTIONS.test(action)) { return; } - if (this.trigger(EVENT_CROP_START, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_CROP_START, { + originalEvent: e, action: action - }).isDefaultPrevented()) { + }) === false) { return; } @@ -1531,7 +1839,7 @@ var handlers = { if (action === ACTION_CROP) { this.cropping = true; - this.$dragBox.addClass(CLASS_MODAL); + addClass(this.dragBox, CLASS_MODAL); } }, cropMove: function cropMove(e) { @@ -1543,24 +1851,23 @@ var handlers = { } var pointers = this.pointers; - var originalEvent = e.originalEvent; e.preventDefault(); - if (this.trigger(EVENT_CROP_MOVE, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_CROP_MOVE, { + originalEvent: e, action: action - }).isDefaultPrevented()) { + }) === false) { return; } - if (originalEvent && originalEvent.changedTouches) { - $.each(originalEvent.changedTouches, function (i, touch) { - $.extend(pointers[touch.identifier], getPointer(touch, true)); + if (e.changedTouches) { + forEach(e.changedTouches, function (touch) { + assign(pointers[touch.identifier], getPointer(touch, true)); }); } else { - $.extend(pointers[originalEvent && originalEvent.pointerId || 0], getPointer(originalEvent || e, true)); + assign(pointers[e.pointerId || 0], getPointer(e, true)); } this.change(e); @@ -1570,17 +1877,16 @@ var handlers = { return; } - var action = this.action; - var pointers = this.pointers; - var originalEvent = e.originalEvent; + var action = this.action, + pointers = this.pointers; - if (originalEvent && originalEvent.changedTouches) { - $.each(originalEvent.changedTouches, function (i, touch) { + if (e.changedTouches) { + forEach(e.changedTouches, function (touch) { delete pointers[touch.identifier]; }); } else { - delete pointers[originalEvent && originalEvent.pointerId || 0]; + delete pointers[e.pointerId || 0]; } if (!action) { @@ -1589,17 +1895,17 @@ var handlers = { e.preventDefault(); - if (!objectKeys(pointers).length) { + if (!Object.keys(pointers).length) { this.action = ''; } if (this.cropping) { this.cropping = false; - this.$dragBox.toggleClass(CLASS_MODAL, this.cropped && this.options.modal); + toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal); } - this.trigger(EVENT_CROP_END, { - originalEvent: originalEvent, + dispatchEvent(this.element, EVENT_CROP_END, { + originalEvent: e, action: action }); } @@ -1608,40 +1914,40 @@ var handlers = { var change = { change: function change(e) { var options = this.options, - pointers = this.pointers, - container = this.container, - canvas = this.canvas, - cropBox = this.cropBox; + canvasData = this.canvasData, + containerData = this.containerData, + cropBoxData = this.cropBoxData, + pointers = this.pointers; var action = this.action; var aspectRatio = options.aspectRatio; - var left = cropBox.left, - top = cropBox.top, - width = cropBox.width, - height = cropBox.height; + 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 = container.width; - var maxHeight = container.height; + 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 (#259) + // Locking aspect ratio in "free mode" by holding shift key if (!aspectRatio && e.shiftKey) { aspectRatio = width && height ? width / height : 1; } if (this.limited) { - minLeft = cropBox.minLeft; - minTop = cropBox.minTop; + minLeft = cropBoxData.minLeft; + minTop = cropBoxData.minTop; - maxWidth = minLeft + Math.min(container.width, canvas.width, canvas.left + canvas.width); - maxHeight = minTop + Math.min(container.height, canvas.height, canvas.top + canvas.height); + 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[objectKeys(pointers)[0]]; + var pointer = pointers[Object.keys(pointers)[0]]; var range = { x: pointer.endX - pointer.startX, y: pointer.endY - pointer.startY @@ -1982,7 +2288,7 @@ var change = { // Zoom canvas case ACTION_ZOOM: - this.zoom(getMaxZoomRatio(pointers), e.originalEvent); + this.zoom(getMaxZoomRatio(pointers), e); renderable = false; break; @@ -1993,11 +2299,11 @@ var change = { break; } - offset = this.$cropper.offset(); + offset = getOffset(this.cropper); left = pointer.startX - offset.left; top = pointer.startY - offset.top; - width = cropBox.minWidth; - height = cropBox.minHeight; + width = cropBoxData.minWidth; + height = cropBoxData.minHeight; if (range.x > 0) { action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST; @@ -2012,7 +2318,7 @@ var change = { // Show the crop box if is hidden if (!this.cropped) { - this.$cropBox.removeClass(CLASS_HIDDEN); + removeClass(this.cropBox, CLASS_HIDDEN); this.cropped = true; if (this.limited) { @@ -2026,16 +2332,16 @@ var change = { } if (renderable) { - cropBox.width = width; - cropBox.height = height; - cropBox.left = left; - cropBox.top = top; + cropBoxData.width = width; + cropBoxData.height = height; + cropBoxData.left = left; + cropBoxData.top = top; this.action = action; this.renderCropBox(); } // Override - $.each(pointers, function (i, p) { + forEach(pointers, function (p) { p.startX = p.endX; p.startY = p.endY; }); @@ -2045,149 +2351,162 @@ var change = { var methods = { // Show the crop box manually crop: function crop() { - if (!this.ready || this.disabled) { - return; - } - - if (!this.cropped) { + if (this.ready && !this.cropped && !this.disabled) { this.cropped = true; this.limitCropBox(true, true); if (this.options.modal) { - this.$dragBox.addClass(CLASS_MODAL); + addClass(this.dragBox, CLASS_MODAL); } - this.$cropBox.removeClass(CLASS_HIDDEN); + removeClass(this.cropBox, CLASS_HIDDEN); + this.setCropBoxData(this.initialCropBoxData); } - this.setCropBoxData(this.initialCropBox); + return this; }, // Reset the image and crop box to their initial states reset: function reset() { - if (!this.ready || this.disabled) { - return; - } + if (this.ready && !this.disabled) { + this.imageData = assign({}, this.initialImageData); + this.canvasData = assign({}, this.initialCanvasData); + this.cropBoxData = assign({}, this.initialCropBoxData); + this.renderCanvas(); - this.image = $.extend({}, this.initialImage); - this.canvas = $.extend({}, this.initialCanvas); - this.cropBox = $.extend({}, this.initialCropBox); - this.renderCanvas(); - - if (this.cropped) { - this.renderCropBox(); + if (this.cropped) { + this.renderCropBox(); + } } + + return this; }, // Clear the crop box clear: function clear() { - if (!this.cropped || this.disabled) { - return; - } + if (this.cropped && !this.disabled) { + assign(this.cropBoxData, { + left: 0, + top: 0, + width: 0, + height: 0 + }); - $.extend(this.cropBox, { - left: 0, - top: 0, - width: 0, - height: 0 - }); + this.cropped = false; + this.renderCropBox(); + this.limitCanvas(true, true); - 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); + } - // Render canvas after crop box rendered - this.renderCanvas(); - this.$dragBox.removeClass(CLASS_MODAL); - this.$cropBox.addClass(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. + * @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one. + * @returns {Cropper} this */ - replace: function replace(url, onlyColorChanged) { + replace: function replace(url) { + var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + if (!this.disabled && url) { if (this.isImg) { - this.$element.attr('src', url); + this.element.src = url; } - if (onlyColorChanged) { + if (hasSameSize) { this.url = url; - this.$clone.attr('src', url); + this.image.src = url; if (this.ready) { - this.$preview.find('img').add(this.$clone2).attr('src', url); + this.viewBoxImage.src = url; + + forEach(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.uncreate(); this.load(url); } } + + return this; }, // Enable (unfreeze) the cropper enable: function enable() { - if (this.ready) { + if (this.ready && this.disabled) { this.disabled = false; - this.$cropper.removeClass(CLASS_DISABLED); + removeClass(this.cropper, CLASS_DISABLED); } + + return this; }, // Disable (freeze) the cropper disable: function disable() { - if (this.ready) { + if (this.ready && !this.disabled) { this.disabled = true; - this.$cropper.addClass(CLASS_DISABLED); + addClass(this.cropper, CLASS_DISABLED); } + + return this; }, - // Destroy the cropper and remove the instance from the image + /** + * Destroy the cropper and remove the instance from the image + * @returns {Cropper} this + */ destroy: function destroy() { - var $element = this.$element; + var element = this.element; - if (this.loaded) { - if (this.isImg && this.replaced) { - $element.attr('src', this.originalUrl); - } + if (!getData(element, NAMESPACE)) { + return this; + } - this.unbuild(); - $element.removeClass(CLASS_HIDDEN); - } else if (this.isImg) { - $element.off(EVENT_LOAD, this.start); - } else if (this.$clone) { - this.$clone.remove(); + if (this.isImg && this.replaced) { + element.src = this.originalUrl; } - $element.removeData(NAMESPACE); + this.uncreate(); + 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. + * @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis. + * @returns {Cropper} this */ - move: function move(offsetX, offsetY) { - var _canvas = this.canvas, - left = _canvas.left, - top = _canvas.top; + move: function move(offsetX) { + var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX; + var _canvasData = this.canvasData, + left = _canvasData.left, + top = _canvasData.top; - this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); + return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY)); }, @@ -2195,28 +2514,25 @@ var methods = { * Move the canvas to an absolute point * @param {number} x - The x-axis coordinate. * @param {number} [y=x] - The y-axis coordinate. + * @returns {Cropper} this */ - moveTo: function moveTo(x, y) { - var canvas = this.canvas; + moveTo: function moveTo(x) { + var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + var canvasData = this.canvasData; var changed = false; - // If "y" is not present, its default value is "x" - if (isUndefined(y)) { - y = x; - } - x = Number(x); y = Number(y); if (this.ready && !this.disabled && this.options.movable) { if (isNumber(x)) { - canvas.left = x; + canvasData.left = x; changed = true; } if (isNumber(y)) { - canvas.top = y; + canvasData.top = y; changed = true; } @@ -2224,16 +2540,19 @@ var methods = { this.renderCanvas(true); } } + + return this; }, /** * Zoom the canvas with a relative ratio - * @param {Number} ratio - The target ratio. - * @param {Event} _event - The related event if any. + * @param {number} ratio - The target ratio. + * @param {Event} _originalEvent - The original event if any. + * @returns {Cropper} this */ - zoom: function zoom(ratio, _event) { - var canvas = this.canvas; + zoom: function zoom(ratio, _originalEvent) { + var canvasData = this.canvasData; ratio = Number(ratio); @@ -2244,23 +2563,24 @@ var methods = { ratio = 1 + ratio; } - this.zoomTo(canvas.width * ratio / canvas.naturalWidth, _event); + return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent); }, /** * Zoom the canvas to an absolute ratio * @param {number} ratio - The target ratio. - * @param {Event} _event - The related event if any. + * @param {Object} pivot - The zoom pivot point coordinate. + * @param {Event} _originalEvent - The original event if any. + * @returns {Cropper} this */ - zoomTo: function zoomTo(ratio, _event) { + zoomTo: function zoomTo(ratio, pivot, _originalEvent) { var options = this.options, - pointers = this.pointers, - canvas = this.canvas; - var width = canvas.width, - height = canvas.height, - naturalWidth = canvas.naturalWidth, - naturalHeight = canvas.naturalHeight; + canvasData = this.canvasData; + var width = canvasData.width, + height = canvasData.height, + naturalWidth = canvasData.naturalWidth, + naturalHeight = canvasData.naturalHeight; ratio = Number(ratio); @@ -2268,87 +2588,95 @@ var methods = { if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) { var newWidth = naturalWidth * ratio; var newHeight = naturalHeight * ratio; - var originalEvent = void 0; - - if (_event) { - originalEvent = _event.originalEvent; - } - if (this.trigger(EVENT_ZOOM, { - originalEvent: originalEvent, + if (dispatchEvent(this.element, EVENT_ZOOM, { + originalEvent: _originalEvent, oldRatio: width / naturalWidth, ratio: newWidth / naturalWidth - }).isDefaultPrevented()) { - return; + }) === false) { + return this; } - if (originalEvent) { - var offset = this.$cropper.offset(); - var center = pointers && objectKeys(pointers).length ? getPointersCenter(pointers) : { - pageX: _event.pageX || originalEvent.pageX || 0, - pageY: _event.pageY || originalEvent.pageY || 0 + 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 - canvas.left -= (newWidth - width) * ((center.pageX - offset.left - canvas.left) / width); - canvas.top -= (newHeight - height) * ((center.pageY - offset.top - canvas.top) / height); + 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 - canvas.left -= (newWidth - width) / 2; - canvas.top -= (newHeight - height) / 2; + canvasData.left -= (newWidth - width) / 2; + canvasData.top -= (newHeight - height) / 2; } - canvas.width = newWidth; - canvas.height = newHeight; + 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 {Cropper} this */ rotate: function rotate(degree) { - this.rotateTo((this.image.rotate || 0) + Number(degree)); + return this.rotateTo((this.imageData.rotate || 0) + Number(degree)); }, /** * Rotate the canvas to an absolute degree * @param {number} degree - The rotate degree. + * @returns {Cropper} this */ rotateTo: function rotateTo(degree) { degree = Number(degree); if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) { - this.image.rotate = degree % 360; + 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 {Cropper} this */ scaleX: function scaleX(_scaleX) { - var scaleY = this.image.scaleY; + var scaleY = this.imageData.scaleY; - this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1); + 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 {Cropper} this */ scaleY: function scaleY(_scaleY) { - var scaleX = this.image.scaleX; + var scaleX = this.imageData.scaleX; - this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); + return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY); }, @@ -2356,10 +2684,11 @@ var methods = { * 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 {Cropper} this */ scale: function scale(scaleX) { var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX; - var image = this.image; + var imageData = this.imageData; var transformed = false; @@ -2368,12 +2697,12 @@ var methods = { if (this.ready && !this.disabled && this.options.scalable) { if (isNumber(scaleX)) { - image.scaleX = scaleX; + imageData.scaleX = scaleX; transformed = true; } if (isNumber(scaleY)) { - image.scaleY = scaleY; + imageData.scaleY = scaleY; transformed = true; } @@ -2381,6 +2710,8 @@ var methods = { this.renderCanvas(true, true); } } + + return this; }, @@ -2389,26 +2720,26 @@ var methods = { * @param {boolean} [rounded=false] - Indicate if round the data values or not. * @returns {Object} The result cropped data. */ - getData: function getData() { + getData: function getData$$1() { var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; var options = this.options, - image = this.image, - canvas = this.canvas, - cropBox = this.cropBox; + imageData = this.imageData, + canvasData = this.canvasData, + cropBoxData = this.cropBoxData; var data = void 0; if (this.ready && this.cropped) { data = { - x: cropBox.left - canvas.left, - y: cropBox.top - canvas.top, - width: cropBox.width, - height: cropBox.height + x: cropBoxData.left - canvasData.left, + y: cropBoxData.top - canvasData.top, + width: cropBoxData.width, + height: cropBoxData.height }; - var ratio = image.width / image.naturalWidth; + var ratio = imageData.width / imageData.naturalWidth; - $.each(data, function (i, n) { + forEach(data, function (n, i) { n /= ratio; data[i] = rounded ? Math.round(n) : n; }); @@ -2422,12 +2753,12 @@ var methods = { } if (options.rotatable) { - data.rotate = image.rotate || 0; + data.rotate = imageData.rotate || 0; } if (options.scalable) { - data.scaleX = image.scaleX || 1; - data.scaleY = image.scaleY || 1; + data.scaleX = imageData.scaleX || 1; + data.scaleY = imageData.scaleY || 1; } return data; @@ -2437,36 +2768,33 @@ var methods = { /** * Set the cropped area position and size with new data * @param {Object} data - The new data. + * @returns {Cropper} this */ - setData: function setData(data) { + setData: function setData$$1(data) { var options = this.options, - image = this.image, - canvas = this.canvas; + imageData = this.imageData, + canvasData = this.canvasData; var cropBoxData = {}; - if ($.isFunction(data)) { - data = data.call(this.element); - } - - if (this.ready && !this.disabled && $.isPlainObject(data)) { + if (this.ready && !this.disabled && isPlainObject(data)) { var transformed = false; if (options.rotatable) { - if (isNumber(data.rotate) && data.rotate !== image.rotate) { - image.rotate = data.rotate; + if (isNumber(data.rotate) && data.rotate !== imageData.rotate) { + imageData.rotate = data.rotate; transformed = true; } } if (options.scalable) { - if (isNumber(data.scaleX) && data.scaleX !== image.scaleX) { - image.scaleX = data.scaleX; + if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) { + imageData.scaleX = data.scaleX; transformed = true; } - if (isNumber(data.scaleY) && data.scaleY !== image.scaleY) { - image.scaleY = data.scaleY; + if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) { + imageData.scaleY = data.scaleY; transformed = true; } } @@ -2475,14 +2803,14 @@ var methods = { this.renderCanvas(true, true); } - var ratio = image.width / image.naturalWidth; + var ratio = imageData.width / imageData.naturalWidth; if (isNumber(data.x)) { - cropBoxData.left = data.x * ratio + canvas.left; + cropBoxData.left = data.x * ratio + canvasData.left; } if (isNumber(data.y)) { - cropBoxData.top = data.y * ratio + canvas.top; + cropBoxData.top = data.y * ratio + canvasData.top; } if (isNumber(data.width)) { @@ -2495,6 +2823,8 @@ var methods = { this.setCropBoxData(cropBoxData); } + + return this; }, @@ -2503,7 +2833,7 @@ var methods = { * @returns {Object} The result container data. */ getContainerData: function getContainerData() { - return this.ready ? $.extend({}, this.container) : {}; + return this.ready ? assign({}, this.containerData) : {}; }, @@ -2512,7 +2842,7 @@ var methods = { * @returns {Object} The result image data. */ getImageData: function getImageData() { - return this.loaded ? $.extend({}, this.image) : {}; + return this.sized ? assign({}, this.imageData) : {}; }, @@ -2521,13 +2851,13 @@ var methods = { * @returns {Object} The result canvas data. */ getCanvasData: function getCanvasData() { - var canvas = this.canvas; + var canvasData = this.canvasData; var data = {}; if (this.ready) { - $.each(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (i, n) { - data[n] = canvas[n]; + forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) { + data[n] = canvasData[n]; }); } @@ -2538,35 +2868,34 @@ var methods = { /** * Set the canvas position and size with new data. * @param {Object} data - The new canvas data. + * @returns {Cropper} this */ setCanvasData: function setCanvasData(data) { - var canvas = this.canvas; - var aspectRatio = canvas.aspectRatio; + var canvasData = this.canvasData; + var aspectRatio = canvasData.aspectRatio; - if ($.isFunction(data)) { - data = data.call(this.$element); - } - - if (this.ready && !this.disabled && $.isPlainObject(data)) { + if (this.ready && !this.disabled && isPlainObject(data)) { if (isNumber(data.left)) { - canvas.left = data.left; + canvasData.left = data.left; } if (isNumber(data.top)) { - canvas.top = data.top; + canvasData.top = data.top; } if (isNumber(data.width)) { - canvas.width = data.width; - canvas.height = data.width / aspectRatio; + canvasData.width = data.width; + canvasData.height = data.width / aspectRatio; } else if (isNumber(data.height)) { - canvas.height = data.height; - canvas.width = data.height * aspectRatio; + canvasData.height = data.height; + canvasData.width = data.height * aspectRatio; } this.renderCanvas(true); } + + return this; }, @@ -2575,62 +2904,66 @@ var methods = { * @returns {Object} The result crop box data. */ getCropBoxData: function getCropBoxData() { - var cropBox = this.cropBox; + var cropBoxData = this.cropBoxData; + var data = void 0; - return this.ready && this.cropped ? { - left: cropBox.left, - top: cropBox.top, - width: cropBox.width, - height: cropBox.height - } : {}; + 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 {Cropper} this */ setCropBoxData: function setCropBoxData(data) { - var cropBox = this.cropBox; + 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 (this.ready && this.cropped && !this.disabled && isPlainObject(data)) { if (isNumber(data.left)) { - cropBox.left = data.left; + cropBoxData.left = data.left; } if (isNumber(data.top)) { - cropBox.top = data.top; + cropBoxData.top = data.top; } - if (isNumber(data.width) && data.width !== cropBox.width) { + if (isNumber(data.width) && data.width !== cropBoxData.width) { widthChanged = true; - cropBox.width = data.width; + cropBoxData.width = data.width; } - if (isNumber(data.height) && data.height !== cropBox.height) { + if (isNumber(data.height) && data.height !== cropBoxData.height) { heightChanged = true; - cropBox.height = data.height; + cropBoxData.height = data.height; } if (aspectRatio) { if (widthChanged) { - cropBox.height = cropBox.width / aspectRatio; + cropBoxData.height = cropBoxData.width / aspectRatio; } else if (heightChanged) { - cropBox.width = cropBox.height * aspectRatio; + cropBoxData.width = cropBoxData.height * aspectRatio; } } this.renderCropBox(); } + + return this; }, @@ -2646,9 +2979,9 @@ var methods = { return null; } - var canvasData = this.canvas; + var canvasData = this.canvasData; - var source = getSourceCanvas(this.$clone[0], this.image, canvasData, options); + var source = getSourceCanvas(this.image, this.imageData, canvasData, options); // Returns the source canvas if it is not cropped. if (!this.cropped) { @@ -2698,6 +3031,7 @@ var methods = { canvas.width = normalizeDecimalNumber(width); canvas.height = normalizeDecimalNumber(height); + context.fillStyle = options.fillColor || 'transparent'; context.fillRect(0, 0, width, height); @@ -2771,9 +3105,10 @@ var methods = { params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale); } - context.drawImage.apply(context, [source].concat(toConsumableArray($.map(params, function (param) { + context.drawImage.apply(context, [source].concat(toConsumableArray(params.map(function (param) { return Math.floor(normalizeDecimalNumber(param)); })))); + return canvas; }, @@ -2781,6 +3116,7 @@ var methods = { /** * Change the aspect ratio of the crop box. * @param {number} aspectRatio - The new aspect ratio. + * @returns {Cropper} this */ setAspectRatio: function setAspectRatio(aspectRatio) { var options = this.options; @@ -2798,34 +3134,47 @@ var methods = { } } } + + return this; }, /** * Change the drag mode. * @param {string} mode - The new drag mode. + * @returns {Cropper} this */ setDragMode: function setDragMode(mode) { - var options = this.options; + var options = this.options, + dragBox = this.dragBox, + face = this.face; + - var croppable = void 0; - var movable = void 0; + if (this.ready && !this.disabled) { + var croppable = mode === DRAG_MODE_CROP; + var movable = options.movable && mode === DRAG_MODE_MOVE; - if (this.loaded && !this.disabled) { - croppable = mode === DRAG_MODE_CROP; - movable = options.movable && mode === DRAG_MODE_MOVE; mode = croppable || movable ? mode : DRAG_MODE_NONE; - this.$dragBox.data(DATA_ACTION, mode).toggleClass(CLASS_CROP, croppable).toggleClass(CLASS_MOVE, movable); + options.dragMode = mode; + 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(#300) - this.$face.data(DATA_ACTION, mode).toggleClass(CLASS_CROP, croppable).toggleClass(CLASS_MOVE, movable); + // 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. @@ -2841,36 +3190,37 @@ var Cropper = function () { } this.element = element; - this.$element = $(element); - this.options = $.extend({}, DEFAULTS, $.isPlainObject(options) && options); - this.completed = false; + this.options = assign({}, DEFAULTS, isPlainObject(options) && options); this.cropped = false; this.disabled = false; - this.isImg = false; - this.limited = false; - this.loaded = false; + this.pointers = {}; this.ready = false; + this.reloading = false; this.replaced = false; - this.wheeling = false; - this.originalUrl = ''; - this.canvas = null; - this.cropBox = null; - this.pointers = {}; + this.sized = false; + this.sizing = false; this.init(); } createClass(Cropper, [{ key: 'init', value: function init() { - var $element = this.$element; + var element = this.element; + var tagName = element.tagName.toLowerCase(); var url = void 0; - if ($element.is('img')) { + if (getData(element, NAMESPACE)) { + return; + } + + setData(element, NAMESPACE, this); + + if (tagName === 'img') { this.isImg = true; - // Should use `$.fn.attr` here. e.g.: "img/picture.jpg" - url = $element.attr('src') || ''; + // e.g.: "img/picture.jpg" + url = element.getAttribute('src') || ''; this.originalUrl = url; // Stop when it's a blank image @@ -2878,26 +3228,14 @@ var Cropper = function () { return; } - // Should use `$.fn.prop` here. e.g.: "http://example.com/img/picture.jpg" - url = $element.prop('src'); - } else if ($element.is('canvas') && window.HTMLCanvasElement) { - url = $element[0].toDataURL(); + // e.g.: "http://example.com/img/picture.jpg" + url = element.src; + } else if (tagName === 'canvas' && window.HTMLCanvasElement) { + url = element.toDataURL(); } this.load(url); } - - // A shortcut for triggering custom events - - }, { - key: 'trigger', - value: function trigger(type, data) { - var e = $.Event(type, data); - - this.$element.trigger(e); - - return e; - } }, { key: 'load', value: function load(url) { @@ -2908,9 +3246,9 @@ var Cropper = function () { } this.url = url; - this.image = {}; + this.imageData = {}; - var $element = this.$element, + var element = this.element, options = this.options; @@ -2932,29 +3270,41 @@ var Cropper = function () { var xhr = new XMLHttpRequest(); + this.reloading = true; + this.xhr = xhr; + + var done = function done() { + _this.reloading = false; + _this.xhr = null; + }; + + xhr.ontimeout = done; + xhr.onabort = done; xhr.onerror = function () { + done(); _this.clone(); }; xhr.onload = function () { + done(); _this.read(xhr.response); }; // Bust cache when there is a "crossOrigin" property - if (options.checkCrossOrigin && isCrossOriginURL(url) && !$element.prop('crossOrigin')) { + if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) { url = addTimestamp(url); } xhr.open('get', url); xhr.responseType = 'arraybuffer'; - xhr.withCredentials = $element.prop('crossOrigin') === 'use-credentials'; + xhr.withCredentials = element.crossOrigin === 'use-credentials'; xhr.send(); } }, { key: 'read', value: function read(arrayBuffer) { var options = this.options, - image = this.image; + imageData = this.imageData; var orientation = getOrientation(arrayBuffer); var rotate = 0; @@ -2972,12 +3322,12 @@ var Cropper = function () { } if (options.rotatable) { - image.rotate = rotate; + imageData.rotate = rotate; } if (options.scalable) { - image.scaleX = scaleX; - image.scaleY = scaleY; + imageData.scaleX = scaleX; + imageData.scaleY = scaleY; } this.clone(); @@ -2985,22 +3335,22 @@ var Cropper = function () { }, { key: 'clone', value: function clone() { - var $element = this.$element, - options = this.options, + var element = this.element, url = this.url; - var crossOrigin = ''; + var crossOrigin = void 0; var crossOriginUrl = void 0; - if (options.checkCrossOrigin && isCrossOriginURL(url)) { - crossOrigin = $element.prop('crossOrigin'); + if (this.options.checkCrossOrigin && isCrossOriginURL(url)) { + crossOrigin = element.crossOrigin; + if (crossOrigin) { crossOriginUrl = url; } else { crossOrigin = 'anonymous'; - // Bust cache (#148) when there is not a "crossOrigin" property + // Bust cache when there is not a "crossOrigin" property crossOriginUrl = addTimestamp(url); } } @@ -3016,88 +3366,136 @@ var Cropper = function () { image.src = crossOriginUrl || url; - var $clone = $(image); + var start = this.start.bind(this); + var stop = this.stop.bind(this); - this.$clone = $clone; + this.image = image; + this.onStart = start; + this.onStop = stop; if (this.isImg) { - if (this.element.complete) { - this.start(); + if (element.complete) { + this.timeout = setTimeout(start, 0); } else { - $element.one(EVENT_LOAD, $.proxy(this.start, this)); + addListener(element, EVENT_LOAD, start, { + once: true + }); } } else { - $clone.one(EVENT_LOAD, $.proxy(this.start, this)).one(EVENT_ERROR, $.proxy(this.stop, this)).addClass(CLASS_HIDE).insertAfter($element); + image.onload = start; + image.onerror = stop; + addClass(image, CLASS_HIDE); + element.parentNode.insertBefore(image, element.nextSibling); } } }, { key: 'start', - value: function start() { + value: function start(event) { var _this2 = this; - var $clone = this.$clone; - - var $image = this.$element; + var image = this.isImg ? this.element : this.image; - if (!this.isImg) { - $clone.off(EVENT_ERROR, this.stop); - $image = $clone; + if (event) { + image.onload = null; + image.onerror = null; } - getImageNaturalSizes($image[0], function (naturalWidth, naturalHeight) { - $.extend(_this2.image, { + this.sizing = true; + + var IS_SAFARI = WINDOW.navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(WINDOW.navigator.userAgent); + var done = function done(naturalWidth, naturalHeight) { + assign(_this2.imageData, { naturalWidth: naturalWidth, naturalHeight: naturalHeight, aspectRatio: naturalWidth / naturalHeight }); - - _this2.loaded = true; + _this2.sizing = false; + _this2.sized = true; _this2.build(); - }); + }; + + // Modern browsers (except Safari) + if (image.naturalWidth && !IS_SAFARI) { + done(image.naturalWidth, image.naturalHeight); + return; + } + + var sizingImage = document.createElement('img'); + var body = document.body || document.documentElement; + + this.sizingImage = sizingImage; + + sizingImage.onload = function () { + done(sizingImage.width, sizingImage.height); + + if (!IS_SAFARI) { + body.removeChild(sizingImage); + } + }; + + sizingImage.src = image.src; + + // iOS Safari will convert the image automatically + // with its orientation once append it into DOM (#279) + if (!IS_SAFARI) { + sizingImage.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(sizingImage); + } } }, { key: 'stop', value: function stop() { - this.$clone.remove(); - this.$clone = null; + var image = this.image; + + + image.onload = null; + image.onerror = null; + image.parentNode.removeChild(image); + this.image = null; } }, { key: 'build', value: function build() { - var _this3 = this; - - if (!this.loaded) { + if (!this.sized || this.ready) { return; } - // Unbuild first when replace - if (this.ready) { - this.unbuild(); - } - - var $element = this.$element, + var element = this.element, options = this.options, - $clone = this.$clone; - - var $cropper = $(TEMPLATE); - var $cropBox = $cropper.find('.' + NAMESPACE + '-crop-box'); - var $face = $cropBox.find('.' + NAMESPACE + '-face'); + image = this.image; // Create cropper elements - this.$container = $element.parent(); - this.$cropper = $cropper; - this.$canvas = $cropper.find('.' + NAMESPACE + '-canvas').append($clone); - this.$dragBox = $cropper.find('.' + NAMESPACE + '-drag-box'); - this.$cropBox = $cropBox; - this.$viewBox = $cropper.find('.' + NAMESPACE + '-view-box'); - this.$face = $face; + + 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 - $element.addClass(CLASS_HIDDEN).after($cropper); + addClass(element, CLASS_HIDDEN); + + // Inserts the cropper after to the current image + container.insertBefore(cropper, element.nextSibling); - // Show the clone image if is hidden + // Show the image if is hidden if (!this.isImg) { - $clone.removeClass(CLASS_HIDE); + removeClass(image, CLASS_HIDE); } this.initPreview(); @@ -3106,55 +3504,51 @@ var Cropper = function () { 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) { - this.$dragBox.addClass(CLASS_MODAL); - } - } else { - $cropBox.addClass(CLASS_HIDDEN); - } + addClass(cropBox, CLASS_HIDDEN); if (!options.guides) { - $cropBox.find('.' + NAMESPACE + '-dashed').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-dashed'), CLASS_HIDDEN); } if (!options.center) { - $cropBox.find('.' + NAMESPACE + '-center').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-center'), CLASS_HIDDEN); } - if (options.cropBoxMovable) { - $face.addClass(CLASS_MOVE).data(DATA_ACTION, ACTION_ALL); + if (options.background) { + addClass(cropper, NAMESPACE + '-bg'); } if (!options.highlight) { - $face.addClass(CLASS_INVISIBLE); + addClass(face, CLASS_INVISIBLE); } - if (options.background) { - $cropper.addClass(NAMESPACE + '-bg'); + if (options.cropBoxMovable) { + addClass(face, CLASS_MOVE); + setData(face, DATA_ACTION, ACTION_ALL); } if (!options.cropBoxResizable) { - $cropBox.find('.' + NAMESPACE + '-line,.' + NAMESPACE + '-point').addClass(CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-line'), CLASS_HIDDEN); + addClass(cropBox.getElementsByClassName(NAMESPACE + '-point'), CLASS_HIDDEN); } - this.setDragMode(options.dragMode); this.render(); this.ready = true; + this.setDragMode(options.dragMode); + + if (options.autoCrop) { + this.crop(); + } + this.setData(options.data); - // Trigger the ready event asynchronously to keep `data('cropper')` is defined - this.completing = setTimeout(function () { - if ($.isFunction(options.ready)) { - $element.one(EVENT_READY, options.ready); - } + if (isFunction(options.ready)) { + addListener(element, EVENT_READY, options.ready, { + once: true + }); + } - _this3.trigger(EVENT_READY); - _this3.trigger(EVENT_CROP, _this3.getData()); - _this3.completed = true; - }, 0); + dispatchEvent(element, EVENT_READY); } }, { key: 'unbuild', @@ -3163,35 +3557,49 @@ var Cropper = function () { return; } - if (!this.completed) { - clearTimeout(this.completing); - } - this.ready = false; - this.completed = false; - this.initialImage = null; - - // Clear `initialCanvas` is necessary when replace - this.initialCanvas = null; - this.initialCropBox = null; - this.container = null; - this.canvas = null; - - // Clear `cropBox` is necessary when replace - this.cropBox = null; this.unbind(); - this.resetPreview(); - this.$preview = null; + this.cropper.parentNode.removeChild(this.cropper); + removeClass(this.element, CLASS_HIDDEN); + } + }, { + key: 'uncreate', + value: function uncreate() { + var element = this.element; + + + if (this.ready) { + this.unbuild(); + this.ready = false; + this.cropped = false; + } else if (this.sizing) { + this.sizingImage.onload = null; + this.sizing = false; + this.sized = false; + } else if (this.reloading) { + this.xhr.abort(); + } else if (this.isImg) { + if (element.complete) { + clearTimeout(this.timeout); + } else { + removeListener(element, EVENT_LOAD, this.onStart); + } + } else if (this.image) { + this.stop(); + } + } - this.$viewBox = null; - this.$cropBox = null; - this.$dragBox = null; - this.$canvas = null; - this.$container = null; + /** + * Get the no conflict cropper class. + * @returns {Cropper} The cropper class. + */ - this.$cropper.remove(); - this.$cropper = null; + }], [{ + key: 'noConflict', + value: function noConflict() { + window.Cropper = AnotherCropper; + return Cropper; } /** @@ -3199,21 +3607,20 @@ var Cropper = function () { * @param {Object} options - The new default options. */ - }], [{ + }, { key: 'setDefaults', value: function setDefaults(options) { - $.extend(DEFAULTS, $.isPlainObject(options) && options); + assign(DEFAULTS, isPlainObject(options) && options); } }]); return Cropper; }(); -if ($.extend) { - $.extend(Cropper.prototype, render, preview, events, handlers, change, methods); -} +assign(Cropper.prototype, render, preview, events, handlers, change, methods); if ($.fn) { - var AnotherCropper = $.fn.cropper; + var AnotherCropper$1 = $.fn.cropper; + var NAMESPACE$1 = 'cropper'; $.fn.cropper = function jQueryCropper(option) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { @@ -3224,35 +3631,44 @@ if ($.fn) { this.each(function (i, element) { var $element = $(element); - var data = $element.data(NAMESPACE); + var isDestroy = option === 'destroy'; + var cropper = $element.data(NAMESPACE$1); - if (!data) { - if (/destroy/.test(option)) { + if (!cropper) { + if (isDestroy) { return; } var options = $.extend({}, $element.data(), $.isPlainObject(option) && option); - data = new Cropper(element, options); - $element.data(NAMESPACE, data); + cropper = new Cropper(element, options); + $element.data(NAMESPACE$1, cropper); } - if (isString(option)) { - var fn = data[option]; + if (typeof option === 'string') { + var fn = cropper[option]; if ($.isFunction(fn)) { - result = fn.apply(data, args); + result = fn.apply(cropper, args); + + if (result === cropper) { + result = undefined; + } + + if (isDestroy) { + $element.removeData(NAMESPACE$1); + } } } }); - return isUndefined(result) ? this : result; + return typeof result === 'undefined' ? this : result; }; $.fn.cropper.Constructor = Cropper; $.fn.cropper.setDefaults = Cropper.setDefaults; $.fn.cropper.noConflict = function noConflict() { - $.fn.cropper = AnotherCropper; + $.fn.cropper = AnotherCropper$1; return this; }; } diff --git a/docs/js/main.js b/docs/js/main.js index f384f785..6dda1d8c 100644 --- a/docs/js/main.js +++ b/docs/js/main.js @@ -17,13 +17,13 @@ $(function () { aspectRatio: 16 / 9, preview: '.img-preview', crop: function (e) { - $dataX.val(Math.round(e.x)); - $dataY.val(Math.round(e.y)); - $dataHeight.val(Math.round(e.height)); - $dataWidth.val(Math.round(e.width)); - $dataRotate.val(e.rotate); - $dataScaleX.val(e.scaleX); - $dataScaleY.val(e.scaleY); + $dataX.val(Math.round(e.detail.x)); + $dataY.val(Math.round(e.detail.y)); + $dataHeight.val(Math.round(e.detail.height)); + $dataWidth.val(Math.round(e.detail.width)); + $dataRotate.val(e.detail.rotate); + $dataScaleX.val(e.detail.scaleX); + $dataScaleY.val(e.detail.scaleY); } }; var originalImageURL = $image.attr('src'); @@ -42,19 +42,19 @@ $(function () { console.log(e.type); }, cropstart: function (e) { - console.log(e.type, e.action); + console.log(e.type, e.detail.action); }, cropmove: function (e) { - console.log(e.type, e.action); + console.log(e.type, e.detail.action); }, cropend: function (e) { - console.log(e.type, e.action); + console.log(e.type, e.detail.action); }, crop: function (e) { - console.log(e.type, e.x, e.y, e.width, e.height, e.rotate, e.scaleX, e.scaleY); + console.log(e.type); }, zoom: function (e) { - console.log(e.type, e.ratio); + console.log(e.type, e.detail.ratio); } }).cropper(options); diff --git a/docs/v0.7.9/css/cropper.css b/docs/v0.7.9/css/cropper.css deleted file mode 100644 index 96770115..00000000 --- a/docs/v0.7.9/css/cropper.css +++ /dev/null @@ -1,278 +0,0 @@ -/*! - * Cropper v0.7.9 - * https://github.com/fengyuanchen/cropper - * - * Copyright 2014-2015 Fengyuan Chen - * Released under the MIT license - */ - -.cropper-container { - position: relative; - overflow: hidden; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - -webkit-tap-highlight-color: transparent; - -webkit-touch-callout: none; -} - -.cropper-container img { - width: 100%; - min-width: 0 !important; - max-width: none !important; - height: 100%; - min-height: 0 !important; - max-height: none !important; -} - -.cropper-modal, -.cropper-canvas { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; -} - -.cropper-canvas { - background-color: #fff; - filter: alpha(opacity=0); - opacity: 0; -} - -.cropper-modal { - background-color: #000; - filter: alpha(opacity=50); - opacity: .5; -} - -.cropper-dragger { - position: absolute; - top: 10%; - left: 10%; - width: 80%; - height: 80%; -} - -.cropper-viewer { - display: block; - width: 100%; - height: 100%; - overflow: hidden; - outline-width: 1px; - outline-style: solid; - outline-color: #69f; - outline-color: rgba(51, 102, 255, .75); -} - -.cropper-dashed { - position: absolute; - display: block; - filter: alpha(opacity=50); - border: 0 dashed #fff; - opacity: .5; -} - -.cropper-dashed.dashed-h { - top: 33.3%; - left: 0; - width: 100%; - height: 33.3%; - border-top-width: 1px; - border-bottom-width: 1px; -} - -.cropper-dashed.dashed-v { - top: 0; - left: 33.3%; - width: 33.3%; - height: 100%; - border-right-width: 1px; - border-left-width: 1px; -} - -.cropper-face, -.cropper-line, -.cropper-point { - position: absolute; - display: block; - width: 100%; - height: 100%; - filter: alpha(opacity=10); - opacity: .1; -} - -.cropper-face { - top: 0; - left: 0; - cursor: move; - background-color: #fff; -} - -.cropper-line { - background-color: #69f; -} - -.cropper-line.line-e { - top: 0; - right: -3px; - width: 5px; - cursor: e-resize; -} - -.cropper-line.line-n { - top: -3px; - left: 0; - height: 5px; - cursor: n-resize; -} - -.cropper-line.line-w { - top: 0; - left: -3px; - width: 5px; - cursor: w-resize; -} - -.cropper-line.line-s { - bottom: -3px; - left: 0; - height: 5px; - cursor: s-resize; -} - -.cropper-point { - width: 5px; - height: 5px; - background-color: #69f; - filter: alpha(opacity=75); - opacity: .75; -} - -.cropper-point.point-e { - top: 50%; - right: -3px; - margin-top: -3px; - cursor: e-resize; -} - -.cropper-point.point-n { - top: -3px; - left: 50%; - margin-left: -3px; - cursor: n-resize; -} - -.cropper-point.point-w { - top: 50%; - left: -3px; - margin-top: -3px; - cursor: w-resize; -} - -.cropper-point.point-s { - bottom: -3px; - left: 50%; - margin-left: -3px; - cursor: s-resize; -} - -.cropper-point.point-ne { - top: -3px; - right: -3px; - cursor: ne-resize; -} - -.cropper-point.point-nw { - top: -3px; - left: -3px; - cursor: nw-resize; -} - -.cropper-point.point-sw { - bottom: -3px; - left: -3px; - cursor: sw-resize; -} - -.cropper-point.point-se { - right: -3px; - bottom: -3px; - width: 20px; - height: 20px; - cursor: se-resize; - filter: alpha(opacity=100); - opacity: 1; -} - -.cropper-point.point-se:before { - position: absolute; - right: -50%; - bottom: -50%; - display: block; - width: 200%; - height: 200%; - content: " "; - background-color: #69f; - filter: alpha(opacity=0); - opacity: 0; -} - -@media (min-width: 768px) { - .cropper-point.point-se { - width: 15px; - height: 15px; - } -} - -@media (min-width: 992px) { - .cropper-point.point-se { - width: 10px; - height: 10px; - } -} - -@media (min-width: 1200px) { - .cropper-point.point-se { - width: 5px; - height: 5px; - filter: alpha(opacity=75); - opacity: .75; - } -} - -/* Helper classes for JavaScript */ - -.cropper-hidden { - display: none !important; -} - -.cropper-invisible { - position: fixed; - top: 0; - left: 0; - z-index: -1; - width: auto !important; - max-width: none !important; - height: auto !important; - max-height: none !important; - filter: alpha(opacity=0); - opacity: 0; -} - -.cropper-move { - cursor: move; -} - -.cropper-crop { - cursor: crosshair; -} - -.cropper-disabled .cropper-canvas, -.cropper-disabled .cropper-face, -.cropper-disabled .cropper-line, -.cropper-disabled .cropper-point { - cursor: not-allowed; -} diff --git a/docs/v0.7.9/css/cropper.min.css b/docs/v0.7.9/css/cropper.min.css deleted file mode 100644 index 4cf08201..00000000 --- a/docs/v0.7.9/css/cropper.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Cropper v0.7.9 - * https://github.com/fengyuanchen/cropper - * - * Copyright 2014-2015 Fengyuan Chen - * Released under the MIT license - */ - -.cropper-container{position:relative;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.cropper-container img{width:100%;height:100%;min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important}.cropper-canvas,.cropper-modal{position:absolute;top:0;right:0;bottom:0;left:0}.cropper-canvas{background-color:#fff;opacity:0;filter:alpha(opacity=0)}.cropper-modal{background-color:#000;opacity:.5;filter:alpha(opacity=50)}.cropper-dragger{position:absolute;top:10%;left:10%;width:80%;height:80%}.cropper-viewer{display:block;width:100%;height:100%;overflow:hidden;outline:#69f solid 1px;outline-color:rgba(51,102,255,.75)}.cropper-dashed{position:absolute;display:block;border:0 dashed #fff;opacity:.5;filter:alpha(opacity=50)}.cropper-dashed.dashed-h{top:33.3%;left:0;width:100%;height:33.3%;border-top-width:1px;border-bottom-width:1px}.cropper-dashed.dashed-v{top:0;left:33.3%;width:33.3%;height:100%;border-right-width:1px;border-left-width:1px}.cropper-face,.cropper-line,.cropper-point{position:absolute;display:block;width:100%;height:100%;opacity:.1;filter:alpha(opacity=10)}.cropper-face{top:0;left:0;cursor:move;background-color:#fff}.cropper-line{background-color:#69f}.cropper-line.line-e{top:0;right:-3px;width:5px;cursor:e-resize}.cropper-line.line-n{top:-3px;left:0;height:5px;cursor:n-resize}.cropper-line.line-w{top:0;left:-3px;width:5px;cursor:w-resize}.cropper-line.line-s{bottom:-3px;left:0;height:5px;cursor:s-resize}.cropper-point{width:5px;height:5px;background-color:#69f;opacity:.75;filter:alpha(opacity=75)}.cropper-point.point-e{top:50%;right:-3px;margin-top:-3px;cursor:e-resize}.cropper-point.point-n{top:-3px;left:50%;margin-left:-3px;cursor:n-resize}.cropper-point.point-w{top:50%;left:-3px;margin-top:-3px;cursor:w-resize}.cropper-point.point-s{bottom:-3px;left:50%;margin-left:-3px;cursor:s-resize}.cropper-point.point-ne{top:-3px;right:-3px;cursor:ne-resize}.cropper-point.point-nw{top:-3px;left:-3px;cursor:nw-resize}.cropper-point.point-sw{bottom:-3px;left:-3px;cursor:sw-resize}.cropper-point.point-se{right:-3px;bottom:-3px;width:20px;height:20px;cursor:se-resize;opacity:1;filter:alpha(opacity=100)}.cropper-point.point-se:before{position:absolute;right:-50%;bottom:-50%;display:block;width:200%;height:200%;content:" ";background-color:#69f;opacity:0;filter:alpha(opacity=0)}@media (min-width:768px){.cropper-point.point-se{width:15px;height:15px}}@media (min-width:992px){.cropper-point.point-se{width:10px;height:10px}}@media (min-width:1200px){.cropper-point.point-se{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}}.cropper-hidden{display:none!important}.cropper-invisible{position:fixed;top:0;left:0;z-index:-1;width:auto!important;max-width:none!important;height:auto!important;max-height:none!important;opacity:0;filter:alpha(opacity=0)}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-canvas,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed} \ No newline at end of file diff --git a/docs/v0.7.9/css/main.css b/docs/v0.7.9/css/main.css deleted file mode 100644 index 9921f24d..00000000 --- a/docs/v0.7.9/css/main.css +++ /dev/null @@ -1,248 +0,0 @@ -/* Main - * ========================================================================== */ - -/* Basic style - * -------------------------------------------------------------------------- */ - -/* Overview */ - -.docs-overview h3, -.docs-getting-started h4 { - border-left: 1px solid #69f; - padding-left: 10px; -} - -.docs-getting-started h4 { - padding-left: 8px; -} - -.img-container, -.img-preview { - background-color: #f7f7f7; - overflow: hidden; - width: 100%; - text-align: center; -} - -.img-container { - box-shadow: inset 0 0 5px #eee; - height: 344px; -} - -.img-container > img { - max-width: 100%; - max-height: inherit; -} - -.img-preview { - margin-bottom: 10px; -} - -.img-preview-sm { - height: 90px; - width: 160px; -} - -.img-preview-xs { - height: 36px; - width: 64px; -} - -.docs-btn-group .input-group { - margin-bottom: 10px; -} - -.docs-btn-group .button-group > .btn { - margin-right: 10px; - margin-bottom: 10px; -} - -.docs-toolbar { - margin-top: 10px; - margin-bottom: -10px; - text-align: center; -} - -.docs-toolbar .docs-tooltip { - display: block; - margin: -6px -12px; - padding: 6px 12px; -} - -.docs-data-url .btn { - margin-right: 10px; - margin-bottom: 10px; -} - -.docs-data-url textarea { - margin-bottom: 10px; -} - -.docs-data-url img { - max-height: 174px; -} - -.docs-flip-horizontal { - -ms-transform: scale(-1, 1); - -webkit-transform: scale(-1, 1); - transform: scale(-1, 1); -} - -.docs-data > .input-group { - margin-bottom: 10px; -} - -.docs-data > .input-group > label { - min-width: 80px; -} - -.docs-data > .input-group > span { - min-width: 50px; -} - - -/* Examples */ - -.bootstrap-modal-cropper img { - width: 100%; -} - -/* Footer */ - -.docs-footer { - border-top: 1px solid #eee; - margin-top: 100px; - padding-top: 30px; - padding-bottom: 30px; -} - - -/* Reset Bootstrap - * -------------------------------------------------------------------------- */ - -code { - white-space: normal; -} - -/* Top navbar */ - -.docs-navbar-top { - margin-bottom: 0; -} - -.docs-navbar-top .nav > li > a { - border-top: 1px solid transparent; -} - -.docs-navbar-top .nav > li > a:hover { - border-color: #85c9de; - background-color: #fcfcfc; -} - -@media (max-width: 767px) { - .docs-navbar-top .nav > li > a { - border-top: 0; - border-left: 1px solid transparent; - } -} - -.docs-navbar-top .navbar-toggle { - border-color: #85c9de; -} - -.docs-navbar-top .navbar-toggle .icon-bar { - background-color: #85c9de; -} - -/* Banner */ - -.docs-jumbotron { - background-color: #85c9de; - color: #fff; -} - -/* Sidebar fixed */ - -@media (min-width: 992px) { - .docs-sidebar.fixed { - position: fixed; - top: 20px; - } -} - -.docs-sidebar .back-to-top { - margin-top: 5px; - padding-left: 11px; - font-size: 12px; -} - -/* Sidebar nav */ - -.docs-sidebar .nav > li > a { - border-left: 1px solid transparent; - padding: 4px 10px; -} - -.docs-sidebar .nav > li > a:hover { - border-color: #85c9de; - background-color: #fcfcfc; -} - -/* Alerts - * -------------------------------------------------------------------------- */ -.docs-alert { - display: none; - position: fixed; - top: 20px; - left: 0; - right: 0; - height: 0; - text-align: center; - opacity: 0.9; -} - -.docs-alert .message { - display: inline-block; - padding: 5px 10px; - border-radius: 2px; - background-color: #aaa; - color: #fff; -} - -.docs-alert .primary { - background-color: #0074d9; -} - -.docs-alert .success { - background-color: #2ecc40; -} - -.docs-alert .info { - background-color: #39cccc; -} - -.docs-alert .warning { - background-color: #ff851b; -} - -.docs-alert .danger { - background-color: #ff4136; -} - -/* Examples - * -------------------------------------------------------------------------- */ -.fixed-dragger-cropper { - max-height: 354px; - overflow: hidden; -} - -.fixed-dragger-cropper > img { - width: 100%; -} - -/* Google code prettify - * -------------------------------------------------------------------------- */ -.prettyprint { - border: 1px solid #ddd !important; - padding: 10px 15px !important; -} diff --git a/docs/v0.7.9/img/picture-1.jpg b/docs/v0.7.9/img/picture-1.jpg deleted file mode 100644 index b60f1dbb..00000000 Binary files a/docs/v0.7.9/img/picture-1.jpg and /dev/null differ diff --git a/docs/v0.7.9/img/picture-2.jpg b/docs/v0.7.9/img/picture-2.jpg deleted file mode 100644 index dcadb53b..00000000 Binary files a/docs/v0.7.9/img/picture-2.jpg and /dev/null differ diff --git a/docs/v0.7.9/index.html b/docs/v0.7.9/index.html deleted file mode 100644 index 55932824..00000000 --- a/docs/v0.7.9/index.html +++ /dev/null @@ -1,914 +0,0 @@ - - - - - - - - - - Cropper - - - - - - - - - - - - -
-
-

Cropper

-

A simple jQuery image cropping plugin.

-

- Download - View on GitHub -

-
-
- - - - -
-

Overview

-
-
-

Image:

-
-
-
- - - - - - - - - -
-
-
-
-

Preview:

-
-
-
-
-
-
-
-
-
-

Data:

-
-
- - - px -
-
- - - px -
-
- - - px -
-
- - - px -
- -
-
-
-
-
-
-

Methods:

-
- - - - - - - - -
- -
-
-
- X - - px -
-
-
-
- Y - - px -
-
-
-
- Width - - px -
-
-
-
- Height - - px -
-
-
- -
-
-
- - - - -
-
-
-
- - - - - deg -
-
-
- -
-
-
- - - - -
-
-
-
- - - - -
-
-
- -
-
-
- - - - -
-
-
-
- - - - -
-
-
- -
-
- - - - -
-
- -
-
-
-
-
-
-
-
-

Options:

-
-
- -
-
- - -
-
-
-
- -
-
- - -
-
-
-
- -
-
- - -
-
-
-
- -
-
- - -
-
-
-
- -
-
- - -
-
-
-
- -
-
- - -
-
-
-
- -
-
- - -
-
-
-
- -
-
- - -
-
-
-
- -
-
- - -
-
-
-
-
-
-
-

Sources:

-

HTML:

-
...
-<div class="img-container">
-  <img src="img/picture-1.jpg">
-</div>
-...
-<div class="img-preview"></div>
-...
-

Javascript:

-
var $image = $(".img-container img"),
-    $dataX = $("#dataX"),
-    $dataY = $("#dataY"),
-    $dataHeight = $("#dataHeight"),
-    $dataWidth = $("#dataWidth");
-
-$image.cropper({
-  aspectRatio: 16 / 9,
-  data: {
-    x: 480,
-    y: 60,
-    width: 640,
-    height: 360
-  },
-  preview: ".img-preview",
-  done: function(data) {
-    $dataX.val(Math.round(data.x));
-    $dataY.val(Math.round(data.y));
-    $dataHeight.val(Math.round(data.height));
-    $dataWidth.val(Math.round(data.width));
-  }
-});
-
-...
-
-$("#reset").click(function() {
-  $image.cropper("reset");
-});
-
-...
-
-
- - -
-

Features

-
    -
  • Supports touch
  • -
  • Supports zoom
  • -
  • Supports rotation
  • -
  • Supports canvas
  • -
  • Supports options
  • -
  • Supports methods
  • -
  • Supports events
  • -
  • Cross-browser support
  • -
-
- - -
-

Getting started

-
-
- -

Installation

-

Include files:

-
<script src="/path/to/jquery.js"></script><!-- jQuery is required -->
-<link  href="/path/to/cropper.css" rel="stylesheet">
-<script src="/path/to/cropper.js"></script>
- - -

Usage

-

Initialize with $.fn.cropper method.

-

HTML:

-
<!-- Wrap the image with a block element -->
-<div class="container">
-  <img src="picture.jpg">
-</div>
-

Javascript:

-
$(".container > img").cropper({
-  aspectRatio: 1.618,
-  done: function(data) {
-    // Output the result data for cropping image.
-  }
-});
-
-

Notes:

-

- The size of the cropper inherits from the size of the image's parent element, so be sure to wrap the image with a visible block element.

-

- The values of the result data was computed with the original size of the image, so you can use them to crop the image directly.

-
- - -

Options

-

You may set cropper options with $().cropper(options).

-

If you want to change the global default options, You may use $.fn.cropper.setDefaults(options).

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDefaultDescription
aspectRatiostring / number"auto"The aspect ratio of the cropping zone.
By default, the cropping zone is free ratio.
dataobject{}Only supports four properties: "x", "y", "width" and "height". By default, the cropping zone will appear in the center of the image.
donefunctionfunction (data) {}This function will be executed when the cropping zone changes by a move, resize or crop.
previewselector""A jquery selector, add extra elements for preview.
multiplebooleanfalseBy default, the plugin only supports one cropper per page. If you intend to use more than one, just initialize them with this option set to true.
modalbooleantrueShow (true) or hide (false) the black modal layer above the cropper.
dashedbooleantrueShow (true) or hide (false) the dashed lines above the cropping zone.
autoCropbooleantrueRender the cropping zone automatically when initialize.
autoCropAreanumber0.8A number between 0 and 1. Define the automatic cropping area size (percentage).
dragCropbooleantrueEnable to remove the current cropping zone and create a new one by dragging over the image.
movablebooleantrueEnable to move the cropping zone.
resizablebooleantrueEnable to resize the cropping zone.
zoomablebooleantrueEnable to zoom the image.
rotatablebooleantrueEnable to rotate the image.
checkImageOriginbooleantrueBy default, the plugin will check the image origin, and if it is a cross-origin image, a "crossOrigin" attribute will be added to the image element to enable "rotate" and "getDataURL".
minWidthnumber0The minimum width (px of original image) of the cropping zone.
Use this option only when you are sure that the image has this minimum width.
minHeightnumber0The minimum height (px of original image) of the cropping zone.
Use this option only when you are sure that the image has this minimum height.
maxWidthnumberInfinityThe maximum width (px of original image) of the cropping zone.
Use this option only when you are sure that the image has this maximum width.
maxHeightnumberInfinityThe maximum height (px of original image) of the cropping zone.
Use this option only when you are sure that the image has this maximum height.
minContainerWidthnumber300The minimum width of the cropper container.
minContainerHeightnumber150The minimum height of the cropper container.
buildfunctionnullAn event handler of the "build.cropper" event.
builtfunctionnullAn event handler of the "built.cropper" event.
dragstartfunctionnullAn event handler of the "dragstart.cropper" event.
dragmovefunctionnullAn event handler of the "dragmove.cropper" event.
dragendfunctionnullAn event handler of the "dragend.cropper" event.
-
- - -

Methods

-

zoom

-
    -
  • Zoom the image.
  • -
  • Param: a number (positive number for zoom in, negative number for zoom out).
  • -
  • Usage: $().cropper("zoom", 0.1) or $().cropper("zoom", -0.1)
  • -
-

rotate

-
    -
  • Rotate the image (Replace the original image with a new rotated image which was generated by canvas)
  • -
  • Param: a number (positive number for rotate right, negative number for rotate left)..
  • -
  • Usage: $().cropper("rotate", 180) or $().cropper("rotate", -180)
  • -
  • Note: Be sure the browser supports canvas before call this method.
  • -
-

enable

-
    -
  • Enable (unfreeze) the cropper
  • -
  • Usage: $().cropper("enable")
  • -
-

disable

-
    -
  • Disable (freeze) the cropper
  • -
  • Usage: $().cropper("disable")
  • -
-

reset

-
    -
  • Reset the cropping zone to the start state.
  • -
  • Add a true param to reset the cropping zone to the default state.
  • -
  • Usage: $().cropper("reset") or $().cropper("reset", true)
  • -
-

clear

-
    -
  • Clear the cropping zone.
  • -
  • Usage: $().cropper("clear").
  • -
-

replace

-
    -
  • Replace the image.
  • -
  • Usage: $().cropper("replace", "example.jpg").
  • -
-

destroy

-
    -
  • Destroy the cropper and remove the instance from the image.
  • -
  • Usage: $().cropper("destroy").
  • -
-

getData

-
    -
  • Get the cropped zone data. Add a true parameter to get rounded data.
  • -
  • Usage: $().cropper("getData") or $().cropper("getData", true).
  • -
-

setData

-
    -
  • Reset the cropped zone with new data.
  • -
  • Param: an object containing "x1", "y1", "width", "height".
  • -
  • Usage: $().cropper("setData", {width: 480, height: 270}).
  • -
  • Tip: If you want to remove the current data, just pass an empty object or null. For example: $().cropper("setData", {}) or $().cropper("setData", null).
  • -
-

setAspectRatio

-
    -
  • Enable to reset the aspect ratio after built.
  • -
  • Param: "auto" or a positive number ("auto" for free ratio).
  • -
  • Usage: $().cropper("setAspectRatio", 1.618).
  • -
-

getImageData

-
    -
  • Get an object containing image data, contains: "naturalWidth", "naturalHeight", "width", "height", "aspectRatio", "ratio" and "rotate".
  • -
  • The "aspectRatio" is the value of "naturalWidth / naturalHeight".
  • -
  • The "ratio" is the value of "width / naturalWidth".
  • -
  • The "rotate" is the rotated degree of the current image.
  • -
  • Usage: $().cropper("getImageData").
  • -
-

setDragMode

-
    -
  • Change the drag mode.
  • -
  • Params: "crop", "move" and "none".
  • -
  • Usage: $().cropper("setDragMode", "crop").
  • -
  • Tips: You can toggle the "crop" and "move" mode by double click on the image.
  • -
-

getDataURL([options[, type[, quality]]])

-
    -
  • Get the data url (base64 image) of the cropped zone.
  • -
  • Param @options: A Object contains: "width", "height". Define the sizes of the result image.
  • -
  • Param @type: A String indicating the image format. The default type is image/png. Other types: "image/jpeg", "image/webp".
  • -
  • Param @quality: A Number between 0 and 1 indicating image quality if the requested type is image/jpeg or image/webp.
  • -
  • Usage: $().cropper("getDataURL") or $().cropper("getDataURL", {width:100, height: 100}, "image/jpeg", 0.6) or $().cropper("getDataURL", "image/jpeg") or $().cropper("getDataURL", "image/jpeg", 0.6).
  • -
  • Note: Be sure the browser supports canvas before call this method.
  • -
- - -

Events

-

build.cropper

-

This event will be fired when the Cropper starts to build.

-

built.cropper

-

This event will be fired when the Cropper has been built.

-

dragstart.cropper

-

This event will be fired before the cropping zone start to move.

-

dragmove.cropper

-

This event will be fired when the cropping zone was moving.

-

dragend.cropper

-

This event will be fired after the cropping zone stop to move.

-
- -
-
- - -
-

Examples

-

Cropper with fixed dragger.

-
-
-

Demo:

-
- Picture -
-
-
-

HTML:

-
<div class="fixed-dragger-cropper">
-  <img src="img/picture-1.jpg">
-</div>
-

JavaScript:

-
$(".fixed-dragger-cropper > img").cropper({
-  aspectRatio: 640 / 320,
-  autoCropArea: 0.6, // Center 60%
-  multiple: false,
-  dragCrop: false,
-  dashed: false,
-  movable: false,
-  resizable: false,
-  built: function () {
-    $(this).cropper("zoom", 0.5);
-  }
-});
-
-
- -
- -

Cropper in a Bootstrap modal

-
-
-

HTML:

-
<div class="modal" id="bootstrap-modal">
-  <div class="modal-dialog">
-    ...
-    <div class="modal-body">
-      <div class="bootstrap-modal-cropper">
-        <img src="img/picture-1.jpg">
-      </div>
-    </div>
-    ...
-  </div>
-</div>
- -

Demo:

-

- -
-
-

JavaScript:

-
var $image = $(".bootstrap-modal-cropper > img"),
-    originalData = {};
-
-$("#bootstrap-modal").on("shown.bs.modal", function() {
-  $image.cropper({
-    multiple: true,
-    data: originalData,
-    done: function(data) {
-      console.log(data);
-    }
-  });
-}).on("hidden.bs.modal", function() {
-  originalData = $image.cropper("getData");
-  $image.cropper("destroy");
-});
-
-
-
- -
- -

Crop avatar A complete example

-

This example require a PHP server, please download and test it.

-

- Download - View the sources -

-
- - - - - -
- - - - - - - - - diff --git a/docs/v0.7.9/js/cropper.js b/docs/v0.7.9/js/cropper.js deleted file mode 100644 index 8c416a39..00000000 --- a/docs/v0.7.9/js/cropper.js +++ /dev/null @@ -1,1641 +0,0 @@ -/*! - * Cropper v0.7.9 - * https://github.com/fengyuanchen/cropper - * - * Copyright 2014-2015 Fengyuan Chen - * Released under the MIT license - */ - -(function (factory) { - if (typeof define === "function" && define.amd) { - // AMD. Register as anonymous module. - define(["jquery"], factory); - } else if (typeof exports === "object") { - // Node / CommonJS - factory(require("jquery")); - } else { - // Browser globals. - factory(jQuery); - } -})(function ($) { - - "use strict"; - - var $window = $(window), - $document = $(document), - location = window.location, - - // Constants - TRUE = true, - FALSE = false, - NULL = null, - NAN = NaN, - INFINITY = Infinity, - STRING_UNDEFINED = "undefined", - STRING_DIRECTIVE = "directive", - CROPPER_NAMESPACE = ".cropper", - - // RegExps - REGEXP_DIRECTIVES = /^(e|n|w|s|ne|nw|sw|se|all|crop|move|zoom)$/, - REGEXP_OPTIONS = /^(x|y|width|height)$/, - REGEXP_PROPERTIES = /^(naturalWidth|naturalHeight|width|height|aspectRatio|ratio|rotate)$/, - - // Classes - CLASS_MODAL = "cropper-modal", - CLASS_HIDDEN = "cropper-hidden", - CLASS_INVISIBLE = "cropper-invisible", - CLASS_MOVE = "cropper-move", - CLASS_CROP = "cropper-crop", - CLASS_DISABLED = "cropper-disabled", - - // Events - EVENT_MOUSE_DOWN = "mousedown touchstart", - EVENT_MOUSE_MOVE = "mousemove touchmove", - EVENT_MOUSE_UP = "mouseup mouseleave touchend touchleave touchcancel", - EVENT_WHEEL = "wheel mousewheel DOMMouseScroll", - EVENT_RESIZE = "resize" + CROPPER_NAMESPACE, // Bind to window with namespace - EVENT_DBLCLICK = "dblclick", - EVENT_BUILD = "build" + CROPPER_NAMESPACE, - EVENT_BUILT = "built" + CROPPER_NAMESPACE, - EVENT_DRAG_START = "dragstart" + CROPPER_NAMESPACE, - EVENT_DRAG_MOVE = "dragmove" + CROPPER_NAMESPACE, - EVENT_DRAG_END = "dragend" + CROPPER_NAMESPACE, - - // Functions - isNumber = function (n) { - return typeof n === "number"; - }, - - toArray = function (obj, offset) { - var args = []; - - if (isNumber(offset)) { // It's necessary for IE8 - args.push(offset); - } - - return args.slice.apply(obj, args); - }, - - // Custom proxy to avoid jQuery's guid - proxy = function (fn, context) { - var args = toArray(arguments, 2); - - return function () { - return fn.apply(context, args.concat(toArray(arguments))); - }; - }, - - addTimestamp = function (url) { - var timestamp = "timestamp=" + (new Date()).getTime(); - - return (url + (url.indexOf("?") === -1 ? "?" : "&") + timestamp); - }, - - // Constructor - Cropper = function (element, options) { - this.element = element; - this.$element = $(element); - this.defaults = $.extend({}, Cropper.DEFAULTS, $.isPlainObject(options) ? options : {}); - this.$original = NULL; - this.ready = FALSE; - this.built = FALSE; - this.cropped = FALSE; - this.rotated = FALSE; - this.disabled = FALSE; - this.replaced = FALSE; - this.init(); - }, - - // Others - sqrt = Math.sqrt, - min = Math.min, - max = Math.max, - abs = Math.abs, - sin = Math.sin, - cos = Math.cos, - num = parseFloat; - - Cropper.prototype = { - constructor: Cropper, - - support: { - canvas: $.isFunction($("")[0].getContext) - }, - - init: function () { - var defaults = this.defaults; - - $.each(defaults, function (i, n) { - switch (i) { - case "aspectRatio": - defaults[i] = abs(num(n)) || NAN; // 0 -> NaN - break; - - case "autoCropArea": - defaults[i] = abs(num(n)) || 0.8; // 0 | NaN -> 0.8 - break; - - case "minWidth": - case "minHeight": - defaults[i] = abs(num(n)) || 0; // NaN -> 0 - break; - - case "maxWidth": - case "maxHeight": - defaults[i] = abs(num(n)) || INFINITY; // 0 | NaN -> Infinity - break; - - // No default - } - }); - - // Set default image data - this.image = { - rotate: 0 - }; - - this.load(); - }, - - load: function () { - var _this = this, - $this = this.$element, - element = this.element, - image = this.image, - crossOrigin = "", - $clone, - url; - - if ($this.is("img")) { - url = $this.prop("src"); - } else if ($this.is("canvas") && this.support.canvas) { - url = element.toDataURL(); - } - - if (!url) { - return; - } - - // Reset image rotate degree - if (this.replaced) { - image.rotate = 0; - } - - if (this.defaults.checkImageOrigin && this.isCrossOriginURL(url)) { - crossOrigin = " crossOrigin"; - url = addTimestamp(url); // Bust cache (#119, #148) - } - - this.$clone = ($clone = $("')); - - $clone.one("load", function () { - image.naturalWidth = this.naturalWidth || $clone.width(); - image.naturalHeight = this.naturalHeight || $clone.height(); - image.aspectRatio = image.naturalWidth / image.naturalHeight; - - _this.url = url; - _this.ready = TRUE; - _this.build(); - }); - - // Hide and prepend the clone iamge to the document body (Don't append to). - $clone.addClass(CLASS_INVISIBLE).prependTo("body"); - }, - - isCrossOriginURL: function (url) { - var parts = url.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i); - - if (parts && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port)) { - return TRUE; - } - - return FALSE; - }, - - build: function () { - var $this = this.$element, - defaults = this.defaults, - buildEvent, - $cropper; - - if (!this.ready) { - return; - } - - if (this.built) { - this.unbuild(); - } - - $this.one(EVENT_BUILD, defaults.build); // Only trigger once - buildEvent = $.Event(EVENT_BUILD); - $this.trigger(buildEvent); - - if (buildEvent.isDefaultPrevented()) { - return; - } - - // Create cropper elements - this.$cropper = ($cropper = $(Cropper.TEMPLATE)); - - // Hide the original image - $this.addClass(CLASS_HIDDEN); - - // Show and prepend the clone iamge to the cropper - this.$clone.removeClass(CLASS_INVISIBLE).prependTo($cropper); - - // Save original image for rotation - if (!this.rotated) { - this.$original = this.$clone.clone(); - - // Append the image to document to avoid "NS_ERROR_NOT_AVAILABLE" error on Firefox when call the "drawImage" method. - this.$original.addClass(CLASS_HIDDEN).prependTo(this.$cropper); - - this.originalImage = $.extend({}, this.image); - } - - this.$container = $this.parent(); - this.$container.append($cropper); - - this.$canvas = $cropper.find(".cropper-canvas"); - this.$dragger = $cropper.find(".cropper-dragger"); - this.$viewer = $cropper.find(".cropper-viewer"); - - defaults.autoCrop ? (this.cropped = TRUE) : this.$dragger.addClass(CLASS_HIDDEN); - defaults.modal && this.$canvas.addClass(CLASS_MODAL); - !defaults.dashed && this.$dragger.find(".cropper-dashed").addClass(CLASS_HIDDEN); - !defaults.movable && this.$dragger.find(".cropper-face").data(STRING_DIRECTIVE, "move"); - !defaults.resizable && this.$dragger.find(".cropper-line, .cropper-point").addClass(CLASS_HIDDEN); - - this.addListeners(); - this.initPreview(); - - this.built = TRUE; // Set `true` before update - defaults.dragCrop && this.setDragMode("crop"); // Set after built - this.update(); - this.replaced = FALSE; // Reset to `false` after update - - $this.one(EVENT_BUILT, defaults.built); // Only trigger once - $this.trigger(EVENT_BUILT); - }, - - unbuild: function () { - if (!this.built) { - return; - } - - this.built = FALSE; - this.removeListeners(); - - this.$preview.empty(); - this.$preview = NULL; - - this.$dragger = NULL; - this.$canvas = NULL; - this.$container = NULL; - - this.$cropper.remove(); - this.$cropper = NULL; - }, - - update: function (data) { - this.initContainer(); - this.initCropper(); - this.initImage(); - this.initDragger(); - - if (data) { - this.setData(data, TRUE); - this.setDragMode("crop"); - } else { - this.setData(this.defaults.data); - } - }, - - resize: function () { - clearTimeout(this.resizing); - this.resizing = setTimeout($.proxy(this.update, this, this.getData()), 200); - }, - - preview: function () { - var image = this.image, - dragger = this.dragger, - width = image.width, - height = image.height, - left = dragger.left - image.left, - top = dragger.top - image.top; - - this.$viewer.find("img").css({ - width: width, - height: height, - marginLeft: -left, - marginTop: -top - }); - - this.$preview.each(function () { - var $this = $(this), - data = $this.data(), - ratio = data.width / dragger.width, - newWidth = data.width, - newHeight = dragger.height * ratio; - - if (newHeight > data.height) { - ratio = data.height / dragger.height, - newWidth = dragger.width * ratio; - newHeight = data.height; - } - - $this.width(newWidth).height(newHeight).find("img").css({ - width: width * ratio, - height: height * ratio, - marginLeft: -left * ratio, - marginTop: -top * ratio - }); - }); - }, - - addListeners: function () { - var defaults = this.defaults; - - this.$element.on(EVENT_DRAG_START, defaults.dragstart).on(EVENT_DRAG_MOVE, defaults.dragmove).on(EVENT_DRAG_END, defaults.dragend); - this.$cropper.on(EVENT_MOUSE_DOWN, $.proxy(this.dragstart, this)).on(EVENT_DBLCLICK, $.proxy(this.dblclick, this)); - - if (defaults.zoomable) { - this.$cropper.on(EVENT_WHEEL, $.proxy(this.wheel, this)); - } - - if (defaults.multiple) { - this.$cropper.on(EVENT_MOUSE_MOVE, $.proxy(this.dragmove, this)).on(EVENT_MOUSE_UP, $.proxy(this.dragend, this)); - } else { - $document.on(EVENT_MOUSE_MOVE, (this._dragmove = proxy(this.dragmove, this))).on(EVENT_MOUSE_UP, (this._dragend = proxy(this.dragend, this))); - } - - $window.on(EVENT_RESIZE, (this._resize = proxy(this.resize, this))); - }, - - removeListeners: function () { - var defaults = this.defaults; - - this.$element.off(EVENT_DRAG_START, defaults.dragstart).off(EVENT_DRAG_MOVE, defaults.dragmove).off(EVENT_DRAG_END, defaults.dragend); - this.$cropper.off(EVENT_MOUSE_DOWN, this.dragstart).off(EVENT_DBLCLICK, this.dblclick); - - if (defaults.zoomable) { - this.$cropper.off(EVENT_WHEEL, this.wheel); - } - - if (defaults.multiple) { - this.$cropper.off(EVENT_MOUSE_MOVE, this.dragmove).off(EVENT_MOUSE_UP, this.dragend); - } else { - $document.off(EVENT_MOUSE_MOVE, this._dragmove).off(EVENT_MOUSE_UP, this._dragend); - } - - $window.off(EVENT_RESIZE, this._resize); - }, - - initPreview: function () { - var url = this.url; - - this.$preview = $(this.defaults.preview); - this.$viewer.html(''); - - this.$preview.each(function () { - var $this = $(this); - - $this.data({ - width: $this.width(), - height: $this.height() - }).html(''); - }); - }, - - initContainer: function () { - var $this = this.$element, - $container = this.$container, - $cropper = this.$cropper, - defaults = this.defaults; - - $cropper.addClass(CLASS_HIDDEN); - $this.removeClass(CLASS_HIDDEN); - - this.container = { - width: max($container.width(), defaults.minContainerWidth), - height: max($container.height(), defaults.minContainerHeight) - }; - - $this.addClass(CLASS_HIDDEN); - $cropper.removeClass(CLASS_HIDDEN); - }, - - initCropper: function () { - var container = this.container, - image = this.image, - cropper; - - if (((image.naturalWidth * container.height / image.naturalHeight) - container.width) >= 0) { - cropper = { - width: container.width, - height: container.width / image.aspectRatio, - left: 0 - }; - - cropper.top = (container.height - cropper.height) / 2; - } else { - cropper = { - width: container.height * image.aspectRatio, - height: container.height, - top: 0 - }; - - cropper.left = (container.width - cropper.width) / 2; - } - - this.$cropper.css({ - width: cropper.width, - height: cropper.height, - left: cropper.left, - top: cropper.top - }); - - this.cropper = cropper; - }, - - initImage: function () { - var image = this.image, - cropper = this.cropper, - defaultImage = { - _width: cropper.width, - _height: cropper.height, - width: cropper.width, - height: cropper.height, - left: 0, - top: 0, - ratio: cropper.width / image.naturalWidth - }; - - this.defaultImage = $.extend({}, image, defaultImage); - - if (image._width !== cropper.width || image._height !== cropper.height) { - $.extend(image, defaultImage); - } else { - image = $.extend({}, defaultImage, image); - - // Reset image ratio - if (this.replaced) { - image.ratio = defaultImage.ratio; - } - } - - this.image = image; - this.renderImage(); - }, - - renderImage: function (mode) { - var image = this.image; - - if (mode === "zoom") { - image.left -= (image.width - image.oldWidth) / 2; - image.top -= (image.height - image.oldHeight) / 2; - } - - image.left = min(max(image.left, image._width - image.width), 0); - image.top = min(max(image.top, image._height - image.height), 0); - - this.$clone.css({ - width: image.width, - height: image.height, - marginLeft: image.left, - marginTop: image.top - }); - - if (mode) { - this.defaults.done(this.getData()); - this.preview(); - } - }, - - initDragger: function () { - var defaults = this.defaults, - cropper = this.cropper, - // If not set, use the original aspect ratio of the image. - aspectRatio = defaults.aspectRatio || this.image.aspectRatio, - ratio = this.image.ratio, - autoCropDragger, - dragger; - - if (((cropper.height * aspectRatio) - cropper.width) >= 0) { - dragger = { - height: cropper.width / aspectRatio, - width: cropper.width, - left: 0, - top: (cropper.height - (cropper.width / aspectRatio)) / 2, - maxWidth: cropper.width, - maxHeight: cropper.width / aspectRatio - }; - } else { - dragger = { - height: cropper.height, - width: cropper.height * aspectRatio, - left: (cropper.width - (cropper.height * aspectRatio)) / 2, - top: 0, - maxWidth: cropper.height * aspectRatio, - maxHeight: cropper.height - }; - } - - dragger.minWidth = 0; - dragger.minHeight = 0; - - if (defaults.aspectRatio) { - if (isFinite(defaults.maxWidth)) { - dragger.maxWidth = min(dragger.maxWidth, defaults.maxWidth * ratio); - dragger.maxHeight = dragger.maxWidth / aspectRatio; - } else if (isFinite(defaults.maxHeight)) { - dragger.maxHeight = min(dragger.maxHeight, defaults.maxHeight * ratio); - dragger.maxWidth = dragger.maxHeight * aspectRatio; - } - - if (defaults.minWidth > 0) { - dragger.minWidth = max(0, defaults.minWidth * ratio); - dragger.minHeight = dragger.minWidth / aspectRatio; - } else if (defaults.minHeight > 0) { - dragger.minHeight = max(0, defaults.minHeight * ratio); - dragger.minWidth = dragger.minHeight * aspectRatio; - } - } else { - dragger.maxWidth = min(dragger.maxWidth, defaults.maxWidth * ratio); - dragger.maxHeight = min(dragger.maxHeight, defaults.maxHeight * ratio); - dragger.minWidth = max(0, defaults.minWidth * ratio); - dragger.minHeight = max(0, defaults.minHeight * ratio); - } - - // minWidth can't be greater than maxWidth, and minHeight too. - dragger.minWidth = min(dragger.maxWidth, dragger.minWidth); - dragger.minHeight = min(dragger.maxHeight, dragger.minHeight); - - // Center the dragger by default - autoCropDragger = $.extend({}, dragger); - - // The width of auto crop area must large than minWidth, and the height too. (#164) - autoCropDragger.width = max(dragger.minWidth, dragger.width * defaults.autoCropArea); - autoCropDragger.height = max(dragger.minHeight, dragger.height * defaults.autoCropArea); - autoCropDragger.left = (cropper.width - autoCropDragger.width) / 2; - autoCropDragger.top = (cropper.height - autoCropDragger.height) / 2; - - autoCropDragger.oldLeft = dragger.oldLeft = dragger.left; - autoCropDragger.oldTop = dragger.oldTop = dragger.top; - - this.autoCropDragger = autoCropDragger; - this.defaultDragger = $.extend({}, dragger); - this.dragger = dragger; - }, - - renderDragger: function () { - var dragger = this.dragger, - cropper = this.cropper; - - if (dragger.width > dragger.maxWidth) { - dragger.width = dragger.maxWidth; - dragger.left = dragger.oldLeft; - } else if (dragger.width < dragger.minWidth) { - dragger.width = dragger.minWidth; - dragger.left = dragger.oldLeft; - } - - if (dragger.height > dragger.maxHeight) { - dragger.height = dragger.maxHeight; - dragger.top = dragger.oldTop; - } else if (dragger.height < dragger.minHeight) { - dragger.height = dragger.minHeight; - dragger.top = dragger.oldTop; - } - - dragger.left = min(max(dragger.left, 0), cropper.width - dragger.width); - dragger.top = min(max(dragger.top, 0), cropper.height - dragger.height); - dragger.oldLeft = dragger.left; - dragger.oldTop = dragger.top; - - // Re-render the dragger - this.dragger = dragger; - - // #186 - if (this.defaults.movable) { - this.$dragger.find(".cropper-face").data(STRING_DIRECTIVE, (dragger.width === cropper.width && dragger.height === cropper.height) ? "move" : "all"); - } - - if (!this.disabled) { - this.defaults.done(this.getData()); - } - - this.$dragger.css({ - width: dragger.width, - height: dragger.height, - left: dragger.left, - top: dragger.top - }); - - this.preview(); - }, - - reset: function (deep) { - if (!this.cropped || this.disabled) { - return; - } - - if (deep) { - this.defaults.data = {}; - } - - this.image = $.extend({}, this.defaultImage); - this.renderImage(); - this.dragger = $.extend({}, this.defaultDragger); - this.setData(this.defaults.data); - }, - - clear: function () { - if (!this.cropped || this.disabled) { - return; - } - - this.cropped = FALSE; - - this.setData({ - x: 0, - y: 0, - width: 0, - height: 0 - }); - - this.$canvas.removeClass(CLASS_MODAL); - this.$dragger.addClass(CLASS_HIDDEN); - }, - - destroy: function () { - var $this = this.$element; - - if (!this.ready) { - this.$clone.off("load").remove(); - } - - this.unbuild(); - $this.removeClass(CLASS_HIDDEN).removeData("cropper"); - - if (this.rotated) { - $this.attr("src", this.$original.attr("src")); - } - }, - - replace: function (url, /*INTERNAL*/ rotated) { - var _this = this, - $this = this.$element, - element = this.element, - context; - - if (!this.disabled && url && url !== this.url && url !== $this.attr("src")) { - if (!rotated) { - this.rotated = FALSE; - this.replaced = TRUE; - } - - if ($this.is("img")) { - $this.attr("src", url); - this.load(); - } else if ($this.is("canvas") && this.support.canvas) { - context = element.getContext("2d"); - - $('').one("load", function () { - element.width = this.width; - element.height = this.height; - context.clearRect(0, 0, element.width, element.height); - context.drawImage(this, 0, 0); - _this.load(); - }); - } - } - }, - - setData: function (data, /*INTERNAL*/ once) { - var cropper = this.cropper, - dragger = this.dragger, - image = this.image, - aspectRatio = this.defaults.aspectRatio; - - if (!this.built || this.disabled || typeof data === STRING_UNDEFINED) { - return; - } - - if (data === NULL || $.isEmptyObject(data)) { - dragger = $.extend({}, this.autoCropDragger); - } - - if ($.isPlainObject(data) && !$.isEmptyObject(data)) { - - if (!once) { - this.defaults.data = data; - } - - data = this.transformData(data); - - if (isNumber(data.x) && data.x <= cropper.width - image.left) { - dragger.left = data.x + image.left; - } - - if (isNumber(data.y) && data.y <= cropper.height - image.top) { - dragger.top = data.y + image.top; - } - - if (aspectRatio) { - if (isNumber(data.width) && data.width <= dragger.maxWidth && data.width >= dragger.minWidth) { - dragger.width = data.width; - dragger.height = dragger.width / aspectRatio; - } else if (isNumber(data.height) && data.height <= dragger.maxHeight && data.height >= dragger.minHeight) { - dragger.height = data.height; - dragger.width = dragger.height * aspectRatio; - } - } else { - if (isNumber(data.width) && data.width <= dragger.maxWidth && data.width >= dragger.minWidth) { - dragger.width = data.width; - } - - if (isNumber(data.height) && data.height <= dragger.maxHeight && data.height >= dragger.minHeight) { - dragger.height = data.height; - } - } - } - - this.dragger = dragger; - this.renderDragger(); - }, - - getData: function (rounded) { - var dragger = this.dragger, - image = this.image, - data = {}; - - if (this.built) { - data = { - x: dragger.left - image.left, - y: dragger.top - image.top, - width: dragger.width, - height: dragger.height - }; - - data = this.transformData(data, TRUE, rounded); - } - - return data; - }, - - transformData: function (data, reversed, rounded) { - var ratio = this.image.ratio, - result = {}; - - $.each(data, function (i, n) { - n = num(n); - - if (REGEXP_OPTIONS.test(i) && !isNaN(n)) { - result[i] = reversed ? (rounded ? Math.round(n / ratio) : n / ratio) : n * ratio; - } - }); - - return result; - }, - - setAspectRatio: function (aspectRatio) { - var freeRatio = aspectRatio === "auto"; - - if (this.disabled) { - return; - } - - aspectRatio = num(aspectRatio); - - if (freeRatio || (!isNaN(aspectRatio) && aspectRatio > 0)) { - this.defaults.aspectRatio = freeRatio ? NAN : aspectRatio; - - if (this.built) { - this.initDragger(); - this.renderDragger(); - this.setData(this.defaults.data); // Reset to initial state - } - } - }, - - getImageData: function () { - var data = {}; - - if (this.ready) { - $.each(this.image, function (name, value) { - if (REGEXP_PROPERTIES.test(name)) { - data[name] = value; - } - }); - } - - return data; - }, - - getDataURL: function (options, type, quality) { - var canvas = $("")[0], - data = this.getData(), - dataURL = "", - context; - - if (!$.isPlainObject(options)) { - quality = type; - type = options; - options = {}; - } - - options = $.extend({ - width: data.width, - height: data.height - }, options); - - if (this.cropped && this.support.canvas) { - canvas.width = options.width; - canvas.height = options.height; - context = canvas.getContext("2d"); - - if (type === "image/jpeg") { - context.fillStyle = "#fff"; - context.fillRect(0, 0, options.width, options.height); - } - - context.drawImage(this.$clone[0], data.x, data.y, data.width, data.height, 0, 0, options.width, options.height); - dataURL = canvas.toDataURL(type, quality); - } - - return dataURL; - }, - - setDragMode: function (mode) { - var $canvas = this.$canvas, - defaults = this.defaults, - cropable = FALSE, - movable = FALSE; - - if (!this.built || this.disabled) { - return; - } - - switch (mode) { - case "crop": - if (defaults.dragCrop) { - cropable = TRUE; - $canvas.data(STRING_DIRECTIVE, mode); - } - - break; - - case "move": - movable = TRUE; - $canvas.data(STRING_DIRECTIVE, mode); - - break; - - default: - $canvas.removeData(STRING_DIRECTIVE); - } - - $canvas.toggleClass(CLASS_CROP, cropable).toggleClass(CLASS_MOVE, movable); - }, - - enable: function () { - if (this.built) { - this.disabled = FALSE; - this.$cropper.removeClass(CLASS_DISABLED); - } - }, - - disable: function () { - if (this.built) { - this.disabled = TRUE; - this.$cropper.addClass(CLASS_DISABLED); - } - }, - - rotate: function (degree) { - var image = this.image; - - degree = num(degree) || 0; - - if (!this.built || degree === 0 || this.disabled || !this.defaults.rotatable || !this.support.canvas) { - return; - } - - this.rotated = TRUE; - degree = (image.rotate = (image.rotate + degree) % 360); - - // replace with "true" to prevent to override the original image - this.replace(this.getRotatedDataURL(degree), true); - }, - - getRotatedDataURL: function (degree) { - var canvas = $("")[0], - context = canvas.getContext("2d"), - originalImage = this.originalImage, - naturalWidth = originalImage.naturalWidth, - naturalHeight = originalImage.naturalHeight, - deg = abs(degree) % 180, - arc = (deg > 90 ? (180 - deg) : deg) * Math.PI / 180, - width = naturalWidth * cos(arc) + naturalHeight * sin(arc), - height = naturalWidth * sin(arc) + naturalHeight * cos(arc); - - canvas.width = width; - canvas.height = height; - context.save(); - context.translate(width / 2, height / 2); - context.rotate(degree * Math.PI / 180); - context.drawImage(this.$original[0], -naturalWidth / 2, -naturalHeight / 2, naturalWidth, naturalHeight); - context.restore(); - - return canvas.toDataURL(); - }, - - zoom: function (delta) { - var image = this.image, - width, - height, - range; - - delta = num(delta); - - if (!this.built || !delta || this.disabled || !this.defaults.zoomable) { - return; - } - - width = image.width * (1 + delta); - height = image.height * (1 + delta); - range = width / image._width; - - if (range > 10) { - return; - } - - if (range < 1) { - width = image._width; - height = image._height; - } - - if (range <= 1) { - this.setDragMode("crop"); - } else { - this.setDragMode("move"); - } - - image.oldWidth = image.width; - image.oldHeight = image.height; - - image.width = width; - image.height = height; - image.ratio = image.width / image.naturalWidth; - - this.renderImage("zoom"); - }, - - dblclick: function () { - if (this.disabled) { - return; - } - - if (this.$canvas.hasClass(CLASS_CROP)) { - this.setDragMode("move"); - } else { - this.setDragMode("crop"); - } - }, - - wheel: function (event) { - var e = event.originalEvent, - delta = 1; - - if (this.disabled) { - return; - } - - event.preventDefault(); - - 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 * 0.1); - }, - - dragstart: function (event) { - var touches = event.originalEvent.touches, - e = event, - directive, - dragStartEvent, - touchesLength; - - if (this.disabled) { - return; - } - - if (touches) { - touchesLength = touches.length; - - if (touchesLength > 1) { - if (this.defaults.zoomable && touchesLength === 2) { - e = touches[1]; - this.startX2 = e.pageX; - this.startY2 = e.pageY; - directive = "zoom"; - } else { - return; - } - } - - e = touches[0]; - } - - directive = directive || $(e.target).data(STRING_DIRECTIVE); - - if (REGEXP_DIRECTIVES.test(directive)) { - event.preventDefault(); - - dragStartEvent = $.Event(EVENT_DRAG_START); - this.$element.trigger(dragStartEvent); - - if (dragStartEvent.isDefaultPrevented()) { - return; - } - - this.directive = directive; - this.cropping = FALSE; - this.startX = e.pageX; - this.startY = e.pageY; - - if (directive === "crop") { - this.cropping = TRUE; - this.$canvas.addClass(CLASS_MODAL); - } - } - }, - - dragmove: function (event) { - var touches = event.originalEvent.touches, - e = event, - dragMoveEvent, - touchesLength; - - if (this.disabled) { - return; - } - - if (touches) { - touchesLength = touches.length; - - if (touchesLength > 1) { - if (this.defaults.zoomable && touchesLength === 2) { - e = touches[1]; - this.endX2 = e.pageX; - this.endY2 = e.pageY; - } else { - return; - } - } - - e = touches[0]; - } - - if (this.directive) { - event.preventDefault(); - - dragMoveEvent = $.Event(EVENT_DRAG_MOVE); - this.$element.trigger(dragMoveEvent); - - if (dragMoveEvent.isDefaultPrevented()) { - return; - } - - this.endX = e.pageX; - this.endY = e.pageY; - - this.dragging(); - } - }, - - dragend: function (event) { - var dragEndEvent; - - if (this.disabled) { - return; - } - - if (this.directive) { - event.preventDefault(); - - dragEndEvent = $.Event(EVENT_DRAG_END); - this.$element.trigger(dragEndEvent); - - if (dragEndEvent.isDefaultPrevented()) { - return; - } - - if (this.cropping) { - this.cropping = FALSE; - this.$canvas.toggleClass(CLASS_MODAL, this.cropped && this.defaults.modal); - } - - this.directive = ""; - } - }, - - dragging: function () { - var directive = this.directive, - image = this.image, - cropper = this.cropper, - maxWidth = cropper.width, - maxHeight = cropper.height, - dragger = this.dragger, - width = dragger.width, - height = dragger.height, - left = dragger.left, - top = dragger.top, - right = left + width, - bottom = top + height, - renderable = TRUE, - aspectRatio = this.defaults.aspectRatio, - range = { - x: this.endX - this.startX, - y: this.endY - this.startY - }, - offset; - - if (aspectRatio) { - range.X = range.y * aspectRatio; - range.Y = range.x / aspectRatio; - } - - switch (directive) { - // Move dragger - case "all": - left += range.x; - top += range.y; - - break; - - // Resize dragger - case "e": - if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= 0 || bottom >= maxHeight))) { - renderable = FALSE; - break; - } - - width += range.x; - - if (aspectRatio) { - height = width / aspectRatio; - top -= range.Y / 2; - } - - if (width < 0) { - directive = "w"; - width = 0; - } - - break; - - case "n": - if (range.y <= 0 && (top <= 0 || aspectRatio && (left <= 0 || right >= maxWidth))) { - renderable = FALSE; - break; - } - - height -= range.y; - top += range.y; - - if (aspectRatio) { - width = height * aspectRatio; - left += range.X / 2; - } - - if (height < 0) { - directive = "s"; - height = 0; - } - - break; - - case "w": - if (range.x <= 0 && (left <= 0 || aspectRatio && (top <= 0 || bottom >= maxHeight))) { - renderable = FALSE; - break; - } - - width -= range.x; - left += range.x; - - if (aspectRatio) { - height = width / aspectRatio; - top += range.Y / 2; - } - - if (width < 0) { - directive = "e"; - width = 0; - } - - break; - - case "s": - if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= 0 || right >= maxWidth))) { - renderable = FALSE; - break; - } - - height += range.y; - - if (aspectRatio) { - width = height * aspectRatio; - left -= range.X / 2; - } - - if (height < 0) { - directive = "n"; - height = 0; - } - - break; - - case "ne": - if (aspectRatio) { - if (range.y <= 0 && (top <= 0 || right >= maxWidth)) { - renderable = FALSE; - break; - } - - height -= range.y; - top += range.y; - width = height * aspectRatio; - } else { - if (range.x >= 0) { - if (right < maxWidth) { - width += range.x; - } else if (range.y <= 0 && top <= 0) { - renderable = FALSE; - } - } else { - width += range.x; - } - - if (range.y <= 0) { - if (top > 0) { - height -= range.y; - top += range.y; - } - } else { - height -= range.y; - top += range.y; - } - } - - if (width < 0 && height < 0) { - directive = "sw"; - height = 0; - width = 0; - } else if (width < 0) { - directive = "nw"; - width = 0; - } else if (height < 0) { - directive = "se"; - height = 0; - } - - break; - - case "nw": - if (aspectRatio) { - if (range.y <= 0 && (top <= 0 || left <= 0)) { - renderable = FALSE; - break; - } - - height -= range.y; - top += range.y; - width = height * aspectRatio; - left += range.X; - } else { - if (range.x <= 0) { - if (left > 0) { - width -= range.x; - left += range.x; - } else if (range.y <= 0 && top <= 0) { - renderable = FALSE; - } - } else { - width -= range.x; - left += range.x; - } - - if (range.y <= 0) { - if (top > 0) { - height -= range.y; - top += range.y; - } - } else { - height -= range.y; - top += range.y; - } - } - - if (width < 0 && height < 0) { - directive = "se"; - height = 0; - width = 0; - } else if (width < 0) { - directive = "ne"; - width = 0; - } else if (height < 0) { - directive = "sw"; - height = 0; - } - - break; - - case "sw": - if (aspectRatio) { - if (range.x <= 0 && (left <= 0 || bottom >= maxHeight)) { - renderable = FALSE; - break; - } - - width -= range.x; - left += range.x; - height = width / aspectRatio; - } else { - if (range.x <= 0) { - if (left > 0) { - 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) { - directive = "ne"; - height = 0; - width = 0; - } else if (width < 0) { - directive = "se"; - width = 0; - } else if (height < 0) { - directive = "nw"; - height = 0; - } - - break; - - case "se": - if (aspectRatio) { - if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) { - renderable = FALSE; - break; - } - - width += range.x; - height = width / aspectRatio; - } else { - 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) { - directive = "nw"; - height = 0; - width = 0; - } else if (width < 0) { - directive = "sw"; - width = 0; - } else if (height < 0) { - directive = "ne"; - height = 0; - } - - break; - - // Move image - case "move": - image.left += range.x; - image.top += range.y; - this.renderImage("move"); - renderable = FALSE; - break; - - // Scale image - case "zoom": - this.zoom(function (x, y, x1, y1, x2, y2) { - return (sqrt(x2 * x2 + y2 * y2) - sqrt(x1 * x1 + y1 * y1)) / sqrt(x * x + y * y); - }( - image.width, - image.height, - abs(this.startX - this.startX2), - abs(this.startY - this.startY2), - abs(this.endX - this.endX2), - abs(this.endY - this.endY2) - )); - - this.endX2 = this.startX2; - this.endY2 = this.startY2; - renderable = FALSE; - break; - - // Crop image - case "crop": - if (range.x && range.y) { - offset = this.$cropper.offset(); - left = this.startX - offset.left; - top = this.startY - offset.top; - width = dragger.minWidth; - height = dragger.minHeight; - - if (range.x > 0) { - if (range.y > 0) { - directive = "se"; - } else { - directive = "ne"; - top -= height; - } - } else { - if (range.y > 0) { - directive = "sw"; - left -= width; - } else { - directive = "nw"; - left -= width; - top -= height; - } - } - - // Show the dragger if is hidden - if (!this.cropped) { - this.cropped = TRUE; - this.$dragger.removeClass(CLASS_HIDDEN); - } - } - - break; - - // No default - } - - if (renderable) { - dragger.width = width; - dragger.height = height; - dragger.left = left; - dragger.top = top; - this.directive = directive; - - this.renderDragger(); - } - - // Override - this.startX = this.endX; - this.startY = this.endY; - } - }; - - // Use the string compressor: Strmin (https://github.com/fengyuanchen/strmin) - Cropper.TEMPLATE = (function (source, words) { - words = words.split(","); - return source.replace(/\d+/g, function (i) { - return words[i]; - }); - })('<0 6="5-container"><0 6="5-canvas"><0 6="5-dragger"><1 6="5-viewer"><1 6="5-8 8-h"><1 6="5-8 8-v"><1 6="5-face" 3-2="all"><1 6="5-7 7-e" 3-2="e"><1 6="5-7 7-n" 3-2="n"><1 6="5-7 7-w" 3-2="w"><1 6="5-7 7-s" 3-2="s"><1 6="5-4 4-e" 3-2="e"><1 6="5-4 4-n" 3-2="n"><1 6="5-4 4-w" 3-2="w"><1 6="5-4 4-s" 3-2="s"><1 6="5-4 4-ne" 3-2="ne"><1 6="5-4 4-nw" 3-2="nw"><1 6="5-4 4-sw" 3-2="sw"><1 6="5-4 4-se" 3-2="se">', "div,span,directive,data,point,cropper,class,line,dashed"); - - /* Template source: -
-
-
- - - - - - - - - - - - - - - - -
-
- */ - - Cropper.DEFAULTS = { - // Basic - aspectRatio: "auto", - autoCropArea: 0.8, // 80% - data: { - // x: 0, - // y: 0, - // width: 300, - // height: 150 - }, - done: $.noop, - preview: "", - - // Toggles - multiple: FALSE, - autoCrop: TRUE, - dragCrop: TRUE, - dashed: TRUE, - modal: TRUE, - movable: TRUE, - resizable: TRUE, - zoomable: TRUE, - rotatable: TRUE, - checkImageOrigin: TRUE, - - // Dimensions - minWidth: 0, - minHeight: 0, - maxWidth: INFINITY, - maxHeight: INFINITY, - minContainerWidth: 300, - minContainerHeight: 150, - - // Events - build: NULL, - built: NULL, - dragstart: NULL, - dragmove: NULL, - dragend: NULL - }; - - Cropper.setDefaults = function (options) { - $.extend(Cropper.DEFAULTS, options); - }; - - // Save the other cropper - Cropper.other = $.fn.cropper; - - // Register as jQuery plugin - $.fn.cropper = function (options) { - var args = toArray(arguments, 1), - result; - - this.each(function () { - var $this = $(this), - data = $this.data("cropper"), - fn; - - if (!data) { - $this.data("cropper", (data = new Cropper(this, options))); - } - - if (typeof options === "string" && $.isFunction((fn = data[options]))) { - result = fn.apply(data, args); - } - }); - - return (typeof result !== STRING_UNDEFINED ? result : this); - }; - - $.fn.cropper.Constructor = Cropper; - $.fn.cropper.setDefaults = Cropper.setDefaults; - - // No conflict - $.fn.cropper.noConflict = function () { - $.fn.cropper = Cropper.other; - return this; - }; -}); diff --git a/docs/v0.7.9/js/cropper.min.js b/docs/v0.7.9/js/cropper.min.js deleted file mode 100644 index 51e1362a..00000000 --- a/docs/v0.7.9/js/cropper.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Cropper v0.7.9 - * https://github.com/fengyuanchen/cropper - * - * Copyright 2014-2015 Fengyuan Chen - * Released under the MIT license - */ - -!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){"use strict";var b=a(window),c=a(document),d=window.location,e=!0,f=!1,g=null,h=0/0,i=1/0,j="undefined",k="directive",l=".cropper",m=/^(e|n|w|s|ne|nw|sw|se|all|crop|move|zoom)$/,n=/^(x|y|width|height)$/,o=/^(naturalWidth|naturalHeight|width|height|aspectRatio|ratio|rotate)$/,p="cropper-modal",q="cropper-hidden",r="cropper-invisible",s="cropper-move",t="cropper-crop",u="cropper-disabled",v="mousedown touchstart",w="mousemove touchmove",x="mouseup mouseleave touchend touchleave touchcancel",y="wheel mousewheel DOMMouseScroll",z="resize"+l,A="dblclick",B="build"+l,C="built"+l,D="dragstart"+l,E="dragmove"+l,F="dragend"+l,G=function(a){return"number"==typeof a},H=function(a,b){var c=[];return G(b)&&c.push(b),c.slice.apply(a,c)},I=function(a,b){var c=H(arguments,2);return function(){return a.apply(b,c.concat(H(arguments)))}},J=function(a){var b="timestamp="+(new Date).getTime();return a+(-1===a.indexOf("?")?"?":"&")+b},K=function(b,c){this.element=b,this.$element=a(b),this.defaults=a.extend({},K.DEFAULTS,a.isPlainObject(c)?c:{}),this.$original=g,this.ready=f,this.built=f,this.cropped=f,this.rotated=f,this.disabled=f,this.replaced=f,this.init()},L=Math.sqrt,M=Math.min,N=Math.max,O=Math.abs,P=Math.sin,Q=Math.cos,R=parseFloat;K.prototype={constructor:K,support:{canvas:a.isFunction(a("")[0].getContext)},init:function(){var b=this.defaults;a.each(b,function(a,c){switch(a){case"aspectRatio":b[a]=O(R(c))||h;break;case"autoCropArea":b[a]=O(R(c))||.8;break;case"minWidth":case"minHeight":b[a]=O(R(c))||0;break;case"maxWidth":case"maxHeight":b[a]=O(R(c))||i}}),this.image={rotate:0},this.load()},load:function(){var b,c,d=this,f=this.$element,g=this.element,h=this.image,i="";f.is("img")?c=f.prop("src"):f.is("canvas")&&this.support.canvas&&(c=g.toDataURL()),c&&(this.replaced&&(h.rotate=0),this.defaults.checkImageOrigin&&this.isCrossOriginURL(c)&&(i=" crossOrigin",c=J(c)),this.$clone=b=a("'),b.one("load",function(){h.naturalWidth=this.naturalWidth||b.width(),h.naturalHeight=this.naturalHeight||b.height(),h.aspectRatio=h.naturalWidth/h.naturalHeight,d.url=c,d.ready=e,d.build()}),b.addClass(r).prependTo("body"))},isCrossOriginURL:function(a){var b=a.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i);return!b||b[1]===d.protocol&&b[2]===d.hostname&&b[3]===d.port?f:e},build:function(){var b,c,d=this.$element,g=this.defaults;this.ready&&(this.built&&this.unbuild(),d.one(B,g.build),b=a.Event(B),d.trigger(b),b.isDefaultPrevented()||(this.$cropper=c=a(K.TEMPLATE),d.addClass(q),this.$clone.removeClass(r).prependTo(c),this.rotated||(this.$original=this.$clone.clone(),this.$original.addClass(q).prependTo(this.$cropper),this.originalImage=a.extend({},this.image)),this.$container=d.parent(),this.$container.append(c),this.$canvas=c.find(".cropper-canvas"),this.$dragger=c.find(".cropper-dragger"),this.$viewer=c.find(".cropper-viewer"),g.autoCrop?this.cropped=e:this.$dragger.addClass(q),g.modal&&this.$canvas.addClass(p),!g.dashed&&this.$dragger.find(".cropper-dashed").addClass(q),!g.movable&&this.$dragger.find(".cropper-face").data(k,"move"),!g.resizable&&this.$dragger.find(".cropper-line, .cropper-point").addClass(q),this.addListeners(),this.initPreview(),this.built=e,g.dragCrop&&this.setDragMode("crop"),this.update(),this.replaced=f,d.one(C,g.built),d.trigger(C)))},unbuild:function(){this.built&&(this.built=f,this.removeListeners(),this.$preview.empty(),this.$preview=g,this.$dragger=g,this.$canvas=g,this.$container=g,this.$cropper.remove(),this.$cropper=g)},update:function(a){this.initContainer(),this.initCropper(),this.initImage(),this.initDragger(),a?(this.setData(a,e),this.setDragMode("crop")):this.setData(this.defaults.data)},resize:function(){clearTimeout(this.resizing),this.resizing=setTimeout(a.proxy(this.update,this,this.getData()),200)},preview:function(){var b=this.image,c=this.dragger,d=b.width,e=b.height,f=c.left-b.left,g=c.top-b.top;this.$viewer.find("img").css({width:d,height:e,marginLeft:-f,marginTop:-g}),this.$preview.each(function(){var b=a(this),h=b.data(),i=h.width/c.width,j=h.width,k=c.height*i;k>h.height&&(i=h.height/c.height,j=c.width*i,k=h.height),b.width(j).height(k).find("img").css({width:d*i,height:e*i,marginLeft:-f*i,marginTop:-g*i})})},addListeners:function(){var d=this.defaults;this.$element.on(D,d.dragstart).on(E,d.dragmove).on(F,d.dragend),this.$cropper.on(v,a.proxy(this.dragstart,this)).on(A,a.proxy(this.dblclick,this)),d.zoomable&&this.$cropper.on(y,a.proxy(this.wheel,this)),d.multiple?this.$cropper.on(w,a.proxy(this.dragmove,this)).on(x,a.proxy(this.dragend,this)):c.on(w,this._dragmove=I(this.dragmove,this)).on(x,this._dragend=I(this.dragend,this)),b.on(z,this._resize=I(this.resize,this))},removeListeners:function(){var a=this.defaults;this.$element.off(D,a.dragstart).off(E,a.dragmove).off(F,a.dragend),this.$cropper.off(v,this.dragstart).off(A,this.dblclick),a.zoomable&&this.$cropper.off(y,this.wheel),a.multiple?this.$cropper.off(w,this.dragmove).off(x,this.dragend):c.off(w,this._dragmove).off(x,this._dragend),b.off(z,this._resize)},initPreview:function(){var b=this.url;this.$preview=a(this.defaults.preview),this.$viewer.html(''),this.$preview.each(function(){var c=a(this);c.data({width:c.width(),height:c.height()}).html('')})},initContainer:function(){var a=this.$element,b=this.$container,c=this.$cropper,d=this.defaults;c.addClass(q),a.removeClass(q),this.container={width:N(b.width(),d.minContainerWidth),height:N(b.height(),d.minContainerHeight)},a.addClass(q),c.removeClass(q)},initCropper:function(){var a,b=this.container,c=this.image;c.naturalWidth*b.height/c.naturalHeight-b.width>=0?(a={width:b.width,height:b.width/c.aspectRatio,left:0},a.top=(b.height-a.height)/2):(a={width:b.height*c.aspectRatio,height:b.height,top:0},a.left=(b.width-a.width)/2),this.$cropper.css({width:a.width,height:a.height,left:a.left,top:a.top}),this.cropper=a},initImage:function(){var b=this.image,c=this.cropper,d={_width:c.width,_height:c.height,width:c.width,height:c.height,left:0,top:0,ratio:c.width/b.naturalWidth};this.defaultImage=a.extend({},b,d),b._width!==c.width||b._height!==c.height?a.extend(b,d):(b=a.extend({},d,b),this.replaced&&(b.ratio=d.ratio)),this.image=b,this.renderImage()},renderImage:function(a){var b=this.image;"zoom"===a&&(b.left-=(b.width-b.oldWidth)/2,b.top-=(b.height-b.oldHeight)/2),b.left=M(N(b.left,b._width-b.width),0),b.top=M(N(b.top,b._height-b.height),0),this.$clone.css({width:b.width,height:b.height,marginLeft:b.left,marginTop:b.top}),a&&(this.defaults.done(this.getData()),this.preview())},initDragger:function(){var b,c,d=this.defaults,e=this.cropper,f=d.aspectRatio||this.image.aspectRatio,g=this.image.ratio;c=e.height*f-e.width>=0?{height:e.width/f,width:e.width,left:0,top:(e.height-e.width/f)/2,maxWidth:e.width,maxHeight:e.width/f}:{height:e.height,width:e.height*f,left:(e.width-e.height*f)/2,top:0,maxWidth:e.height*f,maxHeight:e.height},c.minWidth=0,c.minHeight=0,d.aspectRatio?(isFinite(d.maxWidth)?(c.maxWidth=M(c.maxWidth,d.maxWidth*g),c.maxHeight=c.maxWidth/f):isFinite(d.maxHeight)&&(c.maxHeight=M(c.maxHeight,d.maxHeight*g),c.maxWidth=c.maxHeight*f),d.minWidth>0?(c.minWidth=N(0,d.minWidth*g),c.minHeight=c.minWidth/f):d.minHeight>0&&(c.minHeight=N(0,d.minHeight*g),c.minWidth=c.minHeight*f)):(c.maxWidth=M(c.maxWidth,d.maxWidth*g),c.maxHeight=M(c.maxHeight,d.maxHeight*g),c.minWidth=N(0,d.minWidth*g),c.minHeight=N(0,d.minHeight*g)),c.minWidth=M(c.maxWidth,c.minWidth),c.minHeight=M(c.maxHeight,c.minHeight),b=a.extend({},c),b.width=N(c.minWidth,c.width*d.autoCropArea),b.height=N(c.minHeight,c.height*d.autoCropArea),b.left=(e.width-b.width)/2,b.top=(e.height-b.height)/2,b.oldLeft=c.oldLeft=c.left,b.oldTop=c.oldTop=c.top,this.autoCropDragger=b,this.defaultDragger=a.extend({},c),this.dragger=c},renderDragger:function(){var a=this.dragger,b=this.cropper;a.width>a.maxWidth?(a.width=a.maxWidth,a.left=a.oldLeft):a.widtha.maxHeight?(a.height=a.maxHeight,a.top=a.oldTop):a.height').one("load",function(){i.width=this.width,i.height=this.height,d.clearRect(0,0,i.width,i.height),d.drawImage(this,0,0),g.load()})))},setData:function(b,c){var d=this.cropper,e=this.dragger,f=this.image,h=this.defaults.aspectRatio;this.built&&!this.disabled&&typeof b!==j&&((b===g||a.isEmptyObject(b))&&(e=a.extend({},this.autoCropDragger)),a.isPlainObject(b)&&!a.isEmptyObject(b)&&(c||(this.defaults.data=b),b=this.transformData(b),G(b.x)&&b.x<=d.width-f.left&&(e.left=b.x+f.left),G(b.y)&&b.y<=d.height-f.top&&(e.top=b.y+f.top),h?G(b.width)&&b.width<=e.maxWidth&&b.width>=e.minWidth?(e.width=b.width,e.height=e.width/h):G(b.height)&&b.height<=e.maxHeight&&b.height>=e.minHeight&&(e.height=b.height,e.width=e.height*h):(G(b.width)&&b.width<=e.maxWidth&&b.width>=e.minWidth&&(e.width=b.width),G(b.height)&&b.height<=e.maxHeight&&b.height>=e.minHeight&&(e.height=b.height))),this.dragger=e,this.renderDragger())},getData:function(a){var b=this.dragger,c=this.image,d={};return this.built&&(d={x:b.left-c.left,y:b.top-c.top,width:b.width,height:b.height},d=this.transformData(d,e,a)),d},transformData:function(b,c,d){var e=this.image.ratio,f={};return a.each(b,function(a,b){b=R(b),n.test(a)&&!isNaN(b)&&(f[a]=c?d?Math.round(b/e):b/e:b*e)}),f},setAspectRatio:function(a){var b="auto"===a;this.disabled||(a=R(a),(b||!isNaN(a)&&a>0)&&(this.defaults.aspectRatio=b?h:a,this.built&&(this.initDragger(),this.renderDragger(),this.setData(this.defaults.data))))},getImageData:function(){var b={};return this.ready&&a.each(this.image,function(a,c){o.test(a)&&(b[a]=c)}),b},getDataURL:function(b,c,d){var e,f=a("")[0],g=this.getData(),h="";return a.isPlainObject(b)||(d=c,c=b,b={}),b=a.extend({width:g.width,height:g.height},b),this.cropped&&this.support.canvas&&(f.width=b.width,f.height=b.height,e=f.getContext("2d"),"image/jpeg"===c&&(e.fillStyle="#fff",e.fillRect(0,0,b.width,b.height)),e.drawImage(this.$clone[0],g.x,g.y,g.width,g.height,0,0,b.width,b.height),h=f.toDataURL(c,d)),h},setDragMode:function(a){var b=this.$canvas,c=this.defaults,d=f,g=f;if(this.built&&!this.disabled){switch(a){case"crop":c.dragCrop&&(d=e,b.data(k,a));break;case"move":g=e,b.data(k,a);break;default:b.removeData(k)}b.toggleClass(t,d).toggleClass(s,g)}},enable:function(){this.built&&(this.disabled=f,this.$cropper.removeClass(u))},disable:function(){this.built&&(this.disabled=e,this.$cropper.addClass(u))},rotate:function(a){var b=this.image;a=R(a)||0,this.built&&0!==a&&!this.disabled&&this.defaults.rotatable&&this.support.canvas&&(this.rotated=e,a=b.rotate=(b.rotate+a)%360,this.replace(this.getRotatedDataURL(a),!0))},getRotatedDataURL:function(b){var c=a("")[0],d=c.getContext("2d"),e=this.originalImage,f=e.naturalWidth,g=e.naturalHeight,h=O(b)%180,i=(h>90?180-h:h)*Math.PI/180,j=f*Q(i)+g*P(i),k=f*P(i)+g*Q(i);return c.width=j,c.height=k,d.save(),d.translate(j/2,k/2),d.rotate(b*Math.PI/180),d.drawImage(this.$original[0],-f/2,-g/2,f,g),d.restore(),c.toDataURL()},zoom:function(a){var b,c,d,e=this.image;a=R(a),this.built&&a&&!this.disabled&&this.defaults.zoomable&&(b=e.width*(1+a),c=e.height*(1+a),d=b/e._width,d>10||(1>d&&(b=e._width,c=e._height),this.setDragMode(1>=d?"crop":"move"),e.oldWidth=e.width,e.oldHeight=e.height,e.width=b,e.height=c,e.ratio=e.width/e.naturalWidth,this.renderImage("zoom")))},dblclick:function(){this.disabled||this.setDragMode(this.$canvas.hasClass(t)?"move":"crop")},wheel:function(a){var b=a.originalEvent,c=1;this.disabled||(a.preventDefault(),b.deltaY?c=b.deltaY>0?1:-1:b.wheelDelta?c=-b.wheelDelta/120:b.detail&&(c=b.detail>0?1:-1),this.zoom(.1*c))},dragstart:function(b){var c,d,g,h=b.originalEvent.touches,i=b;if(!this.disabled){if(h){if(g=h.length,g>1){if(!this.defaults.zoomable||2!==g)return;i=h[1],this.startX2=i.pageX,this.startY2=i.pageY,c="zoom"}i=h[0]}if(c=c||a(i.target).data(k),m.test(c)){if(b.preventDefault(),d=a.Event(D),this.$element.trigger(d),d.isDefaultPrevented())return;this.directive=c,this.cropping=f,this.startX=i.pageX,this.startY=i.pageY,"crop"===c&&(this.cropping=e,this.$canvas.addClass(p))}}},dragmove:function(b){var c,d,e=b.originalEvent.touches,f=b;if(!this.disabled){if(e){if(d=e.length,d>1){if(!this.defaults.zoomable||2!==d)return;f=e[1],this.endX2=f.pageX,this.endY2=f.pageY}f=e[0]}if(this.directive){if(b.preventDefault(),c=a.Event(E),this.$element.trigger(c),c.isDefaultPrevented())return;this.endX=f.pageX,this.endY=f.pageY,this.dragging()}}},dragend:function(b){var c;if(!this.disabled&&this.directive){if(b.preventDefault(),c=a.Event(F),this.$element.trigger(c),c.isDefaultPrevented())return;this.cropping&&(this.cropping=f,this.$canvas.toggleClass(p,this.cropped&&this.defaults.modal)),this.directive=""}},dragging:function(){var a,b=this.directive,c=this.image,d=this.cropper,g=d.width,h=d.height,i=this.dragger,j=i.width,k=i.height,l=i.left,m=i.top,n=l+j,o=m+k,p=e,r=this.defaults.aspectRatio,s={x:this.endX-this.startX,y:this.endY-this.startY};switch(r&&(s.X=s.y*r,s.Y=s.x/r),b){case"all":l+=s.x,m+=s.y;break;case"e":if(s.x>=0&&(n>=g||r&&(0>=m||o>=h))){p=f;break}j+=s.x,r&&(k=j/r,m-=s.Y/2),0>j&&(b="w",j=0);break;case"n":if(s.y<=0&&(0>=m||r&&(0>=l||n>=g))){p=f;break}k-=s.y,m+=s.y,r&&(j=k*r,l+=s.X/2),0>k&&(b="s",k=0);break;case"w":if(s.x<=0&&(0>=l||r&&(0>=m||o>=h))){p=f;break}j-=s.x,l+=s.x,r&&(k=j/r,m+=s.Y/2),0>j&&(b="e",j=0);break;case"s":if(s.y>=0&&(o>=h||r&&(0>=l||n>=g))){p=f;break}k+=s.y,r&&(j=k*r,l-=s.X/2),0>k&&(b="n",k=0);break;case"ne":if(r){if(s.y<=0&&(0>=m||n>=g)){p=f;break}k-=s.y,m+=s.y,j=k*r}else s.x>=0?g>n?j+=s.x:s.y<=0&&0>=m&&(p=f):j+=s.x,s.y<=0?m>0&&(k-=s.y,m+=s.y):(k-=s.y,m+=s.y);0>j&&0>k?(b="sw",k=0,j=0):0>j?(b="nw",j=0):0>k&&(b="se",k=0);break;case"nw":if(r){if(s.y<=0&&(0>=m||0>=l)){p=f;break}k-=s.y,m+=s.y,j=k*r,l+=s.X}else s.x<=0?l>0?(j-=s.x,l+=s.x):s.y<=0&&0>=m&&(p=f):(j-=s.x,l+=s.x),s.y<=0?m>0&&(k-=s.y,m+=s.y):(k-=s.y,m+=s.y);0>j&&0>k?(b="se",k=0,j=0):0>j?(b="ne",j=0):0>k&&(b="sw",k=0);break;case"sw":if(r){if(s.x<=0&&(0>=l||o>=h)){p=f;break}j-=s.x,l+=s.x,k=j/r}else s.x<=0?l>0?(j-=s.x,l+=s.x):s.y>=0&&o>=h&&(p=f):(j-=s.x,l+=s.x),s.y>=0?h>o&&(k+=s.y):k+=s.y;0>j&&0>k?(b="ne",k=0,j=0):0>j?(b="se",j=0):0>k&&(b="nw",k=0);break;case"se":if(r){if(s.x>=0&&(n>=g||o>=h)){p=f;break}j+=s.x,k=j/r}else s.x>=0?g>n?j+=s.x:s.y>=0&&o>=h&&(p=f):j+=s.x,s.y>=0?h>o&&(k+=s.y):k+=s.y;0>j&&0>k?(b="nw",k=0,j=0):0>j?(b="sw",j=0):0>k&&(b="ne",k=0);break;case"move":c.left+=s.x,c.top+=s.y,this.renderImage("move"),p=f;break;case"zoom":this.zoom(function(a,b,c,d,e,f){return(L(e*e+f*f)-L(c*c+d*d))/L(a*a+b*b)}(c.width,c.height,O(this.startX-this.startX2),O(this.startY-this.startY2),O(this.endX-this.endX2),O(this.endY-this.endY2))),this.endX2=this.startX2,this.endY2=this.startY2,p=f;break;case"crop":s.x&&s.y&&(a=this.$cropper.offset(),l=this.startX-a.left,m=this.startY-a.top,j=i.minWidth,k=i.minHeight,s.x>0?s.y>0?b="se":(b="ne",m-=k):s.y>0?(b="sw",l-=j):(b="nw",l-=j,m-=k),this.cropped||(this.cropped=e,this.$dragger.removeClass(q)))}p&&(i.width=j,i.height=k,i.left=l,i.top=m,this.directive=b,this.renderDragger()),this.startX=this.endX,this.startY=this.endY}},K.TEMPLATE=function(a,b){return b=b.split(","),a.replace(/\d+/g,function(a){return b[a]})}('<0 6="5-container"><0 6="5-canvas"><0 6="5-dragger"><1 6="5-viewer"><1 6="5-8 8-h"><1 6="5-8 8-v"><1 6="5-face" 3-2="all"><1 6="5-7 7-e" 3-2="e"><1 6="5-7 7-n" 3-2="n"><1 6="5-7 7-w" 3-2="w"><1 6="5-7 7-s" 3-2="s"><1 6="5-4 4-e" 3-2="e"><1 6="5-4 4-n" 3-2="n"><1 6="5-4 4-w" 3-2="w"><1 6="5-4 4-s" 3-2="s"><1 6="5-4 4-ne" 3-2="ne"><1 6="5-4 4-nw" 3-2="nw"><1 6="5-4 4-sw" 3-2="sw"><1 6="5-4 4-se" 3-2="se">',"div,span,directive,data,point,cropper,class,line,dashed"),K.DEFAULTS={aspectRatio:"auto",autoCropArea:.8,data:{},done:a.noop,preview:"",multiple:f,autoCrop:e,dragCrop:e,dashed:e,modal:e,movable:e,resizable:e,zoomable:e,rotatable:e,checkImageOrigin:e,minWidth:0,minHeight:0,maxWidth:i,maxHeight:i,minContainerWidth:300,minContainerHeight:150,build:g,built:g,dragstart:g,dragmove:g,dragend:g},K.setDefaults=function(b){a.extend(K.DEFAULTS,b)},K.other=a.fn.cropper,a.fn.cropper=function(b){var c,d=H(arguments,1);return this.each(function(){var e,f=a(this),g=f.data("cropper");g||f.data("cropper",g=new K(this,b)),"string"==typeof b&&a.isFunction(e=g[b])&&(c=e.apply(g,d))}),typeof c!==j?c:this},a.fn.cropper.Constructor=K,a.fn.cropper.setDefaults=K.setDefaults,a.fn.cropper.noConflict=function(){return a.fn.cropper=K.other,this}}); \ No newline at end of file diff --git a/docs/v0.7.9/js/main.js b/docs/v0.7.9/js/main.js deleted file mode 100644 index dd2c8084..00000000 --- a/docs/v0.7.9/js/main.js +++ /dev/null @@ -1,278 +0,0 @@ -$(function () { - - "use strict"; - - var console = window.console || { log: function () {} }, - $alert = $(".docs-alert"), - $message = $alert.find(".message"), - showMessage = function (message, type) { - $message.text(message); - - if (type) { - $message.addClass(type); - } - - $alert.fadeIn(); - - setTimeout(function () { - $alert.fadeOut(); - }, 3000); - }; - - // Overview - // ------------------------------------------------------------------------- - - (function () { - var $image = $(".img-container > img"), - $dataX = $("#dataX"), - $dataY = $("#dataY"), - $dataHeight = $("#dataHeight"), - $dataWidth = $("#dataWidth"), - options = { - aspectRatio: 16 / 9, - data: { - x: 480, - y: 60, - width: 640, - height: 360 - }, - preview: ".img-preview", - done: function (data) { - $dataX.val(Math.round(data.x)); - $dataY.val(Math.round(data.y)); - $dataHeight.val(Math.round(data.height)); - $dataWidth.val(Math.round(data.width)); - } - }; - - $image.cropper(options).on({ - "build.cropper": function (e) { - console.log(e.type); - }, - "built.cropper": function (e) { - console.log(e.type); - } - }); - - $(document).on("click", "[data-method]", function () { - var data = $(this).data(); - - if (data.method) { - $image.cropper(data.method, data.option); - } - }); - - var $inputImage = $("#inputImage"), - blobURL; - - if (window.URL) { - $inputImage.change(function () { - var files = this.files, - file; - - if (files && files.length) { - file = files[0]; - - if (/^image\/\w+$/.test(file.type)) { - if (blobURL) { - URL.revokeObjectURL(blobURL); // Revoke the old one - } - - blobURL = URL.createObjectURL(file); - $image.cropper("reset", true).cropper("replace", blobURL); - $inputImage.val(""); - } else { - showMessage("Please choose an image file."); - } - } - }); - } else { - $inputImage.parent().remove(); - } - - $("#download").click(function () { - window.open($image.cropper("getDataURL")); - }); - - var $zoomWith = $("#zoomWith"); - - $("#zoom").click(function () { - $image.cropper("zoom", $zoomWith.val()); - }); - - - var $rotateWith = $("#rotateWith"); - - $("#rotate").click(function () { - $image.cropper("rotate", $rotateWith.val()); - }); - - - var $getDataInto = $("#getDataInto"); - - $("#getData").click(function () { - var data = $image.cropper("getData"), - val = ""; - - try { - val = JSON.stringify(data); - } catch (e) { - console.log(data); - } - - $getDataInto.val(val); - }); - - - var $setDataX = $("#setDataX"), - $setDataY = $("#setDataY"), - $setDataWidth = $("#setDataWidth"), - $setDataHeight = $("#setDataHeight"); - - $("#setData").click(function () { - var data = { - x: $setDataX.val(), - y: $setDataY.val(), - width: $setDataWidth.val(), - height: $setDataHeight.val() - }; - - $image.cropper("setData", data); - }); - - - var $setAspectRatioWith = $("#setAspectRatioWith"); - - $("#setAspectRatio").click(function () { - $image.cropper("setAspectRatio", $setAspectRatioWith.val()); - }); - - - var $replaceWith = $("#replaceWith"); - - $("#replace").click(function () { - $image.cropper("replace", $replaceWith.val()); - }); - - - var $getImageDataInto = $("#getImageDataInto"); - - $("#getImageData").click(function () { - var data = $image.cropper("getImageData"), - val = ""; - - try { - val = JSON.stringify(data); - } catch (e) { - console.log(data); - } - - $getImageDataInto.val(val); - }); - - - var $dataURLInto = $("#dataURLInto"), - $dataURLView = $("#dataURLView"); - - $("#getDataURL").click(function () { - var dataURL = $image.cropper("getDataURL"); - - $dataURLInto.text(dataURL); - $dataURLView.html(''); - }); - - $("#getDataURL2").click(function () { - var dataURL = $image.cropper("getDataURL", "image/jpeg"); - - $dataURLInto.text(dataURL); - $dataURLView.html(''); - }); - - $("#getDataURL3").click(function () { - var dataURL = $image.cropper("getDataURL", { - width: 160, - height: 90 - }); - - $dataURLInto.text(dataURL); - $dataURLView.html(''); - }); - - $("#getDataURL4").click(function () { - var dataURL = $image.cropper("getDataURL", { - width: 320, - height: 180 - }, "image/jpeg", 0.8); - - $dataURLInto.text(dataURL); - $dataURLView.html(''); - }); - - $(".docs-options :radio").on("change", function () { - var $this = $(this); - - if ($this.is(":checked")) { - options[$this.attr("name")] = $this.val() === "true" ? true : false; - $image.cropper("destroy").cropper(options); - } - }); - - $("[data-toggle='tooltip']").tooltip(); - }()); - - // Sidebar - // ------------------------------------------------------------------------- - - (function () { - var $sidebar = $(".docs-sidebar"), - offset = $sidebar.offset(), - offsetTop = offset.top, - mainHeight = $sidebar.parents(".row").height() - $sidebar.height(); - - $(window).bind("scroll", function () { - var st = $(this).scrollTop(); - - if (st > offsetTop && (st - offsetTop) < mainHeight) { - $sidebar.addClass("fixed"); - } else { - $sidebar.removeClass("fixed"); - } - }); - }()); - - // Examples - // ------------------------------------------------------------------------- - - // Example 1 - $(".fixed-dragger-cropper > img").cropper({ - aspectRatio: 640 / 320, // 2 / 1 - autoCropArea: 0.6, // Center 60% - multiple: false, - dragCrop: false, - dashed: false, - movable: false, - resizable: false, - built: function () { - $(this).cropper("zoom", 0.5); - } - }); - - - // Example 2 - var $image = $(".bootstrap-modal-cropper > img"), - originalData = {}; - - $("#bootstrap-modal").on("shown.bs.modal", function () { - $image.cropper({ - multiple: true, - data: originalData, - done: function (data) { - console.log(data); - } - }); - }).on("hidden.bs.modal", function () { - originalData = $image.cropper("getData"); // Saves the data on hide - $image.cropper("destroy"); - }); - -}); diff --git a/docs/v1.0.0/css/cropper.min.css b/docs/v1.0.0/css/cropper.min.css deleted file mode 100644 index cf3d0504..00000000 --- a/docs/v1.0.0/css/cropper.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Cropper v1.0.0 - * https://github.com/fengyuanchen/cropper - * - * Copyright (c) 2014-2015 Fengyuan Chen and contributors - * Released under the MIT license - * - * Date: 2015-10-10T02:10:06.999Z - */.cropper-container{position:relative;overflow:hidden;font-size:0;line-height:0;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;direction:ltr!important;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.cropper-container img{display:block;width:100%;min-width:0!important;max-width:none!important;height:100%;min-height:0!important;max-height:none!important;image-orientation:0deg!important}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal{position:absolute;top:0;right:0;bottom:0;left:0}.cropper-drag-box{background-color:#fff;filter:alpha(opacity=0);opacity:0}.cropper-dashed,.cropper-modal{filter:alpha(opacity=50);opacity:.5}.cropper-modal{background-color:#000}.cropper-view-box{display:block;width:100%;height:100%;overflow:hidden;outline:#39f solid 1px;outline-color:rgba(51,153,255,.75)}.cropper-dashed{position:absolute;display:block;border:0 dashed #eee}.cropper-dashed.dashed-h{top:33.33333%;left:0;width:100%;height:33.33333%;border-top-width:1px;border-bottom-width:1px}.cropper-dashed.dashed-v{top:0;left:33.33333%;width:33.33333%;height:100%;border-right-width:1px;border-left-width:1px}.cropper-center{position:absolute;top:50%;left:50%;display:block;width:0;height:0;filter:alpha(opacity=75);opacity:.75}.cropper-center:after,.cropper-center:before{position:absolute;display:block;content:" ";background-color:#eee}.cropper-center:before{top:0;left:-3px;width:7px;height:1px}.cropper-center:after{top:-3px;left:0;width:1px;height:7px}.cropper-face,.cropper-line,.cropper-point{position:absolute;display:block;width:100%;height:100%;filter:alpha(opacity=10);opacity:.1}.cropper-face{top:0;left:0;background-color:#fff}.cropper-line,.cropper-point{background-color:#39f}.cropper-line.line-e{top:0;right:-3px;width:5px;cursor:e-resize}.cropper-line.line-n{top:-3px;left:0;height:5px;cursor:n-resize}.cropper-line.line-w{top:0;left:-3px;width:5px;cursor:w-resize}.cropper-line.line-s{bottom:-3px;left:0;height:5px;cursor:s-resize}.cropper-point{width:5px;height:5px;filter:alpha(opacity=75);opacity:.75}.cropper-point.point-e{top:50%;right:-3px;margin-top:-3px;cursor:e-resize}.cropper-point.point-n{top:-3px;left:50%;margin-left:-3px;cursor:n-resize}.cropper-point.point-w{top:50%;left:-3px;margin-top:-3px;cursor:w-resize}.cropper-point.point-s{bottom:-3px;left:50%;margin-left:-3px;cursor:s-resize}.cropper-point.point-ne{top:-3px;right:-3px;cursor:ne-resize}.cropper-point.point-nw{top:-3px;left:-3px;cursor:nw-resize}.cropper-point.point-sw{bottom:-3px;left:-3px;cursor:sw-resize}.cropper-point.point-se{right:-3px;bottom:-3px;width:20px;height:20px;cursor:se-resize;filter:alpha(opacity=100);opacity:1}.cropper-point.point-se:before{position:absolute;right:-50%;bottom:-50%;display:block;width:200%;height:200%;content:" ";background-color:#39f;filter:alpha(opacity=0);opacity:0}@media (min-width:768px){.cropper-point.point-se{width:15px;height:15px}}@media (min-width:992px){.cropper-point.point-se{width:10px;height:10px}}@media (min-width:1200px){.cropper-point.point-se{width:5px;height:5px;filter:alpha(opacity=75);opacity:.75}}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-invisible{filter:alpha(opacity=0);opacity:0}.cropper-hide{position:absolute;display:block;width:0;height: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/docs/v1.0.0/css/main.css b/docs/v1.0.0/css/main.css deleted file mode 100644 index 3fc7f7a9..00000000 --- a/docs/v1.0.0/css/main.css +++ /dev/null @@ -1,304 +0,0 @@ -/* Main - * ========================================================================== */ - -/* Button - * -------------------------------------------------------------------------- */ - -.btn-primary { - border-color: #0066bf; - background-color: #0074d9; -} - -.btn-primary:hover, -.btn-primary:focus, -.btn-primary:active, -.btn-primary.active, -.btn-primary.active:focus, -.btn-primary.active:hover { - border-color: #005299; - background-color: #005fb3; -} - - -/* Basic style - * -------------------------------------------------------------------------- */ - -body { - overflow-x: hidden; -} - - -/* Header */ - -.docs-header { - margin-bottom: 0; - border-color: #0066bf; - background-color: #0074d9; - color: #fff; -} - -.docs-header .navbar-brand { - color: #eee; -} - -.docs-header .navbar-toggle { - border-color: transparent; - background-color: #0074d9; -} - -.docs-header .navbar-toggle:hover, -.docs-header .navbar-toggle:focus { - border-color: transparent; - background-color: #005fb3; -} - -.docs-header .navbar-collapse { - border-color: #0066bf; -} - -.docs-header .navbar-text { - color: #ddd; -} - -.docs-header .navbar-nav > li > a { - color: #eee; -} - - -/* Jumbotron */ - -.docs-jumbotron { - background-color: #fcfcfc; -} - -.docs-jumbotron .version { - font-size: 14px; - color: #ccc; -} - - -/* Content */ - -.img-container, -.img-preview { - background-color: #f7f7f7; - width: 100%; - text-align: center; - overflow: hidden; -} - -.img-container { - min-height: 200px; - max-height: 516px; - margin-bottom: 20px; -} - -@media (min-width: 768px) { - .img-container { - min-height: 516px; - } -} - -.img-container > img { - max-width: 100%; -} - -.docs-preview { - margin-right: -15px; -} - -.img-preview { - float: left; - margin-right: 10px; - margin-bottom: 10px; -} - -.img-preview > img { - max-width: 100%; -} - -.preview-lg { - width: 263px; - height: 148px; -} - -.preview-md { - width: 139px; - height: 78px; -} - -.preview-sm { - width: 69px; - height: 39px; -} - -.preview-xs { - width: 35px; - height: 20px; - margin-right: 0; -} - -.docs-data > .input-group { - margin-bottom: 10px; -} - -.docs-data > .input-group > label { - min-width: 80px; -} - -.docs-data > .input-group > span { - min-width: 50px; -} - -.docs-buttons > .btn, -.docs-buttons > .btn-group, -.docs-buttons > .form-control { - margin-right: 5px; - margin-bottom: 10px; -} - -.docs-toggles > .btn, -.docs-toggles > .btn-group, -.docs-toggles > .dropdown { - margin-bottom: 10px; -} - -.docs-tooltip { - display: block; - margin: -6px -12px; - padding: 6px 12px; -} - -.docs-tooltip > .icon { - margin: 0 -3px; - vertical-align: top; -} - -.tooltip-inner { - white-space: normal; -} - -.btn-upload .tooltip-inner, -.btn-toggle .tooltip-inner { - white-space: nowrap; -} - -.btn-toggle { - padding: 6px; -} - -.btn-toggle > .docs-tooltip { - margin: -6px; - padding: 6px; -} - -@media (max-width: 400px) { - .btn-group-crop { - margin-right: -15px!important; - } - - .btn-group-crop > .btn { - padding-left: 5px; - padding-right: 5px; - } - - .btn-group-crop .docs-tooltip { - margin-left: -5px; - margin-right: -5px; - padding-left: 5px; - padding-right: 5px; - } -} - -.docs-options .dropdown-menu { - width: 100%; -} - -.docs-options .dropdown-menu > li { - padding: 3px 20px; -} - -.docs-options .dropdown-menu > li:hover { - background-color: #f7f7f7; -} - -.docs-options .dropdown-menu > li > label { - display: block; -} - -.docs-cropped .modal-body { - text-align: center; -} - -.docs-cropped .modal-body > img, -.docs-cropped .modal-body > canvas { - max-width: 100%; -} - -.docs-diagram .modal-dialog { - max-width: 352px; -} - - -/* Footer */ - -.docs-footer { - margin-top: 100px; - padding-top: 10px; - padding-bottom: 10px; - border-top: 1px solid #0066bf; - background-color: #0074d9; - color: #ddd; -} - -.docs-footer a { - color: #eee; -} - -.docs-footer a:hover, -.docs-footer a:focus { - color: #fff; -} - -.docs-footer a + a { - margin-left: 10px; -} - -@media (min-width: 768px) { - .back-to-top { - float: right; - } -} - - -/* Examples - * -------------------------------------------------------------------------- */ - -.cropper-example-1 { - max-height: 331px; -} - -@media (min-width: 768px) { - .cropper-example-1 { - min-height: 305px; - } -} - -.cropper-example-1 > img, -.cropper-example-3 > img { - max-width: 100%; -} - -.cropper-example-3 { - width: 100%; - margin-top: 15px; -} - - -/* Google code prettify - * -------------------------------------------------------------------------- */ - -.prettyprint { - padding: 10px 15px !important; - border: 1px solid #ddd !important; -} diff --git a/docs/v1.0.0/img/picture-2.jpg b/docs/v1.0.0/img/picture-2.jpg deleted file mode 100644 index 05df6dc3..00000000 Binary files a/docs/v1.0.0/img/picture-2.jpg and /dev/null differ diff --git a/docs/v1.0.0/index.html b/docs/v1.0.0/index.html deleted file mode 100644 index c7f471d4..00000000 --- a/docs/v1.0.0/index.html +++ /dev/null @@ -1,697 +0,0 @@ - - - - - - - - - - Cropper - - - - - - - - - - - - - - -
-
-

Cropper v1.0.0

-

A simple jQuery image cropping plugin.

-
-
- - -
-
-
- -
- Picture -
-
-
- -
-
-
-
-
-
- - -
-
- - - px -
-
- - - px -
-
- - - px -
-
- - - px -
-
- - - deg -
-
- - -
-
- - -
-
-
-
-
-
- -
- - -
- -
- - -
- -
- - - - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - - -
- -
- - - -
- - - - - - - - - - - - - -
- -
- -
- - - - - -
- - - - - - Go to CropperJS - -
- -
-
- -
-
-
HTML:
-
...
-<div class="img-container">
-  <img src="img/picture.jpg">
-</div>
-...
-...
-<div class="img-preview preview-lg"></div>
-<div class="img-preview preview-md"></div>
-<div class="img-preview preview-sm"></div>
-<div class="img-preview preview-xs"></div>
-...
-
- -
-
Javascript:
-
$(".img-container > img").cropper({
-  aspectRatio: 16 / 9,
-  preview: ".img-preview",
-  crop: function(e) {
-    $("#dataX").val(Math.round(e.x));
-    $("#dataY").val(Math.round(e.y));
-    $("#dataHeight").val(Math.round(e.height));
-    $("#dataWidth").val(Math.round(e.width));
-    $("#dataRotate").val(e.rotate);
-    $("#dataScaleX").val(e.scaleX);
-    $("#dataScaleY").val(e.scaleY);
-  }
-});
-
- -
-
-
- - -
-

Examples

- - -

Cropper with fixed crop box.

-
-
-
Demo:
-
- Picture -
-
-
-
HTML:
-
<div class="cropper-example-1">
-  <img src="img/picture.jpg" alt="Picture">
-</div>
-
JavaScript:
-
$('.cropper-example-1 > img').cropper({
-  aspectRatio: 16 / 9,
-  autoCropArea: 0.65,
-  strict: false,
-  guides: false,
-  highlight: false,
-  dragCrop: false,
-  cropBoxMovable: false,
-  cropBoxResizable: false
-});
-
-
- - -

Cropper in a Bootstrap modal

-
-
-

Demo:

-

-

HTML:

-
<div class="modal fade" id="cropper-example-2-modal">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      ...
-      <div class="modal-body">
-        <div id="cropper-example-2">
-          <img src="img/picture.jpg" alt="Picture">
-        </div>
-      </div>
-      ...
-    </div>
-  </div>
-</div>
- - - - -
-
-

JavaScript:

-
var $image = $('#cropper-example-2 > img'),
-    cropBoxData,
-    canvasData;
-
-$('#cropper-example-2-modal').on('shown.bs.modal', function () {
-  $image.cropper({
-    autoCropArea: 0.5,
-    built: function () {
-      // Strict mode: set crop box data first
-      $image.cropper('setCropBoxData', cropBoxData);
-      $image.cropper('setCanvasData', canvasData);
-    }
-  });
-}).on('hidden.bs.modal', function () {
-  cropBoxData = $image.cropper('getCropBoxData');
-  canvasData = $image.cropper('getCanvasData');
-  $image.cropper('destroy');
-});
-
-
- - -

Cropper with responsive container.

-
-
-
Demo:
- -
- Picture -
-
-
-
HTML:
-
<button class="btn btn-primary" id="replace-toggle" type="button">Toggle</button>
-
-<div class="cropper-example-3">
-  <img src="img/picture.jpg" alt="Picture">
-</div>
-
CSS:
-
.cropper-example-3 {
-  width: 100%;
-}
-
-.cropper-example-3 > img {
-  max-width: 100%;
-}
-
-
-
JavaScript:
-
var $image = $('.cropper-example-3 > img'),
-    replaced;
-
-$image.cropper({
-  movable: false,
-  zoomable: false,
-  rotatable: false,
-  scalable: false
-});
-
-$('#replace-toggle').click(function () {
-  var url = 'img/picture-2.jpg';
-
-  if (replaced) {
-    url = 'img/picture.jpg';
-  }
-
-  $image.cropper('replace', url);
-  replaced = !replaced;
-});
-
-
- - -

Crop avatar A complete example

-

This example requires a PHP server to upload and crop image. Please download and test it.

- - -
- - - - - - - - - - - - - - diff --git a/docs/v1.0.0/js/cropper.js b/docs/v1.0.0/js/cropper.js deleted file mode 100644 index 124fc639..00000000 --- a/docs/v1.0.0/js/cropper.js +++ /dev/null @@ -1,2519 +0,0 @@ -/*! - * Cropper v1.0.0 - * https://github.com/fengyuanchen/cropper - * - * Copyright (c) 2014-2015 Fengyuan Chen and contributors - * Released under the MIT license - * - * Date: 2015-10-10T02:10:08.624Z - */ - -(function (factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as anonymous module. - define(['jquery'], factory); - } else if (typeof exports === 'object') { - // Node / CommonJS - factory(require('jquery')); - } else { - // Browser globals. - factory(jQuery); - } -})(function ($) { - - 'use strict'; - - // Globals - var $window = $(window); - var $document = $(document); - var location = window.location; - - // Constants - var NAMESPACE = 'cropper'; - - // Classes - var CLASS_MODAL = 'cropper-modal'; - var CLASS_HIDE = 'cropper-hide'; - var CLASS_HIDDEN = 'cropper-hidden'; - var CLASS_INVISIBLE = 'cropper-invisible'; - var CLASS_MOVE = 'cropper-move'; - var CLASS_CROP = 'cropper-crop'; - var CLASS_DISABLED = 'cropper-disabled'; - var CLASS_BG = 'cropper-bg'; - - // Events - var EVENT_MOUSE_DOWN = 'mousedown touchstart pointerdown MSPointerDown'; - var EVENT_MOUSE_MOVE = 'mousemove touchmove pointermove MSPointerMove'; - var EVENT_MOUSE_UP = 'mouseup touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel'; - var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll'; - var EVENT_DBLCLICK = 'dblclick'; - var EVENT_LOAD = 'load.' + NAMESPACE; - var EVENT_ERROR = 'error.' + NAMESPACE; - var EVENT_RESIZE = 'resize.' + NAMESPACE; // Bind to window with namespace - var EVENT_BUILD = 'build.' + NAMESPACE; - var EVENT_BUILT = 'built.' + NAMESPACE; - var EVENT_CROP_START = 'cropstart.' + NAMESPACE; - var EVENT_CROP_MOVE = 'cropmove.' + NAMESPACE; - var EVENT_CROP_END = 'cropend.' + NAMESPACE; - var EVENT_CROP = 'crop.' + NAMESPACE; - var EVENT_ZOOM = 'zoom.' + NAMESPACE; - - // RegExps - var REGEXP_ACTIONS = /^(e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/; - - // Data keys - var DATA_PREVIEW = 'preview'; - var DATA_ACTION = 'action'; - - // Actions - var ACTION_EAST = 'e'; - var ACTION_WEST = 'w'; - var ACTION_SOUTH = 's'; - var ACTION_NORTH = 'n'; - var ACTION_SOUTH_EAST = 'se'; - var ACTION_SOUTH_WEST = 'sw'; - var ACTION_NORTH_EAST = 'ne'; - var ACTION_NORTH_WEST = 'nw'; - var ACTION_ALL = 'all'; - var ACTION_CROP = 'crop'; - var ACTION_MOVE = 'move'; - var ACTION_ZOOM = 'zoom'; - var ACTION_NONE = 'none'; - - // Supports - var SUPPORT_CANVAS = $.isFunction($('')[0].getContext); - - // Maths - var sqrt = Math.sqrt; - var min = Math.min; - var max = Math.max; - var abs = Math.abs; - var sin = Math.sin; - var cos = Math.cos; - var num = parseFloat; - - // Prototype - var prototype = { - version: '1.0.0' - }; - - function isNumber(n) { - return typeof n === 'number' && !isNaN(n); - } - - function isUndefined(n) { - return typeof n === 'undefined'; - } - - function toArray(obj, offset) { - var args = []; - - // This is necessary for IE8 - if (isNumber(offset)) { - args.push(offset); - } - - return args.slice.apply(obj, args); - } - - // Custom proxy to avoid jQuery's guid - function proxy(fn, context) { - var args = toArray(arguments, 2); - - return function () { - return fn.apply(context, args.concat(toArray(arguments))); - }; - } - - function isCrossOriginURL(url) { - var parts = url.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i); - - return parts && ( - parts[1] !== location.protocol || - parts[2] !== location.hostname || - parts[3] !== location.port - ); - } - - function addTimestamp(url) { - var timestamp = 'timestamp=' + (new Date()).getTime(); - - return (url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp); - } - - function getCrossOrigin(crossOrigin) { - return crossOrigin ? ' crossOrigin="' + crossOrigin + '"' : ''; - } - - function getImageSize(image, callback) { - var newImage; - - // Modern browsers - if (image.naturalWidth) { - return callback(image.naturalWidth, image.naturalHeight); - } - - // IE8: Don't use `new Image()` here (#319) - newImage = document.createElement('img'); - - newImage.onload = function () { - callback(this.width, this.height); - }; - - newImage.src = image.src; - } - - function getTransform(options) { - var transforms = []; - var rotate = options.rotate; - var scaleX = options.scaleX; - var scaleY = options.scaleY; - - if (isNumber(rotate)) { - transforms.push('rotate(' + rotate + 'deg)'); - } - - if (isNumber(scaleX) && isNumber(scaleY)) { - transforms.push('scale(' + scaleX + ',' + scaleY + ')'); - } - - return transforms.length ? transforms.join(' ') : 'none'; - } - - function getRotatedSizes(data, reverse) { - var deg = abs(data.degree) % 180; - var arc = (deg > 90 ? (180 - deg) : deg) * Math.PI / 180; - var sinArc = sin(arc); - var cosArc = cos(arc); - var width = data.width; - var height = data.height; - var aspectRatio = data.aspectRatio; - var newWidth; - var newHeight; - - if (!reverse) { - newWidth = width * cosArc + height * sinArc; - newHeight = width * sinArc + height * cosArc; - } else { - newWidth = width / (cosArc + sinArc / aspectRatio); - newHeight = newWidth / aspectRatio; - } - - return { - width: newWidth, - height: newHeight - }; - } - - function getSourceCanvas(image, data) { - var canvas = $('')[0]; - var context = canvas.getContext('2d'); - var x = 0; - var y = 0; - var width = data.naturalWidth; - var height = data.naturalHeight; - var rotate = data.rotate; - var scaleX = data.scaleX; - var scaleY = data.scaleY; - var scalable = isNumber(scaleX) && isNumber(scaleY) && (scaleX !== 1 || scaleY !== 1); - var rotatable = isNumber(rotate) && rotate !== 0; - var advanced = rotatable || scalable; - var canvasWidth = width; - var canvasHeight = height; - var translateX; - var translateY; - var rotated; - - if (scalable) { - translateX = width / 2; - translateY = height / 2; - } - - if (rotatable) { - rotated = getRotatedSizes({ - width: width, - height: height, - degree: rotate - }); - - canvasWidth = rotated.width; - canvasHeight = rotated.height; - translateX = rotated.width / 2; - translateY = rotated.height / 2; - } - - canvas.width = canvasWidth; - canvas.height = canvasHeight; - - if (advanced) { - x = -width / 2; - y = -height / 2; - - context.save(); - context.translate(translateX, translateY); - } - - if (rotatable) { - context.rotate(rotate * Math.PI / 180); - } - - // Should call `scale` after rotated - if (scalable) { - context.scale(scaleX, scaleY); - } - - context.drawImage(image, x, y, width, height); - - if (advanced) { - context.restore(); - } - - return canvas; - } - - function Cropper(element, options) { - this.$element = $(element); - this.options = $.extend({}, Cropper.DEFAULTS, $.isPlainObject(options) && options); - this.ready = false; - this.built = false; - this.complete = false; - this.rotated = false; - this.cropped = false; - this.disabled = false; - this.replaced = false; - this.isImg = false; - this.originalUrl = ''; - this.crossOrigin = ''; - this.canvas = null; - this.cropBox = null; - this.init(); - } - - $.extend(prototype, { - init: function () { - var $this = this.$element; - var url; - - if ($this.is('img')) { - this.isImg = true; - - // Should use `$.fn.attr` here. e.g.: "img/picture.jpg" - this.originalUrl = url = $this.attr('src'); - - // Stop when it's a blank image - if (!url) { - return; - } - - // Should use `$.fn.prop` here. e.g.: "http://example.com/img/picture.jpg" - url = $this.prop('src'); - } else if ($this.is('canvas') && SUPPORT_CANVAS) { - url = $this[0].toDataURL(); - } - - this.load(url); - }, - - // A shortcut for triggering custom events - trigger: function (type, data) { - var e = $.Event(type, data); - - this.$element.trigger(e); - - return e; - }, - - load: function (url) { - var options = this.options; - var $this = this.$element; - var crossOrigin = ''; - var bustCacheUrl; - var $clone; - - if (!url) { - return; - } - - this.url = url; - - // Trigger build event first - $this.one(EVENT_BUILD, options.build); - - if (this.trigger(EVENT_BUILD).isDefaultPrevented()) { - return; - } - - if (options.checkImageOrigin && isCrossOriginURL(url)) { - crossOrigin = $this.prop('crossOrigin'); - - // Bust cache (#148), only when there was not a "crossOrigin" property - if (!crossOrigin) { - crossOrigin = 'anonymous'; - bustCacheUrl = addTimestamp(url); - } - - this.crossOrigin = crossOrigin; - } - - this.$clone = $clone = $(''); - - if (this.isImg) { - if ($this[0].complete) { - this.start(); - } else { - $this.one(EVENT_LOAD, $.proxy(this.start, this)); - } - } else { - $clone. - one(EVENT_LOAD, $.proxy(this.start, this)). - one(EVENT_ERROR, $.proxy(this.stop, this)). - addClass(CLASS_HIDE). - insertAfter($this); - } - }, - - start: function () { - var $image = this.$element; - var $clone = this.$clone; - - if (!this.isImg) { - $clone.off(EVENT_ERROR, this.stop); - $image = $clone; - } - - getImageSize($image[0], $.proxy(function (naturalWidth, naturalHeight) { - this.image = { - naturalWidth: naturalWidth, - naturalHeight: naturalHeight, - aspectRatio: naturalWidth / naturalHeight - }; - - this.ready = true; - this.build(); - }, this)); - }, - - stop: function () { - this.$clone.remove(); - this.$clone = null; - } - }); - - $.extend(prototype, { - build: function () { - var options = this.options; - var $this = this.$element; - var $clone = this.$clone; - var $cropper; - var $cropBox; - var $face; - - if (!this.ready) { - return; - } - - // Unbuild first when replace - if (this.built) { - this.unbuild(); - } - - // Create cropper elements - this.$container = $this.parent(); - this.$cropper = $cropper = $(Cropper.TEMPLATE); - this.$canvas = $cropper.find('.cropper-canvas').append($clone); - this.$dragBox = $cropper.find('.cropper-drag-box'); - this.$cropBox = $cropBox = $cropper.find('.cropper-crop-box'); - this.$viewBox = $cropper.find('.cropper-view-box'); - this.$face = $face = $cropBox.find('.cropper-face'); - - // Hide the original image - $this.addClass(CLASS_HIDDEN).after($cropper); - - // Show the clone image if is hidden - if (!this.isImg) { - $clone.removeClass(CLASS_HIDE); - } - - this.initPreview(); - this.bind(); - - // Format aspect ratio (0 -> NaN) - options.aspectRatio = num(options.aspectRatio) || NaN; - - if (options.autoCrop) { - this.cropped = true; - - if (options.modal) { - this.$dragBox.addClass(CLASS_MODAL); - } - } else { - $cropBox.addClass(CLASS_HIDDEN); - } - - if (!options.guides) { - $cropBox.find('.cropper-dashed').addClass(CLASS_HIDDEN); - } - - if (!options.center) { - $cropBox.find('.cropper-center').addClass(CLASS_HIDDEN); - } - - if (options.cropBoxMovable) { - $face.addClass(CLASS_MOVE).data(DATA_ACTION, ACTION_ALL); - } - - if (!options.highlight) { - $face.addClass(CLASS_INVISIBLE); - } - - if (options.background) { - $cropper.addClass(CLASS_BG); - } - - if (!options.cropBoxResizable) { - $cropBox.find('.cropper-line, .cropper-point').addClass(CLASS_HIDDEN); - } - - this.setDragMode(options.dragCrop ? ACTION_CROP : (options.movable ? ACTION_MOVE : ACTION_NONE)); - - this.render(); - this.built = true; - this.setData(options.data); - $this.one(EVENT_BUILT, options.built); - - // Trigger the built event asynchronously to keep `data('cropper')` is defined - setTimeout($.proxy(function () { - this.trigger(EVENT_BUILT); - this.complete = true; - }, this), 0); - }, - - unbuild: function () { - if (!this.built) { - return; - } - - this.built = false; - this.initialImage = null; - - // Clear `initialCanvas` is necessary when replace - this.initialCanvas = null; - this.initialCropBox = null; - this.container = null; - this.canvas = null; - - // Clear `cropBox` is necessary when replace - this.cropBox = null; - this.unbind(); - - this.resetPreview(); - this.$preview = null; - - this.$viewBox = null; - this.$cropBox = null; - this.$dragBox = null; - this.$canvas = null; - this.$container = null; - - this.$cropper.remove(); - this.$cropper = null; - } - }); - - $.extend(prototype, { - render: function () { - this.initContainer(); - this.initCanvas(); - this.initCropBox(); - - this.renderCanvas(); - - if (this.cropped) { - this.renderCropBox(); - } - }, - - initContainer: function () { - var options = this.options; - var $this = this.$element; - var $container = this.$container; - var $cropper = this.$cropper; - - $cropper.addClass(CLASS_HIDDEN); - $this.removeClass(CLASS_HIDDEN); - - $cropper.css((this.container = { - width: max($container.width(), num(options.minContainerWidth) || 200), - height: max($container.height(), num(options.minContainerHeight) || 100) - })); - - $this.addClass(CLASS_HIDDEN); - $cropper.removeClass(CLASS_HIDDEN); - }, - - // Canvas (image wrapper) - initCanvas: function () { - var container = this.container; - var containerWidth = container.width; - var containerHeight = container.height; - var image = this.image; - var aspectRatio = image.aspectRatio; - var canvas = { - aspectRatio: aspectRatio, - width: containerWidth, - height: containerHeight - }; - - if (containerHeight * aspectRatio > containerWidth) { - canvas.height = containerWidth / aspectRatio; - } else { - canvas.width = containerHeight * aspectRatio; - } - - canvas.oldLeft = canvas.left = (containerWidth - canvas.width) / 2; - canvas.oldTop = canvas.top = (containerHeight - canvas.height) / 2; - - this.canvas = canvas; - this.limitCanvas(true, true); - this.initialImage = $.extend({}, image); - this.initialCanvas = $.extend({}, canvas); - }, - - limitCanvas: function (size, position) { - var options = this.options; - var strict = options.strict; - var container = this.container; - var containerWidth = container.width; - var containerHeight = container.height; - var canvas = this.canvas; - var aspectRatio = canvas.aspectRatio; - var cropBox = this.cropBox; - var cropped = this.cropped && cropBox; - var initialCanvas = this.initialCanvas || canvas; - var minCanvasWidth; - var minCanvasHeight; - - if (size) { - minCanvasWidth = num(options.minCanvasWidth) || 0; - minCanvasHeight = num(options.minCanvasHeight) || 0; - - if (strict) { - if (minCanvasWidth) { - minCanvasWidth = max(minCanvasWidth, cropped ? cropBox.width : initialCanvas.width); - } else if (minCanvasHeight) { - minCanvasHeight = max(minCanvasHeight, cropped ? cropBox.height : initialCanvas.height); - } else if (cropped) { - minCanvasWidth = cropBox.width; - minCanvasHeight = cropBox.height; - - if (minCanvasHeight * aspectRatio > minCanvasWidth) { - minCanvasWidth = minCanvasHeight * aspectRatio; - } else { - minCanvasHeight = minCanvasWidth / aspectRatio; - } - } - } - - if (minCanvasWidth && minCanvasHeight) { - if (minCanvasHeight * aspectRatio > minCanvasWidth) { - minCanvasHeight = minCanvasWidth / aspectRatio; - } else { - minCanvasWidth = minCanvasHeight * aspectRatio; - } - } else if (minCanvasWidth) { - minCanvasHeight = minCanvasWidth / aspectRatio; - } else if (minCanvasHeight) { - minCanvasWidth = minCanvasHeight * aspectRatio; - } - - canvas.minWidth = minCanvasWidth; - canvas.minHeight = minCanvasHeight; - canvas.maxWidth = Infinity; - canvas.maxHeight = Infinity; - } - - if (position) { - if (strict) { - canvas.minLeft = cropped ? - min(cropBox.left, (cropBox.left + cropBox.width) - canvas.width) : - min(0, containerWidth - canvas.width); - canvas.minTop = cropped ? - min(cropBox.top, (cropBox.top + cropBox.height) - canvas.height) : - min(0, containerHeight - canvas.height); - canvas.maxLeft = cropped ? cropBox.left : max(0, containerWidth - canvas.width); - canvas.maxTop = cropped ? cropBox.top : max(0, containerHeight - canvas.height); - } else { - canvas.minLeft = -canvas.width; - canvas.minTop = -canvas.height; - canvas.maxLeft = containerWidth; - canvas.maxTop = containerHeight; - } - } - }, - - renderCanvas: function (changed) { - var options = this.options; - var canvas = this.canvas; - var image = this.image; - var aspectRatio; - var rotated; - - if (this.rotated) { - this.rotated = false; - - // Computes rotated sizes with image sizes - rotated = getRotatedSizes({ - width: image.width, - height: image.height, - degree: image.rotate - }); - - aspectRatio = rotated.width / rotated.height; - - if (aspectRatio !== canvas.aspectRatio) { - canvas.left -= (rotated.width - canvas.width) / 2; - canvas.top -= (rotated.height - canvas.height) / 2; - canvas.width = rotated.width; - canvas.height = rotated.height; - canvas.aspectRatio = aspectRatio; - this.limitCanvas(true, false); - } - } - - if (canvas.width > canvas.maxWidth || canvas.width < canvas.minWidth) { - canvas.left = canvas.oldLeft; - } - - if (canvas.height > canvas.maxHeight || canvas.height < canvas.minHeight) { - canvas.top = canvas.oldTop; - } - - canvas.width = min(max(canvas.width, canvas.minWidth), canvas.maxWidth); - canvas.height = min(max(canvas.height, canvas.minHeight), canvas.maxHeight); - - this.limitCanvas(false, true); - - canvas.oldLeft = canvas.left = min(max(canvas.left, canvas.minLeft), canvas.maxLeft); - canvas.oldTop = canvas.top = min(max(canvas.top, canvas.minTop), canvas.maxTop); - - this.$canvas.css({ - width: canvas.width, - height: canvas.height, - left: canvas.left, - top: canvas.top - }); - - this.renderImage(); - - if (this.cropped && options.strict) { - this.limitCropBox(true, true); - } - - if (changed) { - this.output(); - } - }, - - renderImage: function (changed) { - var canvas = this.canvas; - var image = this.image; - var reversed; - - if (image.rotate) { - reversed = getRotatedSizes({ - width: canvas.width, - height: canvas.height, - degree: image.rotate, - aspectRatio: image.aspectRatio - }, true); - } - - $.extend(image, reversed ? { - width: reversed.width, - height: reversed.height, - left: (canvas.width - reversed.width) / 2, - top: (canvas.height - reversed.height) / 2 - } : { - width: canvas.width, - height: canvas.height, - left: 0, - top: 0 - }); - - this.$clone.css({ - width: image.width, - height: image.height, - marginLeft: image.left, - marginTop: image.top, - transform: getTransform(image) - }); - - if (changed) { - this.output(); - } - }, - - initCropBox: function () { - var options = this.options; - var canvas = this.canvas; - var aspectRatio = options.aspectRatio; - var autoCropArea = num(options.autoCropArea) || 0.8; - var cropBox = { - width: canvas.width, - height: canvas.height - }; - - if (aspectRatio) { - if (canvas.height * aspectRatio > canvas.width) { - cropBox.height = cropBox.width / aspectRatio; - } else { - cropBox.width = cropBox.height * aspectRatio; - } - } - - this.cropBox = cropBox; - this.limitCropBox(true, true); - - // Initialize auto crop area - cropBox.width = min(max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); - cropBox.height = min(max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); - - // The width of auto crop area must large than "minWidth", and the height too. (#164) - cropBox.width = max(cropBox.minWidth, cropBox.width * autoCropArea); - cropBox.height = max(cropBox.minHeight, cropBox.height * autoCropArea); - cropBox.oldLeft = cropBox.left = canvas.left + (canvas.width - cropBox.width) / 2; - cropBox.oldTop = cropBox.top = canvas.top + (canvas.height - cropBox.height) / 2; - - this.initialCropBox = $.extend({}, cropBox); - }, - - limitCropBox: function (size, position) { - var options = this.options; - var strict = options.strict; - var container = this.container; - var containerWidth = container.width; - var containerHeight = container.height; - var canvas = this.canvas; - var cropBox = this.cropBox; - var aspectRatio = options.aspectRatio; - var minCropBoxWidth; - var minCropBoxHeight; - var maxCropBoxWidth; - var maxCropBoxHeight; - - if (size) { - minCropBoxWidth = num(options.minCropBoxWidth) || 0; - minCropBoxHeight = num(options.minCropBoxHeight) || 0; - - // The min/maxCropBoxWidth/Height must be less than containerWidth/Height - minCropBoxWidth = min(minCropBoxWidth, containerWidth); - minCropBoxHeight = min(minCropBoxHeight, containerHeight); - maxCropBoxWidth = min(containerWidth, strict ? canvas.width : containerWidth); - maxCropBoxHeight = min(containerHeight, strict ? canvas.height : containerHeight); - - 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 - cropBox.minWidth = min(minCropBoxWidth, maxCropBoxWidth); - cropBox.minHeight = min(minCropBoxHeight, maxCropBoxHeight); - cropBox.maxWidth = maxCropBoxWidth; - cropBox.maxHeight = maxCropBoxHeight; - } - - if (position) { - if (strict) { - cropBox.minLeft = max(0, canvas.left); - cropBox.minTop = max(0, canvas.top); - cropBox.maxLeft = min(containerWidth, canvas.left + canvas.width) - cropBox.width; - cropBox.maxTop = min(containerHeight, canvas.top + canvas.height) - cropBox.height; - } else { - cropBox.minLeft = 0; - cropBox.minTop = 0; - cropBox.maxLeft = containerWidth - cropBox.width; - cropBox.maxTop = containerHeight - cropBox.height; - } - } - }, - - renderCropBox: function () { - var options = this.options; - var container = this.container; - var containerWidth = container.width; - var containerHeight = container.height; - var cropBox = this.cropBox; - - if (cropBox.width > cropBox.maxWidth || cropBox.width < cropBox.minWidth) { - cropBox.left = cropBox.oldLeft; - } - - if (cropBox.height > cropBox.maxHeight || cropBox.height < cropBox.minHeight) { - cropBox.top = cropBox.oldTop; - } - - cropBox.width = min(max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); - cropBox.height = min(max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); - - this.limitCropBox(false, true); - - cropBox.oldLeft = cropBox.left = min(max(cropBox.left, cropBox.minLeft), cropBox.maxLeft); - cropBox.oldTop = cropBox.top = min(max(cropBox.top, cropBox.minTop), cropBox.maxTop); - - if (options.movable && options.cropBoxMovable) { - - // Turn to move the canvas when the crop box is equal to the container - this.$face.data(DATA_ACTION, (cropBox.width === containerWidth && cropBox.height === containerHeight) ? ACTION_MOVE : ACTION_ALL); - } - - this.$cropBox.css({ - width: cropBox.width, - height: cropBox.height, - left: cropBox.left, - top: cropBox.top - }); - - if (this.cropped && options.strict) { - this.limitCanvas(true, true); - } - - if (!this.disabled) { - this.output(); - } - }, - - output: function () { - this.preview(); - - if (this.complete) { - this.trigger(EVENT_CROP, this.getData()); - } else if (!this.built) { - - // Only trigger one crop event before complete - this.$element.one(EVENT_BUILT, $.proxy(function () { - this.trigger(EVENT_CROP, this.getData()); - }, this)); - } - } - }); - - $.extend(prototype, { - initPreview: function () { - var crossOrigin = getCrossOrigin(this.crossOrigin); - var url = this.url; - - this.$preview = $(this.options.preview); - this.$viewBox.html(''); - this.$preview.each(function () { - var $this = $(this); - - // Save the original size for recover - $this.data(DATA_PREVIEW, { - width: $this.width(), - height: $this.height(), - original: $this.html() - }); - - /** - * Override img element styles - * Add `display:block` to avoid margin top issue - * (Occur only when margin-top <= -height) - */ - $this.html( - '' - ); - }); - }, - - resetPreview: function () { - this.$preview.each(function () { - var $this = $(this); - - $this.html($this.data(DATA_PREVIEW).original).removeData(DATA_PREVIEW); - }); - }, - - preview: function () { - var image = this.image; - var canvas = this.canvas; - var cropBox = this.cropBox; - var cropBoxWidth = cropBox.width; - var cropBoxHeight = cropBox.height; - var width = image.width; - var height = image.height; - var left = cropBox.left - canvas.left - image.left; - var top = cropBox.top - canvas.top - image.top; - - if (!this.cropped || this.disabled) { - return; - } - - this.$viewBox.find('img').css({ - width: width, - height: height, - marginLeft: -left, - marginTop: -top, - transform: getTransform(image) - }); - - this.$preview.each(function () { - var $this = $(this); - var data = $this.data(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; - } - - $this.width(newWidth).height(newHeight).find('img').css({ - width: width * ratio, - height: height * ratio, - marginLeft: -left * ratio, - marginTop: -top * ratio, - transform: getTransform(image) - }); - }); - } - }); - - $.extend(prototype, { - bind: function () { - var options = this.options; - var $this = this.$element; - var $cropper = this.$cropper; - - if ($.isFunction(options.cropstart)) { - $this.on(EVENT_CROP_START, options.cropstart); - } - - if ($.isFunction(options.cropmove)) { - $this.on(EVENT_CROP_MOVE, options.cropmove); - } - - if ($.isFunction(options.cropend)) { - $this.on(EVENT_CROP_END, options.cropend); - } - - if ($.isFunction(options.crop)) { - $this.on(EVENT_CROP, options.crop); - } - - if ($.isFunction(options.zoom)) { - $this.on(EVENT_ZOOM, options.zoom); - } - - $cropper.on(EVENT_MOUSE_DOWN, $.proxy(this.cropStart, this)); - - if (options.zoomable && options.mouseWheelZoom) { - $cropper.on(EVENT_WHEEL, $.proxy(this.wheel, this)); - } - - if (options.doubleClickToggle) { - $cropper.on(EVENT_DBLCLICK, $.proxy(this.dblclick, this)); - } - - $document. - on(EVENT_MOUSE_MOVE, (this._cropMove = proxy(this.cropMove, this))). - on(EVENT_MOUSE_UP, (this._cropEnd = proxy(this.cropEnd, this))); - - if (options.responsive) { - $window.on(EVENT_RESIZE, (this._resize = proxy(this.resize, this))); - } - }, - - unbind: function () { - var options = this.options; - var $this = this.$element; - var $cropper = this.$cropper; - - if ($.isFunction(options.cropstart)) { - $this.off(EVENT_CROP_START, options.cropstart); - } - - if ($.isFunction(options.cropmove)) { - $this.off(EVENT_CROP_MOVE, options.cropmove); - } - - if ($.isFunction(options.cropend)) { - $this.off(EVENT_CROP_END, options.cropend); - } - - if ($.isFunction(options.crop)) { - $this.off(EVENT_CROP, options.crop); - } - - if ($.isFunction(options.zoom)) { - $this.off(EVENT_ZOOM, options.zoom); - } - - $cropper.off(EVENT_MOUSE_DOWN, this.cropStart); - - if (options.zoomable && options.mouseWheelZoom) { - $cropper.off(EVENT_WHEEL, this.wheel); - } - - if (options.doubleClickToggle) { - $cropper.off(EVENT_DBLCLICK, this.dblclick); - } - - $document. - off(EVENT_MOUSE_MOVE, this._cropMove). - off(EVENT_MOUSE_UP, this._cropEnd); - - if (options.responsive) { - $window.off(EVENT_RESIZE, this._resize); - } - } - }); - - $.extend(prototype, { - resize: function () { - var $container = this.$container; - var container = this.container; - var canvasData; - var cropBoxData; - var ratio; - - // Check `container` is necessary for IE8 - if (this.disabled || !container) { - return; - } - - ratio = $container.width() / container.width; - - // Resize when width changed or height changed - if (ratio !== 1 || $container.height() !== container.height) { - canvasData = this.getCanvasData(); - cropBoxData = this.getCropBoxData(); - - this.render(); - this.setCanvasData($.each(canvasData, function (i, n) { - canvasData[i] = n * ratio; - })); - this.setCropBoxData($.each(cropBoxData, function (i, n) { - cropBoxData[i] = n * ratio; - })); - } - }, - - dblclick: function () { - if (this.disabled) { - return; - } - - if (this.$dragBox.hasClass(CLASS_CROP)) { - this.setDragMode(ACTION_MOVE); - } else { - this.setDragMode(ACTION_CROP); - } - }, - - wheel: function (event) { - var originalEvent = event.originalEvent; - var e = originalEvent; - var ratio = num(this.options.wheelZoomRatio) || 0.1; - var delta = 1; - - if (this.disabled) { - return; - } - - event.preventDefault(); - - 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, originalEvent); - }, - - cropStart: function (event) { - var options = this.options; - var originalEvent = event.originalEvent; - var touches = originalEvent && originalEvent.touches; - var e = event; - var touchesLength; - var action; - - if (this.disabled) { - return; - } - - if (touches) { - touchesLength = touches.length; - - if (touchesLength > 1) { - if (options.zoomable && options.touchDragZoom && touchesLength === 2) { - e = touches[1]; - this.startX2 = e.pageX; - this.startY2 = e.pageY; - action = ACTION_ZOOM; - } else { - return; - } - } - - e = touches[0]; - } - - action = action || $(e.target).data(DATA_ACTION); - - if (REGEXP_ACTIONS.test(action)) { - if (this.trigger(EVENT_CROP_START, { - originalEvent: originalEvent, - action: action - }).isDefaultPrevented()) { - return; - } - - event.preventDefault(); - - this.action = action; - this.cropping = false; - - // IE8 has `event.pageX/Y`, but not `event.originalEvent.pageX/Y` - // IE10 has `event.originalEvent.pageX/Y`, but not `event.pageX/Y` - this.startX = e.pageX || originalEvent && originalEvent.pageX; - this.startY = e.pageY || originalEvent && originalEvent.pageY; - - if (action === ACTION_CROP) { - this.cropping = true; - this.$dragBox.addClass(CLASS_MODAL); - } - } - }, - - cropMove: function (event) { - var options = this.options; - var originalEvent = event.originalEvent; - var touches = originalEvent && originalEvent.touches; - var e = event; - var action = this.action; - var touchesLength; - - if (this.disabled) { - return; - } - - if (touches) { - touchesLength = touches.length; - - if (touchesLength > 1) { - if (options.zoomable && options.touchDragZoom && touchesLength === 2) { - e = touches[1]; - this.endX2 = e.pageX; - this.endY2 = e.pageY; - } else { - return; - } - } - - e = touches[0]; - } - - if (action) { - if (this.trigger(EVENT_CROP_MOVE, { - originalEvent: originalEvent, - action: action - }).isDefaultPrevented()) { - return; - } - - event.preventDefault(); - - this.endX = e.pageX || originalEvent && originalEvent.pageX; - this.endY = e.pageY || originalEvent && originalEvent.pageY; - - this.change(e.shiftKey, action === ACTION_ZOOM ? originalEvent : null); - } - }, - - cropEnd: function (event) { - var originalEvent = event.originalEvent; - var action = this.action; - - if (this.disabled) { - return; - } - - if (action) { - event.preventDefault(); - - if (this.cropping) { - this.cropping = false; - this.$dragBox.toggleClass(CLASS_MODAL, this.cropped && this.options.modal); - } - - this.action = ''; - - this.trigger(EVENT_CROP_END, { - originalEvent: originalEvent, - action: action - }); - } - } - }); - - $.extend(prototype, { - change: function (shiftKey, originalEvent) { - var options = this.options; - var aspectRatio = options.aspectRatio; - var action = this.action; - var container = this.container; - var canvas = this.canvas; - var cropBox = this.cropBox; - var width = cropBox.width; - var height = cropBox.height; - var left = cropBox.left; - var top = cropBox.top; - var right = left + width; - var bottom = top + height; - var minLeft = 0; - var minTop = 0; - var maxWidth = container.width; - var maxHeight = container.height; - var renderable = true; - var offset; - var range; - - // Locking aspect ratio in "free mode" by holding shift key (#259) - if (!aspectRatio && shiftKey) { - aspectRatio = width && height ? width / height : 1; - } - - if (options.strict) { - minLeft = cropBox.minLeft; - minTop = cropBox.minTop; - maxWidth = minLeft + min(container.width, canvas.width); - maxHeight = minTop + min(container.height, canvas.height); - } - - range = { - x: this.endX - this.startX, - y: this.endY - this.startY - }; - - if (aspectRatio) { - range.X = range.y * aspectRatio; - range.Y = range.x / aspectRatio; - } - - 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; - } - - width += range.x; - - if (aspectRatio) { - height = width / aspectRatio; - top -= range.Y / 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; - } - - height -= range.y; - top += range.y; - - if (aspectRatio) { - width = height * aspectRatio; - left += range.X / 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; - } - - width -= range.x; - left += range.x; - - if (aspectRatio) { - height = width / aspectRatio; - top += range.Y / 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; - } - - height += range.y; - - if (aspectRatio) { - width = height * aspectRatio; - left -= range.X / 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; - } - - height -= range.y; - top += range.y; - width = height * aspectRatio; - } else { - 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; - } - - height -= range.y; - top += range.y; - width = height * aspectRatio; - left += range.X; - } else { - 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; - } - - width -= range.x; - left += range.x; - height = width / aspectRatio; - } else { - 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; - } - - width += range.x; - height = width / aspectRatio; - } else { - 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((function (x1, y1, x2, y2) { - var z1 = sqrt(x1 * x1 + y1 * y1); - var z2 = sqrt(x2 * x2 + y2 * y2); - - return (z2 - z1) / z1; - })( - abs(this.startX - this.startX2), - abs(this.startY - this.startY2), - abs(this.endX - this.endX2), - abs(this.endY - this.endY2) - ), originalEvent); - this.startX2 = this.endX2; - this.startY2 = this.endY2; - renderable = false; - break; - - // Create crop box - case ACTION_CROP: - if (range.x && range.y) { - offset = this.$cropper.offset(); - left = this.startX - offset.left; - top = this.startY - offset.top; - width = cropBox.minWidth; - height = cropBox.minHeight; - - if (range.x > 0) { - if (range.y > 0) { - action = ACTION_SOUTH_EAST; - } else { - action = ACTION_NORTH_EAST; - top -= height; - } - } else { - if (range.y > 0) { - action = ACTION_SOUTH_WEST; - left -= width; - } else { - action = ACTION_NORTH_WEST; - left -= width; - top -= height; - } - } - - // Show the crop box if is hidden - if (!this.cropped) { - this.cropped = true; - this.$cropBox.removeClass(CLASS_HIDDEN); - } - } - - break; - - // No default - } - - if (renderable) { - cropBox.width = width; - cropBox.height = height; - cropBox.left = left; - cropBox.top = top; - this.action = action; - - this.renderCropBox(); - } - - // Override - this.startX = this.endX; - this.startY = this.endY; - } - }); - - $.extend(prototype, { - - // Show the crop box manually - crop: function () { - if (!this.built || this.disabled) { - return; - } - - if (!this.cropped) { - this.cropped = true; - this.limitCropBox(true, true); - - if (this.options.modal) { - this.$dragBox.addClass(CLASS_MODAL); - } - - this.$cropBox.removeClass(CLASS_HIDDEN); - } - - this.setCropBoxData(this.initialCropBox); - }, - - // Reset the image and crop box to their initial states - reset: function () { - if (!this.built || this.disabled) { - return; - } - - this.image = $.extend({}, this.initialImage); - this.canvas = $.extend({}, this.initialCanvas); - - // Required for strict mode - this.cropBox = $.extend({}, this.initialCropBox); - - this.renderCanvas(); - - if (this.cropped) { - this.renderCropBox(); - } - }, - - // Clear the crop box - clear: function () { - if (!this.cropped || this.disabled) { - return; - } - - $.extend(this.cropBox, { - 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(); - - this.$dragBox.removeClass(CLASS_MODAL); - this.$cropBox.addClass(CLASS_HIDDEN); - }, - - /** - * Replace the image's src and rebuild the cropper - * - * @param {String} url - */ - replace: function (url) { - if (!this.disabled && url) { - if (this.isImg) { - this.replaced = true; - this.$element.attr('src', url); - } - - // Clear previous data - this.options.data = null; - this.load(url); - } - }, - - // Enable (unfreeze) the cropper - enable: function () { - if (this.built) { - this.disabled = false; - this.$cropper.removeClass(CLASS_DISABLED); - } - }, - - // Disable (freeze) the cropper - disable: function () { - if (this.built) { - this.disabled = true; - this.$cropper.addClass(CLASS_DISABLED); - } - }, - - // Destroy the cropper and remove the instance from the image - destroy: function () { - var $this = this.$element; - - if (this.ready) { - if (this.isImg && this.replaced) { - $this.attr('src', this.originalUrl); - } - - this.unbuild(); - $this.removeClass(CLASS_HIDDEN); - } else { - if (this.isImg) { - $this.off(EVENT_LOAD, this.start); - } else if (this.$clone) { - this.$clone.remove(); - } - } - - $this.removeData(NAMESPACE); - }, - - /** - * Move the canvas - * - * @param {Number} offsetX - * @param {Number} offsetY (optional) - */ - move: function (offsetX, offsetY) { - var canvas = this.canvas; - - // If "offsetY" is not present, its default value is "offsetX" - if (isUndefined(offsetY)) { - offsetY = offsetX; - } - - offsetX = num(offsetX); - offsetY = num(offsetY); - - if (this.built && !this.disabled && this.options.movable) { - canvas.left += isNumber(offsetX) ? offsetX : 0; - canvas.top += isNumber(offsetY) ? offsetY : 0; - this.renderCanvas(true); - } - }, - - /** - * Zoom the canvas - * - * @param {Number} ratio - * @param {Event} _originalEvent (private) - */ - zoom: function (ratio, _originalEvent) { - var canvas = this.canvas; - var width; - var height; - - ratio = num(ratio); - - if (ratio && this.built && !this.disabled && this.options.zoomable) { - if (this.trigger(EVENT_ZOOM, { - originalEvent: _originalEvent, - ratio: ratio - }).isDefaultPrevented()) { - return; - } - - if (ratio < 0) { - ratio = 1 / (1 - ratio); - } else { - ratio = 1 + ratio; - } - - width = canvas.width * ratio; - height = canvas.height * ratio; - canvas.left -= (width - canvas.width) / 2; - canvas.top -= (height - canvas.height) / 2; - canvas.width = width; - canvas.height = height; - this.renderCanvas(true); - this.setDragMode(ACTION_MOVE); - } - }, - - /** - * Rotate the canvas - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function#rotate() - * - * @param {Number} degree - */ - rotate: function (degree) { - var image = this.image; - var rotate = image.rotate || 0; - - degree = num(degree) || 0; - - if (this.built && !this.disabled && this.options.rotatable) { - image.rotate = (rotate + degree) % 360; - this.rotated = true; - this.renderCanvas(true); - } - }, - - /** - * Scale the image - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function#scale() - * - * @param {Number} scaleX - * @param {Number} scaleY (optional) - */ - scale: function (scaleX, scaleY) { - var image = this.image; - - // If "scaleY" is not present, its default value is "scaleX" - if (isUndefined(scaleY)) { - scaleY = scaleX; - } - - scaleX = num(scaleX); - scaleY = num(scaleY); - - if (this.built && !this.disabled && this.options.scalable) { - image.scaleX = isNumber(scaleX) ? scaleX : 1; - image.scaleY = isNumber(scaleY) ? scaleY : 1; - this.renderImage(true); - } - }, - - /** - * Get the cropped area position and size data (base on the original image) - * - * @param {Boolean} rounded (optional) - * @return {Object} data - */ - getData: function (rounded) { - var options = this.options; - var image = this.image; - var canvas = this.canvas; - var cropBox = this.cropBox; - var ratio; - var data; - - if (this.built && this.cropped) { - data = { - x: cropBox.left - canvas.left, - y: cropBox.top - canvas.top, - width: cropBox.width, - height: cropBox.height - }; - - ratio = image.width / image.naturalWidth; - - $.each(data, function (i, n) { - n = n / ratio; - data[i] = rounded ? Math.round(n) : n; - }); - - } else { - data = { - x: 0, - y: 0, - width: 0, - height: 0 - }; - } - - if (options.rotatable) { - data.rotate = image.rotate || 0; - } - - if (options.scalable) { - data.scaleX = image.scaleX || 1; - data.scaleY = image.scaleY || 1; - } - - return data; - }, - - /** - * Set the cropped area position and size with new data - * - * @param {Object} data - */ - setData: function (data) { - var options = this.options; - var image = this.image; - var canvas = this.canvas; - var cropBoxData = {}; - var rotated; - var scaled; - var ratio; - - if ($.isFunction(data)) { - data = data.call(this.element); - } - - if (this.built && !this.disabled && $.isPlainObject(data)) { - if (options.rotatable) { - if (isNumber(data.rotate) && data.rotate !== image.rotate) { - image.rotate = data.rotate; - this.rotated = rotated = true; - } - } - - if (options.scalable) { - if (isNumber(data.scaleX) && data.scaleX !== image.scaleX) { - image.scaleX = data.scaleX; - scaled = true; - } - - if (isNumber(data.scaleY) && data.scaleY !== image.scaleY) { - image.scaleY = data.scaleY; - scaled = true; - } - } - - if (rotated) { - this.renderCanvas(); - } else if (scaled) { - this.renderImage(); - } - - ratio = image.width / image.naturalWidth; - - if (isNumber(data.x)) { - cropBoxData.left = data.x * ratio + canvas.left; - } - - if (isNumber(data.y)) { - cropBoxData.top = data.y * ratio + canvas.top; - } - - if (isNumber(data.width)) { - cropBoxData.width = data.width * ratio; - } - - if (isNumber(data.height)) { - cropBoxData.height = data.height * ratio; - } - - this.setCropBoxData(cropBoxData); - } - }, - - /** - * Get the container size data - * - * @return {Object} data - */ - getContainerData: function () { - return this.built ? this.container : {}; - }, - - /** - * Get the image position and size data - * - * @return {Object} data - */ - getImageData: function () { - return this.ready ? this.image : {}; - }, - - /** - * Get the canvas position and size data - * - * @return {Object} data - */ - getCanvasData: function () { - var canvas = this.canvas; - var data; - - if (this.built) { - data = { - left: canvas.left, - top: canvas.top, - width: canvas.width, - height: canvas.height - }; - } - - return data || {}; - }, - - /** - * Set the canvas position and size with new data - * - * @param {Object} data - */ - setCanvasData: function (data) { - var canvas = this.canvas; - var aspectRatio = canvas.aspectRatio; - - if ($.isFunction(data)) { - data = data.call(this.$element); - } - - if (this.built && !this.disabled && $.isPlainObject(data)) { - if (isNumber(data.left)) { - canvas.left = data.left; - } - - if (isNumber(data.top)) { - canvas.top = data.top; - } - - if (isNumber(data.width)) { - canvas.width = data.width; - canvas.height = data.width / aspectRatio; - } else if (isNumber(data.height)) { - canvas.height = data.height; - canvas.width = data.height * aspectRatio; - } - - this.renderCanvas(true); - } - }, - - /** - * Get the crop box position and size data - * - * @return {Object} data - */ - getCropBoxData: function () { - var cropBox = this.cropBox; - var data; - - if (this.built && this.cropped) { - data = { - left: cropBox.left, - top: cropBox.top, - width: cropBox.width, - height: cropBox.height - }; - } - - return data || {}; - }, - - /** - * Set the crop box position and size with new data - * - * @param {Object} data - */ - setCropBoxData: function (data) { - var cropBox = this.cropBox; - var aspectRatio = this.options.aspectRatio; - var widthChanged; - var heightChanged; - - if ($.isFunction(data)) { - data = data.call(this.$element); - } - - if (this.built && this.cropped && !this.disabled && $.isPlainObject(data)) { - - if (isNumber(data.left)) { - cropBox.left = data.left; - } - - if (isNumber(data.top)) { - cropBox.top = data.top; - } - - if (isNumber(data.width) && data.width !== cropBox.width) { - widthChanged = true; - cropBox.width = data.width; - } - - if (isNumber(data.height) && data.height !== cropBox.height) { - heightChanged = true; - cropBox.height = data.height; - } - - if (aspectRatio) { - if (widthChanged) { - cropBox.height = cropBox.width / aspectRatio; - } else if (heightChanged) { - cropBox.width = cropBox.height * aspectRatio; - } - } - - this.renderCropBox(); - } - }, - - /** - * Get a canvas drawn the cropped image - * - * @param {Object} options (optional) - * @return {HTMLCanvasElement} canvas - */ - getCroppedCanvas: function (options) { - var originalWidth; - var originalHeight; - var canvasWidth; - var canvasHeight; - var scaledWidth; - var scaledHeight; - var scaledRatio; - var aspectRatio; - var canvas; - var context; - var data; - - if (!this.built || !this.cropped || !SUPPORT_CANVAS) { - return; - } - - if (!$.isPlainObject(options)) { - options = {}; - } - - data = this.getData(); - originalWidth = data.width; - originalHeight = data.height; - aspectRatio = originalWidth / originalHeight; - - if ($.isPlainObject(options)) { - scaledWidth = options.width; - scaledHeight = options.height; - - if (scaledWidth) { - scaledHeight = scaledWidth / aspectRatio; - scaledRatio = scaledWidth / originalWidth; - } else if (scaledHeight) { - scaledWidth = scaledHeight * aspectRatio; - scaledRatio = scaledHeight / originalHeight; - } - } - - canvasWidth = scaledWidth || originalWidth; - canvasHeight = scaledHeight || originalHeight; - - canvas = $('')[0]; - canvas.width = canvasWidth; - canvas.height = canvasHeight; - context = canvas.getContext('2d'); - - if (options.fillColor) { - context.fillStyle = options.fillColor; - context.fillRect(0, 0, canvasWidth, canvasHeight); - } - - // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage - context.drawImage.apply(context, (function () { - var source = getSourceCanvas(this.$clone[0], this.image); - var sourceWidth = source.width; - var sourceHeight = source.height; - var args = [source]; - - // Source canvas - var srcX = data.x; - var srcY = data.y; - var srcWidth; - var srcHeight; - - // Destination canvas - var dstX; - var dstY; - var dstWidth; - var dstHeight; - - if (srcX <= -originalWidth || srcX > sourceWidth) { - srcX = srcWidth = dstX = dstWidth = 0; - } else if (srcX <= 0) { - dstX = -srcX; - srcX = 0; - srcWidth = dstWidth = min(sourceWidth, originalWidth + srcX); - } else if (srcX <= sourceWidth) { - dstX = 0; - srcWidth = dstWidth = min(originalWidth, sourceWidth - srcX); - } - - if (srcWidth <= 0 || srcY <= -originalHeight || srcY > sourceHeight) { - srcY = srcHeight = dstY = dstHeight = 0; - } else if (srcY <= 0) { - dstY = -srcY; - srcY = 0; - srcHeight = dstHeight = min(sourceHeight, originalHeight + srcY); - } else if (srcY <= sourceHeight) { - dstY = 0; - srcHeight = dstHeight = min(originalHeight, sourceHeight - srcY); - } - - args.push(srcX, srcY, srcWidth, srcHeight); - - // Scale destination sizes - if (scaledRatio) { - dstX *= scaledRatio; - dstY *= scaledRatio; - dstWidth *= scaledRatio; - dstHeight *= scaledRatio; - } - - // Avoid "IndexSizeError" in IE and Firefox - if (dstWidth > 0 && dstHeight > 0) { - args.push(dstX, dstY, dstWidth, dstHeight); - } - - return args; - }).call(this)); - - return canvas; - }, - - /** - * Change the aspect ratio of the crop box - * - * @param {Number} aspectRatio - */ - setAspectRatio: function (aspectRatio) { - var options = this.options; - - if (!this.disabled && !isUndefined(aspectRatio)) { - - // 0 -> NaN - options.aspectRatio = num(aspectRatio) || NaN; - - if (this.built) { - this.initCropBox(); - - if (this.cropped) { - this.renderCropBox(); - } - } - } - }, - - /** - * Change the drag mode - * - * @param {String} mode (optional) - */ - setDragMode: function (mode) { - var options = this.options; - var croppable; - var movable; - - if (this.ready && !this.disabled) { - croppable = options.dragCrop && mode === ACTION_CROP; - movable = options.movable && mode === ACTION_MOVE; - mode = (croppable || movable) ? mode : ACTION_NONE; - - this.$dragBox. - data(DATA_ACTION, mode). - toggleClass(CLASS_CROP, croppable). - toggleClass(CLASS_MOVE, movable); - - if (!options.cropBoxMovable) { - - // Sync drag mode to crop box when it is not movable(#300) - this.$face. - data(DATA_ACTION, mode). - toggleClass(CLASS_CROP, croppable). - toggleClass(CLASS_MOVE, movable); - } - } - } - }); - - $.extend(Cropper.prototype, prototype); - - Cropper.DEFAULTS = { - - // Define the aspect ratio of the crop box - aspectRatio: NaN, - - // An object with the previous cropping result data - data: null, - - // A jQuery selector for adding extra containers to preview - preview: '', - - // Strict mode, the image cannot zoom out less than the container - strict: true, - - // Rebuild when resize the window - responsive: true, - - // Check if the target image is cross origin - checkImageOrigin: 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 create new crop box by dragging over the image - dragCrop: true, - - // 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 wheeling mouse - mouseWheelZoom: true, - - // Define zoom ratio when zoom the image by wheeling mouse - wheelZoomRatio: 0.1, - - // Enable to zoom the image by dragging touch - touchDragZoom: true, - - // Enable to move the crop box - cropBoxMovable: true, - - // Enable to resize the crop box - cropBoxResizable: true, - - // Toggle drag mode between "crop" and "move" when double click on the cropper - doubleClickToggle: true, - - // Size limitation - minCanvasWidth: 0, - minCanvasHeight: 0, - minCropBoxWidth: 0, - minCropBoxHeight: 0, - minContainerWidth: 200, - minContainerHeight: 100, - - // Shortcuts of events - build: null, - built: null, - cropstart: null, - cropmove: null, - cropend: null, - crop: null, - zoom: null - }; - - Cropper.setDefaults = function (options) { - $.extend(Cropper.DEFAULTS, options); - }; - - Cropper.TEMPLATE = ( - '
' + - '
' + - '
' + - '
' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '
' + - '
' - ); - - // Save the other cropper - Cropper.other = $.fn.cropper; - - // Register as jQuery plugin - $.fn.cropper = function (options) { - var args = toArray(arguments, 1); - var result; - - this.each(function () { - var $this = $(this); - var data = $this.data(NAMESPACE); - var fn; - - if (!data) { - if (/destroy/.test(options)) { - return; - } - - $this.data(NAMESPACE, (data = new Cropper(this, options))); - } - - if (typeof options === 'string' && $.isFunction(fn = data[options])) { - result = fn.apply(data, args); - } - }); - - return isUndefined(result) ? this : result; - }; - - $.fn.cropper.Constructor = Cropper; - $.fn.cropper.setDefaults = Cropper.setDefaults; - - // No conflict - $.fn.cropper.noConflict = function () { - $.fn.cropper = Cropper.other; - return this; - }; - -}); diff --git a/docs/v1.0.0/js/cropper.min.js b/docs/v1.0.0/js/cropper.min.js deleted file mode 100644 index 1a619a16..00000000 --- a/docs/v1.0.0/js/cropper.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * Cropper v1.0.0 - * https://github.com/fengyuanchen/cropper - * - * Copyright (c) 2014-2015 Fengyuan Chen and contributors - * Released under the MIT license - * - * Date: 2015-10-10T02:10:08.624Z - */ -!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t("object"==typeof exports?require("jquery"):jQuery)}(function(t){"use strict";function i(t){return"number"==typeof t&&!isNaN(t)}function e(t){return"undefined"==typeof t}function s(t,e){var s=[];return i(e)&&s.push(e),s.slice.apply(t,s)}function o(t,i){var e=s(arguments,2);return function(){return t.apply(i,e.concat(s(arguments)))}}function h(t){var i=t.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i);return i&&(i[1]!==f.protocol||i[2]!==f.hostname||i[3]!==f.port)}function a(t){var i="timestamp="+(new Date).getTime();return t+(-1===t.indexOf("?")?"?":"&")+i}function n(t){return t?' crossOrigin="'+t+'"':""}function r(t,i){var e;return t.naturalWidth?i(t.naturalWidth,t.naturalHeight):(e=document.createElement("img"),e.onload=function(){i(this.width,this.height)},void(e.src=t.src))}function p(t){var e=[],s=t.rotate,o=t.scaleX,h=t.scaleY;return i(s)&&e.push("rotate("+s+"deg)"),i(o)&&i(h)&&e.push("scale("+o+","+h+")"),e.length?e.join(" "):"none"}function c(t,i){var e,s,o=at(t.degree)%180,h=(o>90?180-o:o)*Math.PI/180,a=nt(h),n=rt(h),r=t.width,p=t.height,c=t.aspectRatio;return i?(e=r/(n+a/c),s=e/c):(e=r*n+p*a,s=r*a+p*n),{width:e,height:s}}function d(e,s){var o,h,a,n=t("")[0],r=n.getContext("2d"),p=0,d=0,l=s.naturalWidth,g=s.naturalHeight,u=s.rotate,f=s.scaleX,m=s.scaleY,v=i(f)&&i(m)&&(1!==f||1!==m),w=i(u)&&0!==u,x=w||v,b=l,C=g;return v&&(o=l/2,h=g/2),w&&(a=c({width:l,height:g,degree:u}),b=a.width,C=a.height,o=a.width/2,h=a.height/2),n.width=b,n.height=C,x&&(p=-l/2,d=-g/2,r.save(),r.translate(o,h)),w&&r.rotate(u*Math.PI/180),v&&r.scale(f,m),r.drawImage(e,p,d,l,g),x&&r.restore(),n}function l(i,e){this.$element=t(i),this.options=t.extend({},l.DEFAULTS,t.isPlainObject(e)&&e),this.ready=!1,this.built=!1,this.complete=!1,this.rotated=!1,this.cropped=!1,this.disabled=!1,this.replaced=!1,this.isImg=!1,this.originalUrl="",this.crossOrigin="",this.canvas=null,this.cropBox=null,this.init()}var g=t(window),u=t(document),f=window.location,m="cropper",v="cropper-modal",w="cropper-hide",x="cropper-hidden",b="cropper-invisible",C="cropper-move",y="cropper-crop",B="cropper-disabled",$="cropper-bg",D="mousedown touchstart pointerdown MSPointerDown",Y="mousemove touchmove pointermove MSPointerMove",X="mouseup touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel",T="wheel mousewheel DOMMouseScroll",k="dblclick",M="load."+m,W="error."+m,L="resize."+m,H="build."+m,R="built."+m,z="cropstart."+m,I="cropmove."+m,P="cropend."+m,E="crop."+m,F="zoom."+m,O=/^(e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/,S="preview",j="action",A="e",N="w",U="s",Z="n",_="se",q="sw",K="ne",Q="nw",G="all",J="crop",V="move",tt="zoom",it="none",et=t.isFunction(t("")[0].getContext),st=Math.sqrt,ot=Math.min,ht=Math.max,at=Math.abs,nt=Math.sin,rt=Math.cos,pt=parseFloat,ct={version:"1.0.0"};t.extend(ct,{init:function(){var t,i=this.$element;if(i.is("img")){if(this.isImg=!0,this.originalUrl=t=i.attr("src"),!t)return;t=i.prop("src")}else i.is("canvas")&&et&&(t=i[0].toDataURL());this.load(t)},trigger:function(i,e){var s=t.Event(i,e);return this.$element.trigger(s),s},load:function(i){var e,s,o=this.options,r=this.$element,p="";i&&(this.url=i,r.one(H,o.build),this.trigger(H).isDefaultPrevented()||(o.checkImageOrigin&&h(i)&&(p=r.prop("crossOrigin"),p||(p="anonymous",e=a(i)),this.crossOrigin=p),this.$clone=s=t("'),this.isImg?r[0].complete?this.start():r.one(M,t.proxy(this.start,this)):s.one(M,t.proxy(this.start,this)).one(W,t.proxy(this.stop,this)).addClass(w).insertAfter(r)))},start:function(){var i=this.$element,e=this.$clone;this.isImg||(e.off(W,this.stop),i=e),r(i[0],t.proxy(function(t,i){this.image={naturalWidth:t,naturalHeight:i,aspectRatio:t/i},this.ready=!0,this.build()},this))},stop:function(){this.$clone.remove(),this.$clone=null}}),t.extend(ct,{build:function(){var i,e,s,o=this.options,h=this.$element,a=this.$clone;this.ready&&(this.built&&this.unbuild(),this.$container=h.parent(),this.$cropper=i=t(l.TEMPLATE),this.$canvas=i.find(".cropper-canvas").append(a),this.$dragBox=i.find(".cropper-drag-box"),this.$cropBox=e=i.find(".cropper-crop-box"),this.$viewBox=i.find(".cropper-view-box"),this.$face=s=e.find(".cropper-face"),h.addClass(x).after(i),this.isImg||a.removeClass(w),this.initPreview(),this.bind(),o.aspectRatio=pt(o.aspectRatio)||NaN,o.autoCrop?(this.cropped=!0,o.modal&&this.$dragBox.addClass(v)):e.addClass(x),o.guides||e.find(".cropper-dashed").addClass(x),o.center||e.find(".cropper-center").addClass(x),o.cropBoxMovable&&s.addClass(C).data(j,G),o.highlight||s.addClass(b),o.background&&i.addClass($),o.cropBoxResizable||e.find(".cropper-line, .cropper-point").addClass(x),this.setDragMode(o.dragCrop?J:o.movable?V:it),this.render(),this.built=!0,this.setData(o.data),h.one(R,o.built),setTimeout(t.proxy(function(){this.trigger(R),this.complete=!0},this),0))},unbuild:function(){this.built&&(this.built=!1,this.initialImage=null,this.initialCanvas=null,this.initialCropBox=null,this.container=null,this.canvas=null,this.cropBox=null,this.unbind(),this.resetPreview(),this.$preview=null,this.$viewBox=null,this.$cropBox=null,this.$dragBox=null,this.$canvas=null,this.$container=null,this.$cropper.remove(),this.$cropper=null)}}),t.extend(ct,{render:function(){this.initContainer(),this.initCanvas(),this.initCropBox(),this.renderCanvas(),this.cropped&&this.renderCropBox()},initContainer:function(){var t=this.options,i=this.$element,e=this.$container,s=this.$cropper;s.addClass(x),i.removeClass(x),s.css(this.container={width:ht(e.width(),pt(t.minContainerWidth)||200),height:ht(e.height(),pt(t.minContainerHeight)||100)}),i.addClass(x),s.removeClass(x)},initCanvas:function(){var i=this.container,e=i.width,s=i.height,o=this.image,h=o.aspectRatio,a={aspectRatio:h,width:e,height:s};s*h>e?a.height=e/h:a.width=s*h,a.oldLeft=a.left=(e-a.width)/2,a.oldTop=a.top=(s-a.height)/2,this.canvas=a,this.limitCanvas(!0,!0),this.initialImage=t.extend({},o),this.initialCanvas=t.extend({},a)},limitCanvas:function(t,i){var e,s,o=this.options,h=o.strict,a=this.container,n=a.width,r=a.height,p=this.canvas,c=p.aspectRatio,d=this.cropBox,l=this.cropped&&d,g=this.initialCanvas||p;t&&(e=pt(o.minCanvasWidth)||0,s=pt(o.minCanvasHeight)||0,h&&(e?e=ht(e,l?d.width:g.width):s?s=ht(s,l?d.height:g.height):l&&(e=d.width,s=d.height,s*c>e?e=s*c:s=e/c)),e&&s?s*c>e?s=e/c:e=s*c:e?s=e/c:s&&(e=s*c),p.minWidth=e,p.minHeight=s,p.maxWidth=1/0,p.maxHeight=1/0),i&&(h?(p.minLeft=l?ot(d.left,d.left+d.width-p.width):ot(0,n-p.width),p.minTop=l?ot(d.top,d.top+d.height-p.height):ot(0,r-p.height),p.maxLeft=l?d.left:ht(0,n-p.width),p.maxTop=l?d.top:ht(0,r-p.height)):(p.minLeft=-p.width,p.minTop=-p.height,p.maxLeft=n,p.maxTop=r))},renderCanvas:function(t){var i,e,s=this.options,o=this.canvas,h=this.image;this.rotated&&(this.rotated=!1,e=c({width:h.width,height:h.height,degree:h.rotate}),i=e.width/e.height,i!==o.aspectRatio&&(o.left-=(e.width-o.width)/2,o.top-=(e.height-o.height)/2,o.width=e.width,o.height=e.height,o.aspectRatio=i,this.limitCanvas(!0,!1))),(o.width>o.maxWidth||o.widtho.maxHeight||o.heighte.width?h.height=h.width/s:h.width=h.height*s),this.cropBox=h,this.limitCropBox(!0,!0),h.width=ot(ht(h.width,h.minWidth),h.maxWidth),h.height=ot(ht(h.height,h.minHeight),h.maxHeight),h.width=ht(h.minWidth,h.width*o),h.height=ht(h.minHeight,h.height*o),h.oldLeft=h.left=e.left+(e.width-h.width)/2,h.oldTop=h.top=e.top+(e.height-h.height)/2,this.initialCropBox=t.extend({},h)},limitCropBox:function(t,i){var e,s,o,h,a=this.options,n=a.strict,r=this.container,p=r.width,c=r.height,d=this.canvas,l=this.cropBox,g=a.aspectRatio;t&&(e=pt(a.minCropBoxWidth)||0,s=pt(a.minCropBoxHeight)||0,e=ot(e,p),s=ot(s,c),o=ot(p,n?d.width:p),h=ot(c,n?d.height:c),g&&(e&&s?s*g>e?s=e/g:e=s*g:e?s=e/g:s&&(e=s*g),h*g>o?h=o/g:o=h*g),l.minWidth=ot(e,o),l.minHeight=ot(s,h),l.maxWidth=o,l.maxHeight=h),i&&(n?(l.minLeft=ht(0,d.left),l.minTop=ht(0,d.top),l.maxLeft=ot(p,d.left+d.width)-l.width,l.maxTop=ot(c,d.top+d.height)-l.height):(l.minLeft=0,l.minTop=0,l.maxLeft=p-l.width,l.maxTop=c-l.height))},renderCropBox:function(){var t=this.options,i=this.container,e=i.width,s=i.height,o=this.cropBox;(o.width>o.maxWidth||o.widtho.maxHeight||o.height'),this.$preview.each(function(){var s=t(this);s.data(S,{width:s.width(),height:s.height(),original:s.html()}),s.html("')})},resetPreview:function(){this.$preview.each(function(){var i=t(this);i.html(i.data(S).original).removeData(S)})},preview:function(){var i=this.image,e=this.canvas,s=this.cropBox,o=s.width,h=s.height,a=i.width,n=i.height,r=s.left-e.left-i.left,c=s.top-e.top-i.top;this.cropped&&!this.disabled&&(this.$viewBox.find("img").css({width:a,height:n,marginLeft:-r,marginTop:-c,transform:p(i)}),this.$preview.each(function(){var e=t(this),s=e.data(S),d=s.width,l=s.height,g=d,u=l,f=1;o&&(f=d/o,u=h*f),h&&u>l&&(f=l/h,g=o*f,u=l),e.width(g).height(u).find("img").css({width:a*f,height:n*f,marginLeft:-r*f,marginTop:-c*f,transform:p(i)})}))}}),t.extend(ct,{bind:function(){var i=this.options,e=this.$element,s=this.$cropper;t.isFunction(i.cropstart)&&e.on(z,i.cropstart),t.isFunction(i.cropmove)&&e.on(I,i.cropmove),t.isFunction(i.cropend)&&e.on(P,i.cropend),t.isFunction(i.crop)&&e.on(E,i.crop),t.isFunction(i.zoom)&&e.on(F,i.zoom),s.on(D,t.proxy(this.cropStart,this)),i.zoomable&&i.mouseWheelZoom&&s.on(T,t.proxy(this.wheel,this)),i.doubleClickToggle&&s.on(k,t.proxy(this.dblclick,this)),u.on(Y,this._cropMove=o(this.cropMove,this)).on(X,this._cropEnd=o(this.cropEnd,this)),i.responsive&&g.on(L,this._resize=o(this.resize,this))},unbind:function(){var i=this.options,e=this.$element,s=this.$cropper;t.isFunction(i.cropstart)&&e.off(z,i.cropstart),t.isFunction(i.cropmove)&&e.off(I,i.cropmove),t.isFunction(i.cropend)&&e.off(P,i.cropend),t.isFunction(i.crop)&&e.off(E,i.crop),t.isFunction(i.zoom)&&e.off(F,i.zoom),s.off(D,this.cropStart),i.zoomable&&i.mouseWheelZoom&&s.off(T,this.wheel),i.doubleClickToggle&&s.off(k,this.dblclick),u.off(Y,this._cropMove).off(X,this._cropEnd),i.responsive&&g.off(L,this._resize)}}),t.extend(ct,{resize:function(){var i,e,s,o=this.$container,h=this.container;!this.disabled&&h&&(s=o.width()/h.width,(1!==s||o.height()!==h.height)&&(i=this.getCanvasData(),e=this.getCropBoxData(),this.render(),this.setCanvasData(t.each(i,function(t,e){i[t]=e*s})),this.setCropBoxData(t.each(e,function(t,i){e[t]=i*s}))))},dblclick:function(){this.disabled||(this.$dragBox.hasClass(y)?this.setDragMode(V):this.setDragMode(J))},wheel:function(t){var i=t.originalEvent,e=i,s=pt(this.options.wheelZoomRatio)||.1,o=1;this.disabled||(t.preventDefault(),e.deltaY?o=e.deltaY>0?1:-1:e.wheelDelta?o=-e.wheelDelta/120:e.detail&&(o=e.detail>0?1:-1),this.zoom(-o*s,i))},cropStart:function(i){var e,s,o=this.options,h=i.originalEvent,a=h&&h.touches,n=i;if(!this.disabled){if(a){if(e=a.length,e>1){if(!o.zoomable||!o.touchDragZoom||2!==e)return;n=a[1],this.startX2=n.pageX,this.startY2=n.pageY,s=tt}n=a[0]}if(s=s||t(n.target).data(j),O.test(s)){if(this.trigger(z,{originalEvent:h,action:s}).isDefaultPrevented())return;i.preventDefault(),this.action=s,this.cropping=!1,this.startX=n.pageX||h&&h.pageX,this.startY=n.pageY||h&&h.pageY,s===J&&(this.cropping=!0,this.$dragBox.addClass(v))}}},cropMove:function(t){var i,e=this.options,s=t.originalEvent,o=s&&s.touches,h=t,a=this.action;if(!this.disabled){if(o){if(i=o.length,i>1){if(!e.zoomable||!e.touchDragZoom||2!==i)return;h=o[1],this.endX2=h.pageX,this.endY2=h.pageY}h=o[0]}if(a){if(this.trigger(I,{originalEvent:s,action:a}).isDefaultPrevented())return;t.preventDefault(),this.endX=h.pageX||s&&s.pageX,this.endY=h.pageY||s&&s.pageY,this.change(h.shiftKey,a===tt?s:null)}}},cropEnd:function(t){var i=t.originalEvent,e=this.action;this.disabled||e&&(t.preventDefault(),this.cropping&&(this.cropping=!1,this.$dragBox.toggleClass(v,this.cropped&&this.options.modal)),this.action="",this.trigger(P,{originalEvent:i,action:e}))}}),t.extend(ct,{change:function(t,i){var e,s,o=this.options,h=o.aspectRatio,a=this.action,n=this.container,r=this.canvas,p=this.cropBox,c=p.width,d=p.height,l=p.left,g=p.top,u=l+c,f=g+d,m=0,v=0,w=n.width,b=n.height,C=!0;switch(!h&&t&&(h=c&&d?c/d:1),o.strict&&(m=p.minLeft,v=p.minTop,w=m+ot(n.width,r.width),b=v+ot(n.height,r.height)),s={x:this.endX-this.startX,y:this.endY-this.startY},h&&(s.X=s.y*h,s.Y=s.x/h),a){case G:l+=s.x,g+=s.y;break;case A:if(s.x>=0&&(u>=w||h&&(v>=g||f>=b))){C=!1;break}c+=s.x,h&&(d=c/h,g-=s.Y/2),0>c&&(a=N,c=0);break;case Z:if(s.y<=0&&(v>=g||h&&(m>=l||u>=w))){C=!1;break}d-=s.y,g+=s.y,h&&(c=d*h,l+=s.X/2),0>d&&(a=U,d=0);break;case N:if(s.x<=0&&(m>=l||h&&(v>=g||f>=b))){C=!1;break}c-=s.x,l+=s.x,h&&(d=c/h,g+=s.Y/2),0>c&&(a=A,c=0);break;case U:if(s.y>=0&&(f>=b||h&&(m>=l||u>=w))){C=!1;break}d+=s.y,h&&(c=d*h,l-=s.X/2),0>d&&(a=Z,d=0);break;case K:if(h){if(s.y<=0&&(v>=g||u>=w)){C=!1;break}d-=s.y,g+=s.y,c=d*h}else s.x>=0?w>u?c+=s.x:s.y<=0&&v>=g&&(C=!1):c+=s.x,s.y<=0?g>v&&(d-=s.y,g+=s.y):(d-=s.y,g+=s.y);0>c&&0>d?(a=q,d=0,c=0):0>c?(a=Q,c=0):0>d&&(a=_,d=0);break;case Q:if(h){if(s.y<=0&&(v>=g||m>=l)){C=!1;break}d-=s.y,g+=s.y,c=d*h,l+=s.X}else s.x<=0?l>m?(c-=s.x,l+=s.x):s.y<=0&&v>=g&&(C=!1):(c-=s.x,l+=s.x),s.y<=0?g>v&&(d-=s.y,g+=s.y):(d-=s.y,g+=s.y);0>c&&0>d?(a=_,d=0,c=0):0>c?(a=K,c=0):0>d&&(a=q,d=0);break;case q:if(h){if(s.x<=0&&(m>=l||f>=b)){C=!1;break}c-=s.x,l+=s.x,d=c/h}else s.x<=0?l>m?(c-=s.x,l+=s.x):s.y>=0&&f>=b&&(C=!1):(c-=s.x,l+=s.x),s.y>=0?b>f&&(d+=s.y):d+=s.y;0>c&&0>d?(a=K,d=0,c=0):0>c?(a=_,c=0):0>d&&(a=Q,d=0);break;case _:if(h){if(s.x>=0&&(u>=w||f>=b)){C=!1;break}c+=s.x,d=c/h}else s.x>=0?w>u?c+=s.x:s.y>=0&&f>=b&&(C=!1):c+=s.x,s.y>=0?b>f&&(d+=s.y):d+=s.y;0>c&&0>d?(a=Q,d=0,c=0):0>c?(a=q,c=0):0>d&&(a=K,d=0);break;case V:this.move(s.x,s.y),C=!1;break;case tt:this.zoom(function(t,i,e,s){var o=st(t*t+i*i),h=st(e*e+s*s);return(h-o)/o}(at(this.startX-this.startX2),at(this.startY-this.startY2),at(this.endX-this.endX2),at(this.endY-this.endY2)),i),this.startX2=this.endX2,this.startY2=this.endY2,C=!1;break;case J:s.x&&s.y&&(e=this.$cropper.offset(),l=this.startX-e.left,g=this.startY-e.top,c=p.minWidth,d=p.minHeight,s.x>0?s.y>0?a=_:(a=K,g-=d):s.y>0?(a=q,l-=c):(a=Q,l-=c,g-=d),this.cropped||(this.cropped=!0,this.$cropBox.removeClass(x)))}C&&(p.width=c,p.height=d,p.left=l,p.top=g,this.action=a,this.renderCropBox()),this.startX=this.endX,this.startY=this.endY}}),t.extend(ct,{crop:function(){this.built&&!this.disabled&&(this.cropped||(this.cropped=!0,this.limitCropBox(!0,!0),this.options.modal&&this.$dragBox.addClass(v),this.$cropBox.removeClass(x)),this.setCropBoxData(this.initialCropBox))},reset:function(){this.built&&!this.disabled&&(this.image=t.extend({},this.initialImage),this.canvas=t.extend({},this.initialCanvas),this.cropBox=t.extend({},this.initialCropBox),this.renderCanvas(),this.cropped&&this.renderCropBox())},clear:function(){this.cropped&&!this.disabled&&(t.extend(this.cropBox,{left:0,top:0,width:0,height:0}),this.cropped=!1,this.renderCropBox(),this.limitCanvas(!0,!0),this.renderCanvas(),this.$dragBox.removeClass(v),this.$cropBox.addClass(x))},replace:function(t){!this.disabled&&t&&(this.isImg&&(this.replaced=!0,this.$element.attr("src",t)),this.options.data=null,this.load(t))},enable:function(){this.built&&(this.disabled=!1,this.$cropper.removeClass(B))},disable:function(){this.built&&(this.disabled=!0,this.$cropper.addClass(B))},destroy:function(){var t=this.$element;this.ready?(this.isImg&&this.replaced&&t.attr("src",this.originalUrl),this.unbuild(),t.removeClass(x)):this.isImg?t.off(M,this.start):this.$clone&&this.$clone.remove(),t.removeData(m)},move:function(t,s){var o=this.canvas;e(s)&&(s=t),t=pt(t),s=pt(s),this.built&&!this.disabled&&this.options.movable&&(o.left+=i(t)?t:0,o.top+=i(s)?s:0,this.renderCanvas(!0))},zoom:function(t,i){var e,s,o=this.canvas;if(t=pt(t),t&&this.built&&!this.disabled&&this.options.zoomable){if(this.trigger(F,{originalEvent:i,ratio:t}).isDefaultPrevented())return;t=0>t?1/(1-t):1+t,e=o.width*t,s=o.height*t,o.left-=(e-o.width)/2,o.top-=(s-o.height)/2,o.width=e,o.height=s,this.renderCanvas(!0),this.setDragMode(V)}},rotate:function(t){var i=this.image,e=i.rotate||0;t=pt(t)||0,this.built&&!this.disabled&&this.options.rotatable&&(i.rotate=(e+t)%360,this.rotated=!0,this.renderCanvas(!0))},scale:function(t,s){var o=this.image;e(s)&&(s=t),t=pt(t),s=pt(s),this.built&&!this.disabled&&this.options.scalable&&(o.scaleX=i(t)?t:1,o.scaleY=i(s)?s:1,this.renderImage(!0))},getData:function(i){var e,s,o=this.options,h=this.image,a=this.canvas,n=this.cropBox;return this.built&&this.cropped?(s={x:n.left-a.left,y:n.top-a.top,width:n.width,height:n.height},e=h.width/h.naturalWidth,t.each(s,function(t,o){o/=e,s[t]=i?Math.round(o):o})):s={x:0,y:0,width:0,height:0},o.rotatable&&(s.rotate=h.rotate||0),o.scalable&&(s.scaleX=h.scaleX||1,s.scaleY=h.scaleY||1),s},setData:function(e){var s,o,h,a=this.options,n=this.image,r=this.canvas,p={};t.isFunction(e)&&(e=e.call(this.element)),this.built&&!this.disabled&&t.isPlainObject(e)&&(a.rotatable&&i(e.rotate)&&e.rotate!==n.rotate&&(n.rotate=e.rotate,this.rotated=s=!0),a.scalable&&(i(e.scaleX)&&e.scaleX!==n.scaleX&&(n.scaleX=e.scaleX,o=!0),i(e.scaleY)&&e.scaleY!==n.scaleY&&(n.scaleY=e.scaleY,o=!0)),s?this.renderCanvas():o&&this.renderImage(),h=n.width/n.naturalWidth,i(e.x)&&(p.left=e.x*h+r.left),i(e.y)&&(p.top=e.y*h+r.top),i(e.width)&&(p.width=e.width*h),i(e.height)&&(p.height=e.height*h),this.setCropBoxData(p))},getContainerData:function(){return this.built?this.container:{}},getImageData:function(){return this.ready?this.image:{}},getCanvasData:function(){var t,i=this.canvas;return this.built&&(t={left:i.left,top:i.top,width:i.width,height:i.height}),t||{}},setCanvasData:function(e){var s=this.canvas,o=s.aspectRatio;t.isFunction(e)&&(e=e.call(this.$element)),this.built&&!this.disabled&&t.isPlainObject(e)&&(i(e.left)&&(s.left=e.left),i(e.top)&&(s.top=e.top),i(e.width)?(s.width=e.width,s.height=e.width/o):i(e.height)&&(s.height=e.height,s.width=e.height*o),this.renderCanvas(!0))},getCropBoxData:function(){var t,i=this.cropBox;return this.built&&this.cropped&&(t={left:i.left,top:i.top,width:i.width,height:i.height}),t||{}},setCropBoxData:function(e){var s,o,h=this.cropBox,a=this.options.aspectRatio;t.isFunction(e)&&(e=e.call(this.$element)),this.built&&this.cropped&&!this.disabled&&t.isPlainObject(e)&&(i(e.left)&&(h.left=e.left),i(e.top)&&(h.top=e.top),i(e.width)&&e.width!==h.width&&(s=!0,h.width=e.width),i(e.height)&&e.height!==h.height&&(o=!0,h.height=e.height),a&&(s?h.height=h.width/a:o&&(h.width=h.height*a)),this.renderCropBox())},getCroppedCanvas:function(i){var e,s,o,h,a,n,r,p,c,l,g;return this.built&&this.cropped&&et?(t.isPlainObject(i)||(i={}),g=this.getData(),e=g.width,s=g.height,p=e/s,t.isPlainObject(i)&&(a=i.width,n=i.height,a?(n=a/p,r=a/e):n&&(a=n*p,r=n/s)),o=a||e,h=n||s,c=t("")[0],c.width=o,c.height=h,l=c.getContext("2d"),i.fillColor&&(l.fillStyle=i.fillColor,l.fillRect(0,0,o,h)),l.drawImage.apply(l,function(){var t,i,o,h,a,n,p=d(this.$clone[0],this.image),c=p.width,l=p.height,u=[p],f=g.x,m=g.y;return-e>=f||f>c?f=t=o=a=0:0>=f?(o=-f,f=0,t=a=ot(c,e+f)):c>=f&&(o=0,t=a=ot(e,c-f)),0>=t||-s>=m||m>l?m=i=h=n=0:0>=m?(h=-m,m=0,i=n=ot(l,s+m)):l>=m&&(h=0,i=n=ot(s,l-m)),u.push(f,m,t,i),r&&(o*=r,h*=r,a*=r,n*=r),a>0&&n>0&&u.push(o,h,a,n),u}.call(this)),c):void 0},setAspectRatio:function(t){var i=this.options;this.disabled||e(t)||(i.aspectRatio=pt(t)||NaN,this.built&&(this.initCropBox(),this.cropped&&this.renderCropBox()))},setDragMode:function(t){var i,e,s=this.options;this.ready&&!this.disabled&&(i=s.dragCrop&&t===J,e=s.movable&&t===V,t=i||e?t:it,this.$dragBox.data(j,t).toggleClass(y,i).toggleClass(C,e),s.cropBoxMovable||this.$face.data(j,t).toggleClass(y,i).toggleClass(C,e))}}),t.extend(l.prototype,ct),l.DEFAULTS={aspectRatio:NaN,data:null,preview:"",strict:!0,responsive:!0,checkImageOrigin:!0,modal:!0,guides:!0,center:!0,highlight:!0,background:!0,autoCrop:!0,autoCropArea:.8,dragCrop:!0,movable:!0,rotatable:!0,scalable:!0,zoomable:!0,mouseWheelZoom:!0,wheelZoomRatio:.1,touchDragZoom:!0,cropBoxMovable:!0,cropBoxResizable:!0,doubleClickToggle:!0,minCanvasWidth:0,minCanvasHeight:0,minCropBoxWidth:0,minCropBoxHeight:0,minContainerWidth:200,minContainerHeight:100,build:null,built:null,cropstart:null,cropmove:null,cropend:null,crop:null,zoom:null},l.setDefaults=function(i){t.extend(l.DEFAULTS,i)},l.TEMPLATE='
',l.other=t.fn.cropper,t.fn.cropper=function(i){var o,h=s(arguments,1);return this.each(function(){var e,s=t(this),a=s.data(m);if(!a){if(/destroy/.test(i))return;s.data(m,a=new l(this,i))}"string"==typeof i&&t.isFunction(e=a[i])&&(o=e.apply(a,h))}),e(o)?this:o},t.fn.cropper.Constructor=l,t.fn.cropper.setDefaults=l.setDefaults,t.fn.cropper.noConflict=function(){return t.fn.cropper=l.other,this}}); \ No newline at end of file diff --git a/docs/v1.0.0/js/main.js b/docs/v1.0.0/js/main.js deleted file mode 100644 index af5f8f17..00000000 --- a/docs/v1.0.0/js/main.js +++ /dev/null @@ -1,301 +0,0 @@ -$(function () { - - 'use strict'; - - var console = window.console || { log: function () {} }; - var $body = $('body'); - - - // Tooltip - $('[data-toggle="tooltip"]').tooltip(); - $.fn.tooltip.noConflict(); - $body.tooltip(); - - - // Demo - // --------------------------------------------------------------------------- - - (function () { - var $image = $('.img-container > img'); - var $actions = $('.docs-actions'); - var $download = $('#download'); - var $dataX = $('#dataX'); - var $dataY = $('#dataY'); - var $dataHeight = $('#dataHeight'); - var $dataWidth = $('#dataWidth'); - var $dataRotate = $('#dataRotate'); - var $dataScaleX = $('#dataScaleX'); - var $dataScaleY = $('#dataScaleY'); - var options = { - aspectRatio: 16 / 9, - preview: '.img-preview', - crop: function (e) { - $dataX.val(Math.round(e.x)); - $dataY.val(Math.round(e.y)); - $dataHeight.val(Math.round(e.height)); - $dataWidth.val(Math.round(e.width)); - $dataRotate.val(e.rotate); - $dataScaleX.val(e.scaleX); - $dataScaleY.val(e.scaleY); - } - }; - - $image.on({ - 'build.cropper': function (e) { - console.log(e.type); - }, - 'built.cropper': function (e) { - console.log(e.type); - }, - 'cropstart.cropper': function (e) { - console.log(e.type, e.action); - }, - 'cropmove.cropper': function (e) { - console.log(e.type, e.action); - }, - 'cropend.cropper': function (e) { - console.log(e.type, e.action); - }, - 'crop.cropper': function (e) { - console.log(e.type, e.x, e.y, e.width, e.height, e.rotate, e.scaleX, e.scaleY); - }, - 'zoom.cropper': function (e) { - console.log(e.type, e.ratio); - } - }).cropper(options); - - - // Buttons - if (!$.isFunction(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[0].download === 'undefined') { - $download.addClass('disabled'); - } - - - // Options - $actions.on('change', ':checkbox', function () { - var $this = $(this); - var cropBoxData; - var canvasData; - - if (!$image.data('cropper')) { - return; - } - - options[$this.val()] = $this.prop('checked'); - - cropBoxData = $image.cropper('getCropBoxData'); - canvasData = $image.cropper('getCanvasData'); - options.built = function () { - $image.cropper('setCropBoxData', cropBoxData); - $image.cropper('setCanvasData', canvasData); - }; - - $image.cropper('destroy').cropper(options); - }); - - - // Methods - $actions.on('click', '[data-method]', function () { - var $this = $(this); - var data = $this.data(); - var $target; - var result; - - if ($this.prop('disabled') || $this.hasClass('disabled')) { - return; - } - - if ($image.data('cropper') && data.method) { - data = $.extend({}, data); // Clone a new one - - if (typeof data.target !== 'undefined') { - $target = $(data.target); - - if (typeof data.option === 'undefined') { - try { - data.option = JSON.parse($target.val()); - } catch (e) { - console.log(e.message); - } - } - } - - result = $image.cropper(data.method, data.option, data.secondOption); - - if (data.flip === 'horizontal') { - $(this).data('option', -data.option); - } - - if (data.flip === 'vertical') { - $(this).data('secondOption', -data.secondOption); - } - - if (data.method === 'getCroppedCanvas' && result) { - $('#getCroppedCanvasModal').modal().find('.modal-body').html(result); - - if (!$download.hasClass('disabled')) { - $download.attr('href', result.toDataURL()); - } - } - - if ($.isPlainObject(result) && $target) { - try { - $target.val(JSON.stringify(result)); - } catch (e) { - console.log(e.message); - } - } - - } - }); - - - // Keyboard - $body.on('keydown', function (e) { - - if (!$image.data('cropper') || this.scrollTop > 300) { - return; - } - - switch (e.which) { - case 37: - e.preventDefault(); - $image.cropper('move', -1, 0); - break; - - case 38: - e.preventDefault(); - $image.cropper('move', 0, -1); - break; - - case 39: - e.preventDefault(); - $image.cropper('move', 1, 0); - break; - - case 40: - e.preventDefault(); - $image.cropper('move', 0, 1); - break; - } - - }); - - - // Import image - var $inputImage = $('#inputImage'); - var URL = window.URL || window.webkitURL; - var blobURL; - - if (URL) { - $inputImage.change(function () { - var files = this.files; - var file; - - if (!$image.data('cropper')) { - return; - } - - if (files && files.length) { - file = files[0]; - - if (/^image\/\w+$/.test(file.type)) { - blobURL = URL.createObjectURL(file); - $image.one('built.cropper', function () { - URL.revokeObjectURL(blobURL); // Revoke when load complete - }).cropper('reset').cropper('replace', blobURL); - $inputImage.val(''); - } else { - $body.tooltip('Please choose an image file.', 'warning'); - } - } - }); - } else { - $inputImage.prop('disabled', true).parent().addClass('disabled'); - } - - }()); - - - // Examples - // --------------------------------------------------------------------------- - - // Example 1 - (function () { - $('.cropper-example-1 > img').cropper({ - aspectRatio: 16 / 9, - autoCropArea: 0.65, - strict: false, - guides: false, - highlight: false, - dragCrop: false, - cropBoxMovable: false, - cropBoxResizable: false - }); - })(); - - - // Example 2 - (function () { - var $image = $('#cropper-example-2 > img'); - var cropBoxData; - var canvasData; - - $('#cropper-example-2-modal').on('shown.bs.modal', function () { - $image.cropper({ - autoCropArea: 0.5, - built: function () { - // Strict mode: set crop box data first - $image.cropper('setCropBoxData', cropBoxData); - $image.cropper('setCanvasData', canvasData); - } - }); - }).on('hidden.bs.modal', function () { - cropBoxData = $image.cropper('getCropBoxData'); - canvasData = $image.cropper('getCanvasData'); - $image.cropper('destroy'); - }); - })(); - - - // Example 3 - (function () { - var $image = $('.cropper-example-3 > img'); - var $toggle = $('#replace-toggle'); - var originalText = $toggle.text(); - var replaced; - - $image.cropper({ - movable: false, - zoomable: false, - rotatable: false, - scalable: false - }); - - $toggle.click(function () { - if ($toggle.prop('disabled')) { - return; - } - - $toggle.text('loading').prop('disabled', true); - - $image.one('built.cropper', function () { - $toggle.text(originalText).prop('disabled', false); - }).cropper('replace', replaced ? 'img/picture.jpg' : 'img/picture-2.jpg'); - - replaced = !replaced; - }); - })(); - -}); diff --git a/docs/v2.3.4/css/cropper.css b/docs/v2.3.4/css/cropper.css index fb850233..80598e54 100644 --- a/docs/v2.3.4/css/cropper.css +++ b/docs/v2.3.4/css/cropper.css @@ -2,7 +2,7 @@ * Cropper v2.3.4 * https://github.com/fengyuanchen/cropper * - * Copyright (c) 2014-2016 Fengyuan Chen and contributors + * Copyright (c) 2014-2016 Chen Fengyuan and contributors * Released under the MIT license * * Date: 2016-09-03T05:50:45.412Z diff --git a/docs/v2.3.4/css/cropper.min.css b/docs/v2.3.4/css/cropper.min.css deleted file mode 100644 index 9426dacc..00000000 --- a/docs/v2.3.4/css/cropper.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Cropper v2.3.4 - * https://github.com/fengyuanchen/cropper - * - * Copyright (c) 2014-2016 Fengyuan Chen and contributors - * Released under the MIT license - * - * Date: 2016-09-03T05:50:45.412Z - */.cropper-container{font-size:0;line-height:0;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;direction:ltr!important}.cropper-container img{display:block;width:100%;min-width:0!important;max-width:none!important;height:100%;min-height:0!important;max-height:none!important;image-orientation:0deg!important}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{position:absolute;top:0;right:0;bottom:0;left:0}.cropper-wrap-box{overflow:hidden}.cropper-drag-box{opacity:0;background-color:#fff;filter:alpha(opacity=0)}.cropper-dashed,.cropper-modal{opacity:.5;filter:alpha(opacity=50)}.cropper-modal{background-color:#000}.cropper-view-box{display:block;overflow:hidden;width:100%;height:100%;outline:#39f solid 1px;outline-color:rgba(51,153,255,.75)}.cropper-dashed{position:absolute;display:block;border:0 dashed #eee}.cropper-dashed.dashed-h{top:33.33333%;left:0;width:100%;height:33.33333%;border-top-width:1px;border-bottom-width:1px}.cropper-dashed.dashed-v{top:0;left:33.33333%;width:33.33333%;height:100%;border-right-width:1px;border-left-width:1px}.cropper-center{position:absolute;top:50%;left:50%;display:block;width:0;height:0;opacity:.75;filter:alpha(opacity=75)}.cropper-center:after,.cropper-center:before{position:absolute;display:block;content:' ';background-color:#eee}.cropper-center:before{top:0;left:-3px;width:7px;height:1px}.cropper-center:after{top:-3px;left:0;width:1px;height:7px}.cropper-face,.cropper-line,.cropper-point{position:absolute;display:block;width:100%;height:100%;opacity:.1;filter:alpha(opacity=10)}.cropper-face{top:0;left:0;background-color:#fff}.cropper-line,.cropper-point{background-color:#39f}.cropper-line.line-e{top:0;right:-3px;width:5px;cursor:e-resize}.cropper-line.line-n{top:-3px;left:0;height:5px;cursor:n-resize}.cropper-line.line-w{top:0;left:-3px;width:5px;cursor:w-resize}.cropper-line.line-s{bottom:-3px;left:0;height:5px;cursor:s-resize}.cropper-point{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}.cropper-point.point-e{top:50%;right:-3px;margin-top:-3px;cursor:e-resize}.cropper-point.point-n{top:-3px;left:50%;margin-left:-3px;cursor:n-resize}.cropper-point.point-w{top:50%;left:-3px;margin-top:-3px;cursor:w-resize}.cropper-point.point-s{bottom:-3px;left:50%;margin-left:-3px;cursor:s-resize}.cropper-point.point-ne{top:-3px;right:-3px;cursor:ne-resize}.cropper-point.point-nw{top:-3px;left:-3px;cursor:nw-resize}.cropper-point.point-sw{bottom:-3px;left:-3px;cursor:sw-resize}.cropper-point.point-se{right:-3px;bottom:-3px;width:20px;height:20px;cursor:se-resize;opacity:1;filter:alpha(opacity=100)}.cropper-point.point-se:before{position:absolute;right:-50%;bottom:-50%;display:block;width:200%;height:200%;content:' ';opacity:0;background-color:#39f;filter:alpha(opacity=0)}@media (min-width:768px){.cropper-point.point-se{width:15px;height:15px}}@media (min-width:992px){.cropper-point.point-se{width:10px;height:10px}}@media (min-width:1200px){.cropper-point.point-se{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}}.cropper-invisible{opacity:0;filter:alpha(opacity=0)}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-hide{position:absolute;display:block;width:0;height: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/docs/v1.0.0/img/picture.jpg b/docs/v2.3.4/images/picture.jpg similarity index 100% rename from docs/v1.0.0/img/picture.jpg rename to docs/v2.3.4/images/picture.jpg diff --git a/docs/v2.3.4/img/data.jpg b/docs/v2.3.4/img/data.jpg deleted file mode 100644 index 56926a27..00000000 Binary files a/docs/v2.3.4/img/data.jpg and /dev/null differ diff --git a/docs/v2.3.4/img/icons.png b/docs/v2.3.4/img/icons.png deleted file mode 100644 index 1dc9824e..00000000 Binary files a/docs/v2.3.4/img/icons.png and /dev/null differ diff --git a/docs/v2.3.4/img/layers.jpg b/docs/v2.3.4/img/layers.jpg deleted file mode 100644 index 02b77e7b..00000000 Binary files a/docs/v2.3.4/img/layers.jpg and /dev/null differ diff --git a/docs/v2.3.4/img/picture-2.jpg b/docs/v2.3.4/img/picture-2.jpg deleted file mode 100644 index 05df6dc3..00000000 Binary files a/docs/v2.3.4/img/picture-2.jpg and /dev/null differ diff --git a/docs/v2.3.4/img/picture-3.jpg b/docs/v2.3.4/img/picture-3.jpg deleted file mode 100644 index 472d721b..00000000 Binary files a/docs/v2.3.4/img/picture-3.jpg and /dev/null differ diff --git a/docs/v2.3.4/index.html b/docs/v2.3.4/index.html index 3ff1abda..bd4d0d56 100644 --- a/docs/v2.3.4/index.html +++ b/docs/v2.3.4/index.html @@ -6,11 +6,11 @@ - + Cropper - + @@ -61,7 +61,7 @@

Cropper v2.3.4

- Picture + Picture
@@ -526,8 +526,8 @@

@@ -537,7 +537,7 @@ - + diff --git a/docs/v2.3.4/js/cropper.js b/docs/v2.3.4/js/cropper.js index 27196e10..48c29f6d 100644 --- a/docs/v2.3.4/js/cropper.js +++ b/docs/v2.3.4/js/cropper.js @@ -2,7 +2,7 @@ * Cropper v2.3.4 * https://github.com/fengyuanchen/cropper * - * Copyright (c) 2014-2016 Fengyuan Chen and contributors + * Copyright (c) 2014-2016 Chen Fengyuan and contributors * Released under the MIT license * * Date: 2016-09-03T05:50:45.412Z diff --git a/docs/v2.3.4/js/cropper.min.js b/docs/v2.3.4/js/cropper.min.js deleted file mode 100644 index d285e2c2..00000000 --- a/docs/v2.3.4/js/cropper.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * Cropper v2.3.4 - * https://github.com/fengyuanchen/cropper - * - * Copyright (c) 2014-2016 Fengyuan Chen and contributors - * Released under the MIT license - * - * Date: 2016-09-03T05:50:45.412Z - */ -!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t("object"==typeof exports?require("jquery"):jQuery)}(function(t){"use strict";function i(t){return"number"==typeof t&&!isNaN(t)}function e(t){return"undefined"==typeof t}function s(t,e){var s=[];return i(e)&&s.push(e),s.slice.apply(t,s)}function a(t,i){var e=s(arguments,2);return function(){return t.apply(i,e.concat(s(arguments)))}}function o(t){var i=t.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i);return i&&(i[1]!==C.protocol||i[2]!==C.hostname||i[3]!==C.port)}function h(t){var i="timestamp="+(new Date).getTime();return t+(t.indexOf("?")===-1?"?":"&")+i}function n(t){return t?' crossOrigin="'+t+'"':""}function r(t,i){var e;return t.naturalWidth&&!mt?i(t.naturalWidth,t.naturalHeight):(e=document.createElement("img"),e.onload=function(){i(this.width,this.height)},void(e.src=t.src))}function p(t){var e=[],s=t.rotate,a=t.scaleX,o=t.scaleY;return i(s)&&0!==s&&e.push("rotate("+s+"deg)"),i(a)&&1!==a&&e.push("scaleX("+a+")"),i(o)&&1!==o&&e.push("scaleY("+o+")"),e.length?e.join(" "):"none"}function l(t,i){var e,s,a=Ct(t.degree)%180,o=(a>90?180-a:a)*Math.PI/180,h=bt(o),n=Bt(o),r=t.width,p=t.height,l=t.aspectRatio;return i?(e=r/(n+h/l),s=e/l):(e=r*n+p*h,s=r*h+p*n),{width:e,height:s}}function c(e,s){var a,o,h,n=t("")[0],r=n.getContext("2d"),p=0,c=0,d=s.naturalWidth,g=s.naturalHeight,u=s.rotate,f=s.scaleX,m=s.scaleY,v=i(f)&&i(m)&&(1!==f||1!==m),w=i(u)&&0!==u,x=w||v,C=d*Ct(f||1),b=g*Ct(m||1);return v&&(a=C/2,o=b/2),w&&(h=l({width:C,height:b,degree:u}),C=h.width,b=h.height,a=C/2,o=b/2),n.width=C,n.height=b,x&&(p=-d/2,c=-g/2,r.save(),r.translate(a,o)),w&&r.rotate(u*Math.PI/180),v&&r.scale(f,m),r.drawImage(e,$t(p),$t(c),$t(d),$t(g)),x&&r.restore(),n}function d(i){var e=i.length,s=0,a=0;return e&&(t.each(i,function(t,i){s+=i.pageX,a+=i.pageY}),s/=e,a/=e),{pageX:s,pageY:a}}function g(t,i,e){var s,a="";for(s=i,e+=i;s=8&&(r=s+a)))),r)for(d=c.getUint16(r,o),l=0;l")[0].getContext),mt=b&&/(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(b.userAgent),vt=Number,wt=Math.min,xt=Math.max,Ct=Math.abs,bt=Math.sin,Bt=Math.cos,yt=Math.sqrt,Dt=Math.round,$t=Math.floor,Lt=String.fromCharCode;v.prototype={constructor:v,init:function(){var t,i=this.$element;if(i.is("img")){if(this.isImg=!0,this.originalUrl=t=i.attr("src"),!t)return;t=i.prop("src")}else i.is("canvas")&&ft&&(t=i[0].toDataURL());this.load(t)},trigger:function(i,e){var s=t.Event(i,e);return this.$element.trigger(s),s},load:function(i){var e,s,a=this.options,n=this.$element;if(i&&(n.one(A,a.build),!this.trigger(A).isDefaultPrevented())){if(this.url=i,this.image={},!a.checkOrientation||!B)return this.clone();if(e=t.proxy(this.read,this),V.test(i))return J.test(i)?e(f(i)):this.clone();s=new XMLHttpRequest,s.onerror=s.onabort=t.proxy(function(){this.clone()},this),s.onload=function(){e(this.response)},a.checkCrossOrigin&&o(i)&&n.prop("crossOrigin")&&(i=h(i)),s.open("get",i),s.responseType="arraybuffer",s.send()}},read:function(t){var i=this.options,e=u(t),s=this.image,a=0,o=1,h=1;if(e>1)switch(this.url=m(t),e){case 2:o=-1;break;case 3:a=-180;break;case 4:h=-1;break;case 5:a=90,h=-1;break;case 6:a=90;break;case 7:a=90,o=-1;break;case 8:a=-90}i.rotatable&&(s.rotate=a),i.scalable&&(s.scaleX=o,s.scaleY=h),this.clone()},clone:function(){var i,e,s=this.options,a=this.$element,r=this.url,p="";s.checkCrossOrigin&&o(r)&&(p=a.prop("crossOrigin"),p?i=r:(p="anonymous",i=h(r))),this.crossOrigin=p,this.crossOriginUrl=i,this.$clone=e=t("'),this.isImg?a[0].complete?this.start():a.one(I,t.proxy(this.start,this)):e.one(I,t.proxy(this.start,this)).one(F,t.proxy(this.stop,this)).addClass(X).insertAfter(a)},start:function(){var i=this.$element,e=this.$clone;this.isImg||(e.off(F,this.stop),i=e),r(i[0],t.proxy(function(i,e){t.extend(this.image,{naturalWidth:i,naturalHeight:e,aspectRatio:i/e}),this.isLoaded=!0,this.build()},this))},stop:function(){this.$clone.remove(),this.$clone=null},build:function(){var i,e,s,a=this.options,o=this.$element,h=this.$clone;this.isLoaded&&(this.isBuilt&&this.unbuild(),this.$container=o.parent(),this.$cropper=i=t(v.TEMPLATE),this.$canvas=i.find(".cropper-canvas").append(h),this.$dragBox=i.find(".cropper-drag-box"),this.$cropBox=e=i.find(".cropper-crop-box"),this.$viewBox=i.find(".cropper-view-box"),this.$face=s=e.find(".cropper-face"),o.addClass(Y).after(i),this.isImg||h.removeClass(X),this.initPreview(),this.bind(),a.aspectRatio=xt(0,a.aspectRatio)||NaN,a.viewMode=xt(0,wt(3,Dt(a.viewMode)))||0,a.autoCrop?(this.isCropped=!0,a.modal&&this.$dragBox.addClass(T)):e.addClass(Y),a.guides||e.find(".cropper-dashed").addClass(Y),a.center||e.find(".cropper-center").addClass(Y),a.cropBoxMovable&&s.addClass(M).data(it,lt),a.highlight||s.addClass(k),a.background&&i.addClass(R),a.cropBoxResizable||e.find(".cropper-line, .cropper-point").addClass(Y),this.setDragMode(a.dragMode),this.render(),this.isBuilt=!0,this.setData(a.data),o.one(S,a.built),this.completing=setTimeout(t.proxy(function(){this.trigger(S),this.trigger(K,this.getData()),this.isCompleted=!0},this),0))},unbuild:function(){this.isBuilt&&(this.isCompleted||clearTimeout(this.completing),this.isBuilt=!1,this.isCompleted=!1,this.initialImage=null,this.initialCanvas=null,this.initialCropBox=null,this.container=null,this.canvas=null,this.cropBox=null,this.unbind(),this.resetPreview(),this.$preview=null,this.$viewBox=null,this.$cropBox=null,this.$dragBox=null,this.$canvas=null,this.$container=null,this.$cropper.remove(),this.$cropper=null)},render:function(){this.initContainer(),this.initCanvas(),this.initCropBox(),this.renderCanvas(),this.isCropped&&this.renderCropBox()},initContainer:function(){var t=this.options,i=this.$element,e=this.$container,s=this.$cropper;s.addClass(Y),i.removeClass(Y),s.css(this.container={width:xt(e.width(),vt(t.minContainerWidth)||200),height:xt(e.height(),vt(t.minContainerHeight)||100)}),i.addClass(Y),s.removeClass(Y)},initCanvas:function(){var i,e=this.options.viewMode,s=this.container,a=s.width,o=s.height,h=this.image,n=h.naturalWidth,r=h.naturalHeight,p=90===Ct(h.rotate),l=p?r:n,c=p?n:r,d=l/c,g=a,u=o;o*d>a?3===e?g=o*d:u=a/d:3===e?u=a/d:g=o*d,i={naturalWidth:l,naturalHeight:c,aspectRatio:d,width:g,height:u},i.oldLeft=i.left=(a-g)/2,i.oldTop=i.top=(o-u)/2,this.canvas=i,this.isLimited=1===e||2===e,this.limitCanvas(!0,!0),this.initialImage=t.extend({},h),this.initialCanvas=t.extend({},i)},limitCanvas:function(t,i){var e,s,a,o,h=this.options,n=h.viewMode,r=this.container,p=r.width,l=r.height,c=this.canvas,d=c.aspectRatio,g=this.cropBox,u=this.isCropped&&g;t&&(e=vt(h.minCanvasWidth)||0,s=vt(h.minCanvasHeight)||0,n&&(n>1?(e=xt(e,p),s=xt(s,l),3===n&&(s*d>e?e=s*d:s=e/d)):e?e=xt(e,u?g.width:0):s?s=xt(s,u?g.height:0):u&&(e=g.width,s=g.height,s*d>e?e=s*d:s=e/d)),e&&s?s*d>e?s=e/d:e=s*d:e?s=e/d:s&&(e=s*d),c.minWidth=e,c.minHeight=s,c.maxWidth=1/0,c.maxHeight=1/0),i&&(n?(a=p-c.width,o=l-c.height,c.minLeft=wt(0,a),c.minTop=wt(0,o),c.maxLeft=xt(0,a),c.maxTop=xt(0,o),u&&this.isLimited&&(c.minLeft=wt(g.left,g.left+g.width-c.width),c.minTop=wt(g.top,g.top+g.height-c.height),c.maxLeft=g.left,c.maxTop=g.top,2===n&&(c.width>=p&&(c.minLeft=wt(0,a),c.maxLeft=xt(0,a)),c.height>=l&&(c.minTop=wt(0,o),c.maxTop=xt(0,o))))):(c.minLeft=-c.width,c.minTop=-c.height,c.maxLeft=p,c.maxTop=l))},renderCanvas:function(t){var i,e,s=this.canvas,a=this.image,o=a.rotate,h=a.naturalWidth,n=a.naturalHeight;this.isRotated&&(this.isRotated=!1,e=l({width:a.width,height:a.height,degree:o}),i=e.width/e.height,i!==s.aspectRatio&&(s.left-=(e.width-s.width)/2,s.top-=(e.height-s.height)/2,s.width=e.width,s.height=e.height,s.aspectRatio=i,s.naturalWidth=h,s.naturalHeight=n,o%180&&(e=l({width:h,height:n,degree:o}),s.naturalWidth=e.width,s.naturalHeight=e.height),this.limitCanvas(!0,!1))),(s.width>s.maxWidth||s.widths.maxHeight||s.heighte.width?o.height=o.width/s:o.width=o.height*s),this.cropBox=o,this.limitCropBox(!0,!0),o.width=wt(xt(o.width,o.minWidth),o.maxWidth),o.height=wt(xt(o.height,o.minHeight),o.maxHeight),o.width=xt(o.minWidth,o.width*a),o.height=xt(o.minHeight,o.height*a),o.oldLeft=o.left=e.left+(e.width-o.width)/2,o.oldTop=o.top=e.top+(e.height-o.height)/2,this.initialCropBox=t.extend({},o)},limitCropBox:function(t,i){var e,s,a,o,h=this.options,n=h.aspectRatio,r=this.container,p=r.width,l=r.height,c=this.canvas,d=this.cropBox,g=this.isLimited;t&&(e=vt(h.minCropBoxWidth)||0,s=vt(h.minCropBoxHeight)||0,e=wt(e,p),s=wt(s,l),a=wt(p,g?c.width:p),o=wt(l,g?c.height:l),n&&(e&&s?s*n>e?s=e/n:e=s*n:e?s=e/n:s&&(e=s*n),o*n>a?o=a/n:a=o*n),d.minWidth=wt(e,a),d.minHeight=wt(s,o),d.maxWidth=a,d.maxHeight=o),i&&(g?(d.minLeft=xt(0,c.left),d.minTop=xt(0,c.top),d.maxLeft=wt(p,c.left+c.width)-d.width,d.maxTop=wt(l,c.top+c.height)-d.height):(d.minLeft=0,d.minTop=0,d.maxLeft=p-d.width,d.maxTop=l-d.height))},renderCropBox:function(){var t=this.options,i=this.container,e=i.width,s=i.height,a=this.cropBox;(a.width>a.maxWidth||a.widtha.maxHeight||a.height'),this.$viewBox.html(i),this.$preview.each(function(){var i=t(this);i.data(tt,{width:i.width(),height:i.height(),html:i.html()}),i.html("')})},resetPreview:function(){this.$preview.each(function(){var i=t(this),e=i.data(tt);i.css({width:e.width,height:e.height}).html(e.html).removeData(tt)})},preview:function(){var i=this.image,e=this.canvas,s=this.cropBox,a=s.width,o=s.height,h=i.width,n=i.height,r=s.left-e.left-i.left,l=s.top-e.top-i.top;this.isCropped&&!this.isDisabled&&(this.$clone2.css({width:h,height:n,marginLeft:-r,marginTop:-l,transform:p(i)}),this.$preview.each(function(){var e=t(this),s=e.data(tt),c=s.width,d=s.height,g=c,u=d,f=1;a&&(f=c/a,u=o*f),o&&u>d&&(f=d/o,g=a*f,u=d),e.css({width:g,height:u}).find("img").css({width:h*f,height:n*f,marginLeft:-r*f,marginTop:-l*f,transform:p(i)})}))},bind:function(){var i=this.options,e=this.$element,s=this.$cropper;t.isFunction(i.cropstart)&&e.on(N,i.cropstart),t.isFunction(i.cropmove)&&e.on(_,i.cropmove),t.isFunction(i.cropend)&&e.on(q,i.cropend),t.isFunction(i.crop)&&e.on(K,i.crop),t.isFunction(i.zoom)&&e.on(Z,i.zoom),s.on(z,t.proxy(this.cropStart,this)),i.zoomable&&i.zoomOnWheel&&s.on(E,t.proxy(this.wheel,this)),i.toggleDragModeOnDblclick&&s.on(U,t.proxy(this.dblclick,this)),x.on(O,this._cropMove=a(this.cropMove,this)).on(P,this._cropEnd=a(this.cropEnd,this)),i.responsive&&w.on(j,this._resize=a(this.resize,this))},unbind:function(){var i=this.options,e=this.$element,s=this.$cropper;t.isFunction(i.cropstart)&&e.off(N,i.cropstart),t.isFunction(i.cropmove)&&e.off(_,i.cropmove),t.isFunction(i.cropend)&&e.off(q,i.cropend),t.isFunction(i.crop)&&e.off(K,i.crop),t.isFunction(i.zoom)&&e.off(Z,i.zoom),s.off(z,this.cropStart),i.zoomable&&i.zoomOnWheel&&s.off(E,this.wheel),i.toggleDragModeOnDblclick&&s.off(U,this.dblclick),x.off(O,this._cropMove).off(P,this._cropEnd),i.responsive&&w.off(j,this._resize)},resize:function(){var i,e,s,a=this.options.restore,o=this.$container,h=this.container;!this.isDisabled&&h&&(s=o.width()/h.width,1===s&&o.height()===h.height||(a&&(i=this.getCanvasData(),e=this.getCropBoxData()),this.render(),a&&(this.setCanvasData(t.each(i,function(t,e){i[t]=e*s})),this.setCropBoxData(t.each(e,function(t,i){e[t]=i*s})))))},dblclick:function(){this.isDisabled||(this.$dragBox.hasClass(W)?this.setDragMode(dt):this.setDragMode(ct))},wheel:function(i){var e=i.originalEvent||i,s=vt(this.options.wheelZoomRatio)||.1,a=1;this.isDisabled||(i.preventDefault(),this.wheeling||(this.wheeling=!0,setTimeout(t.proxy(function(){this.wheeling=!1},this),50),e.deltaY?a=e.deltaY>0?1:-1:e.wheelDelta?a=-e.wheelDelta/120:e.detail&&(a=e.detail>0?1:-1),this.zoom(-a*s,i)))},cropStart:function(i){var e,s,a=this.options,o=i.originalEvent,h=o&&o.touches,n=i;if(!this.isDisabled){if(h){if(e=h.length,e>1){if(!a.zoomable||!a.zoomOnTouch||2!==e)return;n=h[1],this.startX2=n.pageX,this.startY2=n.pageY,s=gt}n=h[0]}if(s=s||t(n.target).data(it),Q.test(s)){if(this.trigger(N,{originalEvent:o,action:s}).isDefaultPrevented())return;i.preventDefault(),this.action=s,this.cropping=!1,this.startX=n.pageX||o&&o.pageX,this.startY=n.pageY||o&&o.pageY,s===ct&&(this.cropping=!0,this.$dragBox.addClass(T))}}},cropMove:function(t){var i,e=this.options,s=t.originalEvent,a=s&&s.touches,o=t,h=this.action;if(!this.isDisabled){if(a){if(i=a.length,i>1){if(!e.zoomable||!e.zoomOnTouch||2!==i)return;o=a[1],this.endX2=o.pageX,this.endY2=o.pageY}o=a[0]}if(h){if(this.trigger(_,{originalEvent:s,action:h}).isDefaultPrevented())return;t.preventDefault(),this.endX=o.pageX||s&&s.pageX,this.endY=o.pageY||s&&s.pageY,this.change(o.shiftKey,h===gt?t:null)}}},cropEnd:function(t){var i=t.originalEvent,e=this.action;this.isDisabled||e&&(t.preventDefault(),this.cropping&&(this.cropping=!1,this.$dragBox.toggleClass(T,this.isCropped&&this.options.modal)),this.action="",this.trigger(q,{originalEvent:i,action:e}))},change:function(t,i){var e,s,a=this.options,o=a.aspectRatio,h=this.action,n=this.container,r=this.canvas,p=this.cropBox,l=p.width,c=p.height,d=p.left,g=p.top,u=d+l,f=g+c,m=0,v=0,w=n.width,x=n.height,C=!0;switch(!o&&t&&(o=l&&c?l/c:1),this.isLimited&&(m=p.minLeft,v=p.minTop,w=m+wt(n.width,r.width,r.left+r.width),x=v+wt(n.height,r.height,r.top+r.height)),s={x:this.endX-this.startX,y:this.endY-this.startY},o&&(s.X=s.y*o,s.Y=s.x/o),h){case lt:d+=s.x,g+=s.y;break;case et:if(s.x>=0&&(u>=w||o&&(g<=v||f>=x))){C=!1;break}l+=s.x,o&&(c=l/o,g-=s.Y/2),l<0&&(h=st,l=0);break;case ot:if(s.y<=0&&(g<=v||o&&(d<=m||u>=w))){C=!1;break}c-=s.y,g+=s.y,o&&(l=c*o,d+=s.X/2),c<0&&(h=at,c=0);break;case st:if(s.x<=0&&(d<=m||o&&(g<=v||f>=x))){C=!1;break}l-=s.x,d+=s.x,o&&(c=l/o,g+=s.Y/2),l<0&&(h=et,l=0);break;case at:if(s.y>=0&&(f>=x||o&&(d<=m||u>=w))){C=!1;break}c+=s.y,o&&(l=c*o,d-=s.X/2),c<0&&(h=ot,c=0);break;case rt:if(o){if(s.y<=0&&(g<=v||u>=w)){C=!1;break}c-=s.y,g+=s.y,l=c*o}else s.x>=0?uv&&(c-=s.y,g+=s.y):(c-=s.y,g+=s.y);l<0&&c<0?(h=nt,c=0,l=0):l<0?(h=pt,l=0):c<0&&(h=ht,c=0);break;case pt:if(o){if(s.y<=0&&(g<=v||d<=m)){C=!1;break}c-=s.y,g+=s.y,l=c*o,d+=s.X}else s.x<=0?d>m?(l-=s.x,d+=s.x):s.y<=0&&g<=v&&(C=!1):(l-=s.x,d+=s.x),s.y<=0?g>v&&(c-=s.y,g+=s.y):(c-=s.y,g+=s.y);l<0&&c<0?(h=ht,c=0,l=0):l<0?(h=rt,l=0):c<0&&(h=nt,c=0);break;case nt:if(o){if(s.x<=0&&(d<=m||f>=x)){C=!1;break}l-=s.x,d+=s.x,c=l/o}else s.x<=0?d>m?(l-=s.x,d+=s.x):s.y>=0&&f>=x&&(C=!1):(l-=s.x,d+=s.x),s.y>=0?f=0&&(u>=w||f>=x)){C=!1;break}l+=s.x,c=l/o}else s.x>=0?u=0&&f>=x&&(C=!1):l+=s.x,s.y>=0?f0?h=s.y>0?ht:rt:s.x<0&&(d-=l,h=s.y>0?nt:pt),s.y<0&&(g-=c),this.isCropped||(this.$cropBox.removeClass(Y),this.isCropped=!0,this.isLimited&&this.limitCropBox(!0,!0))}C&&(p.width=l,p.height=c,p.left=d,p.top=g,this.action=h,this.renderCropBox()),this.startX=this.endX,this.startY=this.endY},crop:function(){this.isBuilt&&!this.isDisabled&&(this.isCropped||(this.isCropped=!0,this.limitCropBox(!0,!0),this.options.modal&&this.$dragBox.addClass(T),this.$cropBox.removeClass(Y)),this.setCropBoxData(this.initialCropBox))},reset:function(){this.isBuilt&&!this.isDisabled&&(this.image=t.extend({},this.initialImage),this.canvas=t.extend({},this.initialCanvas),this.cropBox=t.extend({},this.initialCropBox),this.renderCanvas(),this.isCropped&&this.renderCropBox())},clear:function(){this.isCropped&&!this.isDisabled&&(t.extend(this.cropBox,{left:0,top:0,width:0,height:0}),this.isCropped=!1,this.renderCropBox(),this.limitCanvas(!0,!0),this.renderCanvas(),this.$dragBox.removeClass(T),this.$cropBox.addClass(Y))},replace:function(t,i){!this.isDisabled&&t&&(this.isImg&&this.$element.attr("src",t),i?(this.url=t,this.$clone.attr("src",t),this.isBuilt&&this.$preview.find("img").add(this.$clone2).attr("src",t)):(this.isImg&&(this.isReplaced=!0),this.options.data=null,this.load(t)))},enable:function(){this.isBuilt&&(this.isDisabled=!1,this.$cropper.removeClass(H))},disable:function(){this.isBuilt&&(this.isDisabled=!0,this.$cropper.addClass(H))},destroy:function(){var t=this.$element;this.isLoaded?(this.isImg&&this.isReplaced&&t.attr("src",this.originalUrl),this.unbuild(),t.removeClass(Y)):this.isImg?t.off(I,this.start):this.$clone&&this.$clone.remove(),t.removeData(L)},move:function(t,i){var s=this.canvas;this.moveTo(e(t)?t:s.left+vt(t),e(i)?i:s.top+vt(i))},moveTo:function(t,s){var a=this.canvas,o=!1;e(s)&&(s=t),t=vt(t),s=vt(s),this.isBuilt&&!this.isDisabled&&this.options.movable&&(i(t)&&(a.left=t,o=!0),i(s)&&(a.top=s,o=!0),o&&this.renderCanvas(!0))},zoom:function(t,i){var e=this.canvas;t=vt(t),t=t<0?1/(1-t):1+t,this.zoomTo(e.width*t/e.naturalWidth,i)},zoomTo:function(t,i){var e,s,a,o,h,n=this.options,r=this.canvas,p=r.width,l=r.height,c=r.naturalWidth,g=r.naturalHeight;if(t=vt(t),t>=0&&this.isBuilt&&!this.isDisabled&&n.zoomable){if(s=c*t,a=g*t,i&&(e=i.originalEvent),this.trigger(Z,{originalEvent:e,oldRatio:p/c,ratio:s/c}).isDefaultPrevented())return;e?(o=this.$cropper.offset(),h=e.touches?d(e.touches):{pageX:i.pageX||e.pageX||0,pageY:i.pageY||e.pageY||0},r.left-=(s-p)*((h.pageX-o.left-r.left)/p),r.top-=(a-l)*((h.pageY-o.top-r.top)/l)):(r.left-=(s-p)/2,r.top-=(a-l)/2),r.width=s,r.height=a,this.renderCanvas(!0)}},rotate:function(t){this.rotateTo((this.image.rotate||0)+vt(t))},rotateTo:function(t){t=vt(t),i(t)&&this.isBuilt&&!this.isDisabled&&this.options.rotatable&&(this.image.rotate=t%360,this.isRotated=!0,this.renderCanvas(!0))},scale:function(t,s){var a=this.image,o=!1;e(s)&&(s=t),t=vt(t),s=vt(s),this.isBuilt&&!this.isDisabled&&this.options.scalable&&(i(t)&&(a.scaleX=t,o=!0),i(s)&&(a.scaleY=s,o=!0),o&&this.renderImage(!0))},scaleX:function(t){var e=this.image.scaleY;this.scale(t,i(e)?e:1)},scaleY:function(t){var e=this.image.scaleX;this.scale(i(e)?e:1,t)},getData:function(i){var e,s,a=this.options,o=this.image,h=this.canvas,n=this.cropBox;return this.isBuilt&&this.isCropped?(s={x:n.left-h.left,y:n.top-h.top,width:n.width,height:n.height},e=o.width/o.naturalWidth,t.each(s,function(t,a){a/=e,s[t]=i?Dt(a):a})):s={x:0,y:0,width:0,height:0},a.rotatable&&(s.rotate=o.rotate||0),a.scalable&&(s.scaleX=o.scaleX||1,s.scaleY=o.scaleY||1),s},setData:function(e){var s,a,o,h=this.options,n=this.image,r=this.canvas,p={};t.isFunction(e)&&(e=e.call(this.element)),this.isBuilt&&!this.isDisabled&&t.isPlainObject(e)&&(h.rotatable&&i(e.rotate)&&e.rotate!==n.rotate&&(n.rotate=e.rotate,this.isRotated=s=!0),h.scalable&&(i(e.scaleX)&&e.scaleX!==n.scaleX&&(n.scaleX=e.scaleX,a=!0),i(e.scaleY)&&e.scaleY!==n.scaleY&&(n.scaleY=e.scaleY,a=!0)),s?this.renderCanvas():a&&this.renderImage(),o=n.width/n.naturalWidth,i(e.x)&&(p.left=e.x*o+r.left),i(e.y)&&(p.top=e.y*o+r.top),i(e.width)&&(p.width=e.width*o),i(e.height)&&(p.height=e.height*o),this.setCropBoxData(p))},getContainerData:function(){return this.isBuilt?this.container:{}},getImageData:function(){return this.isLoaded?this.image:{}},getCanvasData:function(){var i=this.canvas,e={};return this.isBuilt&&t.each(["left","top","width","height","naturalWidth","naturalHeight"],function(t,s){e[s]=i[s]}),e},setCanvasData:function(e){var s=this.canvas,a=s.aspectRatio;t.isFunction(e)&&(e=e.call(this.$element)),this.isBuilt&&!this.isDisabled&&t.isPlainObject(e)&&(i(e.left)&&(s.left=e.left),i(e.top)&&(s.top=e.top),i(e.width)?(s.width=e.width,s.height=e.width/a):i(e.height)&&(s.height=e.height,s.width=e.height*a),this.renderCanvas(!0))},getCropBoxData:function(){var t,i=this.cropBox;return this.isBuilt&&this.isCropped&&(t={left:i.left,top:i.top,width:i.width,height:i.height}),t||{}},setCropBoxData:function(e){var s,a,o=this.cropBox,h=this.options.aspectRatio;t.isFunction(e)&&(e=e.call(this.$element)),this.isBuilt&&this.isCropped&&!this.isDisabled&&t.isPlainObject(e)&&(i(e.left)&&(o.left=e.left),i(e.top)&&(o.top=e.top),i(e.width)&&(s=!0,o.width=e.width),i(e.height)&&(a=!0,o.height=e.height),h&&(s?o.height=o.width/h:a&&(o.width=o.height*h)),this.renderCropBox())},getCroppedCanvas:function(i){var e,s,a,o,h,n,r,p,l,d,g;if(this.isBuilt&&ft)return this.isCropped?(t.isPlainObject(i)||(i={}),g=this.getData(),e=g.width,s=g.height,p=e/s,t.isPlainObject(i)&&(h=i.width,n=i.height,h?(n=h/p,r=h/e):n&&(h=n*p,r=n/s)),a=$t(h||e),o=$t(n||s),l=t("")[0],l.width=a,l.height=o,d=l.getContext("2d"),i.fillColor&&(d.fillStyle=i.fillColor,d.fillRect(0,0,a,o)),d.drawImage.apply(d,function(){var t,i,a,o,h,n,p=c(this.$clone[0],this.image),l=p.width,d=p.height,u=this.canvas,f=[p],m=g.x+u.naturalWidth*(Ct(g.scaleX||1)-1)/2,v=g.y+u.naturalHeight*(Ct(g.scaleY||1)-1)/2;return m<=-e||m>l?m=t=a=h=0:m<=0?(a=-m,m=0,t=h=wt(l,e+m)):m<=l&&(a=0,t=h=wt(e,l-m)),t<=0||v<=-s||v>d?v=i=o=n=0:v<=0?(o=-v,v=0,i=n=wt(d,s+v)):v<=d&&(o=0,i=n=wt(s,d-v)),f.push($t(m),$t(v),$t(t),$t(i)),r&&(a*=r,o*=r,h*=r,n*=r),h>0&&n>0&&f.push($t(a),$t(o),$t(h),$t(n)),f}.call(this)),l):c(this.$clone[0],this.image)},setAspectRatio:function(t){var i=this.options;this.isDisabled||e(t)||(i.aspectRatio=xt(0,t)||NaN,this.isBuilt&&(this.initCropBox(),this.isCropped&&this.renderCropBox()))},setDragMode:function(t){var i,e,s=this.options;this.isLoaded&&!this.isDisabled&&(i=t===ct,e=s.movable&&t===dt,t=i||e?t:ut,this.$dragBox.data(it,t).toggleClass(W,i).toggleClass(M,e),s.cropBoxMovable||this.$face.data(it,t).toggleClass(W,i).toggleClass(M,e))}},v.DEFAULTS={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,build:null,built:null,cropstart:null,cropmove:null,cropend:null,crop:null,zoom:null},v.setDefaults=function(i){t.extend(v.DEFAULTS,i)},v.TEMPLATE='
',v.other=t.fn.cropper,t.fn.cropper=function(i){var a,o=s(arguments,1);return this.each(function(){var e,s,h=t(this),n=h.data(L);if(!n){if(/destroy/.test(i))return;e=t.extend({},h.data(),t.isPlainObject(i)&&i),h.data(L,n=new v(this,e))}"string"==typeof i&&t.isFunction(s=n[i])&&(a=s.apply(n,o))}),e(a)?this:a},t.fn.cropper.Constructor=v,t.fn.cropper.setDefaults=v.setDefaults,t.fn.cropper.noConflict=function(){return t.fn.cropper=v.other,this}}); \ No newline at end of file diff --git a/docs/v1.0.0/css/cropper.css b/docs/v3.1.6/css/cropper.css similarity index 75% rename from docs/v1.0.0/css/cropper.css rename to docs/v3.1.6/css/cropper.css index 6df89f1f..b7ce603c 100644 --- a/docs/v1.0.0/css/cropper.css +++ b/docs/v3.1.6/css/cropper.css @@ -1,273 +1,288 @@ /*! - * Cropper v1.0.0 + * Cropper v3.1.6 * https://github.com/fengyuanchen/cropper * - * Copyright (c) 2014-2015 Fengyuan Chen and contributors + * Copyright (c) 2014-2018 Chen Fengyuan * Released under the MIT license * - * Date: 2015-10-10T02:10:06.999Z + * Date: 2018-03-01T13:33:39.581Z */ -.cropper-container { - position: relative; - overflow: hidden; + + .cropper-container { + direction: ltr; font-size: 0; line-height: 0; + position: relative; -ms-touch-action: none; - touch-action: none; + touch-action: none; -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - direction: ltr !important; - -webkit-tap-highlight-color: transparent; - -webkit-touch-callout: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } -.cropper-container img { + +.cropper-container img {/*Avoid margin top issue (Occur only when margin-top <= -height) + */ display: block; - width: 100%; - min-width: 0 !important; + height: 100%; + image-orientation: 0deg; + max-height: none !important; max-width: none !important; - height: 100%; min-height: 0 !important; - max-height: none !important; - - image-orientation: 0deg !important; + min-width: 0 !important; + width: 100%; } +.cropper-wrap-box, .cropper-canvas, .cropper-drag-box, .cropper-crop-box, .cropper-modal { - position: absolute; - top: 0; - right: 0; bottom: 0; left: 0; + position: absolute; + right: 0; + top: 0; +} + +.cropper-wrap-box, +.cropper-canvas { + overflow: hidden; } .cropper-drag-box { background-color: #fff; - filter: alpha(opacity=0); opacity: 0; } .cropper-modal { background-color: #000; - filter: alpha(opacity=50); opacity: .5; } .cropper-view-box { display: block; - width: 100%; - height: 100%; - overflow: hidden; + height: 100%; + outline-color: rgba(51, 153, 255, 0.75); outline: 1px solid #39f; - outline-color: rgba(51, 153, 255, .75); + overflow: hidden; + width: 100%; } .cropper-dashed { - position: absolute; - display: block; - filter: alpha(opacity=50); border: 0 dashed #eee; + display: block; opacity: .5; + position: absolute; } + .cropper-dashed.dashed-h { - top: 33.33333%; + border-bottom-width: 1px; + border-top-width: 1px; + height: 33.33333%; left: 0; + top: 33.33333%; width: 100%; - height: 33.33333%; - border-top-width: 1px; - border-bottom-width: 1px; } + .cropper-dashed.dashed-v { - top: 0; + border-left-width: 1px; + border-right-width: 1px; + height: 100%; left: 33.33333%; + top: 0; width: 33.33333%; - height: 100%; - border-right-width: 1px; - border-left-width: 1px; } .cropper-center { - position: absolute; - top: 50%; - left: 50%; display: block; - width: 0; height: 0; - filter: alpha(opacity=75); + left: 50%; opacity: .75; + position: absolute; + top: 50%; + width: 0; } + .cropper-center:before, - .cropper-center:after { - position: absolute; - display: block; - content: " "; +.cropper-center:after { background-color: #eee; + content: ' '; + display: block; + position: absolute; } + .cropper-center:before { - top: 0; + height: 1px; left: -3px; + top: 0; width: 7px; - height: 1px; } + .cropper-center:after { - top: -3px; + height: 7px; left: 0; + top: -3px; width: 1px; - height: 7px; } .cropper-face, .cropper-line, .cropper-point { - position: absolute; display: block; - width: 100%; height: 100%; - filter: alpha(opacity=10); opacity: .1; + position: absolute; + width: 100%; } .cropper-face { - top: 0; - left: 0; background-color: #fff; + left: 0; + top: 0; } .cropper-line { background-color: #39f; } + .cropper-line.line-e { - top: 0; + cursor: ew-resize; right: -3px; + top: 0; width: 5px; - cursor: e-resize; } + .cropper-line.line-n { - top: -3px; - left: 0; + cursor: ns-resize; height: 5px; - cursor: n-resize; + left: 0; + top: -3px; } + .cropper-line.line-w { - top: 0; + cursor: ew-resize; left: -3px; + top: 0; width: 5px; - cursor: w-resize; } + .cropper-line.line-s { bottom: -3px; - left: 0; + cursor: ns-resize; height: 5px; - cursor: s-resize; + left: 0; } .cropper-point { - width: 5px; - height: 5px; background-color: #39f; - filter: alpha(opacity=75); + height: 5px; opacity: .75; + width: 5px; } + .cropper-point.point-e { - top: 50%; - right: -3px; + cursor: ew-resize; margin-top: -3px; - cursor: e-resize; + right: -3px; + top: 50%; } + .cropper-point.point-n { - top: -3px; + cursor: ns-resize; left: 50%; margin-left: -3px; - cursor: n-resize; + top: -3px; } + .cropper-point.point-w { - top: 50%; + cursor: ew-resize; left: -3px; margin-top: -3px; - cursor: w-resize; + top: 50%; } + .cropper-point.point-s { bottom: -3px; + cursor: s-resize; left: 50%; margin-left: -3px; - cursor: s-resize; } + .cropper-point.point-ne { - top: -3px; + cursor: nesw-resize; right: -3px; - cursor: ne-resize; + top: -3px; } + .cropper-point.point-nw { - top: -3px; + cursor: nwse-resize; left: -3px; - cursor: nw-resize; + top: -3px; } + .cropper-point.point-sw { bottom: -3px; + cursor: nesw-resize; left: -3px; - cursor: sw-resize; } + .cropper-point.point-se { - right: -3px; bottom: -3px; - width: 20px; + cursor: nwse-resize; height: 20px; - cursor: se-resize; - filter: alpha(opacity=100); opacity: 1; + right: -3px; + width: 20px; } -.cropper-point.point-se:before { - position: absolute; - right: -50%; - bottom: -50%; - display: block; - width: 200%; - height: 200%; - content: " "; - background-color: #39f; - filter: alpha(opacity=0); - opacity: 0; -} + @media (min-width: 768px) { .cropper-point.point-se { - width: 15px; height: 15px; + width: 15px; } } + @media (min-width: 992px) { .cropper-point.point-se { - width: 10px; height: 10px; + width: 10px; } } + @media (min-width: 1200px) { .cropper-point.point-se { - width: 5px; height: 5px; - filter: alpha(opacity=75); opacity: .75; + width: 5px; } } -.cropper-bg { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC"); +.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 { - filter: alpha(opacity=0); opacity: 0; } +.cropper-bg { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC'); +} + .cropper-hide { - position: absolute; display: block; - width: 0; height: 0; + position: absolute; + width: 0; } .cropper-hidden { diff --git a/docs/v3.1.6/css/main.css b/docs/v3.1.6/css/main.css new file mode 100644 index 00000000..800a1cdd --- /dev/null +++ b/docs/v3.1.6/css/main.css @@ -0,0 +1,253 @@ +.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; + overflow: hidden; +} + +.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/docs/v2.3.4/img/picture.jpg b/docs/v3.1.6/images/picture.jpg similarity index 100% rename from docs/v2.3.4/img/picture.jpg rename to docs/v3.1.6/images/picture.jpg diff --git a/docs/v3.1.6/index.html b/docs/v3.1.6/index.html new file mode 100644 index 00000000..6bf0a76d --- /dev/null +++ b/docs/v3.1.6/index.html @@ -0,0 +1,567 @@ + + + + + + + + + + Cropper + + + + + + + + + + + + +
+
+

Cropper v3.1.6

+

A simple jQuery image cropping plugin.

+
+
+ + +
+
+
+ +
+ Picture +
+
+
+ +
+
+
+
+
+
+ + +
+
+ + + + + + px + +
+
+ + + + + + px + +
+
+ + + + + + px + +
+
+ + + + + + px + +
+
+ + + + + + deg + +
+
+ + + + +
+
+ + + + +
+
+
+
+
+
+ +
+ + +
+ +
+ + +
+ +
+ + + + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + +
+ +
+ + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + +
+ + + + Cropper.js + +
+
+
+ + + + + + + + + + + + diff --git a/docs/v3.1.6/js/cropper.js b/docs/v3.1.6/js/cropper.js new file mode 100644 index 00000000..3757403d --- /dev/null +++ b/docs/v3.1.6/js/cropper.js @@ -0,0 +1,3260 @@ +/*! + * Cropper v3.1.6 + * https://github.com/fengyuanchen/cropper + * + * Copyright (c) 2014-2018 Chen Fengyuan + * Released under the MIT license + * + * Date: 2018-03-01T13:33:48.179Z + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) : + typeof define === 'function' && define.amd ? define(['jquery'], factory) : + (factory(global.jQuery)); +}(this, (function ($) { 'use strict'; + +$ = $ && $.hasOwnProperty('default') ? $['default'] : $; + +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 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 a string. + * @param {*} value - The value to check. + * @returns {boolean} Returns `true` if the given value is a string, else `false`. + */ +function isString(value) { + return typeof value === 'string'; +} + +/** + * 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'; +} + +/** + * Takes a function and returns a new one that will always have a particular context. + * Custom proxy to avoid jQuery's guid. + * @param {Function} fn - The target function. + * @param {Object} context - The new context for the function. + * @returns {Function} The new function. + */ +function proxy(fn, context) { + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; + } + + return function () { + for (var _len2 = arguments.length, args2 = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args2[_key2] = arguments[_key2]; + } + + return fn.apply(context, args.concat(args2)); + }; +} + +/** + * Get the own enumerable properties of a given object. + * @param {Object} obj - The target object. + * @returns {Array} All the own enumerable properties of the given object. + */ +var objectKeys = Object.keys || function objectKeys(obj) { + var keys = []; + + $.each(obj, function (key) { + keys.push(key); + }); + + return keys; +}; + +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 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 transform values base on the given object. + * @param {Object} obj - The target object. + * @returns {string} A string contains transform values. + */ +function getTransformValues(_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 + ')'); + } + + return values.length ? values.join(' ') : 'none'; +} + +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'); + + newImage.onload = function () { + callback(newImage.width, newImage.height); + }; + + newImage.src = image.src; +} + +/** + * 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 (pointerId, pointer) { + delete pointers2[pointerId]; + + $.each(pointers2, function (pointerId2, 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 (pointerId, _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. + * @param {string} [type='contain'] - The adjust type. + * @returns {Object} The result sizes. + */ +function getAdjustedSizes(_ref4) // or 'cover' +{ + var aspectRatio = _ref4.aspectRatio, + height = _ref4.height, + width = _ref4.width; + var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'contain'; + + var isValidNumber = function isValidNumber(value) { + return isFinite(value) && value > 0; + }; + + if (isValidNumber(width) && isValidNumber(height)) { + var 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: 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 _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 = getAdjustedSizes({ + aspectRatio: aspectRatio, + width: maxWidth, + height: maxHeight + }); + var minSizes = getAdjustedSizes({ + aspectRatio: aspectRatio, + width: minWidth, + height: minHeight + }, 'cover'); + var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth)); + var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight)); + var 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.apply(context, [image].concat(toConsumableArray($.map(params, 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 (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 (i, 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; + + + $cropper.addClass(CLASS_HIDDEN); + $element.removeClass(CLASS_HIDDEN); + + $cropper.css(this.container = { + width: Math.max($container.width(), Number(options.minContainerWidth) || 200), + height: Math.max($container.height(), Number(options.minContainerHeight) || 100) + }); + + $element.addClass(CLASS_HIDDEN); + $cropper.removeClass(CLASS_HIDDEN); + }, + + + // Canvas (image wrapper) + initCanvas: function initCanvas() { + var container = this.container, + image = this.image; + var viewMode = this.options.viewMode; + + var rotated = Math.abs(image.rotate) % 180 === 90; + var naturalWidth = rotated ? image.naturalHeight : image.naturalWidth; + var naturalHeight = rotated ? image.naturalWidth : image.naturalHeight; + var aspectRatio = naturalWidth / naturalHeight; + var canvasWidth = container.width; + var canvasHeight = container.height; + + if (container.height * aspectRatio > container.width) { + if (viewMode === 3) { + canvasWidth = container.height * aspectRatio; + } else { + canvasHeight = container.width / aspectRatio; + } + } else if (viewMode === 3) { + canvasHeight = container.width / aspectRatio; + } else { + canvasWidth = container.height * aspectRatio; + } + + var canvas = { + aspectRatio: aspectRatio, + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + width: canvasWidth, + height: canvasHeight + }; + + canvas.left = (container.width - canvasWidth) / 2; + canvas.top = (container.height - canvasHeight) / 2; + canvas.oldLeft = canvas.left; + canvas.oldTop = canvas.top; + + this.canvas = canvas; + this.limited = viewMode === 1 || viewMode === 2; + this.limitCanvas(true, true); + this.initialImage = $.extend({}, image); + this.initialCanvas = $.extend({}, canvas); + }, + limitCanvas: function limitCanvas(isSizeLimited, isPositionLimited) { + var options = this.options, + container = this.container, + canvas = this.canvas, + cropBox = this.cropBox; + var viewMode = options.viewMode; + var aspectRatio = canvas.aspectRatio; + + var cropped = this.cropped && cropBox; + + if (isSizeLimited) { + var minCanvasWidth = Number(options.minCanvasWidth) || 0; + var minCanvasHeight = Number(options.minCanvasHeight) || 0; + + if (viewMode > 0) { + if (viewMode > 1) { + minCanvasWidth = Math.max(minCanvasWidth, container.width); + minCanvasHeight = Math.max(minCanvasHeight, container.height); + + if (viewMode === 3) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } else if (minCanvasWidth) { + minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBox.width : 0); + } else if (minCanvasHeight) { + minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBox.height : 0); + } else if (cropped) { + minCanvasWidth = cropBox.width; + minCanvasHeight = cropBox.height; + + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } + + var _getAdjustedSizes = getAdjustedSizes({ + aspectRatio: aspectRatio, + width: minCanvasWidth, + height: minCanvasHeight + }); + + minCanvasWidth = _getAdjustedSizes.width; + minCanvasHeight = _getAdjustedSizes.height; + + + canvas.minWidth = minCanvasWidth; + canvas.minHeight = minCanvasHeight; + canvas.maxWidth = Infinity; + canvas.maxHeight = Infinity; + } + + if (isPositionLimited) { + if (viewMode > 0) { + var newCanvasLeft = container.width - canvas.width; + var newCanvasTop = container.height - canvas.height; + + canvas.minLeft = Math.min(0, newCanvasLeft); + canvas.minTop = Math.min(0, newCanvasTop); + canvas.maxLeft = Math.max(0, newCanvasLeft); + canvas.maxTop = Math.max(0, newCanvasTop); + + if (cropped && this.limited) { + canvas.minLeft = Math.min(cropBox.left, cropBox.left + cropBox.width - canvas.width); + canvas.minTop = Math.min(cropBox.top, cropBox.top + cropBox.height - canvas.height); + canvas.maxLeft = cropBox.left; + canvas.maxTop = cropBox.top; + + if (viewMode === 2) { + if (canvas.width >= container.width) { + canvas.minLeft = Math.min(0, newCanvasLeft); + canvas.maxLeft = Math.max(0, newCanvasLeft); + } + + if (canvas.height >= container.height) { + canvas.minTop = Math.min(0, newCanvasTop); + canvas.maxTop = Math.max(0, newCanvasTop); + } + } + } + } else { + canvas.minLeft = -canvas.width; + canvas.minTop = -canvas.height; + canvas.maxLeft = container.width; + canvas.maxTop = container.height; + } + } + }, + renderCanvas: function renderCanvas(changed, transformed) { + var canvas = this.canvas, + image = this.image; + + + if (transformed) { + var _getRotatedSizes = getRotatedSizes({ + width: image.naturalWidth * Math.abs(image.scaleX || 1), + height: image.naturalHeight * Math.abs(image.scaleY || 1), + degree: image.rotate || 0 + }), + naturalWidth = _getRotatedSizes.width, + naturalHeight = _getRotatedSizes.height; + + var width = canvas.width * (naturalWidth / canvas.naturalWidth); + var height = canvas.height * (naturalHeight / canvas.naturalHeight); + + canvas.left -= (width - canvas.width) / 2; + canvas.top -= (height - canvas.height) / 2; + canvas.width = width; + canvas.height = height; + canvas.aspectRatio = naturalWidth / naturalHeight; + canvas.naturalWidth = naturalWidth; + canvas.naturalHeight = naturalHeight; + this.limitCanvas(true, false); + } + + if (canvas.width > canvas.maxWidth || canvas.width < canvas.minWidth) { + canvas.left = canvas.oldLeft; + } + + if (canvas.height > canvas.maxHeight || canvas.height < canvas.minHeight) { + canvas.top = canvas.oldTop; + } + + canvas.width = Math.min(Math.max(canvas.width, canvas.minWidth), canvas.maxWidth); + canvas.height = Math.min(Math.max(canvas.height, canvas.minHeight), canvas.maxHeight); + + this.limitCanvas(false, true); + + canvas.left = Math.min(Math.max(canvas.left, canvas.minLeft), canvas.maxLeft); + canvas.top = Math.min(Math.max(canvas.top, canvas.minTop), canvas.maxTop); + canvas.oldLeft = canvas.left; + canvas.oldTop = canvas.top; + + this.$canvas.css({ + width: canvas.width, + height: canvas.height, + transform: getTransformValues({ + translateX: canvas.left, + translateY: canvas.top + }) + }); + + this.renderImage(changed); + + if (this.cropped && this.limited) { + this.limitCropBox(true, true); + } + }, + renderImage: function renderImage(changed) { + var canvas = this.canvas, + image = this.image; + + var width = image.naturalWidth * (canvas.width / canvas.naturalWidth); + var height = image.naturalHeight * (canvas.height / canvas.naturalHeight); + + $.extend(image, { + width: width, + height: height, + left: (canvas.width - width) / 2, + top: (canvas.height - height) / 2 + }); + + this.$clone.css({ + width: image.width, + height: image.height, + transform: getTransformValues($.extend({ + translateX: image.left, + translateY: image.top + }, image)) + }); + + if (changed) { + this.output(); + } + }, + initCropBox: function initCropBox() { + var options = this.options, + canvas = this.canvas; + var aspectRatio = options.aspectRatio; + + var autoCropArea = Number(options.autoCropArea) || 0.8; + var cropBox = { + width: canvas.width, + height: canvas.height + }; + + if (aspectRatio) { + if (canvas.height * aspectRatio > canvas.width) { + cropBox.height = cropBox.width / aspectRatio; + } else { + cropBox.width = cropBox.height * aspectRatio; + } + } + + this.cropBox = cropBox; + this.limitCropBox(true, true); + + // Initialize auto crop area + cropBox.width = Math.min(Math.max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); + cropBox.height = Math.min(Math.max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); + + // The width of auto crop area must large than "minWidth", and the height too. (#164) + cropBox.width = Math.max(cropBox.minWidth, cropBox.width * autoCropArea); + cropBox.height = Math.max(cropBox.minHeight, cropBox.height * autoCropArea); + cropBox.left = canvas.left + (canvas.width - cropBox.width) / 2; + cropBox.top = canvas.top + (canvas.height - cropBox.height) / 2; + cropBox.oldLeft = cropBox.left; + cropBox.oldTop = cropBox.top; + + this.initialCropBox = $.extend({}, cropBox); + }, + limitCropBox: function limitCropBox(isSizeLimited, isPositionLimited) { + var options = this.options, + container = this.container, + canvas = this.canvas, + cropBox = this.cropBox, + limited = this.limited; + var aspectRatio = options.aspectRatio; + + + if (isSizeLimited) { + var minCropBoxWidth = Number(options.minCropBoxWidth) || 0; + var minCropBoxHeight = Number(options.minCropBoxHeight) || 0; + var maxCropBoxWidth = Math.min(container.width, limited ? canvas.width : container.width); + var maxCropBoxHeight = Math.min(container.height, limited ? canvas.height : container.height); + + // The min/maxCropBoxWidth/Height must be less than container's width/Height + minCropBoxWidth = Math.min(minCropBoxWidth, container.width); + minCropBoxHeight = Math.min(minCropBoxHeight, container.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 + cropBox.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth); + cropBox.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight); + cropBox.maxWidth = maxCropBoxWidth; + cropBox.maxHeight = maxCropBoxHeight; + } + + if (isPositionLimited) { + if (limited) { + cropBox.minLeft = Math.max(0, canvas.left); + cropBox.minTop = Math.max(0, canvas.top); + cropBox.maxLeft = Math.min(container.width, canvas.left + canvas.width) - cropBox.width; + cropBox.maxTop = Math.min(container.height, canvas.top + canvas.height) - cropBox.height; + } else { + cropBox.minLeft = 0; + cropBox.minTop = 0; + cropBox.maxLeft = container.width - cropBox.width; + cropBox.maxTop = container.height - cropBox.height; + } + } + }, + renderCropBox: function renderCropBox() { + var options = this.options, + container = this.container, + cropBox = this.cropBox; + + + if (cropBox.width > cropBox.maxWidth || cropBox.width < cropBox.minWidth) { + cropBox.left = cropBox.oldLeft; + } + + if (cropBox.height > cropBox.maxHeight || cropBox.height < cropBox.minHeight) { + cropBox.top = cropBox.oldTop; + } + + cropBox.width = Math.min(Math.max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); + cropBox.height = Math.min(Math.max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); + + this.limitCropBox(false, true); + + cropBox.left = Math.min(Math.max(cropBox.left, cropBox.minLeft), cropBox.maxLeft); + cropBox.top = Math.min(Math.max(cropBox.top, cropBox.minTop), cropBox.maxTop); + cropBox.oldLeft = cropBox.left; + cropBox.oldTop = cropBox.top; + + if (options.movable && options.cropBoxMovable) { + // Turn to move the canvas when the crop box is equal to the container + this.$face.data(DATA_ACTION, cropBox.width >= container.width && cropBox.height >= container.height ? ACTION_MOVE : ACTION_ALL); + } + + this.$cropBox.css({ + width: cropBox.width, + height: cropBox.height, + transform: getTransformValues({ + translateX: cropBox.left, + translateY: cropBox.top + }) + }); + + if (this.cropped && this.limited) { + this.limitCanvas(true, true); + } + + if (!this.disabled) { + this.output(); + } + }, + output: function output() { + this.preview(); + + if (this.completed) { + this.trigger(EVENT_CROP, this.getData()); + } + } +}; + +var preview = { + initPreview: function initPreview() { + var crossOrigin = this.crossOrigin; + + var url = crossOrigin ? this.crossOriginUrl : this.url; + var image = document.createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = url; + + var $clone2 = $(image); + + this.$preview = $(this.options.preview); + this.$clone2 = $clone2; + this.$viewBox.html($clone2); + this.$preview.each(function (i, element) { + var $element = $(element); + var img = document.createElement('img'); + + // Save the original size for recover + $element.data(DATA_PREVIEW, { + width: $element.width(), + height: $element.height(), + html: $element.html() + }); + + 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;"'; + + $element.html(img); + }); + }, + resetPreview: function resetPreview() { + this.$preview.each(function (i, element) { + var $element = $(element); + var data = $element.data(DATA_PREVIEW); + + $element.css({ + width: data.width, + height: data.height + }).html(data.html).removeData(DATA_PREVIEW); + }); + }, + preview: function preview() { + var image = this.image, + canvas = this.canvas, + cropBox = this.cropBox; + var cropBoxWidth = cropBox.width, + cropBoxHeight = cropBox.height; + var width = image.width, + height = image.height; + + var left = cropBox.left - canvas.left - image.left; + var top = cropBox.top - canvas.top - image.top; + + if (!this.cropped || this.disabled) { + return; + } + + this.$clone2.css({ + width: width, + height: height, + transform: getTransformValues($.extend({ + translateX: -left, + translateY: -top + }, image)) + }); + + this.$preview.each(function (i, element) { + var $element = $(element); + var data = $element.data(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; + } + + $element.css({ + width: newWidth, + height: newHeight + }).find('img').css({ + width: width * ratio, + height: height * ratio, + transform: getTransformValues($.extend({ + translateX: -left * ratio, + translateY: -top * ratio + }, image)) + }); + }); + } +}; + +var events = { + bind: function bind() { + var $element = this.$element, + options = this.options, + $cropper = this.$cropper; + + + if ($.isFunction(options.cropstart)) { + $element.on(EVENT_CROP_START, options.cropstart); + } + + if ($.isFunction(options.cropmove)) { + $element.on(EVENT_CROP_MOVE, options.cropmove); + } + + if ($.isFunction(options.cropend)) { + $element.on(EVENT_CROP_END, options.cropend); + } + + if ($.isFunction(options.crop)) { + $element.on(EVENT_CROP, options.crop); + } + + if ($.isFunction(options.zoom)) { + $element.on(EVENT_ZOOM, options.zoom); + } + + $cropper.on(EVENT_POINTER_DOWN, proxy(this.cropStart, this)); + + if (options.zoomable && options.zoomOnWheel) { + $cropper.on(EVENT_WHEEL, proxy(this.wheel, this)); + } + + if (options.toggleDragModeOnDblclick) { + $cropper.on(EVENT_DBLCLICK, proxy(this.dblclick, this)); + } + + $(this.element.ownerDocument).on(EVENT_POINTER_MOVE, this.onCropMove = proxy(this.cropMove, this)).on(EVENT_POINTER_UP, this.onCropEnd = proxy(this.cropEnd, this)); + + if (options.responsive) { + $(window).on(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)) { + $element.off(EVENT_CROP_START, options.cropstart); + } + + if ($.isFunction(options.cropmove)) { + $element.off(EVENT_CROP_MOVE, options.cropmove); + } + + if ($.isFunction(options.cropend)) { + $element.off(EVENT_CROP_END, options.cropend); + } + + if ($.isFunction(options.crop)) { + $element.off(EVENT_CROP, options.crop); + } + + if ($.isFunction(options.zoom)) { + $element.off(EVENT_ZOOM, options.zoom); + } + + $cropper.off(EVENT_POINTER_DOWN, this.cropStart); + + if (options.zoomable && options.zoomOnWheel) { + $cropper.off(EVENT_WHEEL, this.wheel); + } + + if (options.toggleDragModeOnDblclick) { + $cropper.off(EVENT_DBLCLICK, this.dblclick); + } + + $(this.element.ownerDocument).off(EVENT_POINTER_MOVE, this.onCropMove).off(EVENT_POINTER_UP, this.onCropEnd); + + if (options.responsive) { + $(window).off(EVENT_RESIZE, this.onResize); + } + } +}; + +var handlers = { + resize: function resize() { + var options = this.options, + $container = this.$container, + container = this.container; + + var minContainerWidth = Number(options.minContainerWidth) || 200; + var minContainerHeight = Number(options.minContainerHeight) || 100; + + if (this.disabled || container.width <= minContainerWidth || container.height <= minContainerHeight) { + return; + } + + var ratio = $container.width() / container.width; + + // Resize when width changed or height changed + if (ratio !== 1 || $container.height() !== container.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 (i, n) { + canvasData[i] = n * ratio; + })); + this.setCropBoxData($.each(cropBoxData, function (i, n) { + cropBoxData[i] = n * ratio; + })); + } + } + }, + dblclick: function dblclick() { + if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) { + return; + } + + this.setDragMode(this.$dragBox.hasClass(CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP); + }, + wheel: function wheel(event) { + var _this = this; + + var e = event.originalEvent || event; + var ratio = Number(this.options.wheelZoomRatio) || 0.1; + + if (this.disabled) { + return; + } + + event.preventDefault(); + + // Limit wheel speed to prevent zoom too fast + if (this.wheeling) { + return; + } + + this.wheeling = true; + + setTimeout(function () { + _this.wheeling = false; + }, 50); + + var delta = 1; + + 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, event); + }, + cropStart: function cropStart(e) { + if (this.disabled) { + return; + } + + var options = this.options, + pointers = this.pointers; + var originalEvent = e.originalEvent; + + var action = void 0; + + if (originalEvent && originalEvent.changedTouches) { + // Handle touch event + $.each(originalEvent.changedTouches, function (i, touch) { + pointers[touch.identifier] = getPointer(touch); + }); + } else { + // Handle mouse event and pointer event + pointers[originalEvent && originalEvent.pointerId || 0] = getPointer(originalEvent || e); + } + + if (objectKeys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) { + action = ACTION_ZOOM; + } else { + action = $(e.target).data(DATA_ACTION); + } + + if (!REGEXP_ACTIONS.test(action)) { + return; + } + + if (this.trigger(EVENT_CROP_START, { + originalEvent: originalEvent, + action: action + }).isDefaultPrevented()) { + return; + } + + e.preventDefault(); + + this.action = action; + this.cropping = false; + + if (action === ACTION_CROP) { + this.cropping = true; + this.$dragBox.addClass(CLASS_MODAL); + } + }, + cropMove: function cropMove(e) { + var action = this.action; + + + if (this.disabled || !action) { + return; + } + + var pointers = this.pointers; + var originalEvent = e.originalEvent; + + + e.preventDefault(); + + if (this.trigger(EVENT_CROP_MOVE, { + originalEvent: originalEvent, + action: action + }).isDefaultPrevented()) { + return; + } + + if (originalEvent && originalEvent.changedTouches) { + $.each(originalEvent.changedTouches, function (i, touch) { + $.extend(pointers[touch.identifier], getPointer(touch, true)); + }); + } else { + $.extend(pointers[originalEvent && originalEvent.pointerId || 0], getPointer(originalEvent || e, true)); + } + + this.change(e); + }, + cropEnd: function cropEnd(e) { + if (this.disabled) { + return; + } + + var action = this.action; + var pointers = this.pointers; + var originalEvent = e.originalEvent; + + + if (originalEvent && originalEvent.changedTouches) { + $.each(originalEvent.changedTouches, function (i, touch) { + delete pointers[touch.identifier]; + }); + } else { + delete pointers[originalEvent && originalEvent.pointerId || 0]; + } + + if (!action) { + return; + } + + e.preventDefault(); + + if (!objectKeys(pointers).length) { + this.action = ''; + } + + if (this.cropping) { + this.cropping = false; + this.$dragBox.toggleClass(CLASS_MODAL, this.cropped && this.options.modal); + } + + this.trigger(EVENT_CROP_END, { + originalEvent: originalEvent, + action: action + }); + } +}; + +var change = { + change: function change(e) { + var options = this.options, + pointers = this.pointers, + container = this.container, + canvas = this.canvas, + cropBox = this.cropBox; + var action = this.action; + var aspectRatio = options.aspectRatio; + var left = cropBox.left, + top = cropBox.top, + width = cropBox.width, + height = cropBox.height; + + var right = left + width; + var bottom = top + height; + var minLeft = 0; + var minTop = 0; + var maxWidth = container.width; + var maxHeight = container.height; + var renderable = true; + var offset = void 0; + + // Locking aspect ratio in "free mode" by holding shift key (#259) + if (!aspectRatio && e.shiftKey) { + aspectRatio = width && height ? width / height : 1; + } + + if (this.limited) { + minLeft = cropBox.minLeft; + minTop = cropBox.minTop; + + maxWidth = minLeft + Math.min(container.width, canvas.width, canvas.left + canvas.width); + maxHeight = minTop + Math.min(container.height, canvas.height, canvas.top + canvas.height); + } + + var pointer = pointers[objectKeys(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.originalEvent); + renderable = false; + break; + + // Create crop box + case ACTION_CROP: + if (!range.x || !range.y) { + renderable = false; + break; + } + + offset = this.$cropper.offset(); + left = pointer.startX - offset.left; + top = pointer.startY - offset.top; + width = cropBox.minWidth; + height = cropBox.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) { + this.$cropBox.removeClass(CLASS_HIDDEN); + this.cropped = true; + + if (this.limited) { + this.limitCropBox(true, true); + } + } + + break; + + default: + } + + if (renderable) { + cropBox.width = width; + cropBox.height = height; + cropBox.left = left; + cropBox.top = top; + this.action = action; + this.renderCropBox(); + } + + // Override + $.each(pointers, function (i, p) { + p.startX = p.endX; + p.startY = p.endY; + }); + } +}; + +var methods = { + // Show the crop box manually + crop: function crop() { + if (!this.ready || this.disabled) { + return; + } + + if (!this.cropped) { + this.cropped = true; + this.limitCropBox(true, true); + + if (this.options.modal) { + this.$dragBox.addClass(CLASS_MODAL); + } + + this.$cropBox.removeClass(CLASS_HIDDEN); + } + + this.setCropBoxData(this.initialCropBox); + }, + + + // Reset the image and crop box to their initial states + reset: function reset() { + if (!this.ready || this.disabled) { + return; + } + + this.image = $.extend({}, this.initialImage); + this.canvas = $.extend({}, this.initialCanvas); + this.cropBox = $.extend({}, this.initialCropBox); + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + }, + + + // Clear the crop box + clear: function clear() { + if (!this.cropped || this.disabled) { + return; + } + + $.extend(this.cropBox, { + 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(); + this.$dragBox.removeClass(CLASS_MODAL); + this.$cropBox.addClass(CLASS_HIDDEN); + }, + + + /** + * 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. + */ + replace: function replace(url, onlyColorChanged) { + if (!this.disabled && url) { + if (this.isImg) { + this.$element.attr('src', url); + } + + if (onlyColorChanged) { + this.url = url; + this.$clone.attr('src', url); + + if (this.ready) { + this.$preview.find('img').add(this.$clone2).attr('src', url); + } + } else { + if (this.isImg) { + this.replaced = true; + } + + // Clear previous data + this.options.data = null; + this.load(url); + } + } + }, + + + // Enable (unfreeze) the cropper + enable: function enable() { + if (this.ready) { + this.disabled = false; + this.$cropper.removeClass(CLASS_DISABLED); + } + }, + + + // Disable (freeze) the cropper + disable: function disable() { + if (this.ready) { + this.disabled = true; + this.$cropper.addClass(CLASS_DISABLED); + } + }, + + + // Destroy the cropper and remove the instance from the image + destroy: function destroy() { + var $element = this.$element; + + + if (this.loaded) { + if (this.isImg && this.replaced) { + $element.attr('src', this.originalUrl); + } + + this.unbuild(); + $element.removeClass(CLASS_HIDDEN); + } else if (this.isImg) { + $element.off(EVENT_LOAD, this.start); + } else if (this.$clone) { + this.$clone.remove(); + } + + $element.removeData(NAMESPACE); + }, + + + /** + * 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. + */ + move: function move(offsetX, offsetY) { + var _canvas = this.canvas, + left = _canvas.left, + top = _canvas.top; + + + 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. + */ + moveTo: function moveTo(x, y) { + var canvas = this.canvas; + + var changed = false; + + // If "y" is not present, its default value is "x" + if (isUndefined(y)) { + y = x; + } + + x = Number(x); + y = Number(y); + + if (this.ready && !this.disabled && this.options.movable) { + if (isNumber(x)) { + canvas.left = x; + changed = true; + } + + if (isNumber(y)) { + canvas.top = y; + changed = true; + } + + if (changed) { + this.renderCanvas(true); + } + } + }, + + + /** + * Zoom the canvas with a relative ratio + * @param {Number} ratio - The target ratio. + * @param {Event} _event - The related event if any. + */ + zoom: function zoom(ratio, _event) { + var canvas = this.canvas; + + + ratio = Number(ratio); + + if (ratio < 0) { + ratio = 1 / (1 - ratio); + } else { + ratio = 1 + ratio; + } + + this.zoomTo(canvas.width * ratio / canvas.naturalWidth, _event); + }, + + + /** + * Zoom the canvas to an absolute ratio + * @param {number} ratio - The target ratio. + * @param {Event} _event - The related event if any. + */ + zoomTo: function zoomTo(ratio, _event) { + var options = this.options, + pointers = this.pointers, + canvas = this.canvas; + var width = canvas.width, + height = canvas.height, + naturalWidth = canvas.naturalWidth, + naturalHeight = canvas.naturalHeight; + + + ratio = Number(ratio); + + if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) { + var newWidth = naturalWidth * ratio; + var newHeight = naturalHeight * ratio; + var originalEvent = void 0; + + if (_event) { + originalEvent = _event.originalEvent; + } + + if (this.trigger(EVENT_ZOOM, { + originalEvent: originalEvent, + oldRatio: width / naturalWidth, + ratio: newWidth / naturalWidth + }).isDefaultPrevented()) { + return; + } + + if (originalEvent) { + var offset = this.$cropper.offset(); + var center = pointers && objectKeys(pointers).length ? getPointersCenter(pointers) : { + pageX: _event.pageX || originalEvent.pageX || 0, + pageY: _event.pageY || originalEvent.pageY || 0 + }; + + // Zoom from the triggering point of the event + canvas.left -= (newWidth - width) * ((center.pageX - offset.left - canvas.left) / width); + canvas.top -= (newHeight - height) * ((center.pageY - offset.top - canvas.top) / height); + } else { + // Zoom from the center of the canvas + canvas.left -= (newWidth - width) / 2; + canvas.top -= (newHeight - height) / 2; + } + + canvas.width = newWidth; + canvas.height = newHeight; + this.renderCanvas(true); + } + }, + + + /** + * Rotate the canvas with a relative degree + * @param {number} degree - The rotate degree. + */ + rotate: function rotate(degree) { + this.rotateTo((this.image.rotate || 0) + Number(degree)); + }, + + + /** + * Rotate the canvas to an absolute degree + * @param {number} degree - The rotate degree. + */ + rotateTo: function rotateTo(degree) { + degree = Number(degree); + + if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) { + this.image.rotate = degree % 360; + this.renderCanvas(true, true); + } + }, + + + /** + * Scale the image on the x-axis. + * @param {number} scaleX - The scale ratio on the x-axis. + */ + scaleX: function scaleX(_scaleX) { + var scaleY = this.image.scaleY; + + + this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1); + }, + + + /** + * Scale the image on the y-axis. + * @param {number} scaleY - The scale ratio on the y-axis. + */ + scaleY: function scaleY(_scaleY) { + var scaleX = this.image.scaleX; + + + 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. + */ + scale: function scale(scaleX) { + var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX; + var image = this.image; + + var transformed = false; + + scaleX = Number(scaleX); + scaleY = Number(scaleY); + + if (this.ready && !this.disabled && this.options.scalable) { + if (isNumber(scaleX)) { + image.scaleX = scaleX; + transformed = true; + } + + if (isNumber(scaleY)) { + image.scaleY = scaleY; + transformed = true; + } + + if (transformed) { + this.renderCanvas(true, true); + } + } + }, + + + /** + * 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() { + var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var options = this.options, + image = this.image, + canvas = this.canvas, + cropBox = this.cropBox; + + var data = void 0; + + if (this.ready && this.cropped) { + data = { + x: cropBox.left - canvas.left, + y: cropBox.top - canvas.top, + width: cropBox.width, + height: cropBox.height + }; + + var ratio = image.width / image.naturalWidth; + + $.each(data, function (i, n) { + n /= ratio; + data[i] = rounded ? Math.round(n) : n; + }); + } else { + data = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + } + + if (options.rotatable) { + data.rotate = image.rotate || 0; + } + + if (options.scalable) { + data.scaleX = image.scaleX || 1; + data.scaleY = image.scaleY || 1; + } + + return data; + }, + + + /** + * Set the cropped area position and size with new data + * @param {Object} data - The new data. + */ + setData: function setData(data) { + var options = this.options, + image = this.image, + canvas = this.canvas; + + 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 !== image.rotate) { + image.rotate = data.rotate; + transformed = true; + } + } + + if (options.scalable) { + if (isNumber(data.scaleX) && data.scaleX !== image.scaleX) { + image.scaleX = data.scaleX; + transformed = true; + } + + if (isNumber(data.scaleY) && data.scaleY !== image.scaleY) { + image.scaleY = data.scaleY; + transformed = true; + } + } + + if (transformed) { + this.renderCanvas(true, true); + } + + var ratio = image.width / image.naturalWidth; + + if (isNumber(data.x)) { + cropBoxData.left = data.x * ratio + canvas.left; + } + + if (isNumber(data.y)) { + cropBoxData.top = data.y * ratio + canvas.top; + } + + if (isNumber(data.width)) { + cropBoxData.width = data.width * ratio; + } + + if (isNumber(data.height)) { + cropBoxData.height = data.height * ratio; + } + + this.setCropBoxData(cropBoxData); + } + }, + + + /** + * Get the container size data. + * @returns {Object} The result container data. + */ + getContainerData: function getContainerData() { + return this.ready ? $.extend({}, this.container) : {}; + }, + + + /** + * Get the image position and size data. + * @returns {Object} The result image data. + */ + getImageData: function getImageData() { + return this.loaded ? $.extend({}, this.image) : {}; + }, + + + /** + * Get the canvas position and size data. + * @returns {Object} The result canvas data. + */ + getCanvasData: function getCanvasData() { + var canvas = this.canvas; + + var data = {}; + + if (this.ready) { + $.each(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (i, n) { + data[n] = canvas[n]; + }); + } + + return data; + }, + + + /** + * Set the canvas position and size with new data. + * @param {Object} data - The new canvas data. + */ + setCanvasData: function setCanvasData(data) { + var canvas = this.canvas; + var aspectRatio = canvas.aspectRatio; + + + if ($.isFunction(data)) { + data = data.call(this.$element); + } + + if (this.ready && !this.disabled && $.isPlainObject(data)) { + if (isNumber(data.left)) { + canvas.left = data.left; + } + + if (isNumber(data.top)) { + canvas.top = data.top; + } + + if (isNumber(data.width)) { + canvas.width = data.width; + canvas.height = data.width / aspectRatio; + } else if (isNumber(data.height)) { + canvas.height = data.height; + canvas.width = data.height * aspectRatio; + } + + this.renderCanvas(true); + } + }, + + + /** + * Get the crop box position and size data. + * @returns {Object} The result crop box data. + */ + getCropBoxData: function getCropBoxData() { + var cropBox = this.cropBox; + + + return this.ready && this.cropped ? { + left: cropBox.left, + top: cropBox.top, + width: cropBox.width, + height: cropBox.height + } : {}; + }, + + + /** + * Set the crop box position and size with new data. + * @param {Object} data - The new crop box data. + */ + setCropBoxData: function setCropBoxData(data) { + var cropBox = this.cropBox; + 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)) { + cropBox.left = data.left; + } + + if (isNumber(data.top)) { + cropBox.top = data.top; + } + + if (isNumber(data.width) && data.width !== cropBox.width) { + widthChanged = true; + cropBox.width = data.width; + } + + if (isNumber(data.height) && data.height !== cropBox.height) { + heightChanged = true; + cropBox.height = data.height; + } + + if (aspectRatio) { + if (widthChanged) { + cropBox.height = cropBox.width / aspectRatio; + } else if (heightChanged) { + cropBox.width = cropBox.height * aspectRatio; + } + } + + this.renderCropBox(); + } + }, + + + /** + * 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.canvas; + + var source = getSourceCanvas(this.$clone[0], this.image, canvasData, options); + + // Returns the source canvas if it is not cropped. + if (!this.cropped) { + return source; + } + + var _getData = this.getData(), + initialX = _getData.x, + initialY = _getData.y, + initialWidth = _getData.width, + initialHeight = _getData.height; + + var ratio = source.width / Math.floor(canvasData.naturalWidth); + + if (ratio !== 1) { + initialX *= ratio; + initialY *= ratio; + initialWidth *= ratio; + initialHeight *= ratio; + } + + var aspectRatio = initialWidth / initialHeight; + var maxSizes = getAdjustedSizes({ + aspectRatio: aspectRatio, + width: options.maxWidth || Infinity, + height: options.maxHeight || Infinity + }); + var minSizes = getAdjustedSizes({ + aspectRatio: aspectRatio, + width: options.minWidth || 0, + height: options.minHeight || 0 + }, 'cover'); + + var _getAdjustedSizes = getAdjustedSizes({ + aspectRatio: aspectRatio, + width: options.width || (ratio !== 1 ? source.width : initialWidth), + height: options.height || (ratio !== 1 ? source.height : initialHeight) + }), + width = _getAdjustedSizes.width, + height = _getAdjustedSizes.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 = initialX; + var srcY = initialY; + 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($.map(params, function (param) { + return Math.floor(normalizeDecimalNumber(param)); + })))); + return canvas; + }, + + + /** + * Change the aspect ratio of the crop box. + * @param {number} aspectRatio - The new aspect ratio. + */ + 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(); + } + } + } + }, + + + /** + * Change the drag mode. + * @param {string} mode - The new drag mode. + */ + setDragMode: function setDragMode(mode) { + var options = this.options; + + var croppable = void 0; + var movable = void 0; + + if (this.loaded && !this.disabled) { + croppable = mode === DRAG_MODE_CROP; + movable = options.movable && mode === DRAG_MODE_MOVE; + mode = croppable || movable ? mode : DRAG_MODE_NONE; + + this.$dragBox.data(DATA_ACTION, mode).toggleClass(CLASS_CROP, croppable).toggleClass(CLASS_MOVE, movable); + + if (!options.cropBoxMovable) { + // Sync drag mode to crop box when it is not movable(#300) + this.$face.data(DATA_ACTION, mode).toggleClass(CLASS_CROP, croppable).toggleClass(CLASS_MOVE, movable); + } + } + } +}; + +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.$element = $(element); + this.options = $.extend({}, DEFAULTS, $.isPlainObject(options) && options); + this.completed = 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.canvas = null; + this.cropBox = null; + this.pointers = {}; + this.init(); + } + + createClass(Cropper, [{ + key: 'init', + value: function init() { + var $element = this.$element; + + var url = void 0; + + if ($element.is('img')) { + this.isImg = true; + + // Should use `$.fn.attr` here. e.g.: "img/picture.jpg" + url = $element.attr('src') || ''; + this.originalUrl = url; + + // Stop when it's a blank image + if (!url) { + return; + } + + // Should use `$.fn.prop` here. e.g.: "http://example.com/img/picture.jpg" + url = $element.prop('src'); + } else if ($element.is('canvas') && window.HTMLCanvasElement) { + url = $element[0].toDataURL(); + } + + this.load(url); + } + + // A shortcut for triggering custom events + + }, { + key: 'trigger', + value: function trigger(type, data) { + var e = $.Event(type, data); + + this.$element.trigger(e); + + return e; + } + }, { + key: 'load', + value: function load(url) { + var _this = this; + + if (!url) { + return; + } + + this.url = url; + this.image = {}; + + 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); + }; + + // Bust cache when there is a "crossOrigin" property + if (options.checkCrossOrigin && isCrossOriginURL(url) && !$element.prop('crossOrigin')) { + url = addTimestamp(url); + } + + xhr.open('get', url); + xhr.responseType = 'arraybuffer'; + xhr.withCredentials = $element.prop('crossOrigin') === 'use-credentials'; + xhr.send(); + } + }, { + key: 'read', + value: function read(arrayBuffer) { + var options = this.options, + image = this.image; + + 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) { + image.rotate = rotate; + } + + if (options.scalable) { + image.scaleX = scaleX; + image.scaleY = scaleY; + } + + this.clone(); + } + }, { + key: 'clone', + value: function clone() { + var $element = this.$element, + options = this.options, + url = this.url; + + var crossOrigin = ''; + var crossOriginUrl = void 0; + + if (options.checkCrossOrigin && isCrossOriginURL(url)) { + crossOrigin = $element.prop('crossOrigin'); + + if (crossOrigin) { + crossOriginUrl = url; + } else { + crossOrigin = 'anonymous'; + + // Bust cache (#148) 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 $clone = $(image); + + this.$clone = $clone; + + if (this.isImg) { + if (this.element.complete) { + this.start(); + } else { + $element.one(EVENT_LOAD, $.proxy(this.start, this)); + } + } else { + $clone.one(EVENT_LOAD, $.proxy(this.start, this)).one(EVENT_ERROR, $.proxy(this.stop, this)).addClass(CLASS_HIDE).insertAfter($element); + } + } + }, { + key: 'start', + value: function start() { + var _this2 = this; + + var $clone = this.$clone; + + var $image = this.$element; + + if (!this.isImg) { + $clone.off(EVENT_ERROR, this.stop); + $image = $clone; + } + + getImageNaturalSizes($image[0], function (naturalWidth, naturalHeight) { + $.extend(_this2.image, { + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + aspectRatio: naturalWidth / naturalHeight + }); + + _this2.loaded = true; + _this2.build(); + }); + } + }, { + key: 'stop', + value: function stop() { + this.$clone.remove(); + this.$clone = 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, + $clone = this.$clone; + + var $cropper = $(TEMPLATE); + var $cropBox = $cropper.find('.' + NAMESPACE + '-crop-box'); + var $face = $cropBox.find('.' + NAMESPACE + '-face'); + + // Create cropper elements + this.$container = $element.parent(); + this.$cropper = $cropper; + this.$canvas = $cropper.find('.' + NAMESPACE + '-canvas').append($clone); + this.$dragBox = $cropper.find('.' + NAMESPACE + '-drag-box'); + this.$cropBox = $cropBox; + this.$viewBox = $cropper.find('.' + NAMESPACE + '-view-box'); + this.$face = $face; + + // Hide the original image + $element.addClass(CLASS_HIDDEN).after($cropper); + + // Show the clone image if is hidden + if (!this.isImg) { + $clone.removeClass(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) { + this.$dragBox.addClass(CLASS_MODAL); + } + } else { + $cropBox.addClass(CLASS_HIDDEN); + } + + if (!options.guides) { + $cropBox.find('.' + NAMESPACE + '-dashed').addClass(CLASS_HIDDEN); + } + + if (!options.center) { + $cropBox.find('.' + NAMESPACE + '-center').addClass(CLASS_HIDDEN); + } + + if (options.cropBoxMovable) { + $face.addClass(CLASS_MOVE).data(DATA_ACTION, ACTION_ALL); + } + + if (!options.highlight) { + $face.addClass(CLASS_INVISIBLE); + } + + if (options.background) { + $cropper.addClass(NAMESPACE + '-bg'); + } + + if (!options.cropBoxResizable) { + $cropBox.find('.' + NAMESPACE + '-line,.' + NAMESPACE + '-point').addClass(CLASS_HIDDEN); + } + + this.setDragMode(options.dragMode); + this.render(); + this.ready = true; + this.setData(options.data); + + // Trigger the ready event asynchronously to keep `data('cropper')` is defined + this.completing = setTimeout(function () { + if ($.isFunction(options.ready)) { + $element.one(EVENT_READY, options.ready); + } + + _this3.trigger(EVENT_READY); + _this3.trigger(EVENT_CROP, _this3.getData()); + _this3.completed = true; + }, 0); + } + }, { + key: 'unbuild', + value: function unbuild() { + if (!this.ready) { + return; + } + + if (!this.completed) { + clearTimeout(this.completing); + } + + this.ready = false; + this.completed = false; + this.initialImage = null; + + // Clear `initialCanvas` is necessary when replace + this.initialCanvas = null; + this.initialCropBox = null; + this.container = null; + this.canvas = null; + + // Clear `cropBox` is necessary when replace + this.cropBox = null; + this.unbind(); + + this.resetPreview(); + this.$preview = null; + + this.$viewBox = null; + this.$cropBox = null; + this.$dragBox = null; + this.$canvas = null; + this.$container = null; + + this.$cropper.remove(); + this.$cropper = null; + } + + /** + * Change the default options. + * @param {Object} options - The new default options. + */ + + }], [{ + key: 'setDefaults', + value: function setDefaults(options) { + $.extend(DEFAULTS, $.isPlainObject(options) && options); + } + }]); + return Cropper; +}(); + +if ($.extend) { + $.extend(Cropper.prototype, render, preview, events, handlers, change, methods); +} + +if ($.fn) { + var AnotherCropper = $.fn.cropper; + + $.fn.cropper = function jQueryCropper(option) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + var result = void 0; + + this.each(function (i, element) { + var $element = $(element); + var data = $element.data(NAMESPACE); + + if (!data) { + if (/destroy/.test(option)) { + return; + } + + var options = $.extend({}, $element.data(), $.isPlainObject(option) && option); + + data = new Cropper(element, options); + $element.data(NAMESPACE, data); + } + + if (isString(option)) { + var fn = data[option]; + + if ($.isFunction(fn)) { + result = fn.apply(data, args); + } + } + }); + + return isUndefined(result) ? this : result; + }; + + $.fn.cropper.Constructor = Cropper; + $.fn.cropper.setDefaults = Cropper.setDefaults; + $.fn.cropper.noConflict = function noConflict() { + $.fn.cropper = AnotherCropper; + return this; + }; +} + +}))); diff --git a/docs/v3.1.6/js/main.js b/docs/v3.1.6/js/main.js new file mode 100644 index 00000000..f384f785 --- /dev/null +++ b/docs/v3.1.6/js/main.js @@ -0,0 +1,275 @@ +$(function () { + + 'use strict'; + + var console = window.console || { log: function () {} }; + var URL = window.URL || window.webkitURL; + var $image = $('#image'); + var $download = $('#download'); + var $dataX = $('#dataX'); + var $dataY = $('#dataY'); + var $dataHeight = $('#dataHeight'); + var $dataWidth = $('#dataWidth'); + var $dataRotate = $('#dataRotate'); + var $dataScaleX = $('#dataScaleX'); + var $dataScaleY = $('#dataScaleY'); + var options = { + aspectRatio: 16 / 9, + preview: '.img-preview', + crop: function (e) { + $dataX.val(Math.round(e.x)); + $dataY.val(Math.round(e.y)); + $dataHeight.val(Math.round(e.height)); + $dataWidth.val(Math.round(e.width)); + $dataRotate.val(e.rotate); + $dataScaleX.val(e.scaleX); + $dataScaleY.val(e.scaleY); + } + }; + var originalImageURL = $image.attr('src'); + var uploadedImageName = 'cropped.jpg'; + var uploadedImageType = 'image/jpeg'; + var uploadedImageURL; + + + // Tooltip + $('[data-toggle="tooltip"]').tooltip(); + + + // Cropper + $image.on({ + ready: function (e) { + console.log(e.type); + }, + cropstart: function (e) { + console.log(e.type, e.action); + }, + cropmove: function (e) { + console.log(e.type, e.action); + }, + cropend: function (e) { + console.log(e.type, e.action); + }, + crop: function (e) { + console.log(e.type, e.x, e.y, e.width, e.height, e.rotate, e.scaleX, e.scaleY); + }, + zoom: function (e) { + console.log(e.type, e.ratio); + } + }).cropper(options); + + + // Buttons + if (!$.isFunction(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[0].download === 'undefined') { + $download.addClass('disabled'); + } + + + // Options + $('.docs-toggles').on('change', 'input', function () { + var $this = $(this); + var name = $this.attr('name'); + var type = $this.prop('type'); + var cropBoxData; + var canvasData; + + if (!$image.data('cropper')) { + return; + } + + if (type === 'checkbox') { + options[name] = $this.prop('checked'); + cropBoxData = $image.cropper('getCropBoxData'); + canvasData = $image.cropper('getCanvasData'); + + options.ready = function () { + $image.cropper('setCropBoxData', cropBoxData); + $image.cropper('setCanvasData', canvasData); + }; + } else if (type === 'radio') { + options[name] = $this.val(); + } + + $image.cropper('destroy').cropper(options); + }); + + + // Methods + $('.docs-buttons').on('click', '[data-method]', function () { + var $this = $(this); + var data = $this.data(); + var cropper = $image.data('cropper'); + var cropped; + var $target; + var result; + + if ($this.prop('disabled') || $this.hasClass('disabled')) { + return; + } + + if (cropper && data.method) { + data = $.extend({}, data); // Clone a new one + + if (typeof data.target !== 'undefined') { + $target = $(data.target); + + if (typeof data.option === 'undefined') { + try { + data.option = JSON.parse($target.val()); + } catch (e) { + console.log(e.message); + } + } + } + + cropped = cropper.cropped; + + switch (data.method) { + case 'rotate': + if (cropped && options.viewMode > 0) { + $image.cropper('clear'); + } + + break; + + case 'getCroppedCanvas': + if (uploadedImageType === 'image/jpeg') { + if (!data.option) { + data.option = {}; + } + + data.option.fillColor = '#fff'; + } + + break; + } + + result = $image.cropper(data.method, data.option, data.secondOption); + + switch (data.method) { + case 'rotate': + if (cropped && options.viewMode > 0) { + $image.cropper('crop'); + } + + break; + + case 'scaleX': + case 'scaleY': + $(this).data('option', -data.option); + break; + + case 'getCroppedCanvas': + if (result) { + // Bootstrap's Modal + $('#getCroppedCanvasModal').modal().find('.modal-body').html(result); + + if (!$download.hasClass('disabled')) { + download.download = uploadedImageName; + $download.attr('href', result.toDataURL(uploadedImageType)); + } + } + + break; + + case 'destroy': + if (uploadedImageURL) { + URL.revokeObjectURL(uploadedImageURL); + uploadedImageURL = ''; + $image.attr('src', originalImageURL); + } + + break; + } + + if ($.isPlainObject(result) && $target) { + try { + $target.val(JSON.stringify(result)); + } catch (e) { + console.log(e.message); + } + } + + } + }); + + + // Keyboard + $(document.body).on('keydown', function (e) { + + if (!$image.data('cropper') || this.scrollTop > 300) { + return; + } + + switch (e.which) { + case 37: + e.preventDefault(); + $image.cropper('move', -1, 0); + break; + + case 38: + e.preventDefault(); + $image.cropper('move', 0, -1); + break; + + case 39: + e.preventDefault(); + $image.cropper('move', 1, 0); + break; + + case 40: + e.preventDefault(); + $image.cropper('move', 0, 1); + break; + } + + }); + + + // Import image + var $inputImage = $('#inputImage'); + + if (URL) { + $inputImage.change(function () { + var files = this.files; + var file; + + if (!$image.data('cropper')) { + return; + } + + if (files && files.length) { + file = files[0]; + + if (/^image\/\w+$/.test(file.type)) { + uploadedImageName = file.name; + uploadedImageType = file.type; + + if (uploadedImageURL) { + URL.revokeObjectURL(uploadedImageURL); + } + + uploadedImageURL = URL.createObjectURL(file); + $image.cropper('destroy').attr('src', uploadedImageURL).cropper(options); + $inputImage.val(''); + } else { + window.alert('Please choose an image file.'); + } + } + }); + } else { + $inputImage.prop('disabled', true).parent().addClass('disabled'); + } + +}); diff --git a/package-lock.json b/package-lock.json index db0573fe..6462ebf2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,23 +1,217 @@ { "name": "cropper", - "version": "3.1.6", + "version": "4.0.0-alpha", "lockfileVersion": 1, "requires": true, "dependencies": { + "@commitlint/cli": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-6.1.2.tgz", + "integrity": "sha1-3Ex1B6st7pKoIel1NVbxrB4mGIM=", + "dev": true, + "requires": { + "@commitlint/format": "6.1.2", + "@commitlint/lint": "6.1.2", + "@commitlint/load": "6.1.2", + "@commitlint/read": "6.1.2", + "babel-polyfill": "6.26.0", + "chalk": "2.3.1", + "get-stdin": "5.0.1", + "lodash.merge": "4.6.1", + "lodash.pick": "4.4.0", + "meow": "3.7.0" + } + }, + "@commitlint/config-angular": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/config-angular/-/config-angular-6.1.2.tgz", + "integrity": "sha1-k0Xo43shSQCqj+DQq8yRy4rgKJQ=", + "dev": true, + "requires": { + "@commitlint/config-angular-type-enum": "6.1.2" + } + }, + "@commitlint/config-angular-type-enum": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/config-angular-type-enum/-/config-angular-type-enum-6.1.2.tgz", + "integrity": "sha1-z0K9qwwEbIDNM5DM5jPeked9MBw=", + "dev": true + }, + "@commitlint/ensure": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-6.1.2.tgz", + "integrity": "sha1-wnpp4hPPvkcCMmH0FpVZwVQ3jFE=", + "dev": true, + "requires": { + "lodash.camelcase": "4.3.0", + "lodash.kebabcase": "4.1.1", + "lodash.snakecase": "4.1.1", + "lodash.startcase": "4.4.0", + "lodash.upperfirst": "4.3.1" + } + }, + "@commitlint/execute-rule": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-6.1.2.tgz", + "integrity": "sha1-74x+4Qcm+GMhHUlL6OTq8AGg4lg=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "@commitlint/format": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-6.1.2.tgz", + "integrity": "sha1-9G+pb4dDacFmtCDj7Vn3RcO7PUk=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "chalk": "2.3.1" + } + }, + "@commitlint/is-ignored": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-6.1.2.tgz", + "integrity": "sha1-JU1bq0gII63PT6lFyuHqjVMyYuE=", + "dev": true, + "requires": { + "semver": "5.5.0" + } + }, + "@commitlint/lint": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-6.1.2.tgz", + "integrity": "sha1-p8W8BR6wU51Bkk+wwRrxO/4YbLI=", + "dev": true, + "requires": { + "@commitlint/is-ignored": "6.1.2", + "@commitlint/parse": "6.1.2", + "@commitlint/rules": "6.1.2", + "babel-runtime": "6.26.0", + "lodash.topairs": "4.3.0" + } + }, + "@commitlint/load": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-6.1.2.tgz", + "integrity": "sha1-INFtL9cr09HtaiK3I0sf1VyV+9w=", + "dev": true, + "requires": { + "@commitlint/execute-rule": "6.1.2", + "@commitlint/resolve-extends": "6.1.2", + "babel-runtime": "6.26.0", + "cosmiconfig": "4.0.0", + "lodash.merge": "4.6.1", + "lodash.mergewith": "4.6.1", + "lodash.pick": "4.4.0", + "lodash.topairs": "4.3.0", + "resolve-from": "4.0.0" + } + }, + "@commitlint/message": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-6.1.2.tgz", + "integrity": "sha1-fw9xhYuuIxCrRYhq7/P4rkhIPCE=", + "dev": true + }, + "@commitlint/parse": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-6.1.2.tgz", + "integrity": "sha1-kgyCpBrCiwFp8aXUrUEVzv2pYgU=", + "dev": true, + "requires": { + "conventional-changelog-angular": "1.6.6", + "conventional-commits-parser": "2.1.5" + } + }, + "@commitlint/read": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-6.1.2.tgz", + "integrity": "sha1-bznWLMEgwTnQdewgXtHb/GgfFz8=", + "dev": true, + "requires": { + "@commitlint/top-level": "6.1.2", + "@marionebl/sander": "0.6.1", + "babel-runtime": "6.26.0", + "git-raw-commits": "1.3.4" + } + }, + "@commitlint/resolve-extends": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-6.1.2.tgz", + "integrity": "sha1-tItxlSQ9yTgbzzQcL8trHoA9qLQ=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "lodash.merge": "4.6.1", + "lodash.omit": "4.5.0", + "require-uncached": "1.0.3", + "resolve-from": "4.0.0", + "resolve-global": "0.1.0" + } + }, + "@commitlint/rules": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-6.1.2.tgz", + "integrity": "sha1-LO/6e/adH+MnvLF496cb1OCU41U=", + "dev": true, + "requires": { + "@commitlint/ensure": "6.1.2", + "@commitlint/message": "6.1.2", + "@commitlint/to-lines": "6.1.2", + "babel-runtime": "6.26.0" + } + }, + "@commitlint/to-lines": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-6.1.2.tgz", + "integrity": "sha1-AdAnL+mKUw5lOO+TT5cK6uP6SYw=", + "dev": true + }, + "@commitlint/top-level": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-6.1.2.tgz", + "integrity": "sha1-KAwXmvxRfSpYwceapQGe3/pdRD0=", + "dev": true, + "requires": { + "find-up": "2.1.0" + } + }, + "@marionebl/sander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@marionebl/sander/-/sander-0.6.1.tgz", + "integrity": "sha1-GViWWHTyS8Ub5Ih1/rUNZC/EH3s=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, "JSONStream": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-0.8.4.tgz", - "integrity": "sha1-kWV9/m/4V0gwZhMrRhi2Lo9Ih70=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", "dev": true, "requires": { - "jsonparse": "0.0.5", + "jsonparse": "1.3.1", "through": "2.3.8" } }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "dev": true, + "requires": { + "mime-types": "2.1.18", + "negotiator": "0.6.1" + } + }, "acorn": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.4.1.tgz", - "integrity": "sha512-XLmq3H/BVvW6/GbxKryGxWORz1ebilSsUDlyC27bXhWGWAZWkGwS6FLHjOlwFXNFoWFQEO/Df4u0YYd0K3BQgQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.0.tgz", + "integrity": "sha512-arn53F07VXmls4o4pUhSzBa4fvaagPRe7AVZ8l7NHxFWUie2DsuFSBMMNAkgzRlOhEhzAnxeKyaWVzOH4xqp/g==", "dev": true }, "acorn-jsx": { @@ -37,22 +231,63 @@ } } }, + "acorn-node": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.3.0.tgz", + "integrity": "sha512-efP54n3d1aLfjL2UMdaXa6DsswwzJeI5rqhbFvXMrKiJ6eJFpf+7R0zN7t8IC+XKn2YOAFAv6xbBNgHUkoHWLw==", + "dev": true, + "requires": { + "acorn": "5.5.0", + "xtend": "4.0.1" + } + }, + "addressparser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", + "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=", + "dev": true, + "optional": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "agent-base": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", + "dev": true, + "requires": { + "extend": "3.0.1", + "semver": "5.0.3" + }, + "dependencies": { + "semver": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", + "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", + "dev": true + } + } + }, "ajv": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz", - "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=", + "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", - "json-schema-traverse": "0.3.1", - "json-stable-stringify": "1.0.1" + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "ajv-keywords": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz", - "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz", + "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=", "dev": true }, "alphanum-sort": { @@ -67,6 +302,49 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "amqplib": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", + "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", + "dev": true, + "optional": true, + "requires": { + "bitsyntax": "0.0.4", + "bluebird": "3.5.1", + "buffer-more-ints": "0.0.2", + "readable-stream": "1.1.14", + "safe-buffer": "5.1.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, + "optional": 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, + "optional": 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, + "optional": true + } + } + }, "ansi-align": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", @@ -89,10 +367,13 @@ "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 + "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.1" + } }, "anymatch": { "version": "1.3.2", @@ -102,12 +383,23 @@ "requires": { "micromatch": "2.3.11", "normalize-path": "2.1.1" + }, + "dependencies": { + "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" + } + } } }, "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "1.0.3" @@ -152,6 +444,12 @@ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "dev": true + }, "array-map": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", @@ -164,6 +462,12 @@ "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", "dev": true }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -185,6 +489,12 @@ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", "dev": true }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -195,7 +505,28 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true + "dev": true, + "optional": true + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } }, "assert-plus": { "version": "1.0.0", @@ -203,23 +534,70 @@ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "ast-types": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.2.tgz", + "integrity": "sha512-aL+pcOQ+6dpWd0xrUe+Obo2CgdkFvsntkXEmzZKqEN4cR0PStF+1MBuc4V+YZsv4Q36luvyjG7F4lc+wH2bmag==", + "dev": true, + "optional": true + }, + "astw": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz", + "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", + "dev": true, + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, + "async": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz", + "integrity": "sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw=", + "dev": true, + "optional": true, + "requires": { + "lodash": "4.17.5" + } + }, "async-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", "dev": true }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "dev": true, + "optional": true }, "atob": { "version": "2.0.3", @@ -234,7 +612,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000744", + "caniuse-db": "1.0.30000810", "normalize-range": "0.1.2", "num2fraction": "1.2.2", "postcss": "5.2.18", @@ -247,8 +625,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000744", - "electron-to-chromium": "1.3.24" + "caniuse-db": "1.0.30000810", + "electron-to-chromium": "1.3.34" } } } @@ -257,13 +635,25 @@ "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 + "dev": true, + "optional": true }, "aws4": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", - "dev": true + "dev": true, + "optional": true + }, + "axios": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz", + "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=", + "dev": true, + "optional": true, + "requires": { + "follow-redirects": "1.0.0" + } }, "babel-code-frame": { "version": "6.26.0", @@ -274,6 +664,33 @@ "chalk": "1.1.3", "esutils": "2.0.2", "js-tokens": "3.0.2" + }, + "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 + } } }, "babel-core": { @@ -283,7 +700,7 @@ "dev": true, "requires": { "babel-code-frame": "6.26.0", - "babel-generator": "6.26.0", + "babel-generator": "6.26.1", "babel-helpers": "6.24.1", "babel-messages": "6.23.0", "babel-register": "6.26.0", @@ -292,21 +709,21 @@ "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", - "convert-source-map": "1.5.0", + "convert-source-map": "1.5.1", "debug": "2.6.9", "json5": "0.5.1", - "lodash": "4.17.4", + "lodash": "4.17.5", "minimatch": "3.0.4", "path-is-absolute": "1.0.1", - "private": "0.1.7", + "private": "0.1.8", "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=", + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "dev": true, "requires": { "babel-messages": "6.23.0", @@ -314,7 +731,7 @@ "babel-types": "6.26.0", "detect-indent": "4.0.0", "jsesc": "1.3.0", - "lodash": "4.17.4", + "lodash": "4.17.5", "source-map": "0.5.7", "trim-right": "1.0.1" } @@ -351,7 +768,7 @@ "babel-helper-function-name": "6.24.1", "babel-runtime": "6.26.0", "babel-types": "6.26.0", - "lodash": "4.17.4" + "lodash": "4.17.5" } }, "babel-helper-explode-assignable-expression": { @@ -416,7 +833,7 @@ "requires": { "babel-runtime": "6.26.0", "babel-types": "6.26.0", - "lodash": "4.17.4" + "lodash": "4.17.5" } }, "babel-helper-remap-async-to-generator": { @@ -540,7 +957,7 @@ "babel-template": "6.26.0", "babel-traverse": "6.26.0", "babel-types": "6.26.0", - "lodash": "4.17.4" + "lodash": "4.17.5" } }, "babel-plugin-transform-es2015-classes": { @@ -776,6 +1193,25 @@ "babel-types": "6.26.0" } }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "core-js": "2.5.3", + "regenerator-runtime": "0.10.5" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true + } + } + }, "babel-preset-env": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", @@ -809,9 +1245,9 @@ "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" + "browserslist": "2.11.3", + "invariant": "2.2.3", + "semver": "5.5.0" } }, "babel-register": { @@ -822,9 +1258,9 @@ "requires": { "babel-core": "6.26.0", "babel-runtime": "6.26.0", - "core-js": "2.5.1", + "core-js": "2.5.3", "home-or-tmp": "2.0.0", - "lodash": "4.17.4", + "lodash": "4.17.5", "mkdirp": "0.5.1", "source-map-support": "0.4.18" } @@ -835,8 +1271,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.1", - "regenerator-runtime": "0.11.0" + "core-js": "2.5.3", + "regenerator-runtime": "0.11.1" } }, "babel-template": { @@ -849,7 +1285,7 @@ "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", - "lodash": "4.17.4" + "lodash": "4.17.5" } }, "babel-traverse": { @@ -865,8 +1301,8 @@ "babylon": "6.18.0", "debug": "2.6.9", "globals": "9.18.0", - "invariant": "2.2.2", - "lodash": "4.17.4" + "invariant": "2.2.3", + "lodash": "4.17.5" } }, "babel-types": { @@ -877,7 +1313,7 @@ "requires": { "babel-runtime": "6.26.0", "esutils": "2.0.2", - "lodash": "4.17.4", + "lodash": "4.17.5", "to-fast-properties": "1.0.3" } }, @@ -887,6 +1323,12 @@ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "dev": true }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -925,20 +1367,104 @@ } } }, - "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, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64-js": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", + "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "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" } }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, "binary-extensions": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", - "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "bitsyntax": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz", + "integrity": "sha1-6xDMb4K4xJDj6FaY8H6D1G4MuoI=", + "dev": true, + "optional": true, + "requires": { + "buffer-more-ints": "0.0.2" + } + }, + "bl": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", + "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", + "dev": true, + "optional": true, + "requires": { + "readable-stream": "2.0.6" + }, + "dependencies": { + "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, + "optional": true + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "optional": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "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, + "optional": true + } + } + }, + "blob": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", "dev": true }, "bluebird": { @@ -947,77 +1473,59 @@ "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", "dev": true }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.2", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.16" + } + }, "boom": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "dev": true, + "optional": true, "requires": { - "hoek": "4.2.0" + "hoek": "4.2.1" } }, "boxen": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.2.2.tgz", - "integrity": "sha1-Px1AMsMP/qnUsCwyLq8up0HcvOU=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", "dev": true, "requires": { "ansi-align": "2.0.0", "camelcase": "4.1.0", - "chalk": "2.3.0", + "chalk": "2.3.1", "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" - } - } + "widest-line": "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=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "1.0.0", @@ -1035,14 +1543,261 @@ "repeat-element": "1.1.2" } }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.4.tgz", + "integrity": "sha512-Q4Rvn7P6ObyWfc4stqLWHtG1MJ8vVtjgT24Zbu+8UTzxYuZouqZsmNRRTFVMY/Ux0eIKv1d+JWzsInTX+fdHPQ==", + "dev": true, + "requires": { + "JSONStream": "1.3.2", + "combine-source-map": "0.8.0", + "defined": "1.0.0", + "safe-buffer": "5.1.1", + "through2": "2.0.3", + "umd": "3.0.1" + } + }, + "browser-resolve": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", + "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "browserify": { + "version": "14.5.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-14.5.0.tgz", + "integrity": "sha512-gKfOsNQv/toWz+60nSPfYzuwSEdzvV2WdxrVPUbPD/qui44rAkB3t3muNtmmGYHqrG56FGwX9SUEQmzNLAeS7g==", + "dev": true, + "requires": { + "JSONStream": "1.3.2", + "assert": "1.4.1", + "browser-pack": "6.0.4", + "browser-resolve": "1.11.2", + "browserify-zlib": "0.2.0", + "buffer": "5.1.0", + "cached-path-relative": "1.0.1", + "concat-stream": "1.5.2", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "defined": "1.0.0", + "deps-sort": "2.0.0", + "domain-browser": "1.1.7", + "duplexer2": "0.1.4", + "events": "1.1.1", + "glob": "7.1.2", + "has": "1.0.1", + "htmlescape": "1.1.1", + "https-browserify": "1.0.0", + "inherits": "2.0.3", + "insert-module-globals": "7.0.2", + "labeled-stream-splicer": "2.0.0", + "module-deps": "4.1.1", + "os-browserify": "0.3.0", + "parents": "1.0.1", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "read-only-stream": "2.0.0", + "readable-stream": "2.3.4", + "resolve": "1.5.0", + "shasum": "1.0.2", + "shell-quote": "1.6.1", + "stream-browserify": "2.0.1", + "stream-http": "2.8.0", + "string_decoder": "1.0.3", + "subarg": "1.0.0", + "syntax-error": "1.4.0", + "through2": "2.0.3", + "timers-browserify": "1.4.2", + "tty-browserify": "0.0.1", + "url": "0.11.0", + "util": "0.10.3", + "vm-browserify": "0.0.4", + "xtend": "4.0.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.0.6", + "typedarray": "0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "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 + } + } + }, + "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 + } + } + }, + "browserify-aes": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "dev": true, + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "dev": true, + "requires": { + "browserify-aes": "1.1.1", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.3" + } + }, + "browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "randombytes": "2.0.6" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "1.0.6" + } + }, "browserslist": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.5.0.tgz", - "integrity": "sha512-6Vw1LIigGw8zCK0gxczksUMZlO+oPUwBazAztMmFL/F8D5wB0qCuxRJGYgYM3JzaO0v2ZMRIg+nnnOgNsPGHeA==", + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", + "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", + "dev": true, + "requires": { + "caniuse-lite": "1.0.30000810", + "electron-to-chromium": "1.3.34" + } + }, + "buffer": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", + "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", + "dev": true, + "requires": { + "base64-js": "1.2.3", + "ieee754": "1.1.8" + } + }, + "buffer-more-ints": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz", + "integrity": "sha1-JrOIXRD6E9t/wBquOquHAZngEkw=", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "buildmail": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-4.0.1.tgz", + "integrity": "sha1-h393OLeHKYccmhBeO4N9K+EaenI=", "dev": true, + "optional": true, "requires": { - "caniuse-lite": "1.0.30000744", - "electron-to-chromium": "1.3.24" + "addressparser": "1.0.1", + "libbase64": "0.1.0", + "libmime": "3.0.0", + "libqp": "1.1.0", + "nodemailer-fetch": "1.6.0", + "nodemailer-shared": "1.1.0", + "punycode": "1.4.1" } }, "builtin-modules": { @@ -1051,6 +1806,18 @@ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -1076,6 +1843,12 @@ } } }, + "cached-path-relative": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", + "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", + "dev": true + }, "caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", @@ -1085,6 +1858,12 @@ "callsites": "0.2.0" } }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, "callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", @@ -1092,19 +1871,20 @@ "dev": true }, "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "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=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", "dev": true, "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" + "camelcase": "4.1.0", + "map-obj": "2.0.0", + "quick-lru": "1.1.0" } }, "caniuse-api": { @@ -1114,7 +1894,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000744", + "caniuse-db": "1.0.30000810", "lodash.memoize": "4.1.2", "lodash.uniq": "4.5.0" }, @@ -1125,22 +1905,22 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000744", - "electron-to-chromium": "1.3.24" + "caniuse-db": "1.0.30000810", + "electron-to-chromium": "1.3.34" } } } }, "caniuse-db": { - "version": "1.0.30000744", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000744.tgz", - "integrity": "sha1-AHWP991fcTjTShVgjcz3Glllb/4=", + "version": "1.0.30000810", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000810.tgz", + "integrity": "sha1-vSWDDEHvq2Qzmi44H0lnc0PIRQk=", "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=", + "version": "1.0.30000810", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000810.tgz", + "integrity": "sha512-/0Q00Oie9C72P8zQHtFvzmkrMC3oOFUnMWjCy5F2+BE8lzICm91hQPhh0+XIsAFPKOe2Dh3pKgbRmU3EKxfldA==", "dev": true }, "capture-stack-trace": { @@ -1153,19 +1933,32 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "dev": true, + "optional": true + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "1.1.0", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.8" + } }, "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", + "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", "dev": true, "requires": { - "ansi-styles": "2.2.1", + "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "supports-color": "5.2.0" } }, "chardet": { @@ -1174,6 +1967,12 @@ "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", "dev": true }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, "chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", @@ -1191,6 +1990,22 @@ "readdirp": "2.1.0" } }, + "ci-info": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz", + "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", @@ -1204,11 +2019,38 @@ "dev": true, "requires": { "chalk": "1.1.3" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + }, + "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 + } + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { @@ -1242,7 +2084,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -1262,7 +2104,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -1314,42 +2156,37 @@ "dev": true }, "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz", + "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", "dev": true, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", "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" - } + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "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": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "ansi-regex": "3.0.0" } } } }, "clone": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", - "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", + "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", "dev": true }, "clone-regexp": { @@ -1374,7 +2211,7 @@ "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", "dev": true, "requires": { - "q": "1.5.0" + "q": "1.5.1" } }, "code-point-at": { @@ -1399,15 +2236,15 @@ "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", "dev": true, "requires": { - "clone": "1.0.2", - "color-convert": "1.9.0", + "clone": "1.0.3", + "color-convert": "1.9.1", "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=", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", "dev": true, "requires": { "color-name": "1.1.3" @@ -1435,9 +2272,9 @@ } }, "colorguard": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/colorguard/-/colorguard-1.2.0.tgz", - "integrity": "sha1-8/rK9cquuk71RlPZ+yW7cxd8DYQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colorguard/-/colorguard-1.2.1.tgz", + "integrity": "sha512-qYVKTg626qpDg4/eBnPXidEPXn5+krbYqHVfyyEFBWV5z3IF4p44HKY/eE2t1ohlcrlIkDgHmFJMfQ8qMLnSFw==", "dev": true, "requires": { "chalk": "1.1.3", @@ -1452,6 +2289,34 @@ "yargs": "1.3.3" }, "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" + } + }, + "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" + } + }, "postcss-reporter": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-1.4.1.tgz", @@ -1459,11 +2324,17 @@ "dev": true, "requires": { "chalk": "1.1.3", - "lodash": "4.17.4", + "lodash": "4.17.5", "log-symbols": "1.0.2", "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 + }, "yargs": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.3.3.tgz", @@ -1489,19 +2360,70 @@ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true }, + "combine-lists": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", + "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", + "dev": true, + "requires": { + "lodash": "4.17.5" + } + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "1.1.3", + "inline-source-map": "0.6.2", + "lodash.memoize": "3.0.4", + "source-map": "0.5.7" + }, + "dependencies": { + "convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "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=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "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==", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", + "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==", + "dev": true + }, + "compare-func": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", + "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", + "dev": true, + "requires": { + "array-ify": "1.0.0", + "dot-prop": "3.0.0" + } + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", "dev": true }, "component-emitter": { @@ -1510,6 +2432,12 @@ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", "dev": true }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1523,7 +2451,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.4", "typedarray": "0.0.6" } }, @@ -1535,22 +2463,116 @@ "requires": { "dot-prop": "4.2.0", "graceful-fs": "4.1.11", - "make-dir": "1.1.0", + "make-dir": "1.2.0", "unique-string": "1.0.0", "write-file-atomic": "2.3.0", "xdg-basedir": "3.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "connect": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.0", + "parseurl": "1.3.2", + "utils-merge": "1.0.1" + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "0.1.4" } }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", "dev": true }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "conventional-changelog-angular": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz", + "integrity": "sha512-suQnFSqCxRwyBxY68pYTsFkG0taIdinHLNEAX5ivtw8bCRnIgnpvcHmlR/yjUyZIrNPYAoXlY1WiEKWgSE4BNg==", + "dev": true, + "requires": { + "compare-func": "1.3.2", + "q": "1.5.1" + } + }, + "conventional-commits-parser": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.5.tgz", + "integrity": "sha512-jaAP61py+ISMF3/n3yIiIuY5h6mJlucOqawu5mLB1HaQADLvg/y5UB3pT7HSucZJan34lp7+7ylQPfbKEGmxrA==", + "dev": true, + "requires": { + "JSONStream": "1.3.2", + "is-text-path": "1.0.1", + "lodash": "4.17.5", + "meow": "4.0.0", + "split2": "2.2.0", + "through2": "2.0.3", + "trim-off-newlines": "1.0.1" + }, + "dependencies": { + "meow": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.0.tgz", + "integrity": "sha512-Me/kel335m6vMKmEmA6c87Z6DUFW3JqkINRnxkbC+A/PUm0D5Fl2dEBQrPKnqCL9Te/CIa1MUt/0InMJhuC/sw==", + "dev": true, + "requires": { + "camelcase-keys": "4.2.0", + "decamelize-keys": "1.1.0", + "loud-rejection": "1.6.0", + "minimist": "1.2.0", + "minimist-options": "3.0.2", + "normalize-package-data": "2.4.0", + "read-pkg-up": "3.0.0", + "redent": "2.0.0", + "trim-newlines": "2.0.0" + } + } + } + }, "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=", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", "dev": true }, "copy-descriptor": { @@ -1560,9 +2582,9 @@ "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=", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", + "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=", "dev": true }, "core-util-is": { @@ -1572,26 +2594,15 @@ "dev": true }, "cosmiconfig": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", - "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", + "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", "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 - } + "js-yaml": "3.10.0", + "parse-json": "4.0.0", + "require-from-string": "2.0.1" } }, "cp-file": { @@ -1606,7 +2617,15 @@ "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1", - "readable-stream": "2.3.3" + "readable-stream": "2.3.4" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "cpy": { @@ -1633,6 +2652,16 @@ "meow": "3.7.0" } }, + "create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "elliptic": "6.4.0" + } + }, "create-error-class": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", @@ -1642,6 +2671,38 @@ "capture-stack-trace": "1.0.0" } }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.10" + } + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.10" + } + }, + "cropperjs": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.3.1.tgz", + "integrity": "sha512-ohkKN8W5Bpdu9dedydEoXGkGByBKASQ8FxYN6Iu/7BiWi1YGkaLc51/R0Bfr2KXzeVP8bh6e3SkZLBAAYHuxvw==", + "dev": true + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -1658,6 +2719,7 @@ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", "dev": true, + "optional": true, "requires": { "boom": "5.2.0" }, @@ -1667,12 +2729,32 @@ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", "dev": true, + "optional": true, "requires": { - "hoek": "4.2.0" + "hoek": "4.2.1" } } } }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.14", + "public-encrypt": "4.0.0", + "randombytes": "2.0.6", + "randomfill": "1.0.4" + } + }, "crypto-random-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", @@ -1741,6 +2823,65 @@ "duplexer2": "0.0.2", "ldjson-stream": "1.2.1", "through2": "0.6.5" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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": { + "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" + } + } + } + } } }, "css-tokenize": { @@ -1850,23 +2991,58 @@ "array-find-index": "1.0.2" } }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "dargs": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz", + "integrity": "sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, + "optional": 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==", + "data-uri-to-buffer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", + "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", "dev": true, - "requires": { - "ms": "2.0.0" - } + "optional": true + }, + "date-format": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz", + "integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg=", + "dev": true + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "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", @@ -1874,12 +3050,39 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "1.2.0", + "map-obj": "1.0.1" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, "deep-extend": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", @@ -1926,90 +3129,41 @@ "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=", + "degenerator": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", + "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", "dev": true, + "optional": 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" + "ast-types": "0.11.2", + "escodegen": "1.9.1", + "esprima": "3.1.3" }, "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=", + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "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" - } + "optional": true } } }, - "del-cli": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/del-cli/-/del-cli-1.1.0.tgz", - "integrity": "sha1-J1V9aaC335ncuqHjSgnmrGWR0sQ=", + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", "dev": true, "requires": { - "del": "3.0.0", - "meow": "3.7.0", - "update-notifier": "2.3.0" + "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" }, "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", @@ -2030,27 +3184,60 @@ "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 } } }, + "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" + } + }, "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 }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, "dependency-graph": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.0.tgz", "integrity": "sha512-QzVBbA603vbxF1SMvYmGbE9ZXl+ggb+2SbHvIeOw0w753lgbXC2bZOnCmvG9qr+zlrKK/E0rqtCXOfrRGKH4/Q==", "dev": true }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "1.3.2", + "shasum": "1.0.2", + "subarg": "1.0.0", + "through2": "2.0.3" + } + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, "detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", @@ -2060,12 +3247,39 @@ "repeating": "2.0.1" } }, + "detective": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", + "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", + "dev": true, + "requires": { + "acorn": "5.5.0", + "defined": "1.0.0" + } + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, "diff": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", "dev": true }, + "diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.6" + } + }, "dir-glob": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", @@ -2074,23 +3288,6 @@ "requires": { "arrify": "1.0.1", "path-type": "3.0.0" - }, - "dependencies": { - "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 - } } }, "doctrine": { @@ -2109,12 +3306,12 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000744", + "caniuse-db": "1.0.30000810", "css-rule-stream": "1.1.0", "duplexer2": "0.0.2", "jsonfilter": "1.1.2", "ldjson-stream": "1.2.1", - "lodash": "4.17.4", + "lodash": "4.17.5", "multimatch": "2.1.0", "postcss": "5.2.18", "source-map": "0.4.4", @@ -2128,8 +3325,34 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000744", - "electron-to-chromium": "1.3.24" + "caniuse-db": "1.0.30000810", + "electron-to-chromium": "1.3.34" + } + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "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" + } + }, + "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" } }, "is-fullwidth-code-point": { @@ -2141,6 +3364,12 @@ "number-is-nan": "1.0.1" } }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, "os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", @@ -2150,6 +3379,18 @@ "lcid": "1.0.0" } }, + "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" + } + }, "source-map": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", @@ -2170,6 +3411,36 @@ "strip-ansi": "3.0.1" } }, + "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 + }, + "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": { + "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" + } + } + } + }, "yargs": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", @@ -2187,15 +3458,40 @@ } } }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "1.0.1", + "ent": "2.2.0", + "extend": "3.0.1", + "void-elements": "2.0.1" + } + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true + }, "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==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", "dev": true, "requires": { "is-obj": "1.0.1" } }, + "double-ended-queue": { + "version": "2.1.0-0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=", + "dev": true, + "optional": true + }, "duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", @@ -2203,38 +3499,12 @@ "dev": true }, "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "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 - } + "readable-stream": "2.3.4" } }, "duplexer3": { @@ -2260,9 +3530,9 @@ "dev": true, "requires": { "bluebird": "3.5.1", - "commander": "2.11.0", + "commander": "2.14.1", "lru-cache": "3.2.0", - "semver": "5.4.1", + "semver": "5.5.0", "sigmund": "1.0.1" }, "dependencies": { @@ -2277,10 +3547,112 @@ } } }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, "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=", + "version": "1.3.34", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz", + "integrity": "sha1-2TSY9AORuwwWpgPYJBuZUUBBV+0=", + "dev": true + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "engine.io": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", + "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", + "dev": true, + "requires": { + "accepts": "1.3.5", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "3.1.0", + "engine.io-parser": "2.1.2", + "uws": "9.14.0", + "ws": "3.3.3" + }, + "dependencies": { + "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" + } + } + } + }, + "engine.io-client": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.5.tgz", + "integrity": "sha512-Rv9vgb83zrNVhRircUXHi4mtbJhgy2oWtJOCZEbCLFs2HiDSWmh/aOEj8TwoKsn8zXGqTuQuPSoU4v3E10bR6A==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "3.1.0", + "engine.io-parser": "2.1.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "3.3.3", + "xmlhttprequest-ssl": "1.5.5", + "yeast": "0.1.2" + }, + "dependencies": { + "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" + } + } + } + }, + "engine.io-parser": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", + "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.4", + "has-binary2": "1.0.2" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", "dev": true }, "error-ex": { @@ -2293,9 +3665,9 @@ } }, "es-abstract": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.9.0.tgz", - "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", "dev": true, "requires": { "es-to-primitive": "1.1.1", @@ -2317,9 +3689,24 @@ } }, "es6-promise": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.2.tgz", - "integrity": "sha512-LSas5vsuA6Q4nEdf9wokY5/AJYXry98i0IzXsv49rYsgDGDNDPbqAYR1Pe23iFxygfbGZNR/5VrHXBCh2BhvUQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "4.2.4" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, "escape-string-regexp": { @@ -2328,6 +3715,36 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "escodegen": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", + "dev": true, + "optional": true, + "requires": { + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.6.1" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true, + "optional": 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, + "optional": true + } + } + }, "eslint": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.1.tgz", @@ -2350,14 +3767,14 @@ "functional-red-black-tree": "1.0.1", "glob": "7.1.2", "globals": "11.3.0", - "ignore": "3.3.5", + "ignore": "3.3.7", "imurmurhash": "0.1.4", "inquirer": "3.3.0", "is-resolvable": "1.1.0", "js-yaml": "3.10.0", "json-stable-stringify-without-jsonify": "1.0.1", "levn": "0.3.0", - "lodash": "4.17.4", + "lodash": "4.17.5", "minimatch": "3.0.4", "mkdirp": "0.5.1", "natural-compare": "1.4.0", @@ -2366,51 +3783,19 @@ "pluralize": "7.0.0", "progress": "2.0.0", "require-uncached": "1.0.3", - "semver": "5.4.1", + "semver": "5.5.0", "strip-ansi": "4.0.0", "strip-json-comments": "2.0.1", - "table": "4.0.2", + "table": "4.0.3", "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -2420,48 +3805,12 @@ "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.3.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.3.0.tgz", "integrity": "sha512-kkpcKNlmQan9Z5ZmgqKH/SMbSmjxQ7QjyNqfXVc8VJcoBV2UEg+sxQD15GQofGRh2hfpwUb70VC31DR7Rq5Hdw==", "dev": true }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "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", @@ -2470,15 +3819,6 @@ "requires": { "ansi-regex": "3.0.0" } - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -2524,7 +3864,7 @@ "eslint-import-resolver-node": "0.3.2", "eslint-module-utils": "2.1.1", "has": "1.0.1", - "lodash": "4.17.4", + "lodash": "4.17.5", "minimatch": "3.0.4", "read-pkg-up": "2.0.0" }, @@ -2539,15 +3879,6 @@ "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", @@ -2560,6 +3891,15 @@ "strip-bom": "3.0.0" } }, + "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-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -2569,6 +3909,12 @@ "pify": "2.3.0" } }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", @@ -2589,12 +3935,6 @@ "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 } } }, @@ -2610,7 +3950,7 @@ "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", "dev": true, "requires": { - "esrecurse": "4.2.0", + "esrecurse": "4.2.1", "estraverse": "4.2.0" } }, @@ -2626,14 +3966,14 @@ "integrity": "sha512-Zy3tAJDORxQZLl2baguiRU1syPERAIg0L+JB2MWorORgTu/CplzvxS9WWA7Xh4+Q+eOQihNs/1o1Xep8cvCxWQ==", "dev": true, "requires": { - "acorn": "5.4.1", + "acorn": "5.5.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=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", "dev": true }, "esquery": { @@ -2646,13 +3986,12 @@ } }, "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" + "estraverse": "4.2.0" } }, "estraverse": { @@ -2688,6 +4027,28 @@ "through": "2.3.8" } }, + "eventemitter3": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", + "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" + } + }, "execa": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", @@ -2712,6 +4073,50 @@ "clone-regexp": "1.0.0" } }, + "expand-braces": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", + "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", + "dev": true, + "requires": { + "array-slice": "0.2.3", + "array-unique": "0.2.1", + "braces": "0.1.5" + }, + "dependencies": { + "braces": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", + "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", + "dev": true, + "requires": { + "expand-range": "0.1.1" + } + }, + "expand-range": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", + "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", + "dev": true, + "requires": { + "is-number": "0.1.1", + "repeat-string": "0.2.2" + } + }, + "is-number": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", + "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", + "dev": true + }, + "repeat-string": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", + "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", + "dev": true + } + } + }, "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", @@ -2789,6 +4194,12 @@ "yauzl": "2.4.1" }, "dependencies": { + "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.0", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", @@ -2807,9 +4218,9 @@ "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=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, "fast-json-stable-stringify": { @@ -2852,6 +4263,13 @@ "object-assign": "4.1.1" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -2871,14 +4289,36 @@ "repeat-string": "1.6.1" } }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" + }, + "dependencies": { + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + } + } + }, "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "locate-path": "2.0.0" } }, "flat-cache": { @@ -2891,6 +4331,43 @@ "del": "2.2.2", "graceful-fs": "4.1.11", "write": "0.2.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "flatten": { @@ -2899,11 +4376,21 @@ "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 + "follow-redirects": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", + "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.9" + } + }, + "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", @@ -2924,17 +4411,19 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "dev": true, + "optional": true }, "form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "dev": true, + "optional": true, "requires": { "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "combined-stream": "1.0.6", + "mime-types": "2.1.18" } }, "fragment-cache": { @@ -2952,15 +4441,24 @@ "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", "dev": true }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "1.0.0" + } + }, "fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", "dev": true, "requires": { "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1" + "jsonfile": "4.0.0", + "universalify": "0.1.1" } }, "fs.realpath": { @@ -3873,6 +5371,46 @@ } } }, + "ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "dev": true, + "optional": true, + "requires": { + "readable-stream": "1.1.14", + "xregexp": "2.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true, + "optional": 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, + "optional": 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, + "optional": true + } + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -3891,16 +5429,39 @@ "integrity": "sha1-szmUr0V6gRVwDUEPMXczy+egkEs=", "dev": true }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true, + "optional": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "optional": true, + "requires": { + "is-property": "1.0.2" + } + }, "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-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "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=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", "dev": true }, "get-stream": { @@ -3909,6 +5470,21 @@ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, + "get-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.1.tgz", + "integrity": "sha512-7aelVrYqCLuVjq2kEKRTH8fXPTC0xKTkM+G7UlFkEwCXY3sFbSxvY375JoFowOAYbkaU47SrBvOefUlLZZ+6QA==", + "dev": true, + "optional": true, + "requires": { + "data-uri-to-buffer": "1.2.0", + "debug": "2.6.9", + "extend": "3.0.1", + "file-uri-to-path": "1.0.0", + "ftp": "0.3.10", + "readable-stream": "2.3.4" + } + }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -3920,16 +5496,50 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, + "optional": true, "requires": { "assert-plus": "1.0.0" } }, + "git-raw-commits": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.4.tgz", + "integrity": "sha512-G3O+41xHbscpgL5nA0DUkbFVgaAz5rd57AMSIMew8p7C8SyFwZDyn08MoXHkTl9zcD0LmxsLFPxbqFY4YPbpPA==", + "dev": true, + "requires": { + "dargs": "4.1.0", + "lodash.template": "4.4.0", + "meow": "4.0.0", + "split2": "2.2.0", + "through2": "2.0.3" + }, + "dependencies": { + "meow": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.0.tgz", + "integrity": "sha512-Me/kel335m6vMKmEmA6c87Z6DUFW3JqkINRnxkbC+A/PUm0D5Fl2dEBQrPKnqCL9Te/CIa1MUt/0InMJhuC/sw==", + "dev": true, + "requires": { + "camelcase-keys": "4.2.0", + "decamelize-keys": "1.1.0", + "loud-rejection": "1.6.0", + "minimist": "1.2.0", + "minimist-options": "3.0.2", + "normalize-package-data": "2.4.0", + "read-pkg-up": "3.0.0", + "redent": "2.0.0", + "trim-newlines": "2.0.0" + } + } + } + }, "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "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", @@ -3957,12 +5567,12 @@ } }, "global-dirs": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.0.tgz", - "integrity": "sha1-ENNAOeDfBCcuJizyQiT3IJQ0308=", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", "dev": true, "requires": { - "ini": "1.3.4" + "ini": "1.3.5" } }, "globals": { @@ -3983,6 +5593,27 @@ "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1" + }, + "dependencies": { + "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" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "globjoin": { @@ -4016,19 +5647,27 @@ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "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 + "dev": true, + "optional": 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, + "optional": true, "requires": { - "ajv": "5.2.3", + "ajv": "5.5.2", "har-schema": "2.0.0" } }, @@ -4050,10 +5689,33 @@ "ansi-regex": "2.1.1" } }, + "has-binary2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.2.tgz", + "integrity": "sha1-6D26SfC5vk0CbSc2U1DZ8D9Uvpg=", + "dev": true, + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "has-value": { @@ -4100,7 +5762,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -4111,19 +5773,28 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } }, - "hasha": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", - "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", "dev": true, "requires": { - "is-stream": "1.1.0", - "pinkie-promise": "2.0.1" + "inherits": "2.0.3" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" } }, "hawk": { @@ -4131,17 +5802,46 @@ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", "dev": true, + "optional": true, "requires": { "boom": "4.3.1", "cryptiles": "3.1.2", - "hoek": "4.2.0", + "hoek": "4.2.1", "sntp": "2.1.0" } }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hipchat-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hipchat-notifier/-/hipchat-notifier-1.1.0.tgz", + "integrity": "sha1-ttJJdVQ3wZEII2d5nTupoPI7Ix4=", + "dev": true, + "optional": true, + "requires": { + "lodash": "4.17.5", + "request": "2.83.0" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", "dev": true }, "home-or-tmp": { @@ -4172,27 +5872,125 @@ "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", "dev": true }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.4.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + } + } + }, + "http-proxy": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz", + "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=", + "dev": true, + "requires": { + "eventemitter3": "1.2.0", + "requires-port": "1.0.0" + } + }, + "http-proxy-agent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-1.0.0.tgz", + "integrity": "sha1-zBzjjkU7+YSg93AtLdWcc9CBKEo=", + "dev": true, + "requires": { + "agent-base": "2.1.1", + "debug": "2.6.9", + "extend": "3.0.1" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, + "optional": true, "requires": { "assert-plus": "1.0.0", "jsprim": "1.4.1", "sshpk": "1.13.1" } }, + "httpntlm": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz", + "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=", + "dev": true, + "requires": { + "httpreq": "0.4.24", + "underscore": "1.7.0" + } + }, + "httpreq": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz", + "integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=", + "dev": true + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "https-proxy-agent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", + "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", + "dev": true, + "requires": { + "agent-base": "2.1.1", + "debug": "2.6.9", + "extend": "3.0.1" + } + }, + "husky": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", + "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", + "dev": true, + "requires": { + "is-ci": "1.1.0", + "normalize-path": "1.0.0", + "strip-indent": "2.0.0" + } + }, "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 }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, "ignore": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", "dev": true }, "import-lazy": { @@ -4208,13 +6006,10 @@ "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" - } + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true }, "indexes-of": { "version": "1.0.1", @@ -4222,6 +6017,19 @@ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", "dev": true }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflection": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.10.0.tgz", + "integrity": "sha1-W//LEZetPoEFD44X4hZoCH7p6y8=", + "dev": true, + "optional": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4239,11 +6047,20 @@ "dev": true }, "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, "inquirer": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", @@ -4256,7 +6073,7 @@ "cli-width": "2.2.0", "external-editor": "2.1.0", "figures": "2.0.0", - "lodash": "4.17.4", + "lodash": "4.17.5", "mute-stream": "0.0.7", "run-async": "2.3.0", "rx-lite": "4.0.8", @@ -4272,32 +6089,6 @@ "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -4306,22 +6097,92 @@ "requires": { "ansi-regex": "3.0.0" } - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, + } + } + }, + "insert-module-globals": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.2.tgz", + "integrity": "sha512-p3s7g96Nm62MbHRuj9ZXab0DuJNWD7qcmdUXCOQ/ZZn42DtDXfsLill7bq19lDCx3K3StypqUnuE3H2VmIJFUw==", + "dev": true, + "requires": { + "JSONStream": "1.3.2", + "combine-source-map": "0.7.2", + "concat-stream": "1.5.2", + "is-buffer": "1.1.6", + "lexical-scope": "1.2.0", + "process": "0.11.10", + "through2": "2.0.3", + "xtend": "4.0.1" + }, + "dependencies": { + "combine-source-map": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", + "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", + "dev": true, + "requires": { + "convert-source-map": "1.1.3", + "inline-source-map": "0.6.2", + "lodash.memoize": "3.0.4", + "source-map": "0.5.7" + } + }, + "concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.0.6", + "typedarray": "0.0.6" + } + }, + "convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "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 + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, "requires": { - "has-flag": "3.0.0" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" } + }, + "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 } } }, "invariant": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz", + "integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==", "dev": true, "requires": { "loose-envify": "1.3.1" @@ -4333,10 +6194,17 @@ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, + "ip": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.0.1.tgz", + "integrity": "sha1-x+NWzeoiWucbNtcPLnGpK6TkJZA=", + "dev": true, + "optional": 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==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz", + "integrity": "sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y=", "dev": true }, "is-absolute-url": { @@ -4374,13 +6242,13 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.10.0" + "binary-extensions": "1.11.0" } }, "is-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "is-builtin-module": { @@ -4398,6 +6266,15 @@ "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", "dev": true }, + "is-ci": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", + "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", + "dev": true, + "requires": { + "ci-info": "1.1.2" + } + }, "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", @@ -4503,8 +6380,8 @@ "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", "dev": true, "requires": { - "global-dirs": "0.1.0", - "is-path-inside": "1.0.0" + "global-dirs": "0.1.1", + "is-path-inside": "1.0.1" } }, "is-module": { @@ -4513,6 +6390,27 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true, + "optional": true + }, + "is-my-json-valid": { + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", + "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", + "dev": true, + "optional": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "is-my-ip-valid": "1.0.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, "is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", @@ -4563,13 +6461,13 @@ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", "dev": true, "requires": { - "is-path-inside": "1.0.0" + "is-path-inside": "1.0.1" } }, "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=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { "path-is-inside": "1.0.2" @@ -4616,6 +6514,13 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true, + "optional": true + }, "is-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", @@ -4676,11 +6581,21 @@ "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", "dev": true }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "1.7.0" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "dev": true, + "optional": true }, "is-utf8": { "version": "0.2.1", @@ -4700,6 +6615,12 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, + "isbinaryfile": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz", + "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4725,7 +6646,8 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "dev": true, + "optional": true }, "jquery": { "version": "3.3.1", @@ -4734,9 +6656,9 @@ "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==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz", + "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw==", "dev": true }, "js-tokens": { @@ -4746,13 +6668,13 @@ "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=", + "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": "2.7.3" + "argparse": "1.0.10", + "esprima": "4.0.0" } }, "jsbn": { @@ -4778,7 +6700,8 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "dev": true, + "optional": true }, "json-schema-traverse": { "version": "0.3.1", @@ -4787,9 +6710,9 @@ "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=", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", "dev": true, "requires": { "jsonify": "0.0.0" @@ -4814,9 +6737,9 @@ "dev": true }, "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "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" @@ -4834,12 +6757,40 @@ "through2": "0.6.5" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "jsonparse": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-0.0.5.tgz", + "integrity": "sha1-MwVCrT8KZUZlt3jz6y2an6UHrGQ=", "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" + } + }, "stream-combiner": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", @@ -4849,6 +6800,22 @@ "duplexer": "0.1.1", "through": "2.3.8" } + }, + "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 + }, + "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" + } } } }, @@ -4859,16 +6826,24 @@ "dev": true }, "jsonparse": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-0.0.5.tgz", - "integrity": "sha1-MwVCrT8KZUZlt3jz6y2an6UHrGQ=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true, + "optional": true + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, + "optional": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -4876,142 +6851,656 @@ "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=", + "karma": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.0.tgz", + "integrity": "sha512-K9Kjp8CldLyL9ANSUctDyxC7zH3hpqXj/K09qVf06K3T/kXaHtFZ5tQciK7OzQu68FLvI89Na510kqQ2LCbpIw==", "dev": true, "requires": { - "graceful-fs": "4.1.11" + "bluebird": "3.5.1", + "body-parser": "1.18.2", + "browserify": "14.5.0", + "chokidar": "1.7.0", + "colors": "1.1.2", + "combine-lists": "1.0.1", + "connect": "3.6.6", + "core-js": "2.5.3", + "di": "0.0.1", + "dom-serialize": "2.2.1", + "expand-braces": "0.1.2", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "http-proxy": "1.16.2", + "isbinaryfile": "3.0.2", + "lodash": "4.17.5", + "log4js": "2.5.3", + "mime": "1.6.0", + "minimatch": "3.0.4", + "optimist": "0.6.1", + "qjobs": "1.2.0", + "range-parser": "1.2.0", + "rimraf": "2.6.2", + "safe-buffer": "5.1.1", + "socket.io": "2.0.4", + "source-map": "0.6.1", + "tmp": "0.0.33", + "useragent": "2.3.0" + }, + "dependencies": { + "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 + } } }, - "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==", + "karma-chai": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", + "integrity": "sha1-vuWtQEAFF4Ea40u5RfdikJEIt5o=", "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" - } - }, - "lazy-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", - "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", - "dev": true, - "requires": { - "set-getter": "0.1.0" - } - }, - "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=", + "karma-chrome-launcher": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", + "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", "dev": true, "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" + "fs-access": "1.0.1", + "which": "1.3.0" } }, - "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=", + "karma-mocha": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz", + "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=", "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" + "minimist": "1.2.0" } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "karma-mocha-reporter": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", + "integrity": "sha1-FRIAlejtgZGG5HoLAS8810GJVWA=", "dev": true, "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" + "chalk": "2.3.1", + "log-symbols": "2.2.0", + "strip-ansi": "4.0.0" }, "dependencies": { - "path-exists": { + "ansi-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "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" + } } } }, - "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.endswith": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.endswith/-/lodash.endswith-4.2.1.tgz", - "integrity": "sha1-/tWawXOO0+I27dcGTsRWRIs3vAk=", - "dev": true - }, - "lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", - "dev": true + "karma-rollup-preprocessor": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/karma-rollup-preprocessor/-/karma-rollup-preprocessor-5.1.1.tgz", + "integrity": "sha512-HRzuR6mf5V0/5h78qp2J+bOjuqqHPz2yOzHpnWfr+OlHMF5//cxOXNh4nY7WbES+cr2/hObYiofD9On7kuIXBQ==", + "dev": true, + "requires": { + "chokidar": "2.0.2", + "object-assign": "4.1.1" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "3.1.9", + "normalize-path": "2.1.1" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz", + "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==", + "dev": true, + "requires": { + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "define-property": "1.0.0", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "kind-of": "6.0.2", + "repeat-element": "1.1.2", + "snapdragon": "0.8.1", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "chokidar": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.2.tgz", + "integrity": "sha512-l32Hw3wqB0L2kGVmSbK/a+xXLDrUEsc84pSgMkmwygHvD7ubRsP/vxxHa5BtB6oix1XLLVCHyYMsckRXxThmZw==", + "dev": true, + "requires": { + "anymatch": "2.0.0", + "async-each": "1.0.1", + "braces": "2.3.1", + "fsevents": "1.1.3", + "glob-parent": "3.1.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "4.0.0", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.0.4" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.1", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.1", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + } + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "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.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "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.6" + } + } + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "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.6" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "micromatch": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.9.tgz", + "integrity": "sha512-SlIz6sv5UPaAVVFRKodKjCg48EbNoIhgetzfK/Cy0v5U52Z6zB136M8tp0UC9jM53LYbmIRihJszvvqpKkfm9g==", + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.1", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.9", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.1", + "to-regex": "3.0.2" + } + }, + "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" + } + } + } + }, + "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.6" + } + }, + "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 + }, + "labeled-stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", + "integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "isarray": "0.0.1", + "stream-splicer": "2.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "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" + } + }, + "lazy-cache": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", + "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", + "dev": true, + "requires": { + "set-getter": "0.1.0" + } + }, + "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" + }, + "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" + } + }, + "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" + } + }, + "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 + }, + "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" + } + } + } + }, + "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" + } + }, + "lexical-scope": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", + "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", + "dev": true, + "requires": { + "astw": "2.2.0" + } + }, + "libbase64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", + "integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=", + "dev": true + }, + "libmime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz", + "integrity": "sha1-UaGp50SOy9Ms2lRCFnW7IbwJPaY=", + "dev": true, + "requires": { + "iconv-lite": "0.4.15", + "libbase64": "0.1.0", + "libqp": "1.1.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", + "dev": true + } + } + }, + "libqp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz", + "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=", + "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" + } }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "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" + } + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", + "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.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, + "lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", "dev": true }, "lodash.memoize": { @@ -5020,10 +7509,40 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, - "lodash.startswith": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.startswith/-/lodash.startswith-4.2.1.tgz", - "integrity": "sha1-xZjErc4YiiflMUVzHNxsDnF3YAw=", + "lodash.merge": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", + "dev": true + }, + "lodash.mergewith": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", + "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "dev": true + }, + "lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", + "dev": true + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true + }, + "lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=", + "dev": true + }, + "lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha1-lDbjTtJgk+1/+uGTYUQ1CRXZrdg=", "dev": true }, "lodash.template": { @@ -5045,19 +7564,268 @@ "lodash._reinterpolate": "3.0.0" } }, + "lodash.topairs": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.topairs/-/lodash.topairs-4.3.0.tgz", + "integrity": "sha1-O23qo31g+xFnE8RsXxfqGQ7EjWQ=", + "dev": true + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", "dev": true }, + "lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=", + "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=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "dev": true, "requires": { - "chalk": "1.1.3" + "chalk": "2.3.1" + } + }, + "log4js": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.5.3.tgz", + "integrity": "sha512-YL/qpTxYtK0iWWbuKCrevDZz5lh+OjyHHD+mICqpjnYGKdNRBvPeh/1uYjkKUemT1CSO4wwLOwphWMpKAnD9kw==", + "dev": true, + "requires": { + "amqplib": "0.5.2", + "axios": "0.15.3", + "circular-json": "0.5.1", + "date-format": "1.2.0", + "debug": "3.1.0", + "hipchat-notifier": "1.1.0", + "loggly": "1.1.1", + "mailgun-js": "0.7.15", + "nodemailer": "2.7.2", + "redis": "2.8.0", + "semver": "5.5.0", + "slack-node": "0.2.0", + "streamroller": "0.7.0" + }, + "dependencies": { + "circular-json": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.1.tgz", + "integrity": "sha512-UjgcRlTAhAkLeXmDe2wK7ktwy/tgAqxiSndTIPiFZuIPLZmzHzWMwUIe9h9m/OokypG7snxCDEuwJshGBdPvaw==", + "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" + } + } + } + }, + "loggly": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/loggly/-/loggly-1.1.1.tgz", + "integrity": "sha1-Cg/B0/o6XsRP3HuJe+uipGlc6+4=", + "dev": true, + "optional": true, + "requires": { + "json-stringify-safe": "5.0.1", + "request": "2.75.0", + "timespan": "2.3.0" + }, + "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, + "optional": true + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true, + "optional": true + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true, + "optional": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "optional": 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" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "optional": true, + "requires": { + "boom": "2.10.1" + } + }, + "form-data": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz", + "integrity": "sha1-bwrrrcxdoWwT4ezBETfYX5uIOyU=", + "dev": true, + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" + } + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "optional": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.14.1", + "is-my-json-valid": "2.17.2", + "pinkie-promise": "2.0.1" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "optional": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", + "dev": true, + "optional": true + }, + "qs": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", + "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", + "dev": true, + "optional": true + }, + "request": { + "version": "2.75.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz", + "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=", + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "bl": "1.1.2", + "caseless": "0.11.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.0.0", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "node-uuid": "1.4.8", + "oauth-sign": "0.8.2", + "qs": "6.2.3", + "stringstream": "0.0.5", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.4.3" + } + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "optional": true, + "requires": { + "hoek": "2.16.3" + } + }, + "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, + "optional": true + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true, + "optional": true + } } }, "loose-envify": { @@ -5110,23 +7878,82 @@ "vlq": "0.2.3" } }, - "make-dir": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz", - "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==", + "mailcomposer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz", + "integrity": "sha1-DhxEsqB890DuF9wUm6AJ8Zyt/rQ=", "dev": true, + "optional": true, "requires": { - "pify": "3.0.0" + "buildmail": "4.0.1", + "libmime": "3.0.0" + } + }, + "mailgun-js": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.7.15.tgz", + "integrity": "sha1-7jZqINrGTDwVwD1sGz4O15UlKrs=", + "dev": true, + "optional": true, + "requires": { + "async": "2.1.5", + "debug": "2.2.0", + "form-data": "2.1.4", + "inflection": "1.10.0", + "is-stream": "1.1.0", + "path-proxy": "1.0.0", + "proxy-agent": "2.0.0", + "q": "1.4.1", + "tsscmp": "1.0.5" }, "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "optional": true, + "requires": { + "ms": "0.7.1" + } + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true, + "optional": true + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", + "dev": true, + "optional": true } } }, + "make-dir": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", + "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", + "dev": true, + "requires": { + "pify": "3.0.0" + } + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -5134,9 +7961,9 @@ "dev": true }, "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", "dev": true }, "map-stream": { @@ -5166,13 +7993,41 @@ "integrity": "sha1-jUEmgWi/htEQK5gQnijlMeejRXg=", "dev": true }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "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" + "mimic-fn": "1.2.0" } }, "memorystream": { @@ -5199,10 +8054,154 @@ "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=", + "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" + } + }, + "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" + } + }, + "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 + }, + "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" + } + }, + "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" + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "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-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" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "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-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" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true } } @@ -5226,6 +8225,27 @@ "object.omit": "2.0.1", "parse-glob": "3.0.4", "regex-cache": "0.4.4" + }, + "dependencies": { + "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" + } + } + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0" } }, "mime": { @@ -5235,24 +8255,36 @@ "dev": true }, "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", "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=", + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "dev": true, "requires": { - "mime-db": "1.30.0" + "mime-db": "1.33.0" } }, "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", "dev": true }, "minimatch": { @@ -5261,15 +8293,25 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "1.1.11" } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "requires": { + "arrify": "1.0.1", + "is-plain-obj": "1.1.0" + } + }, "mixin-deep": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", @@ -5298,6 +8340,128 @@ "dev": true, "requires": { "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.1.tgz", + "integrity": "sha512-SpwyojlnE/WRBNGtvJSNfllfm5PqEDFxcWluSIgLeSBJtXG4DmoX2NNAeEA7rP5kK+79VgtVq8nG6HskaL1ykg==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + }, + "dependencies": { + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "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" + } + }, + "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" + } + } + } + }, + "module-deps": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", + "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", + "dev": true, + "requires": { + "JSONStream": "1.3.2", + "browser-resolve": "1.11.2", + "cached-path-relative": "1.0.1", + "concat-stream": "1.5.2", + "defined": "1.0.0", + "detective": "4.7.1", + "duplexer2": "0.1.4", + "inherits": "2.0.3", + "parents": "1.0.1", + "readable-stream": "2.3.4", + "resolve": "1.5.0", + "stream-combiner2": "1.1.1", + "subarg": "1.0.0", + "through2": "2.0.3", + "xtend": "4.0.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.0.6", + "typedarray": "0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + } + } + }, + "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 + }, + "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 + } } }, "ms": { @@ -5377,6 +8541,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, "nested-error-stacks": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.2.tgz", @@ -5386,61 +8556,105 @@ "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==", + "netmask": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", + "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", + "dev": true, + "optional": true + }, + "nodemailer": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-2.7.2.tgz", + "integrity": "sha1-8kLmSa7q45tsftdA73sGHEBNMPk=", "dev": true, + "optional": true, "requires": { - "chalk": "2.3.0", - "minimist": "1.2.0", - "phantomjs-prebuilt": "2.1.16", - "qunit-phantomjs-runner": "2.3.1" + "libmime": "3.0.0", + "mailcomposer": "4.0.1", + "nodemailer-direct-transport": "3.3.2", + "nodemailer-shared": "1.1.0", + "nodemailer-smtp-pool": "2.8.2", + "nodemailer-smtp-transport": "2.7.2", + "socks": "1.1.9" }, "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==", + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", "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 + "optional": true }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "socks": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.9.tgz", + "integrity": "sha1-Yo1+TQSRJDVEWsC25Fk3bLPm1pE=", "dev": true, + "optional": true, "requires": { - "has-flag": "2.0.0" + "ip": "1.1.5", + "smart-buffer": "1.1.15" } } } }, + "nodemailer-direct-transport": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-3.3.2.tgz", + "integrity": "sha1-6W+vuQNYVglH5WkBfZfmBzilCoY=", + "dev": true, + "optional": true, + "requires": { + "nodemailer-shared": "1.1.0", + "smtp-connection": "2.12.0" + } + }, + "nodemailer-fetch": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz", + "integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=", + "dev": true + }, + "nodemailer-shared": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz", + "integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=", + "dev": true, + "requires": { + "nodemailer-fetch": "1.6.0" + } + }, + "nodemailer-smtp-pool": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/nodemailer-smtp-pool/-/nodemailer-smtp-pool-2.8.2.tgz", + "integrity": "sha1-LrlNbPhXgLG0clzoU7nL1ejajHI=", + "dev": true, + "optional": true, + "requires": { + "nodemailer-shared": "1.1.0", + "nodemailer-wellknown": "0.1.10", + "smtp-connection": "2.12.0" + } + }, + "nodemailer-smtp-transport": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.7.2.tgz", + "integrity": "sha1-A9ccdjFPFKx9vHvwM6am0W1n+3c=", + "dev": true, + "optional": true, + "requires": { + "nodemailer-shared": "1.1.0", + "nodemailer-wellknown": "0.1.10", + "smtp-connection": "2.12.0" + } + }, + "nodemailer-wellknown": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz", + "integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=", + "dev": true + }, "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -5449,18 +8663,15 @@ "requires": { "hosted-git-info": "2.5.0", "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" } }, "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" - } + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true }, "normalize-range": { "version": "0.1.2", @@ -5493,7 +8704,7 @@ "dev": true, "requires": { "ansi-styles": "3.2.0", - "chalk": "2.3.0", + "chalk": "2.3.1", "cross-spawn": "5.1.0", "memorystream": "0.3.1", "minimatch": "3.0.4", @@ -5501,97 +8712,6 @@ "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": { @@ -5603,6 +8723,12 @@ "path-key": "2.0.1" } }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, "num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", @@ -5619,7 +8745,8 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5627,6 +8754,12 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -5736,6 +8869,15 @@ } } }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5746,9 +8888,9 @@ } }, "onecolor": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/onecolor/-/onecolor-3.0.4.tgz", - "integrity": "sha1-daRvgNpseqpbTarhekcZi9llJJQ=", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/onecolor/-/onecolor-3.0.5.tgz", + "integrity": "sha1-Nu/zIgE3nv3xGA+0ReUajiQl+fY=", "dev": true }, "onetime": { @@ -5757,7 +8899,31 @@ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { - "mimic-fn": "1.1.0" + "mimic-fn": "1.2.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "0.0.10", + "wordwrap": "0.0.3" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } } }, "optionator": { @@ -5774,6 +8940,12 @@ "wordwrap": "1.0.0" } }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -5804,10 +8976,13 @@ "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 + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "dev": true, + "requires": { + "p-try": "1.0.0" + } }, "p-locate": { "version": "2.0.0", @@ -5815,7 +8990,7 @@ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { - "p-limit": "1.1.0" + "p-limit": "1.2.0" } }, "p-map": { @@ -5824,6 +8999,53 @@ "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", "dev": true }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pac-proxy-agent": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz", + "integrity": "sha512-QBELCWyLYPgE2Gj+4wUEiMscHrQ8nRPBzYItQNOHWavwBt25ohZHQC4qnd5IszdVVrFbLsQ+dPkm6eqdjJAmwQ==", + "dev": true, + "optional": true, + "requires": { + "agent-base": "2.1.1", + "debug": "2.6.9", + "extend": "3.0.1", + "get-uri": "2.0.1", + "http-proxy-agent": "1.0.0", + "https-proxy-agent": "1.0.0", + "pac-resolver": "2.0.0", + "raw-body": "2.3.2", + "socks-proxy-agent": "2.1.1" + } + }, + "pac-resolver": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-2.0.0.tgz", + "integrity": "sha1-mbiNLxk/ve78HJpSnB8yYKtSd80=", + "dev": true, + "optional": true, + "requires": { + "co": "3.0.6", + "degenerator": "1.0.4", + "ip": "1.0.1", + "netmask": "1.0.6", + "thunkify": "2.1.2" + }, + "dependencies": { + "co": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/co/-/co-3.0.6.tgz", + "integrity": "sha1-FEXyJsXrlWE45oyawwFn6n0ua9o=", + "dev": true, + "optional": true + } + } + }, "package-json": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", @@ -5831,9 +9053,37 @@ "dev": true, "requires": { "got": "6.7.1", - "registry-auth-token": "3.3.1", + "registry-auth-token": "3.3.2", "registry-url": "3.1.0", - "semver": "5.4.1" + "semver": "5.5.0" + } + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "dev": true, + "requires": { + "asn1.js": "4.10.1", + "browserify-aes": "1.1.1", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" } }, "parse-glob": { @@ -5849,20 +9099,51 @@ } }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "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" + } + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "1.0.2" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", "dev": true, "requires": { - "error-ex": "1.3.1" + "better-assert": "1.0.2" } }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", @@ -5870,13 +9151,10 @@ "dev": true }, "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" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true }, "path-is-absolute": { "version": "1.0.1", @@ -5902,17 +9180,46 @@ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-proxy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-proxy/-/path-proxy-1.0.0.tgz", + "integrity": "sha1-GOijaFn8nS8aU7SN7hOFQ8Ag3l4=", + "dev": true, + "optional": true, + "requires": { + "inflection": "1.3.8" + }, + "dependencies": { + "inflection": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.3.8.tgz", + "integrity": "sha1-y9Fg2p91sUw8xjV41POWeEvzAU4=", + "dev": true, + "optional": true + } + } + }, "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "pify": "3.0.0" } }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, "pause-stream": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", @@ -5922,6 +9229,19 @@ "through": "2.3.8" } }, + "pbkdf2": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "dev": true, + "requires": { + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.10" + } + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -5932,37 +9252,13 @@ "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.2.2", - "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 - } - } + "optional": true }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "pinkie": { @@ -5986,7 +9282,7 @@ "integrity": "sha1-GVV2CVno0aEcsqUOyD7sRwYz5J8=", "dev": true, "requires": { - "onecolor": "3.0.4", + "onecolor": "3.0.5", "synesthesia": "1.0.1" } }, @@ -5996,37 +9292,11 @@ "integrity": "sha1-LaSh3m7EQjxfw3lOkwuB1EkOxoY=", "dev": true, "requires": { - "browserslist": "2.5.0", + "browserslist": "2.11.3", "postcss": "6.0.19", "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -6043,15 +9313,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -6062,6 +9323,27 @@ "dev": true, "requires": { "find-up": "1.1.2" + }, + "dependencies": { + "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" + } + }, + "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" + } + } } }, "pleeease-filters": { @@ -6070,36 +9352,10 @@ "integrity": "sha1-ZjKy+wVkjSdY2GU4T7zteeHMrsc=", "dev": true, "requires": { - "onecolor": "3.0.4", + "onecolor": "3.0.5", "postcss": "6.0.19" }, "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -6116,15 +9372,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -6134,7 +9381,7 @@ "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", "dev": true, "requires": { - "irregular-plurals": "1.3.0" + "irregular-plurals": "1.4.0" } }, "pluralize": { @@ -6156,11 +9403,44 @@ "dev": true, "requires": { "chalk": "1.1.3", - "js-base64": "2.3.2", + "js-base64": "2.4.3", "source-map": "0.5.7", "supports-color": "3.2.3" }, "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" + }, + "dependencies": { + "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 + } + } + }, + "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 + }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", @@ -6183,38 +9463,12 @@ "postcss": "6.0.19" }, "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -6231,15 +9485,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -6253,32 +9498,6 @@ "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -6295,15 +9514,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -6338,15 +9548,6 @@ "yargs": "11.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" - } - }, "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", @@ -6409,17 +9610,6 @@ } } }, - "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, "chokidar": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.2.tgz", @@ -6437,7 +9627,7 @@ "normalize-path": "2.1.1", "path-is-absolute": "1.0.1", "readdirp": "2.1.0", - "upath": "1.0.2" + "upath": "1.0.4" } }, "expand-brackets": { @@ -6551,37 +9741,6 @@ } } }, - "fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", - "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" - } - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -6612,17 +9771,11 @@ "array-union": "1.0.2", "dir-glob": "2.0.0", "glob": "7.1.2", - "ignore": "3.3.5", + "ignore": "3.3.7", "pify": "3.0.0", "slash": "1.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -6638,7 +9791,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -6658,7 +9811,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -6693,7 +9846,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -6704,15 +9857,6 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "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" - } - }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", @@ -6740,11 +9884,14 @@ "to-regex": "3.0.2" } }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "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" + } }, "postcss": { "version": "6.0.19", @@ -6762,15 +9909,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -6786,32 +9924,6 @@ "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -6828,15 +9940,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -6852,26 +9955,6 @@ "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.1" - } - }, - "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, "color": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color/-/color-2.0.1.tgz", @@ -6882,15 +9965,6 @@ "color-string": "1.5.2" } }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, "color-string": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz", @@ -6901,12 +9975,6 @@ "simple-swizzle": "0.2.2" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -6923,15 +9991,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -6946,33 +10005,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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.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-convert": "1.9.1", "color-string": "1.5.2" } }, @@ -6986,12 +10025,6 @@ "simple-swizzle": "0.2.2" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7008,15 +10041,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -7031,32 +10055,6 @@ "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7072,16 +10070,7 @@ "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": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } + "dev": true } } }, @@ -7097,33 +10086,13 @@ "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.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-convert": "1.9.1", "color-string": "1.5.2" } }, @@ -7137,12 +10106,6 @@ "simple-swizzle": "0.2.2" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7159,15 +10122,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -7181,32 +10135,6 @@ "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7223,15 +10151,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -7245,32 +10164,6 @@ "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7287,15 +10180,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -7310,32 +10194,6 @@ "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7352,15 +10210,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -7424,15 +10273,6 @@ "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.2.6", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz", @@ -7447,16 +10287,6 @@ "postcss-value-parser": "3.3.0" } }, - "browserslist": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", - "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", - "dev": true, - "requires": { - "caniuse-lite": "1.0.30000810", - "electron-to-chromium": "1.3.34" - } - }, "caniuse-api": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-2.0.0.tgz", @@ -7469,35 +10299,6 @@ "lodash.uniq": "4.5.0" } }, - "caniuse-lite": { - "version": "1.0.30000810", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000810.tgz", - "integrity": "sha512-/0Q00Oie9C72P8zQHtFvzmkrMC3oOFUnMWjCy5F2+BE8lzICm91hQPhh0+XIsAFPKOe2Dh3pKgbRmU3EKxfldA==", - "dev": true - }, - "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "electron-to-chromium": { - "version": "1.3.34", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz", - "integrity": "sha1-2TSY9AORuwwWpgPYJBuZUUBBV+0=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7536,15 +10337,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -7557,32 +10349,6 @@ "postcss": "6.0.19" }, "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7599,15 +10365,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -7621,32 +10378,6 @@ "postcss": "6.0.19" }, "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7663,15 +10394,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -7685,32 +10407,6 @@ "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7727,15 +10423,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -7804,32 +10491,6 @@ "postcss": "6.0.19" }, "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7846,15 +10507,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -7867,32 +10519,6 @@ "postcss": "6.0.19" }, "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -7906,18 +10532,9 @@ }, "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": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -7928,44 +10545,18 @@ "dev": true, "requires": { "babel-register": "6.26.0", - "postcss": "6.0.13" + "postcss": "6.0.19" }, "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==", + "version": "6.0.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", + "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", "dev": true, "requires": { - "chalk": "2.1.0", + "chalk": "2.3.1", "source-map": "0.6.1", - "supports-color": "4.4.0" + "supports-color": "5.2.0" } }, "source-map": { @@ -7973,15 +10564,6 @@ "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" - } } } }, @@ -7995,32 +10577,37 @@ "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "postcss": { + "version": "6.0.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", + "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", + "chalk": "2.3.1", + "source-map": "0.6.1", "supports-color": "5.2.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 - }, + } + } + }, + "postcss-import": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.1.0.tgz", + "integrity": "sha512-5l327iI75POonjxkXgdRCUS+AlzAdBx4pOvMEhTKTCjb1p8IEeVR9yx3cPbmN7LIWJLbfnIXxAhoB4jpD0c/Cw==", + "dev": true, + "requires": { + "postcss": "6.0.19", + "postcss-value-parser": "3.3.0", + "read-cache": "1.0.0", + "resolve": "1.5.0" + }, + "dependencies": { "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -8037,15 +10624,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -8059,32 +10637,6 @@ "postcss": "6.0.19" }, "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -8101,15 +10653,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -8132,6 +10675,38 @@ "object-assign": "4.1.1", "postcss-load-options": "1.2.0", "postcss-load-plugins": "2.3.0" + }, + "dependencies": { + "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.10.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" + } + }, + "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" + } + }, + "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 + } } }, "postcss-load-options": { @@ -8142,6 +10717,38 @@ "requires": { "cosmiconfig": "2.2.2", "object-assign": "4.1.1" + }, + "dependencies": { + "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.10.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" + } + }, + "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" + } + }, + "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 + } } }, "postcss-load-plugins": { @@ -8152,43 +10759,49 @@ "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.19" }, "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", "dev": true, "requires": { - "color-convert": "1.9.0" + "is-directory": "0.3.1", + "js-yaml": "3.10.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" } }, - "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "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": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "error-ex": "1.3.1" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 - }, + } + } + }, + "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.19" + }, + "dependencies": { "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -8205,15 +10818,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -8262,8 +10866,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000744", - "electron-to-chromium": "1.3.24" + "caniuse-db": "1.0.30000810", + "electron-to-chromium": "1.3.34" } } } @@ -8328,32 +10932,6 @@ "postcss": "6.0.19" }, "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -8370,15 +10948,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -8423,32 +10992,6 @@ "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -8465,53 +11008,18 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.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.19" - }, - "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, + "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.19" + }, + "dependencies": { "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -8528,15 +11036,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -8579,32 +11078,6 @@ "postcss": "6.0.19" }, "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -8621,15 +11094,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -8640,46 +11104,11 @@ "dev": true, "requires": { "chalk": "2.3.1", - "lodash": "4.17.4", + "lodash": "4.17.5", "log-symbols": "2.2.0", "postcss": "6.0.19" }, "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "2.3.1" - } - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -8696,15 +11125,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -8715,49 +11135,23 @@ "dev": true }, "postcss-scss": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-1.0.2.tgz", - "integrity": "sha1-/0XPM1S4ee6JpOtoaA9GrJuxT5Q=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-1.0.4.tgz", + "integrity": "sha512-IFj42Hz2cBHHFvZTqkJqU08JCCM/MZU5/uNkTUZBaBFP2d4C5unw4HyCL52RfCwJb6KoVUD3eoepxMh1dfBFCQ==", "dev": true, "requires": { - "postcss": "6.0.13" + "postcss": "6.0.19" }, "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==", + "version": "6.0.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", + "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", "dev": true, "requires": { - "chalk": "2.1.0", + "chalk": "2.3.1", "source-map": "0.6.1", - "supports-color": "4.4.0" + "supports-color": "5.2.0" } }, "source-map": { @@ -8765,15 +11159,6 @@ "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" - } } } }, @@ -8787,38 +11172,12 @@ "postcss": "6.0.19" }, "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -8835,15 +11194,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -8857,38 +11207,12 @@ "postcss": "6.0.19" }, "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.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "postcss": { "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", @@ -8905,15 +11229,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } } } }, @@ -8934,7 +11249,7 @@ "integrity": "sha1-MrHpr6kTuyJaatB21QPY+YO7SoI=", "dev": true, "requires": { - "lodash": "4.17.4", + "lodash": "4.17.5", "postcss": "5.2.18" } }, @@ -8962,64 +11277,27 @@ } }, "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==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.1.tgz", + "integrity": "sha512-Ya5KIjGptgz0OtrVYfi2UbLxVAZ6Emc4Of+Grx4Sf1deWlRpFwLr8FrtkUxfqh+XiZIVkXbjQrddE10ESpNmdA==", "dev": true, "requires": { "mime": "1.6.0", "minimatch": "3.0.4", "mkdirp": "0.5.1", - "postcss": "6.0.16", - "xxhashjs": "0.2.1" + "postcss": "6.0.19", + "xxhashjs": "0.2.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.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" - }, - "dependencies": { - "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" - } - } - } - }, - "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.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz", - "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==", + "version": "6.0.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", + "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", "dev": true, "requires": { - "chalk": "2.3.0", + "chalk": "2.3.1", "source-map": "0.6.1", - "supports-color": "5.1.0" + "supports-color": "5.2.0" } }, "source-map": { @@ -9027,15 +11305,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", - "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } } } }, @@ -9081,15 +11350,21 @@ "dev": true }, "private": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", - "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", "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=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, "progress": { @@ -9098,6 +11373,38 @@ "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", "dev": true }, + "proxy-agent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-2.0.0.tgz", + "integrity": "sha1-V+tTR6qAXXTsaByyVknbo5yTNJk=", + "dev": true, + "optional": true, + "requires": { + "agent-base": "2.1.1", + "debug": "2.6.9", + "extend": "3.0.1", + "http-proxy-agent": "1.0.0", + "https-proxy-agent": "1.0.0", + "lru-cache": "2.6.5", + "pac-proxy-agent": "1.1.0", + "socks-proxy-agent": "2.1.1" + }, + "dependencies": { + "lru-cache": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz", + "integrity": "sha1-5W1jVBSO3o13B7WNFDIg/QjfD9U=", + "dev": true, + "optional": true + } + } + }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "dev": true + }, "ps-tree": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz", @@ -9107,22 +11414,89 @@ "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=", + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.6" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "puppeteer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.1.1.tgz", + "integrity": "sha1-rb8l5J9e8DRDwQq44JqVTKDHv+4=", + "dev": true, + "requires": { + "debug": "2.6.9", + "extract-zip": "1.6.6", + "https-proxy-agent": "2.1.1", + "mime": "1.6.0", + "progress": "2.0.0", + "proxy-from-env": "1.0.0", + "rimraf": "2.6.2", + "ws": "3.3.3" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz", + "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==", + "dev": true, + "requires": { + "es6-promisify": "5.0.0" + } + }, + "https-proxy-agent": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.1.1.tgz", + "integrity": "sha512-LK6tQUR/VOkTI6ygAfWUKKP95I+e6M1h7N3PncGu1CATHCnex+CAv9ttR0lbHu1Uk2PXm/WoAHFo6JCGwMjVMw==", + "dev": true, + "requires": { + "agent-base": "4.2.0", + "debug": "3.1.0" + }, + "dependencies": { + "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" + } + } + } + } + } + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true }, - "q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", - "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", "dev": true }, "qs": { @@ -9141,19 +11515,22 @@ "strict-uri-encode": "1.1.0" } }, - "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" - } + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true }, - "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=", + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", "dev": true }, "randomatic": { @@ -9181,7 +11558,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -9192,29 +11569,58 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "2.0.6", + "safe-buffer": "5.1.1" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + } + }, "rc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", - "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.5.tgz", + "integrity": "sha1-J1zWh/bjs2zHVrqibf7oCnkDAf0=", "dev": true, "requires": { "deep-extend": "0.4.2", - "ini": "1.3.4", + "ini": "1.3.5", "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": { @@ -9224,6 +11630,14 @@ "dev": true, "requires": { "pify": "2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "read-file-stdin": { @@ -9235,37 +11649,46 @@ "gather-stream": "1.0.0" } }, + "read-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "2.3.4" + } + }, "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "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": "1.1.0", + "load-json-file": "4.0.0", "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "path-type": "3.0.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=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "2.1.0", + "read-pkg": "3.0.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==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz", + "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==", "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", + "process-nextick-args": "2.0.0", "safe-buffer": "5.1.1", "string_decoder": "1.0.3", "util-deprecate": "1.0.2" @@ -9279,20 +11702,46 @@ "requires": { "graceful-fs": "4.1.11", "minimatch": "3.0.4", - "readable-stream": "2.3.3", + "readable-stream": "2.3.4", "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=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "requires": { + "indent-string": "3.2.0", + "strip-indent": "2.0.0" + } + }, + "redis": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", + "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", "dev": true, + "optional": true, "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" + "double-ended-queue": "2.1.0-0", + "redis-commands": "1.3.5", + "redis-parser": "2.6.0" } }, + "redis-commands": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", + "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==", + "dev": true, + "optional": true + }, + "redis-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", + "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=", + "dev": true, + "optional": true + }, "reduce-css-calc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", @@ -9336,9 +11785,9 @@ "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==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", "dev": true }, "regenerator-transform": { @@ -9349,7 +11798,7 @@ "requires": { "babel-runtime": "6.26.0", "babel-types": "6.26.0", - "private": "0.1.7" + "private": "0.1.8" } }, "regex-cache": { @@ -9383,12 +11832,12 @@ } }, "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=", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", + "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", "dev": true, "requires": { - "rc": "1.2.2", + "rc": "1.2.5", "safe-buffer": "5.1.1" } }, @@ -9398,7 +11847,7 @@ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", "dev": true, "requires": { - "rc": "1.2.2" + "rc": "1.2.5" } }, "regjsgen": { @@ -9456,38 +11905,43 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", "dev": true, + "optional": true, "requires": { "aws-sign2": "0.7.0", "aws4": "1.6.0", "caseless": "0.12.0", - "combined-stream": "1.0.5", + "combined-stream": "1.0.6", "extend": "3.0.1", "forever-agent": "0.6.1", - "form-data": "2.3.1", + "form-data": "2.3.2", "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", + "mime-types": "2.1.18", "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", + "tough-cookie": "2.3.4", "tunnel-agent": "0.6.0", - "uuid": "3.1.0" + "uuid": "3.2.1" } }, - "request-progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", - "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", + "requestretry": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", + "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==", "dev": true, + "optional": true, "requires": { - "throttleit": "1.0.0" + "extend": "3.0.1", + "lodash": "4.17.5", + "request": "2.83.0", + "when": "3.7.8" } }, "require-directory": { @@ -9497,9 +11951,9 @@ "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=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.1.tgz", + "integrity": "sha1-xUUjPp19pmFunVmt+zn8n1iGdv8=", "dev": true }, "require-main-filename": { @@ -9522,8 +11976,22 @@ "requires": { "caller-path": "0.1.0", "resolve-from": "1.0.1" + }, + "dependencies": { + "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 + } } }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, "resolve": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", @@ -9534,11 +12002,20 @@ } }, "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolve-global": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-0.1.0.tgz", + "integrity": "sha1-j7As/Vt9sgEY6IYxHxWvlb0V+9k=", + "dev": true, + "requires": { + "global-dirs": "0.1.1" + } + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -9580,28 +12057,22 @@ "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" - } - } + } + }, + "ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "dev": true, + "requires": { + "hash-base": "2.0.2", + "inherits": "2.0.3" } }, "rollup": { - "version": "0.56.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.56.2.tgz", - "integrity": "sha512-vZIn0P+xA1glmc4DwRsUC9ce6SSE5gZT2YKaRiSYHwJXHcRtXWHOvrY2NtUR8Gk+EoszyyoXMfw9OrYCCKCYCA==", + "version": "0.56.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.56.3.tgz", + "integrity": "sha512-/iH4RfioboHgBjo7TbQcdMad/ifVGY/ToOB1AsW7oZHUhfhm+low6QlrImUSaJO1JqklOpWEKlD+b3MZYLuptA==", "dev": true }, "rollup-plugin-babel": { @@ -9619,7 +12090,7 @@ "integrity": "sha512-PYs3OiYgENFYEmI3vOEm5nrp3eY90YZqd5vGmQqeXmhJsAWFIrFdROCvOasqJ1HgeTvqyYo9IGXnFDyoboNcgQ==", "dev": true, "requires": { - "acorn": "5.4.1", + "acorn": "5.5.0", "estree-walker": "0.5.1", "magic-string": "0.22.4", "resolve": "1.5.0", @@ -9748,9 +12219,9 @@ "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==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, "semver-diff": { @@ -9759,7 +12230,7 @@ "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", "dev": true, "requires": { - "semver": "5.4.1" + "semver": "5.5.0" } }, "set-blocking": { @@ -9806,6 +12277,32 @@ } } }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + }, + "sha.js": { + "version": "2.4.10", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz", + "integrity": "sha512-vnwmrFDlOExK4Nm16J2KMWHLrp14lBrjxMxBJpu++EnsuBmpiYaM/MEs46Vxxm/4FvdP5yTwuCTO9it5FSjrqA==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "0.0.1", + "sha.js": "2.4.10" + } + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -9862,6 +12359,16 @@ } } }, + "slack-node": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/slack-node/-/slack-node-0.2.0.tgz", + "integrity": "sha1-3kuN3aqLeT9h29KTgQT9q/N9+jA=", + "dev": true, + "optional": true, + "requires": { + "requestretry": "1.13.0" + } + }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -9877,6 +12384,22 @@ "is-fullwidth-code-point": "2.0.0" } }, + "smart-buffer": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", + "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=", + "dev": true + }, + "smtp-connection": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz", + "integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=", + "dev": true, + "requires": { + "httpntlm": "1.6.1", + "nodemailer-shared": "1.1.0" + } + }, "snapdragon": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz", @@ -9926,7 +12449,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -9946,7 +12469,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -10012,8 +12535,107 @@ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "dev": true, + "optional": true, + "requires": { + "hoek": "4.2.1" + } + }, + "socket.io": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz", + "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=", + "dev": true, + "requires": { + "debug": "2.6.9", + "engine.io": "3.1.5", + "socket.io-adapter": "1.1.1", + "socket.io-client": "2.0.4", + "socket.io-parser": "3.1.3" + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "dev": true + }, + "socket.io-client": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz", + "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "2.6.9", + "engine.io-client": "3.1.5", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "3.1.3", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", + "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "3.1.0", + "has-binary2": "1.0.2", + "isarray": "2.0.1" + }, + "dependencies": { + "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" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "socks": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz", + "integrity": "sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=", + "dev": true, + "requires": { + "ip": "1.1.5", + "smart-buffer": "1.1.15" + }, + "dependencies": { + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + } + } + }, + "socks-proxy-agent": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz", + "integrity": "sha512-sFtmYqdUK5dAMh85H0LEVFUCO7OhJJe1/z2x/Z6mxp3s7/QPf1RkZmpZy+BpuU0bEjcV9npqKjq9Y3kwFUjnxw==", + "dev": true, "requires": { - "hoek": "4.2.0" + "agent-base": "2.1.1", + "extend": "3.0.1", + "socks": "1.1.10" } }, "sort-keys": { @@ -10060,24 +12682,35 @@ "dev": true }, "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { - "spdx-license-ids": "1.2.2" + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" } }, - "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=", + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", "dev": true }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" + } + }, "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=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, "specificity": { @@ -10105,12 +12738,12 @@ } }, "split2": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", - "integrity": "sha1-At2smtwD7Au3jBKC7Aecpuha6QA=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", "dev": true, "requires": { - "through2": "0.6.5" + "through2": "2.0.3" } }, "sprintf-js": { @@ -10124,6 +12757,7 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", "dev": true, + "optional": true, "requires": { "asn1": "0.2.3", "assert-plus": "1.0.0", @@ -10169,7 +12803,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -10189,7 +12823,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -10213,19 +12847,91 @@ } } }, - "stdin": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/stdin/-/stdin-0.0.1.tgz", - "integrity": "sha1-0wQZgarsPf28d6GzjWNy449ftx4=", - "dev": true + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + }, + "stdin": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/stdin/-/stdin-0.0.1.tgz", + "integrity": "sha1-0wQZgarsPf28d6GzjWNy449ftx4=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.4" + } + }, + "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" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "0.1.4", + "readable-stream": "2.3.4" + } + }, + "stream-http": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.0.tgz", + "integrity": "sha512-sZOFxI/5xw058XIRHl4dU3dZ+TTOIGJR78Dvo0oEAejIt4ou27k+3ne1zYmCV+v7UucbxIFQuOgnkTVHh8YPnw==", + "dev": true, + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.4", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.4" + } }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "streamroller": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", + "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", "dev": true, "requires": { - "duplexer": "0.1.1" + "date-format": "1.2.0", + "debug": "3.1.0", + "mkdirp": "0.5.1", + "readable-stream": "2.3.4" + }, + "dependencies": { + "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" + } + } } }, "strict-uri-encode": { @@ -10268,7 +12974,7 @@ "dev": true, "requires": { "define-properties": "1.1.2", - "es-abstract": "1.9.0", + "es-abstract": "1.10.0", "function-bind": "1.1.1" } }, @@ -10285,7 +12991,8 @@ "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true + "dev": true, + "optional": true }, "strip-ansi": { "version": "3.0.1", @@ -10297,13 +13004,10 @@ } }, "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" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true }, "strip-eof": { "version": "1.0.0", @@ -10312,13 +13016,10 @@ "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" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true }, "strip-json-comments": { "version": "2.0.1", @@ -10344,8 +13045,8 @@ "editorconfig": "0.13.3", "globby": "6.1.0", "minimist": "1.2.0", - "postcss": "6.0.13", - "postcss-scss": "1.0.2", + "postcss": "6.0.19", + "postcss-scss": "1.0.4", "postcss-sorting": "2.1.0", "postcss-value-parser": "3.3.0", "stdin": "0.0.1", @@ -10354,26 +13055,22 @@ }, "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" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "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" + "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" } }, "globby": { @@ -10389,38 +13086,50 @@ "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=", + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "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==", + "version": "6.0.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", + "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", "dev": true, "requires": { - "chalk": "2.1.0", + "chalk": "2.3.1", "source-map": "0.6.1", - "supports-color": "4.4.0" + "supports-color": "5.2.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.1" + } + }, "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", + "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "5.2.0" + } + }, + "supports-color": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", + "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "dev": true, + "requires": { + "has-flag": "3.0.0" } } } @@ -10432,13 +13141,10 @@ "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" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true } } }, @@ -10461,21 +13167,43 @@ "write-file-stdout": "0.0.2" }, "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 + }, "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": "1.0.30000810", + "electron-to-chromium": "1.3.34" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "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" + } + }, + "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" + } }, "postcss-reporter": { "version": "1.4.1", @@ -10484,10 +13212,16 @@ "dev": true, "requires": { "chalk": "1.1.3", - "lodash": "4.17.4", + "lodash": "4.17.5", "log-symbols": "1.0.2", "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 } } }, @@ -10499,8 +13233,8 @@ "requires": { "autoprefixer": "6.7.7", "balanced-match": "0.4.2", - "chalk": "2.1.0", - "colorguard": "1.2.0", + "chalk": "2.3.1", + "colorguard": "1.2.1", "cosmiconfig": "2.2.2", "debug": "2.6.9", "doiuse": "2.6.0", @@ -10510,10 +13244,10 @@ "globby": "6.1.0", "globjoin": "0.1.4", "html-tags": "2.0.0", - "ignore": "3.3.5", + "ignore": "3.3.7", "imurmurhash": "0.1.4", "known-css-properties": "0.2.0", - "lodash": "4.17.4", + "lodash": "4.17.5", "log-symbols": "1.0.2", "mathml-tag-names": "2.0.1", "meow": "3.7.0", @@ -10535,17 +13269,14 @@ "stylehacks": "2.3.2", "sugarss": "0.2.0", "svg-tags": "1.0.0", - "table": "4.0.2" + "table": "4.0.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" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true }, "balanced-match": { "version": "0.4.2", @@ -10553,35 +13284,19 @@ "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==", + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", "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" + "is-directory": "0.3.1", + "js-yaml": "3.10.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" } }, "globby": { @@ -10597,10 +13312,43 @@ "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=", + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "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" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "postcss-reporter": { @@ -10610,17 +13358,11 @@ "dev": true, "requires": { "chalk": "1.1.3", - "lodash": "4.17.4", + "lodash": "4.17.5", "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", @@ -10633,12 +13375,6 @@ "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 } } }, @@ -10651,6 +13387,12 @@ "postcss": "5.2.18" } }, + "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 + }, "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", @@ -10658,13 +13400,10 @@ "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" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true } } }, @@ -10674,11 +13413,20 @@ "integrity": "sha1-2338oFQbUGIBDH4uIedFeR/AiKw=", "dev": true, "requires": { - "lodash": "4.17.4", + "lodash": "4.17.5", "postcss": "5.2.18", "stylelint": "7.13.0" } }, + "subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", + "dev": true, + "requires": { + "minimist": "1.2.0" + } + }, "sugarss": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-0.2.0.tgz", @@ -10689,10 +13437,13 @@ } }, "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 + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", + "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } }, "svg-tags": { "version": "1.0.0", @@ -10713,6 +13464,24 @@ "mkdirp": "0.5.1", "sax": "1.2.4", "whet.extend": "0.9.9" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "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.10", + "esprima": "2.7.3" + } + } } }, "synesthesia": { @@ -10732,53 +13501,38 @@ } } }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "1.3.0" + } + }, "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", + "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", "dev": true, "requires": { - "ajv": "5.2.3", - "ajv-keywords": "2.1.0", - "chalk": "2.1.0", - "lodash": "4.17.4", + "ajv": "6.2.0", + "ajv-keywords": "3.1.0", + "chalk": "2.3.1", + "lodash": "4.17.5", "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==", + }, + "dependencies": { + "ajv": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", + "integrity": "sha1-r6wpW7qgFSRJ5SJ0LkVHwa6TKNI=", "dev": true, "requires": { - "has-flag": "2.0.0" + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } } } @@ -10792,18 +13546,18 @@ "execa": "0.7.0" } }, + "text-extensions": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.7.0.tgz", + "integrity": "sha512-AKXZeDq230UaSzaO5s3qQUZOaC7iKbzq0jOFL614R7d9R593HLqAOL0cYoqLdkNrjBSOdmoQI06yigq1TSBXAg==", + "dev": true + }, "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", @@ -10811,47 +13565,44 @@ "dev": true }, "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "readable-stream": "1.0.34", + "readable-stream": "2.3.4", "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 - } } }, + "thunkify": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", + "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=", + "dev": true, + "optional": 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 }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "0.11.10" + } + }, + "timespan": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", + "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=", + "dev": true, + "optional": true + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -10861,6 +13612,18 @@ "os-tmpdir": "1.0.2" } }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -10910,18 +13673,25 @@ } }, "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "dev": true, + "optional": 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=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true + }, + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", "dev": true }, "trim-right": { @@ -10930,11 +13700,25 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "tsscmp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.5.tgz", + "integrity": "sha1-fcSjOvcVgatDN9qR2FylQn69mpc=", + "dev": true, + "optional": true + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "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, + "optional": true, "requires": { "safe-buffer": "5.1.1" } @@ -10955,6 +13739,22 @@ "prelude-ls": "1.1.2" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.18" + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -10971,12 +13771,6 @@ "source-map": "0.6.1" }, "dependencies": { - "commander": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", - "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -10985,6 +13779,24 @@ } } }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "umd": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz", + "integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4=", + "dev": true + }, + "underscore": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", + "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", + "dev": true + }, "union-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", @@ -11066,6 +13878,12 @@ "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", "dev": true }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -11119,16 +13937,10 @@ "dev": true }, "upath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.2.tgz", - "integrity": "sha512-fCmij7T5LnwUme3dbnVSejvOHHlARjB3ikJFwgZfz386pHmf/gueuTLRFU94FZEaeCLlbQrweiUU700gG41tUw==", - "dev": true, - "requires": { - "lodash.endswith": "4.2.1", - "lodash.isfunction": "3.0.9", - "lodash.isstring": "4.0.1", - "lodash.startswith": "4.2.1" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.4.tgz", + "integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==", + "dev": true }, "update-notifier": { "version": "2.3.0", @@ -11136,8 +13948,8 @@ "integrity": "sha1-TognpruRUUCrCTVZ1wFOPruDdFE=", "dev": true, "requires": { - "boxen": "1.2.2", - "chalk": "2.3.0", + "boxen": "1.3.0", + "chalk": "2.3.1", "configstore": "3.1.1", "import-lazy": "2.1.0", "is-installed-globally": "0.1.0", @@ -11145,43 +13957,6 @@ "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" - } - } } }, "urix": { @@ -11190,6 +13965,24 @@ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, "url-parse-lax": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", @@ -11234,7 +14027,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -11254,7 +14047,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -11284,26 +14077,67 @@ } } }, + "useragent": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", + "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "tmp": "0.0.33" + } + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, "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==", + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", "dev": true }, + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", + "dev": true, + "optional": true + }, + "uws": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", + "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", + "dev": true, + "optional": 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=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "dev": true, "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" } }, "vendors": { @@ -11317,6 +14151,7 @@ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, + "optional": true, "requires": { "assert-plus": "1.0.0", "core-util-is": "1.0.2", @@ -11335,6 +14170,28 @@ "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", "dev": true }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "when": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", + "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=", + "dev": true, + "optional": true + }, "whet.extend": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", @@ -11357,34 +14214,12 @@ "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=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.0.tgz", + "integrity": "sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=", "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" - } - } + "string-width": "2.1.1" } }, "window-size": { @@ -11463,12 +14298,36 @@ "integrity": "sha1-wlLXx8WxtAKJdjDjRTx7/mkNnKE=", "dev": true }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "1.0.0", + "safe-buffer": "5.1.1", + "ultron": "1.1.1" + } + }, "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 }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true + }, + "xregexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", + "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", + "dev": true, + "optional": true + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", @@ -11476,9 +14335,9 @@ "dev": true }, "xxhashjs": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.1.tgz", - "integrity": "sha1-m76b6JYUKXbfo0wGGy0GjEPTDeA=", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", + "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", "dev": true, "requires": { "cuint": "0.2.2" @@ -11514,43 +14373,6 @@ "which-module": "2.0.0", "y18n": "3.2.1", "yargs-parser": "9.0.2" - }, - "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 - }, - "cliui": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz", - "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", - "dev": true, - "requires": { - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "wrap-ansi": "2.1.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" - } - }, - "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" - } - } } }, "yargs-parser": { @@ -11560,14 +14382,6 @@ "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": { @@ -11578,6 +14392,12 @@ "requires": { "fd-slicer": "1.0.1" } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true } } } diff --git a/package.json b/package.json index ea46acb0..8985ffe4 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "cropper", "description": "A simple jQuery image cropping plugin.", - "version": "3.1.6", + "version": "4.0.0-alpha", "main": "dist/cropper.common.js", "module": "dist/cropper.esm.js", - "browser": "dist/cropper.js", + "unpkg": "dist/cropper.js", "repository": "fengyuanchen/cropper", "homepage": "https://fengyuanchen.github.io/cropper", "license": "MIT", @@ -19,13 +19,14 @@ "keywords": [ "image", "crop", - "cropper", - "cropping", - "processing", "move", "zoom", "rotate", "scale", + "cropper", + "cropper.js", + "cropping", + "processing", "jquery", "plugin", "jquery-plugin", @@ -38,38 +39,54 @@ ], "scripts": { "build": "npm run build:css && npm run build:js", - "build:css": "postcss src/css/cropper.css -o dist/cropper.css --no-map", + "build:css": "postcss src/index.css -o dist/cropper.css --no-map", "build:js": "rollup -c", "clear": "del-cli dist", + "commitmsg": "npm run lint && commitlint -e", "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", + "lint": "eslint src test --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", + "test": "karma start test/karma.conf.js", + "watch:css": "postcss src/index.css -o docs/css/cropper.css -m -w", "watch:js": "rollup -c -m -w" }, + "dependencies": { + "cropperjs": "^1.3.1" + }, "devDependencies": { + "@commitlint/cli": "^6.1.2", + "@commitlint/config-angular": "^6.1.2", "babel-core": "^6.26.0", "babel-plugin-external-helpers": "^6.22.0", "babel-preset-env": "^1.6.1", + "chai": "^4.1.2", "cpy-cli": "^1.0.1", "cssnano": "^3.10.0", "del-cli": "^1.1.0", "eslint": "^4.18.1", "eslint-config-airbnb-base": "^12.1.0", "eslint-plugin-import": "^2.9.0", + "husky": "^0.14.3", "jquery": "^3.3.1", - "node-qunit-phantomjs": "^2.0.0", + "karma": "^2.0.0", + "karma-chai": "^0.1.0", + "karma-chrome-launcher": "^2.2.0", + "karma-mocha": "^1.3.0", + "karma-mocha-reporter": "^2.2.5", + "karma-rollup-preprocessor": "^5.1.1", + "mocha": "^5.0.1", "npm-run-all": "^4.1.2", "postcss-cli": "^5.0.0", "postcss-cssnext": "^3.1.0", "postcss-header": "^1.0.0", - "postcss-url": "^7.3.0", - "rollup": "^0.56.2", + "postcss-import": "^11.1.0", + "postcss-url": "^7.3.1", + "puppeteer": "^1.1.1", + "rollup": "^0.56.3", "rollup-plugin-babel": "^3.0.3", "rollup-plugin-commonjs": "^8.3.0", "rollup-plugin-node-resolve": "^3.0.3",