| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642 | /*! * Cropper.js v1.5.4 * https://fengyuanchen.github.io/cropperjs * * Copyright 2015-present Chen Fengyuan * Released under the MIT license * * Date: 2019-08-03T08:38:42.128Z */(function (global, factory) {  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :  typeof define === 'function' && define.amd ? define(factory) :  (global = global || self, global.Cropper = factory());}(this, function () { 'use strict';  function _typeof(obj) {    if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {      _typeof = function (obj) {        return typeof obj;      };    } else {      _typeof = function (obj) {        return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;      };    }    return _typeof(obj);  }  function _classCallCheck(instance, Constructor) {    if (!(instance instanceof Constructor)) {      throw new TypeError("Cannot call a class as a 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);    }  }  function _createClass(Constructor, protoProps, staticProps) {    if (protoProps) _defineProperties(Constructor.prototype, protoProps);    if (staticProps) _defineProperties(Constructor, staticProps);    return Constructor;  }  function _toConsumableArray(arr) {    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();  }  function _arrayWithoutHoles(arr) {    if (Array.isArray(arr)) {      for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];      return arr2;    }  }  function _iterableToArray(iter) {    if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);  }  function _nonIterableSpread() {    throw new TypeError("Invalid attempt to spread non-iterable instance");  }  var IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';  var WINDOW = IS_BROWSER ? window : {};  var IS_TOUCH_DEVICE = IS_BROWSER ? 'ontouchstart' in WINDOW.document.documentElement : false;  var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;  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 = "".concat(NAMESPACE, "-crop");  var CLASS_DISABLED = "".concat(NAMESPACE, "-disabled");  var CLASS_HIDDEN = "".concat(NAMESPACE, "-hidden");  var CLASS_HIDE = "".concat(NAMESPACE, "-hide");  var CLASS_INVISIBLE = "".concat(NAMESPACE, "-invisible");  var CLASS_MODAL = "".concat(NAMESPACE, "-modal");  var CLASS_MOVE = "".concat(NAMESPACE, "-move"); // Data keys  var DATA_ACTION = "".concat(NAMESPACE, "Action");  var DATA_PREVIEW = "".concat(NAMESPACE, "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_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';  var EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';  var EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';  var EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;  var EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;  var EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;  var EVENT_READY = 'ready';  var EVENT_RESIZE = 'resize';  var EVENT_WHEEL = 'wheel';  var EVENT_ZOOM = 'zoom'; // Mime types  var MIME_TYPE_JPEG = 'image/jpeg'; // 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; // Misc  // Inspired by the default width and height of a canvas element.  var MIN_CONTAINER_WIDTH = 200;  var MIN_CONTAINER_HEIGHT = 100;  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 initial aspect ratio of the crop box    initialAspectRatio: NaN,    // 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 = '<div class="cropper-container" touch-action="none">' + '<div class="cropper-wrap-box">' + '<div class="cropper-canvas"></div>' + '</div>' + '<div class="cropper-drag-box"></div>' + '<div class="cropper-crop-box">' + '<span class="cropper-view-box"></span>' + '<span class="cropper-dashed dashed-h"></span>' + '<span class="cropper-dashed dashed-v"></span>' + '<span class="cropper-center"></span>' + '<span class="cropper-face"></span>' + '<span class="cropper-line line-e" data-cropper-action="e"></span>' + '<span class="cropper-line line-n" data-cropper-action="n"></span>' + '<span class="cropper-line line-w" data-cropper-action="w"></span>' + '<span class="cropper-line line-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-e" data-cropper-action="e"></span>' + '<span class="cropper-point point-n" data-cropper-action="n"></span>' + '<span class="cropper-point point-w" data-cropper-action="w"></span>' + '<span class="cropper-point point-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-ne" data-cropper-action="ne"></span>' + '<span class="cropper-point point-nw" data-cropper-action="nw"></span>' + '<span class="cropper-point point-sw" data-cropper-action="sw"></span>' + '<span class="cropper-point point-se" data-cropper-action="se"></span>' + '</div>' + '</div>';  /**   * 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 a positive number.   * @param {*} value - The value to check.   * @returns {boolean} Returns `true` if the given value is a positive number, else `false`.   */  var isPositiveNumber = function isPositiveNumber(value) {    return value > 0 && value < Infinity;  };  /**   * Check if the given value is undefined.   * @param {*} value - The value to check.   * @returns {boolean} Returns `true` if the given value is undefined, else `false`.   */  function isUndefined(value) {    return typeof value === 'undefined';  }  /**   * Check if the given value is an object.   * @param {*} value - The value to check.   * @returns {boolean} Returns `true` if the given value is an object, else `false`.   */  function isObject(value) {    return _typeof(value) === '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 (error) {      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';  }  var slice = Array.prototype.slice;  /**   * Convert array-like or iterable object to an array.   * @param {*} value - The value to convert.   * @returns {Array} Returns a new array.   */  function toArray(value) {    return Array.from ? Array.from(value) : slice.call(value);  }  /**   * 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 */      ) {          toArray(data).forEach(function (value, key) {            callback.call(data, value, key, data);          });        } else if (isObject(data)) {        Object.keys(data).forEach(function (key) {          callback.call(data, data[key], key, data);        });      }    }    return data;  }  /**   * Extend the given object.   * @param {*} target - The target object to extend.   * @param {*} args - The rest objects for merging to the target object.   * @returns {Object} The extended object.   */  var assign = Object.assign || function assign(target) {    for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {      args[_key - 1] = arguments[_key];    }    if (isObject(target) && args.length > 0) {      args.forEach(function (arg) {        if (isObject(arg)) {          Object.keys(arg).forEach(function (key) {            target[key] = arg[key];          });        }      });    }    return target;  };  var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;  /**   * Normalize decimal number.   * Check out {@link http://0.30000000000000004.com/}   * @param {number} value - The value to normalize.   * @param {number} [times=100000000000] - The times for normalizing.   * @returns {number} Returns the normalized number.   */  function normalizeDecimalNumber(value) {    var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;    return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;  }  var REGEXP_SUFFIX = /^width|height|left|top|marginLeft|marginTop$/;  /**   * Apply styles to the given element.   * @param {Element} element - The target element.   * @param {Object} styles - The styles for applying.   */  function setStyle(element, styles) {    var style = element.style;    forEach(styles, function (value, property) {      if (REGEXP_SUFFIX.test(property) && isNumber(value)) {        value = "".concat(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 = "".concat(className, " ").concat(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_CAMEL_CASE = /([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 toParamCase(value) {    return value.replace(REGEXP_CAMEL_CASE, '$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];    }    if (element.dataset) {      return element.dataset[name];    }    return element.getAttribute("data-".concat(toParamCase(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-".concat(toParamCase(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 (error) {        element[name] = undefined;      }    } else if (element.dataset) {      // #128 Safari not allows to delete dataset property      try {        delete element.dataset[name];      } catch (error) {        element.dataset[name] = undefined;      }    } else {      element.removeAttribute("data-".concat(toParamCase(name)));    }  }  var REGEXP_SPACES = /\s\s*/;  var onceSupported = function () {    var supported = false;    if (IS_BROWSER) {      var once = false;      var listener = function listener() {};      var options = Object.defineProperty({}, 'once', {        get: function get() {          supported = true;          return once;        },        /**         * This setter can fix a `TypeError` in strict mode         * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}         * @param {boolean} value - The value to set         */        set: function set(value) {          once = value;        }      });      WINDOW.addEventListener('test', listener, options);      WINDOW.removeEventListener('test', listener, options);    }    return supported;  }();  /**   * 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] : {};    var handler = listener;    type.trim().split(REGEXP_SPACES).forEach(function (event) {      if (!onceSupported) {        var listeners = element.listeners;        if (listeners && listeners[event] && listeners[event][listener]) {          handler = listeners[event][listener];          delete listeners[event][listener];          if (Object.keys(listeners[event]).length === 0) {            delete listeners[event];          }          if (Object.keys(listeners).length === 0) {            delete element.listeners;          }        }      }      element.removeEventListener(event, handler, 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] : {};    var _handler = listener;    type.trim().split(REGEXP_SPACES).forEach(function (event) {      if (options.once && !onceSupported) {        var _element$listeners = element.listeners,            listeners = _element$listeners === void 0 ? {} : _element$listeners;        _handler = function handler() {          delete listeners[event][listener];          element.removeEventListener(event, _handler, options);          for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {            args[_key2] = arguments[_key2];          }          listener.apply(element, args);        };        if (!listeners[event]) {          listeners[event] = {};        }        if (listeners[event][listener]) {          element.removeEventListener(event, listeners[event][listener], options);        }        listeners[event][listener] = _handler;        element.listeners = listeners;      }      element.addEventListener(event, _handler, 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; // 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 = /^(\w+:)\/\/([^:/?#]*):?(\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 !== null && (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=".concat(new Date().getTime());    return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp;  }  /**   * Get transforms base on the given object.   * @param {Object} obj - The target object.   * @returns {string} A string contains transform values.   */  function getTransforms(_ref) {    var rotate = _ref.rotate,        scaleX = _ref.scaleX,        scaleY = _ref.scaleY,        translateX = _ref.translateX,        translateY = _ref.translateY;    var values = [];    if (isNumber(translateX) && translateX !== 0) {      values.push("translateX(".concat(translateX, "px)"));    }    if (isNumber(translateY) && translateY !== 0) {      values.push("translateY(".concat(translateY, "px)"));    } // Rotate should come first before scale to match orientation transform    if (isNumber(rotate) && rotate !== 0) {      values.push("rotate(".concat(rotate, "deg)"));    }    if (isNumber(scaleX) && scaleX !== 1) {      values.push("scaleX(".concat(scaleX, ")"));    }    if (isNumber(scaleY) && scaleY !== 1) {      values.push("scaleY(".concat(scaleY, ")"));    }    var transform = values.length ? values.join(' ') : 'none';    return {      WebkitTransform: transform,      msTransform: transform,      transform: transform    };  }  /**   * 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 = assign({}, pointers);    var ratios = [];    forEach(pointers, function (pointer, pointerId) {      delete pointers2[pointerId];      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);        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    };    return endOnly ? end : assign({      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;    forEach(pointers, function (_ref3) {      var startX = _ref3.startX,          startY = _ref3.startY;      pageX += startX;      pageY += startY;      count += 1;    });    pageX /= count;    pageY /= count;    return {      pageX: pageX,      pageY: pageY    };  }  /**   * 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 isValidWidth = isPositiveNumber(width);    var isValidHeight = isPositiveNumber(height);    if (isValidWidth && isValidHeight) {      var adjustedWidth = height * aspectRatio;      if (type === 'contain' && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {        height = width / aspectRatio;      } else {        width = height * aspectRatio;      }    } else if (isValidWidth) {      height = width / aspectRatio;    } else if (isValidHeight) {      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 imageAspectRatio = _ref6.aspectRatio,        imageNaturalWidth = _ref6.naturalWidth,        imageNaturalHeight = _ref6.naturalHeight,        _ref6$rotate = _ref6.rotate,        rotate = _ref6$rotate === void 0 ? 0 : _ref6$rotate,        _ref6$scaleX = _ref6.scaleX,        scaleX = _ref6$scaleX === void 0 ? 1 : _ref6$scaleX,        _ref6$scaleY = _ref6.scaleY,        scaleY = _ref6$scaleY === void 0 ? 1 : _ref6$scaleY;    var aspectRatio = _ref7.aspectRatio,        naturalWidth = _ref7.naturalWidth,        naturalHeight = _ref7.naturalHeight;    var _ref8$fillColor = _ref8.fillColor,        fillColor = _ref8$fillColor === void 0 ? 'transparent' : _ref8$fillColor,        _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled,        imageSmoothingEnabled = _ref8$imageSmoothingE === void 0 ? true : _ref8$imageSmoothingE,        _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality,        imageSmoothingQuality = _ref8$imageSmoothingQ === void 0 ? 'low' : _ref8$imageSmoothingQ,        _ref8$maxWidth = _ref8.maxWidth,        maxWidth = _ref8$maxWidth === void 0 ? Infinity : _ref8$maxWidth,        _ref8$maxHeight = _ref8.maxHeight,        maxHeight = _ref8$maxHeight === void 0 ? Infinity : _ref8$maxHeight,        _ref8$minWidth = _ref8.minWidth,        minWidth = _ref8$minWidth === void 0 ? 0 : _ref8$minWidth,        _ref8$minHeight = _ref8.minHeight,        minHeight = _ref8$minHeight === void 0 ? 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)); // Note: should always use image's natural sizes for drawing as    // imageData.naturalWidth === canvasData.naturalHeight when rotate % 180 === 90    var destMaxSizes = getAdjustedSizes({      aspectRatio: imageAspectRatio,      width: maxWidth,      height: maxHeight    });    var destMinSizes = getAdjustedSizes({      aspectRatio: imageAspectRatio,      width: minWidth,      height: minHeight    }, 'cover');    var destWidth = Math.min(destMaxSizes.width, Math.max(destMinSizes.width, imageNaturalWidth));    var destHeight = Math.min(destMaxSizes.height, Math.max(destMinSizes.height, imageNaturalHeight));    var params = [-destWidth / 2, -destHeight / 2, destWidth, destHeight];    canvas.width = normalizeDecimalNumber(width);    canvas.height = normalizeDecimalNumber(height);    context.fillStyle = fillColor;    context.fillRect(0, 0, width, height);    context.save();    context.translate(width / 2, height / 2);    context.rotate(rotate * Math.PI / 180);    context.scale(scaleX, scaleY);    context.imageSmoothingEnabled = imageSmoothingEnabled;    context.imageSmoothingQuality = imageSmoothingQuality;    context.drawImage.apply(context, [image].concat(_toConsumableArray(params.map(function (param) {      return Math.floor(normalizeDecimalNumber(param));    }))));    context.restore();    return canvas;  }  var fromCharCode = String.fromCharCode;  /**   * Get string from char code in data view.   * @param {DataView} dataView - The data view for read.   * @param {number} start - The start index.   * @param {number} length - The read length.   * @returns {string} The read result.   */  function getStringFromCharCode(dataView, start, length) {    var str = '';    length += start;    for (var 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);    forEach(uint8, function (value, i) {      uint8[i] = binary.charCodeAt(i);    });    return arrayBuffer;  }  /**   * Transform array buffer to Data URL.   * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.   * @param {string} mimeType - The mime type of the Data URL.   * @returns {string} The result Data URL.   */  function arrayBufferToDataURL(arrayBuffer, mimeType) {    var chunks = []; // Chunk Typed Array for better performance (#435)    var chunkSize = 8192;    var uint8 = new Uint8Array(arrayBuffer);    while (uint8.length > 0) {      // XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9      // eslint-disable-next-line prefer-spread      chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));      uint8 = uint8.subarray(chunkSize);    }    return "data:".concat(mimeType, ";base64,").concat(btoa(chunks.join('')));  }  /**   * Get orientation value from given array buffer.   * @param {ArrayBuffer} arrayBuffer - The array buffer to read.   * @returns {number} The read orientation value.   */  function resetAndGetOrientation(arrayBuffer) {    var dataView = new DataView(arrayBuffer);    var orientation; // Ignores range error when the image does not have correct Exif information    try {      var littleEndian;      var app1Start;      var ifdStart; // 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 + 1 < 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;        var i;        for (i = 0; i < _length; i += 1) {          _offset = ifdStart + i * 12 + 2;          if (dataView.getUint16(_offset, littleEndian) === 0x0112          /* Orientation */          ) {              // 8 is the offset of the current tag's value              _offset += 8; // Get the original orientation value              orientation = dataView.getUint16(_offset, littleEndian); // Override the orientation with its default value              dataView.setUint16(_offset, 1, littleEndian);              break;            }        }      }    } catch (error) {      orientation = 1;    }    return orientation;  }  /**   * Parse Exif Orientation value.   * @param {number} orientation - The orientation to parse.   * @returns {Object} The parsed result.   */  function parseOrientation(orientation) {    var rotate = 0;    var scaleX = 1;    var scaleY = 1;    switch (orientation) {      // Flip horizontal      case 2:        scaleX = -1;        break;      // Rotate left 180°      case 3:        rotate = -180;        break;      // Flip vertical      case 4:        scaleY = -1;        break;      // Flip vertical and rotate right 90°      case 5:        rotate = 90;        scaleY = -1;        break;      // Rotate right 90°      case 6:        rotate = 90;        break;      // Flip horizontal and rotate right 90°      case 7:        rotate = 90;        scaleX = -1;        break;      // Rotate left 90°      case 8:        rotate = -90;        break;      default:    }    return {      rotate: rotate,      scaleX: scaleX,      scaleY: scaleY    };  }  var render = {    render: function render() {      this.initContainer();      this.initCanvas();      this.initCropBox();      this.renderCanvas();      if (this.cropped) {        this.renderCropBox();      }    },    initContainer: function initContainer() {      var element = this.element,          options = this.options,          container = this.container,          cropper = this.cropper;      addClass(cropper, CLASS_HIDDEN);      removeClass(element, CLASS_HIDDEN);      var containerData = {        width: Math.max(container.offsetWidth, Number(options.minContainerWidth) || 200),        height: Math.max(container.offsetHeight, Number(options.minContainerHeight) || 100)      };      this.containerData = containerData;      setStyle(cropper, {        width: containerData.width,        height: containerData.height      });      addClass(element, CLASS_HIDDEN);      removeClass(cropper, CLASS_HIDDEN);    },    // Canvas (image wrapper)    initCanvas: function initCanvas() {      var containerData = this.containerData,          imageData = this.imageData;      var viewMode = this.options.viewMode;      var rotated = Math.abs(imageData.rotate) % 180 === 90;      var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth;      var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight;      var aspectRatio = naturalWidth / naturalHeight;      var canvasWidth = containerData.width;      var canvasHeight = containerData.height;      if (containerData.height * aspectRatio > containerData.width) {        if (viewMode === 3) {          canvasWidth = containerData.height * aspectRatio;        } else {          canvasHeight = containerData.width / aspectRatio;        }      } else if (viewMode === 3) {        canvasHeight = containerData.width / aspectRatio;      } else {        canvasWidth = containerData.height * aspectRatio;      }      var canvasData = {        aspectRatio: aspectRatio,        naturalWidth: naturalWidth,        naturalHeight: naturalHeight,        width: canvasWidth,        height: canvasHeight      };      canvasData.left = (containerData.width - canvasWidth) / 2;      canvasData.top = (containerData.height - canvasHeight) / 2;      canvasData.oldLeft = canvasData.left;      canvasData.oldTop = canvasData.top;      this.canvasData = canvasData;      this.limited = viewMode === 1 || viewMode === 2;      this.limitCanvas(true, true);      this.initialImageData = assign({}, imageData);      this.initialCanvasData = assign({}, canvasData);    },    limitCanvas: function limitCanvas(sizeLimited, positionLimited) {      var options = this.options,          containerData = this.containerData,          canvasData = this.canvasData,          cropBoxData = this.cropBoxData;      var viewMode = options.viewMode;      var aspectRatio = canvasData.aspectRatio;      var cropped = this.cropped && cropBoxData;      if (sizeLimited) {        var minCanvasWidth = Number(options.minCanvasWidth) || 0;        var minCanvasHeight = Number(options.minCanvasHeight) || 0;        if (viewMode > 1) {          minCanvasWidth = Math.max(minCanvasWidth, containerData.width);          minCanvasHeight = Math.max(minCanvasHeight, containerData.height);          if (viewMode === 3) {            if (minCanvasHeight * aspectRatio > minCanvasWidth) {              minCanvasWidth = minCanvasHeight * aspectRatio;            } else {              minCanvasHeight = minCanvasWidth / aspectRatio;            }          }        } else if (viewMode > 0) {          if (minCanvasWidth) {            minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0);          } else if (minCanvasHeight) {            minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0);          } else if (cropped) {            minCanvasWidth = cropBoxData.width;            minCanvasHeight = cropBoxData.height;            if (minCanvasHeight * aspectRatio > minCanvasWidth) {              minCanvasWidth = minCanvasHeight * aspectRatio;            } else {              minCanvasHeight = minCanvasWidth / aspectRatio;            }          }        }        var _getAdjustedSizes = getAdjustedSizes({          aspectRatio: aspectRatio,          width: minCanvasWidth,          height: minCanvasHeight        });        minCanvasWidth = _getAdjustedSizes.width;        minCanvasHeight = _getAdjustedSizes.height;        canvasData.minWidth = minCanvasWidth;        canvasData.minHeight = minCanvasHeight;        canvasData.maxWidth = Infinity;        canvasData.maxHeight = Infinity;      }      if (positionLimited) {        if (viewMode > (cropped ? 0 : 1)) {          var newCanvasLeft = containerData.width - canvasData.width;          var newCanvasTop = containerData.height - canvasData.height;          canvasData.minLeft = Math.min(0, newCanvasLeft);          canvasData.minTop = Math.min(0, newCanvasTop);          canvasData.maxLeft = Math.max(0, newCanvasLeft);          canvasData.maxTop = Math.max(0, newCanvasTop);          if (cropped && this.limited) {            canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width));            canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height));            canvasData.maxLeft = cropBoxData.left;            canvasData.maxTop = cropBoxData.top;            if (viewMode === 2) {              if (canvasData.width >= containerData.width) {                canvasData.minLeft = Math.min(0, newCanvasLeft);                canvasData.maxLeft = Math.max(0, newCanvasLeft);              }              if (canvasData.height >= containerData.height) {                canvasData.minTop = Math.min(0, newCanvasTop);                canvasData.maxTop = Math.max(0, newCanvasTop);              }            }          }        } else {          canvasData.minLeft = -canvasData.width;          canvasData.minTop = -canvasData.height;          canvasData.maxLeft = containerData.width;          canvasData.maxTop = containerData.height;        }      }    },    renderCanvas: function renderCanvas(changed, transformed) {      var canvasData = this.canvasData,          imageData = this.imageData;      if (transformed) {        var _getRotatedSizes = getRotatedSizes({          width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),          height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),          degree: imageData.rotate || 0        }),            naturalWidth = _getRotatedSizes.width,            naturalHeight = _getRotatedSizes.height;        var width = canvasData.width * (naturalWidth / canvasData.naturalWidth);        var height = canvasData.height * (naturalHeight / canvasData.naturalHeight);        canvasData.left -= (width - canvasData.width) / 2;        canvasData.top -= (height - canvasData.height) / 2;        canvasData.width = width;        canvasData.height = height;        canvasData.aspectRatio = naturalWidth / naturalHeight;        canvasData.naturalWidth = naturalWidth;        canvasData.naturalHeight = naturalHeight;        this.limitCanvas(true, false);      }      if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) {        canvasData.left = canvasData.oldLeft;      }      if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) {        canvasData.top = canvasData.oldTop;      }      canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);      canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);      this.limitCanvas(false, true);      canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft);      canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop);      canvasData.oldLeft = canvasData.left;      canvasData.oldTop = canvasData.top;      setStyle(this.canvas, assign({        width: canvasData.width,        height: canvasData.height      }, getTransforms({        translateX: canvasData.left,        translateY: canvasData.top      })));      this.renderImage(changed);      if (this.cropped && this.limited) {        this.limitCropBox(true, true);      }    },    renderImage: function renderImage(changed) {      var canvasData = this.canvasData,          imageData = this.imageData;      var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth);      var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight);      assign(imageData, {        width: width,        height: height,        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();      }    },    initCropBox: function initCropBox() {      var options = this.options,          canvasData = this.canvasData;      var aspectRatio = options.aspectRatio || options.initialAspectRatio;      var autoCropArea = Number(options.autoCropArea) || 0.8;      var cropBoxData = {        width: canvasData.width,        height: canvasData.height      };      if (aspectRatio) {        if (canvasData.height * aspectRatio > canvasData.width) {          cropBoxData.height = cropBoxData.width / aspectRatio;        } else {          cropBoxData.width = cropBoxData.height * aspectRatio;        }      }      this.cropBoxData = cropBoxData;      this.limitCropBox(true, true); // Initialize auto crop area      cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);      cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); // The width/height of auto crop area must large than "minWidth/Height"      cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea);      cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea);      cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2;      cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2;      cropBoxData.oldLeft = cropBoxData.left;      cropBoxData.oldTop = cropBoxData.top;      this.initialCropBoxData = assign({}, cropBoxData);    },    limitCropBox: function limitCropBox(sizeLimited, positionLimited) {      var options = this.options,          containerData = this.containerData,          canvasData = this.canvasData,          cropBoxData = this.cropBoxData,          limited = this.limited;      var aspectRatio = options.aspectRatio;      if (sizeLimited) {        var minCropBoxWidth = Number(options.minCropBoxWidth) || 0;        var minCropBoxHeight = Number(options.minCropBoxHeight) || 0;        var maxCropBoxWidth = limited ? Math.min(containerData.width, canvasData.width, canvasData.width + canvasData.left, containerData.width - canvasData.left) : containerData.width;        var maxCropBoxHeight = limited ? Math.min(containerData.height, canvasData.height, canvasData.height + canvasData.top, containerData.height - canvasData.top) : containerData.height; // The min/maxCropBoxWidth/Height must be less than container's width/height        minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width);        minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height);        if (aspectRatio) {          if (minCropBoxWidth && minCropBoxHeight) {            if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {              minCropBoxHeight = minCropBoxWidth / aspectRatio;            } else {              minCropBoxWidth = minCropBoxHeight * aspectRatio;            }          } else if (minCropBoxWidth) {            minCropBoxHeight = minCropBoxWidth / aspectRatio;          } else if (minCropBoxHeight) {            minCropBoxWidth = minCropBoxHeight * aspectRatio;          }          if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {            maxCropBoxHeight = maxCropBoxWidth / aspectRatio;          } else {            maxCropBoxWidth = maxCropBoxHeight * aspectRatio;          }        } // The minWidth/Height must be less than maxWidth/Height        cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth);        cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight);        cropBoxData.maxWidth = maxCropBoxWidth;        cropBoxData.maxHeight = maxCropBoxHeight;      }      if (positionLimited) {        if (limited) {          cropBoxData.minLeft = Math.max(0, canvasData.left);          cropBoxData.minTop = Math.max(0, canvasData.top);          cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width;          cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height;        } else {          cropBoxData.minLeft = 0;          cropBoxData.minTop = 0;          cropBoxData.maxLeft = containerData.width - cropBoxData.width;          cropBoxData.maxTop = containerData.height - cropBoxData.height;        }      }    },    renderCropBox: function renderCropBox() {      var options = this.options,          containerData = this.containerData,          cropBoxData = this.cropBoxData;      if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) {        cropBoxData.left = cropBoxData.oldLeft;      }      if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) {        cropBoxData.top = cropBoxData.oldTop;      }      cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);      cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);      this.limitCropBox(false, true);      cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft);      cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop);      cropBoxData.oldLeft = cropBoxData.left;      cropBoxData.oldTop = cropBoxData.top;      if (options.movable && options.cropBoxMovable) {        // Turn to move the canvas when the crop box is equal to the container        setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL);      }      setStyle(this.cropBox, assign({        width: cropBoxData.width,        height: cropBoxData.height      }, getTransforms({        translateX: cropBoxData.left,        translateY: cropBoxData.top      })));      if (this.cropped && this.limited) {        this.limitCanvas(true, true);      }      if (!this.disabled) {        this.output();      }    },    output: function output() {      this.preview();      dispatchEvent(this.element, EVENT_CROP, this.getData());    }  };  var preview = {    initPreview: function initPreview() {      var element = this.element,          crossOrigin = this.crossOrigin;      var preview = this.options.preview;      var url = crossOrigin ? this.crossOriginUrl : this.url;      var alt = element.alt || 'The image to preview';      var image = document.createElement('img');      if (crossOrigin) {        image.crossOrigin = crossOrigin;      }      image.src = url;      image.alt = alt;      this.viewBox.appendChild(image);      this.viewBoxImage = image;      if (!preview) {        return;      }      var previews = preview;      if (typeof preview === 'string') {        previews = 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        setData(el, DATA_PREVIEW, {          width: el.offsetWidth,          height: el.offsetHeight,          html: el.innerHTML        });        if (crossOrigin) {          img.crossOrigin = crossOrigin;        }        img.src = url;        img.alt = alt;        /**         * 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;"';        el.innerHTML = '';        el.appendChild(img);      });    },    resetPreview: function resetPreview() {      forEach(this.previews, function (element) {        var data = getData(element, DATA_PREVIEW);        setStyle(element, {          width: data.width,          height: data.height        });        element.innerHTML = data.html;        removeData(element, DATA_PREVIEW);      });    },    preview: function preview() {      var imageData = this.imageData,          canvasData = this.canvasData,          cropBoxData = this.cropBoxData;      var cropBoxWidth = cropBoxData.width,          cropBoxHeight = cropBoxData.height;      var width = imageData.width,          height = imageData.height;      var left = cropBoxData.left - canvasData.left - imageData.left;      var top = cropBoxData.top - canvasData.top - imageData.top;      if (!this.cropped || this.disabled) {        return;      }      setStyle(this.viewBoxImage, assign({        width: width,        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;        var newHeight = originalHeight;        var ratio = 1;        if (cropBoxWidth) {          ratio = originalWidth / cropBoxWidth;          newHeight = cropBoxHeight * ratio;        }        if (cropBoxHeight && newHeight > originalHeight) {          ratio = originalHeight / cropBoxHeight;          newWidth = cropBoxWidth * ratio;          newHeight = originalHeight;        }        setStyle(element, {          width: newWidth,          height: newHeight        });        setStyle(element.getElementsByTagName('img')[0], 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,          options = this.options,          cropper = this.cropper;      if (isFunction(options.cropstart)) {        addListener(element, EVENT_CROP_START, options.cropstart);      }      if (isFunction(options.cropmove)) {        addListener(element, EVENT_CROP_MOVE, options.cropmove);      }      if (isFunction(options.cropend)) {        addListener(element, EVENT_CROP_END, options.cropend);      }      if (isFunction(options.crop)) {        addListener(element, EVENT_CROP, options.crop);      }      if (isFunction(options.zoom)) {        addListener(element, EVENT_ZOOM, options.zoom);      }      addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this));      if (options.zoomable && options.zoomOnWheel) {        addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {          passive: false,          capture: true        });      }      if (options.toggleDragModeOnDblclick) {        addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(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) {        addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));      }    },    unbind: function unbind() {      var element = this.element,          options = this.options,          cropper = this.cropper;      if (isFunction(options.cropstart)) {        removeListener(element, EVENT_CROP_START, options.cropstart);      }      if (isFunction(options.cropmove)) {        removeListener(element, EVENT_CROP_MOVE, options.cropmove);      }      if (isFunction(options.cropend)) {        removeListener(element, EVENT_CROP_END, options.cropend);      }      if (isFunction(options.crop)) {        removeListener(element, EVENT_CROP, options.crop);      }      if (isFunction(options.zoom)) {        removeListener(element, EVENT_ZOOM, options.zoom);      }      removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart);      if (options.zoomable && options.zoomOnWheel) {        removeListener(cropper, EVENT_WHEEL, this.onWheel, {          passive: false,          capture: true        });      }      if (options.toggleDragModeOnDblclick) {        removeListener(cropper, EVENT_DBLCLICK, this.onDblclick);      }      removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove);      removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd);      if (options.responsive) {        removeListener(window, EVENT_RESIZE, this.onResize);      }    }  };  var handlers = {    resize: function resize() {      var options = this.options,          container = this.container,          containerData = this.containerData;      var minContainerWidth = Number(options.minContainerWidth) || MIN_CONTAINER_WIDTH;      var minContainerHeight = Number(options.minContainerHeight) || MIN_CONTAINER_HEIGHT;      if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) {        return;      }      var ratio = container.offsetWidth / containerData.width; // Resize when width changed or height changed      if (ratio !== 1 || container.offsetHeight !== containerData.height) {        var canvasData;        var cropBoxData;        if (options.restore) {          canvasData = this.getCanvasData();          cropBoxData = this.getCropBoxData();        }        this.render();        if (options.restore) {          this.setCanvasData(forEach(canvasData, function (n, i) {            canvasData[i] = n * ratio;          }));          this.setCropBoxData(forEach(cropBoxData, function (n, i) {            cropBoxData[i] = n * ratio;          }));        }      }    },    dblclick: function dblclick() {      if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) {        return;      }      this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP);    },    wheel: function wheel(event) {      var _this = this;      var ratio = Number(this.options.wheelZoomRatio) || 0.1;      var delta = 1;      if (this.disabled) {        return;      }      event.preventDefault(); // Limit wheel speed to prevent zoom too fast (#21)      if (this.wheeling) {        return;      }      this.wheeling = true;      setTimeout(function () {        _this.wheeling = false;      }, 50);      if (event.deltaY) {        delta = event.deltaY > 0 ? 1 : -1;      } else if (event.wheelDelta) {        delta = -event.wheelDelta / 120;      } else if (event.detail) {        delta = event.detail > 0 ? 1 : -1;      }      this.zoom(-delta * ratio, event);    },    cropStart: function cropStart(event) {      var buttons = event.buttons,          button = event.button;      if (this.disabled // No primary button (Usually the left button)      // Note that touch events have no `buttons` or `button` property      || isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0 // Open context menu      || event.ctrlKey) {        return;      }      var options = this.options,          pointers = this.pointers;      var action;      if (event.changedTouches) {        // Handle touch event        forEach(event.changedTouches, function (touch) {          pointers[touch.identifier] = getPointer(touch);        });      } else {        // Handle mouse event and pointer event        pointers[event.pointerId || 0] = getPointer(event);      }      if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) {        action = ACTION_ZOOM;      } else {        action = getData(event.target, DATA_ACTION);      }      if (!REGEXP_ACTIONS.test(action)) {        return;      }      if (dispatchEvent(this.element, EVENT_CROP_START, {        originalEvent: event,        action: action      }) === false) {        return;      } // This line is required for preventing page zooming in iOS browsers      event.preventDefault();      this.action = action;      this.cropping = false;      if (action === ACTION_CROP) {        this.cropping = true;        addClass(this.dragBox, CLASS_MODAL);      }    },    cropMove: function cropMove(event) {      var action = this.action;      if (this.disabled || !action) {        return;      }      var pointers = this.pointers;      event.preventDefault();      if (dispatchEvent(this.element, EVENT_CROP_MOVE, {        originalEvent: event,        action: action      }) === false) {        return;      }      if (event.changedTouches) {        forEach(event.changedTouches, function (touch) {          // The first parameter should not be undefined (#432)          assign(pointers[touch.identifier] || {}, getPointer(touch, true));        });      } else {        assign(pointers[event.pointerId || 0] || {}, getPointer(event, true));      }      this.change(event);    },    cropEnd: function cropEnd(event) {      if (this.disabled) {        return;      }      var action = this.action,          pointers = this.pointers;      if (event.changedTouches) {        forEach(event.changedTouches, function (touch) {          delete pointers[touch.identifier];        });      } else {        delete pointers[event.pointerId || 0];      }      if (!action) {        return;      }      event.preventDefault();      if (!Object.keys(pointers).length) {        this.action = '';      }      if (this.cropping) {        this.cropping = false;        toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal);      }      dispatchEvent(this.element, EVENT_CROP_END, {        originalEvent: event,        action: action      });    }  };  var change = {    change: function change(event) {      var options = this.options,          canvasData = this.canvasData,          containerData = this.containerData,          cropBoxData = this.cropBoxData,          pointers = this.pointers;      var action = this.action;      var aspectRatio = options.aspectRatio;      var left = cropBoxData.left,          top = cropBoxData.top,          width = cropBoxData.width,          height = cropBoxData.height;      var right = left + width;      var bottom = top + height;      var minLeft = 0;      var minTop = 0;      var maxWidth = containerData.width;      var maxHeight = containerData.height;      var renderable = true;      var offset; // Locking aspect ratio in "free mode" by holding shift key      if (!aspectRatio && event.shiftKey) {        aspectRatio = width && height ? width / height : 1;      }      if (this.limited) {        minLeft = cropBoxData.minLeft;        minTop = cropBoxData.minTop;        maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width);        maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height);      }      var pointer = pointers[Object.keys(pointers)[0]];      var range = {        x: pointer.endX - pointer.startX,        y: pointer.endY - pointer.startY      };      var check = function check(side) {        switch (side) {          case ACTION_EAST:            if (right + range.x > maxWidth) {              range.x = maxWidth - right;            }            break;          case ACTION_WEST:            if (left + range.x < minLeft) {              range.x = minLeft - left;            }            break;          case ACTION_NORTH:            if (top + range.y < minTop) {              range.y = minTop - top;            }            break;          case ACTION_SOUTH:            if (bottom + range.y > maxHeight) {              range.y = maxHeight - bottom;            }            break;          default:        }      };      switch (action) {        // Move crop box        case ACTION_ALL:          left += range.x;          top += range.y;          break;        // Resize crop box        case ACTION_EAST:          if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) {            renderable = false;            break;          }          check(ACTION_EAST);          width += range.x;          if (width < 0) {            action = ACTION_WEST;            width = -width;            left -= width;          }          if (aspectRatio) {            height = width / aspectRatio;            top += (cropBoxData.height - height) / 2;          }          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 (height < 0) {            action = ACTION_SOUTH;            height = -height;            top -= height;          }          if (aspectRatio) {            width = height * aspectRatio;            left += (cropBoxData.width - width) / 2;          }          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 (width < 0) {            action = ACTION_EAST;            width = -width;            left -= width;          }          if (aspectRatio) {            height = width / aspectRatio;            top += (cropBoxData.height - height) / 2;          }          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 (height < 0) {            action = ACTION_NORTH;            height = -height;            top -= height;          }          if (aspectRatio) {            width = height * aspectRatio;            left += (cropBoxData.width - width) / 2;          }          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 = -height;            width = -width;            top -= height;            left -= width;          } else if (width < 0) {            action = ACTION_NORTH_WEST;            width = -width;            left -= width;          } else if (height < 0) {            action = ACTION_SOUTH_EAST;            height = -height;            top -= height;          }          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 += cropBoxData.width - width;          } 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 = -height;            width = -width;            top -= height;            left -= width;          } else if (width < 0) {            action = ACTION_NORTH_EAST;            width = -width;            left -= width;          } else if (height < 0) {            action = ACTION_SOUTH_WEST;            height = -height;            top -= height;          }          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 = -height;            width = -width;            top -= height;            left -= width;          } else if (width < 0) {            action = ACTION_SOUTH_EAST;            width = -width;            left -= width;          } else if (height < 0) {            action = ACTION_NORTH_WEST;            height = -height;            top -= height;          }          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 = -height;            width = -width;            top -= height;            left -= width;          } else if (width < 0) {            action = ACTION_SOUTH_WEST;            width = -width;            left -= width;          } else if (height < 0) {            action = ACTION_NORTH_EAST;            height = -height;            top -= height;          }          break;        // Move canvas        case ACTION_MOVE:          this.move(range.x, range.y);          renderable = false;          break;        // Zoom canvas        case ACTION_ZOOM:          this.zoom(getMaxZoomRatio(pointers), event);          renderable = false;          break;        // Create crop box        case ACTION_CROP:          if (!range.x || !range.y) {            renderable = false;            break;          }          offset = getOffset(this.cropper);          left = pointer.startX - offset.left;          top = pointer.startY - offset.top;          width = cropBoxData.minWidth;          height = cropBoxData.minHeight;          if (range.x > 0) {            action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;          } else if (range.x < 0) {            left -= width;            action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;          }          if (range.y < 0) {            top -= height;          } // Show the crop box if is hidden          if (!this.cropped) {            removeClass(this.cropBox, CLASS_HIDDEN);            this.cropped = true;            if (this.limited) {              this.limitCropBox(true, true);            }          }          break;        default:      }      if (renderable) {        cropBoxData.width = width;        cropBoxData.height = height;        cropBoxData.left = left;        cropBoxData.top = top;        this.action = action;        this.renderCropBox();      } // Override      forEach(pointers, function (p) {        p.startX = p.endX;        p.startY = p.endY;      });    }  };  var methods = {    // Show the crop box manually    crop: function crop() {      if (this.ready && !this.cropped && !this.disabled) {        this.cropped = true;        this.limitCropBox(true, true);        if (this.options.modal) {          addClass(this.dragBox, CLASS_MODAL);        }        removeClass(this.cropBox, CLASS_HIDDEN);        this.setCropBoxData(this.initialCropBoxData);      }      return this;    },    // Reset the image and crop box to their initial states    reset: function reset() {      if (this.ready && !this.disabled) {        this.imageData = assign({}, this.initialImageData);        this.canvasData = assign({}, this.initialCanvasData);        this.cropBoxData = assign({}, this.initialCropBoxData);        this.renderCanvas();        if (this.cropped) {          this.renderCropBox();        }      }      return this;    },    // Clear the crop box    clear: function clear() {      if (this.cropped && !this.disabled) {        assign(this.cropBoxData, {          left: 0,          top: 0,          width: 0,          height: 0        });        this.cropped = false;        this.renderCropBox();        this.limitCanvas(true, true); // Render canvas after crop box rendered        this.renderCanvas();        removeClass(this.dragBox, CLASS_MODAL);        addClass(this.cropBox, CLASS_HIDDEN);      }      return this;    },    /**     * Replace the image's src and rebuild the cropper     * @param {string} url - The new URL.     * @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one.     * @returns {Cropper} this     */    replace: function replace(url) {      var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;      if (!this.disabled && url) {        if (this.isImg) {          this.element.src = url;        }        if (hasSameSize) {          this.url = url;          this.image.src = url;          if (this.ready) {            this.viewBoxImage.src = url;            forEach(this.previews, function (element) {              element.getElementsByTagName('img')[0].src = url;            });          }        } else {          if (this.isImg) {            this.replaced = true;          }          this.options.data = null;          this.uncreate();          this.load(url);        }      }      return this;    },    // Enable (unfreeze) the cropper    enable: function enable() {      if (this.ready && this.disabled) {        this.disabled = false;        removeClass(this.cropper, CLASS_DISABLED);      }      return this;    },    // Disable (freeze) the cropper    disable: function disable() {      if (this.ready && !this.disabled) {        this.disabled = true;        addClass(this.cropper, CLASS_DISABLED);      }      return this;    },    /**     * Destroy the cropper and remove the instance from the image     * @returns {Cropper} this     */    destroy: function destroy() {      var element = this.element;      if (!element[NAMESPACE]) {        return this;      }      element[NAMESPACE] = undefined;      if (this.isImg && this.replaced) {        element.src = this.originalUrl;      }      this.uncreate();      return this;    },    /**     * Move the canvas with relative offsets     * @param {number} offsetX - The relative offset distance on the x-axis.     * @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis.     * @returns {Cropper} this     */    move: function move(offsetX) {      var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX;      var _this$canvasData = this.canvasData,          left = _this$canvasData.left,          top = _this$canvasData.top;      return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY));    },    /**     * Move the canvas to an absolute point     * @param {number} x - The x-axis coordinate.     * @param {number} [y=x] - The y-axis coordinate.     * @returns {Cropper} this     */    moveTo: function moveTo(x) {      var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;      var canvasData = this.canvasData;      var changed = false;      x = Number(x);      y = Number(y);      if (this.ready && !this.disabled && this.options.movable) {        if (isNumber(x)) {          canvasData.left = x;          changed = true;        }        if (isNumber(y)) {          canvasData.top = y;          changed = true;        }        if (changed) {          this.renderCanvas(true);        }      }      return this;    },    /**     * Zoom the canvas with a relative ratio     * @param {number} ratio - The target ratio.     * @param {Event} _originalEvent - The original event if any.     * @returns {Cropper} this     */    zoom: function zoom(ratio, _originalEvent) {      var canvasData = this.canvasData;      ratio = Number(ratio);      if (ratio < 0) {        ratio = 1 / (1 - ratio);      } else {        ratio = 1 + ratio;      }      return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent);    },    /**     * Zoom the canvas to an absolute ratio     * @param {number} ratio - The target ratio.     * @param {Object} pivot - The zoom pivot point coordinate.     * @param {Event} _originalEvent - The original event if any.     * @returns {Cropper} this     */    zoomTo: function zoomTo(ratio, pivot, _originalEvent) {      var options = this.options,          canvasData = this.canvasData;      var width = canvasData.width,          height = canvasData.height,          naturalWidth = canvasData.naturalWidth,          naturalHeight = canvasData.naturalHeight;      ratio = Number(ratio);      if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) {        var newWidth = naturalWidth * ratio;        var newHeight = naturalHeight * ratio;        if (dispatchEvent(this.element, EVENT_ZOOM, {          ratio: ratio,          oldRatio: width / naturalWidth,          originalEvent: _originalEvent        }) === false) {          return this;        }        if (_originalEvent) {          var pointers = this.pointers;          var offset = getOffset(this.cropper);          var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {            pageX: _originalEvent.pageX,            pageY: _originalEvent.pageY          }; // Zoom from the triggering point of the event          canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width);          canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height);        } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {          canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width);          canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height);        } else {          // Zoom from the center of the canvas          canvasData.left -= (newWidth - width) / 2;          canvasData.top -= (newHeight - height) / 2;        }        canvasData.width = newWidth;        canvasData.height = newHeight;        this.renderCanvas(true);      }      return this;    },    /**     * Rotate the canvas with a relative degree     * @param {number} degree - The rotate degree.     * @returns {Cropper} this     */    rotate: function rotate(degree) {      return this.rotateTo((this.imageData.rotate || 0) + Number(degree));    },    /**     * Rotate the canvas to an absolute degree     * @param {number} degree - The rotate degree.     * @returns {Cropper} this     */    rotateTo: function rotateTo(degree) {      degree = Number(degree);      if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) {        this.imageData.rotate = degree % 360;        this.renderCanvas(true, true);      }      return this;    },    /**     * Scale the image on the x-axis.     * @param {number} scaleX - The scale ratio on the x-axis.     * @returns {Cropper} this     */    scaleX: function scaleX(_scaleX) {      var scaleY = this.imageData.scaleY;      return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1);    },    /**     * Scale the image on the y-axis.     * @param {number} scaleY - The scale ratio on the y-axis.     * @returns {Cropper} this     */    scaleY: function scaleY(_scaleY) {      var scaleX = this.imageData.scaleX;      return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY);    },    /**     * Scale the image     * @param {number} scaleX - The scale ratio on the x-axis.     * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.     * @returns {Cropper} this     */    scale: function scale(scaleX) {      var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;      var imageData = this.imageData;      var transformed = false;      scaleX = Number(scaleX);      scaleY = Number(scaleY);      if (this.ready && !this.disabled && this.options.scalable) {        if (isNumber(scaleX)) {          imageData.scaleX = scaleX;          transformed = true;        }        if (isNumber(scaleY)) {          imageData.scaleY = scaleY;          transformed = true;        }        if (transformed) {          this.renderCanvas(true, true);        }      }      return this;    },    /**     * Get the cropped area position and size data (base on the original image)     * @param {boolean} [rounded=false] - Indicate if round the data values or not.     * @returns {Object} The result cropped data.     */    getData: function getData() {      var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;      var options = this.options,          imageData = this.imageData,          canvasData = this.canvasData,          cropBoxData = this.cropBoxData;      var data;      if (this.ready && this.cropped) {        data = {          x: cropBoxData.left - canvasData.left,          y: cropBoxData.top - canvasData.top,          width: cropBoxData.width,          height: cropBoxData.height        };        var ratio = imageData.width / imageData.naturalWidth;        forEach(data, function (n, i) {          data[i] = n / ratio;        });        if (rounded) {          // In case rounding off leads to extra 1px in right or bottom border          // we should round the top-left corner and the dimension (#343).          var bottom = Math.round(data.y + data.height);          var right = Math.round(data.x + data.width);          data.x = Math.round(data.x);          data.y = Math.round(data.y);          data.width = right - data.x;          data.height = bottom - data.y;        }      } else {        data = {          x: 0,          y: 0,          width: 0,          height: 0        };      }      if (options.rotatable) {        data.rotate = imageData.rotate || 0;      }      if (options.scalable) {        data.scaleX = imageData.scaleX || 1;        data.scaleY = imageData.scaleY || 1;      }      return data;    },    /**     * Set the cropped area position and size with new data     * @param {Object} data - The new data.     * @returns {Cropper} this     */    setData: function setData(data) {      var options = this.options,          imageData = this.imageData,          canvasData = this.canvasData;      var cropBoxData = {};      if (this.ready && !this.disabled && isPlainObject(data)) {        var transformed = false;        if (options.rotatable) {          if (isNumber(data.rotate) && data.rotate !== imageData.rotate) {            imageData.rotate = data.rotate;            transformed = true;          }        }        if (options.scalable) {          if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) {            imageData.scaleX = data.scaleX;            transformed = true;          }          if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) {            imageData.scaleY = data.scaleY;            transformed = true;          }        }        if (transformed) {          this.renderCanvas(true, true);        }        var ratio = imageData.width / imageData.naturalWidth;        if (isNumber(data.x)) {          cropBoxData.left = data.x * ratio + canvasData.left;        }        if (isNumber(data.y)) {          cropBoxData.top = data.y * ratio + canvasData.top;        }        if (isNumber(data.width)) {          cropBoxData.width = data.width * ratio;        }        if (isNumber(data.height)) {          cropBoxData.height = data.height * ratio;        }        this.setCropBoxData(cropBoxData);      }      return this;    },    /**     * Get the container size data.     * @returns {Object} The result container data.     */    getContainerData: function getContainerData() {      return this.ready ? assign({}, this.containerData) : {};    },    /**     * Get the image position and size data.     * @returns {Object} The result image data.     */    getImageData: function getImageData() {      return this.sized ? assign({}, this.imageData) : {};    },    /**     * Get the canvas position and size data.     * @returns {Object} The result canvas data.     */    getCanvasData: function getCanvasData() {      var canvasData = this.canvasData;      var data = {};      if (this.ready) {        forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) {          data[n] = canvasData[n];        });      }      return data;    },    /**     * Set the canvas position and size with new data.     * @param {Object} data - The new canvas data.     * @returns {Cropper} this     */    setCanvasData: function setCanvasData(data) {      var canvasData = this.canvasData;      var aspectRatio = canvasData.aspectRatio;      if (this.ready && !this.disabled && isPlainObject(data)) {        if (isNumber(data.left)) {          canvasData.left = data.left;        }        if (isNumber(data.top)) {          canvasData.top = data.top;        }        if (isNumber(data.width)) {          canvasData.width = data.width;          canvasData.height = data.width / aspectRatio;        } else if (isNumber(data.height)) {          canvasData.height = data.height;          canvasData.width = data.height * aspectRatio;        }        this.renderCanvas(true);      }      return this;    },    /**     * Get the crop box position and size data.     * @returns {Object} The result crop box data.     */    getCropBoxData: function getCropBoxData() {      var cropBoxData = this.cropBoxData;      var data;      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 cropBoxData = this.cropBoxData;      var aspectRatio = this.options.aspectRatio;      var widthChanged;      var heightChanged;      if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) {        if (isNumber(data.left)) {          cropBoxData.left = data.left;        }        if (isNumber(data.top)) {          cropBoxData.top = data.top;        }        if (isNumber(data.width) && data.width !== cropBoxData.width) {          widthChanged = true;          cropBoxData.width = data.width;        }        if (isNumber(data.height) && data.height !== cropBoxData.height) {          heightChanged = true;          cropBoxData.height = data.height;        }        if (aspectRatio) {          if (widthChanged) {            cropBoxData.height = cropBoxData.width / aspectRatio;          } else if (heightChanged) {            cropBoxData.width = cropBoxData.height * aspectRatio;          }        }        this.renderCropBox();      }      return this;    },    /**     * Get a canvas drawn the cropped image.     * @param {Object} [options={}] - The config options.     * @returns {HTMLCanvasElement} - The result canvas.     */    getCroppedCanvas: function getCroppedCanvas() {      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};      if (!this.ready || !window.HTMLCanvasElement) {        return null;      }      var canvasData = this.canvasData;      var source = getSourceCanvas(this.image, this.imageData, canvasData, options); // Returns the source canvas if it is not cropped.      if (!this.cropped) {        return source;      }      var _this$getData = this.getData(),          initialX = _this$getData.x,          initialY = _this$getData.y,          initialWidth = _this$getData.width,          initialHeight = _this$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 === void 0 ? 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;      var srcHeight; // Destination canvas parameters      var dstX;      var dstY;      var dstWidth;      var dstHeight;      if (srcX <= -initialWidth || srcX > sourceWidth) {        srcX = 0;        srcWidth = 0;        dstX = 0;        dstWidth = 0;      } else if (srcX <= 0) {        dstX = -srcX;        srcX = 0;        srcWidth = Math.min(sourceWidth, initialWidth + srcX);        dstWidth = srcWidth;      } else if (srcX <= sourceWidth) {        dstX = 0;        srcWidth = Math.min(initialWidth, sourceWidth - srcX);        dstWidth = srcWidth;      }      if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) {        srcY = 0;        srcHeight = 0;        dstY = 0;        dstHeight = 0;      } else if (srcY <= 0) {        dstY = -srcY;        srcY = 0;        srcHeight = Math.min(sourceHeight, initialHeight + srcY);        dstHeight = srcHeight;      } else if (srcY <= sourceHeight) {        dstY = 0;        srcHeight = Math.min(initialHeight, sourceHeight - srcY);        dstHeight = srcHeight;      }      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);      } // All the numerical parameters should be integer for `drawImage`      // https://github.com/fengyuanchen/cropper/issues/476      context.drawImage.apply(context, [source].concat(_toConsumableArray(params.map(function (param) {        return Math.floor(normalizeDecimalNumber(param));      }))));      return canvas;    },    /**     * Change the aspect ratio of the crop box.     * @param {number} aspectRatio - The new aspect ratio.     * @returns {Cropper} this     */    setAspectRatio: function setAspectRatio(aspectRatio) {      var options = this.options;      if (!this.disabled && !isUndefined(aspectRatio)) {        // 0 -> NaN        options.aspectRatio = Math.max(0, aspectRatio) || NaN;        if (this.ready) {          this.initCropBox();          if (this.cropped) {            this.renderCropBox();          }        }      }      return this;    },    /**     * Change the drag mode.     * @param {string} mode - The new drag mode.     * @returns {Cropper} this     */    setDragMode: function setDragMode(mode) {      var options = this.options,          dragBox = this.dragBox,          face = this.face;      if (this.ready && !this.disabled) {        var croppable = mode === DRAG_MODE_CROP;        var movable = options.movable && mode === DRAG_MODE_MOVE;        mode = croppable || movable ? mode : DRAG_MODE_NONE;        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          setData(face, DATA_ACTION, mode);          toggleClass(face, CLASS_CROP, croppable);          toggleClass(face, CLASS_MOVE, movable);        }      }      return this;    }  };  var AnotherCropper = WINDOW.Cropper;  var Cropper =  /*#__PURE__*/  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 <img> or <canvas> element.');      }      this.element = element;      this.options = assign({}, DEFAULTS, isPlainObject(options) && options);      this.cropped = false;      this.disabled = false;      this.pointers = {};      this.ready = false;      this.reloading = false;      this.replaced = false;      this.sized = false;      this.sizing = false;      this.init();    }    _createClass(Cropper, [{      key: "init",      value: function init() {        var element = this.element;        var tagName = element.tagName.toLowerCase();        var url;        if (element[NAMESPACE]) {          return;        }        element[NAMESPACE] = this;        if (tagName === 'img') {          this.isImg = true; // e.g.: "img/picture.jpg"          url = element.getAttribute('src') || '';          this.originalUrl = url; // Stop when it's a blank image          if (!url) {            return;          } // e.g.: "http://example.com/img/picture.jpg"          url = element.src;        } else if (tagName === 'canvas' && window.HTMLCanvasElement) {          url = element.toDataURL();        }        this.load(url);      }    }, {      key: "load",      value: function load(url) {        var _this = this;        if (!url) {          return;        }        this.url = url;        this.imageData = {};        var element = this.element,            options = this.options;        if (!options.rotatable && !options.scalable) {          options.checkOrientation = false;        } // Only IE10+ supports Typed Arrays        if (!options.checkOrientation || !window.ArrayBuffer) {          this.clone();          return;        } // Detect the mime type of the image directly if it is a Data URL        if (REGEXP_DATA_URL.test(url)) {          // Read ArrayBuffer from Data URL of JPEG images directly for better performance          if (REGEXP_DATA_URL_JPEG.test(url)) {            this.read(dataURLToArrayBuffer(url));          } else {            // Only a JPEG image may contains Exif Orientation information,            // the rest types of Data URLs are not necessary to check orientation at all.            this.clone();          }          return;        } // 1. Detect the mime type of the image by a XMLHttpRequest.        // 2. Load the image as ArrayBuffer for reading orientation if its a JPEG image.        var xhr = new XMLHttpRequest();        var clone = this.clone.bind(this);        this.reloading = true;        this.xhr = xhr; // 1. Cross origin requests are only supported for protocol schemes:        // http, https, data, chrome, chrome-extension.        // 2. Access to XMLHttpRequest from a Data URL will be blocked by CORS policy        // in some browsers as IE11 and Safari.        xhr.onabort = clone;        xhr.onerror = clone;        xhr.ontimeout = clone;        xhr.onprogress = function () {          // Abort the request directly if it not a JPEG image for better performance          if (xhr.getResponseHeader('content-type') !== MIME_TYPE_JPEG) {            xhr.abort();          }        };        xhr.onload = function () {          _this.read(xhr.response);        };        xhr.onloadend = function () {          _this.reloading = false;          _this.xhr = null;        }; // Bust cache when there is a "crossOrigin" property to avoid browser cache error        if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) {          url = addTimestamp(url);        }        xhr.open('GET', url);        xhr.responseType = 'arraybuffer';        xhr.withCredentials = element.crossOrigin === 'use-credentials';        xhr.send();      }    }, {      key: "read",      value: function read(arrayBuffer) {        var options = this.options,            imageData = this.imageData; // Reset the orientation value to its default value 1        // as some iOS browsers will render image with its orientation        var orientation = resetAndGetOrientation(arrayBuffer);        var rotate = 0;        var scaleX = 1;        var scaleY = 1;        if (orientation > 1) {          // Generate a new URL which has the default orientation value          this.url = arrayBufferToDataURL(arrayBuffer, MIME_TYPE_JPEG);          var _parseOrientation = parseOrientation(orientation);          rotate = _parseOrientation.rotate;          scaleX = _parseOrientation.scaleX;          scaleY = _parseOrientation.scaleY;        }        if (options.rotatable) {          imageData.rotate = rotate;        }        if (options.scalable) {          imageData.scaleX = scaleX;          imageData.scaleY = scaleY;        }        this.clone();      }    }, {      key: "clone",      value: function clone() {        var element = this.element,            url = this.url;        var crossOrigin = element.crossOrigin;        var crossOriginUrl = url;        if (this.options.checkCrossOrigin && isCrossOriginURL(url)) {          if (!crossOrigin) {            crossOrigin = 'anonymous';          } // Bust cache when there is not a "crossOrigin" property (#519)          crossOriginUrl = addTimestamp(url);        }        this.crossOrigin = crossOrigin;        this.crossOriginUrl = crossOriginUrl;        var image = document.createElement('img');        if (crossOrigin) {          image.crossOrigin = crossOrigin;        }        image.src = crossOriginUrl || url;        image.alt = element.alt || 'The image to crop';        this.image = image;        image.onload = this.start.bind(this);        image.onerror = this.stop.bind(this);        addClass(image, CLASS_HIDE);        element.parentNode.insertBefore(image, element.nextSibling);      }    }, {      key: "start",      value: function start() {        var _this2 = this;        var image = this.image;        image.onload = null;        image.onerror = null;        this.sizing = true; // Match all browsers that use WebKit as the layout engine in iOS devices,        // such as Safari for iOS, Chrome for iOS, and in-app browsers.        var isIOSWebKit = WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent);        var done = function done(naturalWidth, naturalHeight) {          assign(_this2.imageData, {            naturalWidth: naturalWidth,            naturalHeight: naturalHeight,            aspectRatio: naturalWidth / naturalHeight          });          _this2.sizing = false;          _this2.sized = true;          _this2.build();        }; // Most modern browsers (excepts iOS WebKit)        if (image.naturalWidth && !isIOSWebKit) {          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 (!isIOSWebKit) {            body.removeChild(sizingImage);          }        };        sizingImage.src = image.src; // iOS WebKit will convert the image automatically        // with its orientation once append it into DOM (#279)        if (!isIOSWebKit) {          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() {        var image = this.image;        image.onload = null;        image.onerror = null;        image.parentNode.removeChild(image);        this.image = null;      }    }, {      key: "build",      value: function build() {        if (!this.sized || this.ready) {          return;        }        var element = this.element,            options = this.options,            image = this.image; // Create cropper elements        var container = element.parentNode;        var template = document.createElement('div');        template.innerHTML = TEMPLATE;        var cropper = template.querySelector(".".concat(NAMESPACE, "-container"));        var canvas = cropper.querySelector(".".concat(NAMESPACE, "-canvas"));        var dragBox = cropper.querySelector(".".concat(NAMESPACE, "-drag-box"));        var cropBox = cropper.querySelector(".".concat(NAMESPACE, "-crop-box"));        var face = cropBox.querySelector(".".concat(NAMESPACE, "-face"));        this.container = container;        this.cropper = cropper;        this.canvas = canvas;        this.dragBox = dragBox;        this.cropBox = cropBox;        this.viewBox = cropper.querySelector(".".concat(NAMESPACE, "-view-box"));        this.face = face;        canvas.appendChild(image); // Hide the original image        addClass(element, CLASS_HIDDEN); // Inserts the cropper after to the current image        container.insertBefore(cropper, element.nextSibling); // Show the image if is hidden        if (!this.isImg) {          removeClass(image, CLASS_HIDE);        }        this.initPreview();        this.bind();        options.initialAspectRatio = Math.max(0, options.initialAspectRatio) || NaN;        options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;        options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;        addClass(cropBox, CLASS_HIDDEN);        if (!options.guides) {          addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-dashed")), CLASS_HIDDEN);        }        if (!options.center) {          addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-center")), CLASS_HIDDEN);        }        if (options.background) {          addClass(cropper, "".concat(NAMESPACE, "-bg"));        }        if (!options.highlight) {          addClass(face, CLASS_INVISIBLE);        }        if (options.cropBoxMovable) {          addClass(face, CLASS_MOVE);          setData(face, DATA_ACTION, ACTION_ALL);        }        if (!options.cropBoxResizable) {          addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-line")), CLASS_HIDDEN);          addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-point")), CLASS_HIDDEN);        }        this.render();        this.ready = true;        this.setDragMode(options.dragMode);        if (options.autoCrop) {          this.crop();        }        this.setData(options.data);        if (isFunction(options.ready)) {          addListener(element, EVENT_READY, options.ready, {            once: true          });        }        dispatchEvent(element, EVENT_READY);      }    }, {      key: "unbuild",      value: function unbuild() {        if (!this.ready) {          return;        }        this.ready = false;        this.unbind();        this.resetPreview();        this.cropper.parentNode.removeChild(this.cropper);        removeClass(this.element, CLASS_HIDDEN);      }    }, {      key: "uncreate",      value: function uncreate() {        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.onabort = null;          this.xhr.abort();        } else if (this.image) {          this.stop();        }      }      /**       * Get the no conflict cropper class.       * @returns {Cropper} The cropper class.       */    }], [{      key: "noConflict",      value: function noConflict() {        window.Cropper = AnotherCropper;        return Cropper;      }      /**       * Change the default options.       * @param {Object} options - The new default options.       */    }, {      key: "setDefaults",      value: function setDefaults(options) {        assign(DEFAULTS, isPlainObject(options) && options);      }    }]);    return Cropper;  }();  assign(Cropper.prototype, render, preview, events, handlers, change, methods);  return Cropper;}));/*! * jQuery Cropper v1.0.0 * https://github.com/fengyuanchen/jquery-cropper * * Copyright (c) 2018 Chen Fengyuan * Released under the MIT license * * Date: 2018-04-01T06:20:13.168Z */(function (global, factory) {  typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery'), require('cropperjs')) :  typeof define === 'function' && define.amd ? define(['jquery', 'cropperjs'], factory) :  (factory(global.jQuery,global.Cropper));}(this, (function ($,Cropper) { 'use strict';  $ = $ && $.hasOwnProperty('default') ? $['default'] : $;  Cropper = Cropper && Cropper.hasOwnProperty('default') ? Cropper['default'] : Cropper;  if ($.fn) {    var AnotherCropper = $.fn.cropper;    var NAMESPACE = '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 isDestroy = option === 'destroy';        var cropper = $element.data(NAMESPACE);        if (!cropper) {          if (isDestroy) {            return;          }          var options = $.extend({}, $element.data(), $.isPlainObject(option) && option);          cropper = new Cropper(element, options);          $element.data(NAMESPACE, cropper);        }        if (typeof option === 'string') {          var fn = cropper[option];          if ($.isFunction(fn)) {            result = fn.apply(cropper, args);            if (result === cropper) {              result = undefined;            }            if (isDestroy) {              $element.removeData(NAMESPACE);            }          }        }      });      return result !== undefined ? result : this;    };    $.fn.cropper.Constructor = Cropper;    $.fn.cropper.setDefaults = Cropper.setDefaults;    $.fn.cropper.noConflict = function noConflict() {      $.fn.cropper = AnotherCropper;      return this;    };  }})));
 |