pax_global_header00006660000000000000000000000064117337524400014520gustar00rootroot0000000000000052 comment=5905a02ec48fc1a130b56324af29097534515b7b jscropperui-1.2.2/000077500000000000000000000000001173375244000140675ustar00rootroot00000000000000jscropperui-1.2.2/cropper.css000066400000000000000000000073611173375244000162620ustar00rootroot00000000000000.imgCrop_wrap { /* width: 500px; @done_in_js */ /* height: 375px; @done_in_js */ position: relative; cursor: crosshair; } /* an extra classname is applied for Opera < 9.0 to fix it's lack of opacity support */ .imgCrop_wrap.opera8 .imgCrop_overlay, .imgCrop_wrap.opera8 .imgCrop_clickArea { background-color: transparent; } /* fix for IE displaying all boxes at line-height by default, although they are still 1 pixel high until we combine them with the pointless span */ .imgCrop_wrap, .imgCrop_wrap * { font-size: 0; line-height: 0; opacity: 1; filter:alpha(opacity=100); } .imgCrop_overlay { background-color: #000; opacity: 0.5; filter:alpha(opacity=50); position: absolute; width: 100%; height: 100%; } .imgCrop_selArea { position: absolute; /* @done_in_js top: 20px; left: 20px; width: 200px; height: 200px; background: transparent url(castle.jpg) no-repeat -210px -110px; */ cursor: move; z-index: 2; } /* clickArea is all a fix for IE 5.5 & 6 to allow the user to click on the given area */ .imgCrop_clickArea { width: 100%; height: 100%; background-color: #FFF; opacity: 0.01; filter:alpha(opacity=01); } .imgCrop_marqueeHoriz { position: absolute; width: 100%; height: 1px; background: transparent url(marqueeHoriz.gif) repeat-x 0 0; z-index: 3; } .imgCrop_marqueeVert { position: absolute; height: 100%; width: 1px; background: transparent url(marqueeVert.gif) repeat-y 0 0; z-index: 3; } /* * FIX MARCHING ANTS IN IE * As IE <6 tries to load background images we can uncomment the follwoing hack * to remove that issue, not as pretty - but is anything in IE? * And yes I do know that 'filter' is evil, but it will make it look semi decent in IE * * html .imgCrop_marqueeHoriz, * html .imgCrop_marqueeVert { background: transparent; filter: Invert; } * html .imgCrop_marqueeNorth { border-top: 1px dashed #000; } * html .imgCrop_marqueeEast { border-right: 1px dashed #000; } * html .imgCrop_marqueeSouth { border-bottom: 1px dashed #000; } * html .imgCrop_marqueeWest { border-left: 1px dashed #000; } */ .imgCrop_marqueeNorth { top: 0; left: 0; } .imgCrop_marqueeEast { top: 0; right: 0; } .imgCrop_marqueeSouth { bottom: 0px; left: 0; } .imgCrop_marqueeWest { top: 0; left: 0; } .imgCrop_handle { position: absolute; border: 1px solid #333; width: 6px; height: 6px; background: #FFF; opacity: 0.5; filter:alpha(opacity=50); z-index: 4; } /* fix IE 5 box model */ * html .imgCrop_handle { width: 8px; height: 8px; wid\th: 6px; hei\ght: 6px; } .imgCrop_handleN { top: -3px; left: 0; /* margin-left: 49%; @done_in_js */ cursor: n-resize; } .imgCrop_handleNE { top: -3px; right: -3px; cursor: ne-resize; } .imgCrop_handleE { top: 0; right: -3px; /* margin-top: 49%; @done_in_js */ cursor: e-resize; } .imgCrop_handleSE { right: -3px; bottom: -3px; cursor: se-resize; } .imgCrop_handleS { right: 0; bottom: -3px; /* margin-right: 49%; @done_in_js */ cursor: s-resize; } .imgCrop_handleSW { left: -3px; bottom: -3px; cursor: sw-resize; } .imgCrop_handleW { top: 0; left: -3px; /* margin-top: 49%; @done_in_js */ cursor: w-resize; } .imgCrop_handleNW { top: -3px; left: -3px; cursor: nw-resize; } /** * Create an area to click & drag around on as the default browser behaviour is to let you drag the image */ .imgCrop_dragArea { width: 100%; height: 100%; z-index: 200; position: absolute; top: 0; left: 0; } .imgCrop_previewWrap { /* width: 200px; @done_in_js */ /* height: 200px; @done_in_js */ overflow: hidden; position: relative; } .imgCrop_previewWrap img { position: absolute; }jscropperui-1.2.2/cropper.uncompressed.js000066400000000000000000001433251173375244000206150ustar00rootroot00000000000000/** * Image Cropper (v. 1.2.2 - 2011-07-04 ) * Copyright (c) 2006-2011 David Spurr (http://www.defusion.org.uk/) * * The image cropper provides a way to draw a crop area on an image and capture * the coordinates of the drawn crop area. * * Features include: * - Based on Prototype and Scriptaculous * - Image editing package styling, the crop area functions and looks * like those found in popular image editing software * - Dynamic inclusion of required styles * - Drag to draw areas * - Shift drag to draw/resize areas as squares * - Selection area can be moved * - Seleciton area can be resized using resize handles * - Allows dimension ratio limited crop areas * - Allows minimum dimension crop areas * - Allows maximum dimesion crop areas * - If both min & max dimension options set to the same value for a single axis,then the cropper will not * display the resize handles as appropriate (when min & max dimensions are passed for both axes this * results in a 'fixed size' crop area) * - Allows dynamic preview of resultant crop ( if minimum width & height are provided ), this is * implemented as a subclass so can be excluded when not required * - Movement of selection area by arrow keys ( shift + arrow key will move selection area by * 10 pixels ) * - All operations stay within bounds of image * - All functionality & display compatible with most popular browsers supported by Prototype: * PC: IE 9, 8, 7, 6 & 5.5, Firefox 2+, Opera 8.5 (see known issues) & 9.0b +, Google Chrome * MAC: Camino 1.0, Firefox 2+, Safari 3.x+, Google Chrome * * Requires: * - Prototype v. 1.5.0_rc0 > (as packaged with Scriptaculous 1.6.1) * - Scriptaculous v. 1.6.1 > modules: dragdrop * Recommended (for IE9+ support): * - Prototype v. 1.7.0 > * - Scriptaculous v. 1.9.0 > * * Known issues: * - Safari animated gifs, only one of each will animate, this seems to be a known Safari issue * * - After drawing an area and then clicking to start a new drag in IE 5.5 the rendered height * appears as the last height until the user drags, this appears to be the related to the error * that the forceReRender() method fixes for IE 6, i.e. IE 5.5 is not redrawing the box properly. * * - Lack of CSS opacity support in Opera before version 9 mean we disable those style rules, these * could be fixed by using PNGs with transparency if Opera 8.5 support is high priority for you * * - Marching ants keep reloading in IE <6, it is a known issue in IE and I have * found no viable workarounds that can be included in the release. If this really is an issue for you * either try this post: http://mir.aculo.us/articles/2005/08/28/internet-explorer-and-ajax-image-caching-woes * or uncomment the 'FIX MARCHING ANTS IN IE' rules in the CSS file * * - Styling & borders on image, any CSS styling applied directly to the image itself (floats, borders, padding, margin, etc.) will * cause problems with the cropper. The use of a wrapper element to apply these styles to is recommended. * * - overflow: auto or overflow: scroll on parent will cause cropper to burst out of parent in IE and Opera (maybe Mac browsers too) * I'm not sure why yet. * * Usage: * See Cropper.Img & Cropper.ImgWithPreview for usage details * * Changelog: * v1.2.2 - 2011-07-04 * + Support for latest versions of Prototype & script.aculo.us (1.7.0 & 1.9.0 respectively) * + Support notice for IE9 * * v1.2.1 - 2009-10-06 * + Added support for latest versions of Prototype & script.aculo.us * (1.6.1.0 & 1.8.2 respectively). Changes provided by Tom Hirashima. * - No-longer package prototype & script.aculo.us with the release * * Changed tests to use google ajax libraries api to load prototype & script.aculo.us * + Added option to not auto include the cropper CSS file * * #00008 - Fixed bug: Dynamic include of cropper CSS expected cropper.js and failed when using cropper.uncompressed.js * * #00028 - Fixed bug: Doesn't work with latest script.aculo.us - Fix by Tom Hirashima * * #00030 - Fixed bug: Doesn't work in Firefox 3.5 (CSS include issue) * * #00007 - Fixed bug: onEndCrop isn't called when moving with keys * * #00011 - Fixed bug: The image that is to be cropped does not show in IE6.0 -- included CSS fix * * Tidied up source code & fixed issues that jslint found so it will compress better * * v1.2.0 - 2006-10-30 * + Added id to the preview image element using 'imgCrop_[originalImageID]' * * #00001 - Fixed bug: Doesn't account for scroll offsets * * #00009 - Fixed bug: Placing the cropper inside differently positioned elements causes incorrect co-ordinates and display * * #00013 - Fixed bug: I-bar cursor appears on drag plane * * #00014 - Fixed bug: If ID for image tag is not found in document script throws error * * Fixed bug with drag start co-ordinates if wrapper element has moved in browser (e.g. dragged to a new position) * * Fixed bug with drag start co-ordinates if image contained in a wrapper with scrolling - this may be buggy if image * has other ancestors with scrolling applied (except the body) * * #00015 - Fixed bug: When cropper removed and then reapplied onEndCrop callback gets called multiple times, solution suggestion from Bill Smith * * Various speed increases & code cleanup which meant improved performance in Mac - which allowed removal of different overlay methods for * IE and all other browsers, which led to a fix for: * * #00010 - Fixed bug: Select area doesn't adhere to image size when image resized using img attributes * - #00006 - Removed default behaviour of automatically setting a ratio when both min width & height passed, the ratioDimensions must be passed in * + #00005 - Added ability to set maximum crop dimensions, if both min & max set as the same value then we'll get a fixed cropper size on the axes as appropriate * and the resize handles will not be displayed as appropriate * * Switched keydown for keypress for moving select area with cursor keys (makes for nicer action) - doesn't appear to work in Safari * * v1.1.3 - 2006-08-21 * * Fixed wrong cursor on western handle in CSS * + #00008 & #00003 - Added feature: Allow to set dimensions & position for cropper on load * * #00002 - Fixed bug: Pressing 'remove cropper' twice removes image in IE * * v1.1.2 - 2006-06-09 * * Fixed bugs with ratios when GCD is low (patch submitted by Andy Skelton) * * v1.1.1 - 2006-06-03 * * Fixed bug with rendering issues fix in IE 5.5 * * Fixed bug with endCrop callback issues once cropper had been removed & reset in IE * * v1.1.0 - 2006-06-02 * * Fixed bug with IE constantly trying to reload select area background image * * Applied more robust fix to Safari & IE rendering issues * + Added method to reset parameters - useful for when dynamically changing img cropper attached to * + Added method to remove cropper from image * * v1.0.0 - 2006-05-18 * + Initial verison * * * Copyright (c) 2006-2011, David Spurr (http://www.defusion.org.uk/) * * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the David Spurr nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * http://www.opensource.org/licenses/bsd-license.php * * See scriptaculous.js for full scriptaculous licence */ /** * Extend the Draggable class to allow us to pass the rendering * down to the Cropper object. */ var CropDraggable = Class.create(Draggable, { initialize: function(element) { this.options = Object.extend( { /** * The draw method to defer drawing to */ drawMethod: function() {} }, arguments[1] || {} ); this.element = $(element); this.handle = this.element; this.delta = this.currentDelta(); this.dragging = false; this.eventMouseDown = this.initDrag.bindAsEventListener(this); Event.observe(this.handle, "mousedown", this.eventMouseDown); Draggables.register(this); }, /** * Defers the drawing of the draggable to the supplied method */ draw: function(point) { var pos = Element.cumulativeOffset(this.element), d = this.currentDelta(); pos[0] -= d[0]; pos[1] -= d[1]; var p = [0,1].map(function(i) { return (point[i]-pos[i]-this.offset[i]); }.bind(this)); this.options.drawMethod( p ); } }); /** * The Cropper object, this will attach itself to the provided image by wrapping it with * the generated xHTML structure required by the cropper. * * Usage: * @param obj Image element to attach to * @param obj Optional options: * - ratioDim obj * The pixel dimensions to apply as a restrictive ratio, with properties x & y * * - minWidth int * The minimum width for the select area in pixels * * - minHeight int * The mimimum height for the select area in pixels * * - maxWidth int * The maximum width for the select areas in pixels (if both minWidth & maxWidth set to same the width of the cropper will be fixed) * * - maxHeight int * The maximum height for the select areas in pixels (if both minHeight & maxHeight set to same the height of the cropper will be fixed) * * - displayOnInit int * Whether to display the select area on initialisation, only used when providing minimum width & height or ratio * * - onEndCrop func * The callback function to provide the crop details to on end of a crop (see below) * * - captureKeys boolean * Whether to capture the keys for moving the select area, as these can cause some problems at the moment * * - onloadCoords obj * A coordinates object with properties x1, y1, x2 & y2; for the coordinates of the select area to display onload * * - autoIncludeCSS boolean * Whether to automatically include the stylesheet (assumes it lives in the same location as the cropper JS file) *- --------------------------------------------- * * The callback function provided via the onEndCrop option should accept the following parameters: * - coords obj * The coordinates object with properties x1, y1, x2 & y2; for the coordinates of the select area * * - dimensions obj * The dimensions object with properites width & height; for the dimensions of the select area * * * Example: * function onEndCrop( coords, dimensions ) { * $( 'x1' ).value = coords.x1; * $( 'y1' ).value = coords.y1; * $( 'x2' ).value = coords.x2; * $( 'y2' ).value = coords.y2; * $( 'width' ).value = dimensions.width; * $( 'height' ).value = dimensions.height; * } * */ var Cropper = {}; Cropper.Img = Class.create({ /** * Initialises the class * * @access public * @param obj Image element to attach to * @param obj Options * @return void */ initialize: function(element, options) { this.options = Object.extend( { /** * @var obj * The pixel dimensions to apply as a restrictive ratio */ ratioDim: { x: 0, y: 0 }, /** * @var int * The minimum pixel width, also used as restrictive ratio if min height passed too */ minWidth: 0, /** * @var int * The minimum pixel height, also used as restrictive ratio if min width passed too */ minHeight: 0, /** * @var boolean * Whether to display the select area on initialisation, only used when providing minimum width & height or ratio */ displayOnInit: false, /** * @var function * The call back function to pass the final values to */ onEndCrop: Prototype.emptyFunction, /** * @var boolean * Whether to capture key presses or not */ captureKeys: true, /** * @var obj Coordinate object x1, y1, x2, y2 * The coordinates to optionally display the select area at onload */ onloadCoords: null, /** * @var int * The maximum width for the select areas in pixels (if both minWidth & maxWidth set to same the width of the cropper will be fixed) */ maxWidth: 0, /** * @var int * The maximum height for the select areas in pixels (if both minHeight & maxHeight set to same the height of the cropper will be fixed) */ maxHeight: 0, /** * @var boolean - default true * Whether to automatically include the stylesheet (assumes it lives in the same location as the cropper JS file) */ autoIncludeCSS: true }, options || {} ); /** * @var obj * The img node to attach to */ this.img = $( element ); /** * @var obj * The x & y coordinates of the click point */ this.clickCoords = { x: 0, y: 0 }; /** * @var boolean * Whether the user is dragging */ this.dragging = false; /** * @var boolean * Whether the user is resizing */ this.resizing = false; /** * @var boolean * Whether the user is on a webKit browser */ this.isWebKit = /Konqueror|Safari|KHTML/.test( navigator.userAgent ); /** * @var boolean * Whether the user is on IE */ this.isIE = /MSIE/.test( navigator.userAgent ); /** * @var boolean * Whether the user is on Opera below version 9 */ this.isOpera8 = /Opera\s[1-8]/.test( navigator.userAgent ); /** * @var int * The x ratio */ this.ratioX = 0; /** * @var int * The y ratio */ this.ratioY = 0; /** * @var boolean * Whether we've attached sucessfully */ this.attached = false; /** * @var boolean * Whether we've got a fixed width (if minWidth EQ or GT maxWidth then we have a fixed width * in the case of minWidth > maxWidth maxWidth wins as the fixed width) */ this.fixedWidth = ( this.options.maxWidth > 0 && ( this.options.minWidth >= this.options.maxWidth ) ); /** * @var boolean * Whether we've got a fixed height (if minHeight EQ or GT maxHeight then we have a fixed height * in the case of minHeight > maxHeight maxHeight wins as the fixed height) */ this.fixedHeight = ( this.options.maxHeight > 0 && ( this.options.minHeight >= this.options.maxHeight ) ); // quit if the image element doesn't exist if( typeof this.img == 'undefined' ) { return; } // include the stylesheet if( this.options.autoIncludeCSS ) { $$('script').each(function(s) { if( s.src.match( /\/cropper([^\/]*)\.js/ ) ) { var path = s.src.replace( /\/cropper([^\/]*)\.js.*/, '' ), style = document.createElement( 'link' ); style.rel = 'stylesheet'; style.type = 'text/css'; style.href = path + '/cropper.css'; style.media = 'screen'; document.getElementsByTagName( 'head' )[0].appendChild( style ); } }); } // calculate the ratio when neccessary if( this.options.ratioDim.x > 0 && this.options.ratioDim.y > 0 ) { var gcd = this.getGCD( this.options.ratioDim.x, this.options.ratioDim.y ); this.ratioX = this.options.ratioDim.x / gcd; this.ratioY = this.options.ratioDim.y / gcd; // dump( 'RATIO : ' + this.ratioX + ':' + this.ratioY + '\n' ); } // initialise sub classes this.subInitialize(); // only load the event observers etc. once the image is loaded // this is done after the subInitialize() call just in case the sub class does anything // that will affect the result of the call to onLoad() if( this.img.complete || this.isWebKit ) { this.onLoad(); // for some reason Safari seems to support img.complete but returns 'undefined' on the this.img object } else { Event.observe( this.img, 'load', this.onLoad.bindAsEventListener( this) ); } }, /** * The Euclidean algorithm used to find the greatest common divisor * * @acces private * @param int Value 1 * @param int Value 2 * @return int */ getGCD : function( a , b ) { if( b === 0 ) { return a; } return this.getGCD(b, a % b ); }, /** * Attaches the cropper to the image once it has loaded * * @access private * @return void */ onLoad: function( ) { /* * Build the container and all related elements, will result in the following * *
* *
* *
*
*
*
*
* * *
*
*
*
* *
*
*
*
*
*
*
*
*
*
*
*
*
*/ var cNamePrefix = 'imgCrop_'; // get the point to insert the container var insertPoint = this.img.parentNode; // apply an extra class to the wrapper to fix Opera below version 9 var fixOperaClass = ''; if( this.isOpera8 ) { fixOperaClass = ' opera8'; } this.imgWrap = new Element( 'div', { 'class': cNamePrefix + 'wrap' + fixOperaClass } ); this.north = new Element( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'north' }).insert(new Element( 'span' )); this.east = new Element( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'east' }).insert(new Element( 'span' )); this.south = new Element( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'south' }).insert(new Element( 'span' )); this.west = new Element( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'west' }).insert(new Element( 'span' )); var overlays = [ this.north, this.east, this.south, this.west ]; this.dragArea = new Element( 'div', { 'class': cNamePrefix + 'dragArea' } ); overlays.each(function(o){this.dragArea.insert(o);}, this); this.handleN = new Element( 'div', { 'class': cNamePrefix + 'handle ' + cNamePrefix + 'handleN' } ); this.handleNE = new Element( 'div', { 'class': cNamePrefix + 'handle ' + cNamePrefix + 'handleNE' } ); this.handleE = new Element( 'div', { 'class': cNamePrefix + 'handle ' + cNamePrefix + 'handleE' } ); this.handleSE = new Element( 'div', { 'class': cNamePrefix + 'handle ' + cNamePrefix + 'handleSE' } ); this.handleS = new Element( 'div', { 'class': cNamePrefix + 'handle ' + cNamePrefix + 'handleS' } ); this.handleSW = new Element( 'div', { 'class': cNamePrefix + 'handle ' + cNamePrefix + 'handleSW' } ); this.handleW = new Element( 'div', { 'class': cNamePrefix + 'handle ' + cNamePrefix + 'handleW' } ); this.handleNW = new Element( 'div', { 'class': cNamePrefix + 'handle ' + cNamePrefix + 'handleNW' } ); this.selArea = new Element( 'div', { 'class': cNamePrefix + 'selArea' }); [ new Element( 'div', { 'class': cNamePrefix + 'marqueeHoriz ' + cNamePrefix + 'marqueeNorth' }).insert(new Element( 'span' )), new Element( 'div', { 'class': cNamePrefix + 'marqueeVert ' + cNamePrefix + 'marqueeEast' }).insert(new Element( 'span' )), new Element( 'div', { 'class': cNamePrefix + 'marqueeHoriz ' + cNamePrefix + 'marqueeSouth' }).insert(new Element( 'span' )), new Element( 'div', { 'class': cNamePrefix + 'marqueeVert ' + cNamePrefix + 'marqueeWest' }).insert(new Element( 'span' )), this.handleN, this.handleNE, this.handleE, this.handleSE, this.handleS, this.handleSW, this.handleW, this.handleNW, new Element( 'div', { 'class': cNamePrefix + 'clickArea' } ) ].each(function(o){this.selArea.insert(o);}, this); this.imgWrap.appendChild( this.img ); this.imgWrap.appendChild( this.dragArea ); this.dragArea.appendChild( this.selArea ); this.dragArea.appendChild( new Element( 'div', { 'class': cNamePrefix + 'clickArea' } ) ); insertPoint.appendChild( this.imgWrap ); // add event observers this.startDragBind = this.startDrag.bindAsEventListener( this ); Event.observe( this.dragArea, 'mousedown', this.startDragBind ); this.onDragBind = this.onDrag.bindAsEventListener( this ); Event.observe( document, 'mousemove', this.onDragBind ); this.endCropBind = this.endCrop.bindAsEventListener( this ); Event.observe( document, 'mouseup', this.endCropBind ); this.resizeBind = this.startResize.bindAsEventListener( this ); this.handles = [ this.handleN, this.handleNE, this.handleE, this.handleSE, this.handleS, this.handleSW, this.handleW, this.handleNW ]; this.registerHandles( true ); if( this.options.captureKeys ) { this.keysBind = this.handleKeys.bindAsEventListener( this ); Event.observe( document, 'keypress', this.keysBind ); } // attach the dragable to the select area var x = new CropDraggable( this.selArea, { drawMethod: this.moveArea.bindAsEventListener( this ) } ); this.setParams(); }, /** * Manages adding or removing the handle event handler and hiding or displaying them as appropriate * * @access private * @param boolean registration true = add, false = remove * @return void */ registerHandles: function( registration ) { for( var i = 0; i < this.handles.length; i++ ) { var handle = $( this.handles[i] ); if( registration ) { var hideHandle = false; // whether to hide the handle // disable handles asappropriate if we've got fixed dimensions // if both dimensions are fixed we don't need to do much if( this.fixedWidth && this.fixedHeight ) { hideHandle = true; } else if( this.fixedWidth || this.fixedHeight ) { // if one of the dimensions is fixed then just hide those handles var isCornerHandle = handle.className.match( /([S|N][E|W])$/ ), isWidthHandle = handle.className.match( /(E|W)$/ ), isHeightHandle = handle.className.match( /(N|S)$/ ); if( isCornerHandle || ( this.fixedWidth && isWidthHandle ) || ( this.fixedHeight && isHeightHandle ) ) { hideHandle = true; } } if( hideHandle ) { handle.hide(); } else { Event.observe( handle, 'mousedown', this.resizeBind ); } } else { handle.show(); Event.stopObserving( handle, 'mousedown', this.resizeBind ); } } }, /** * Sets up all the cropper parameters, this can be used to reset the cropper when dynamically * changing the images * * @access private * @return void */ setParams: function() { /** * @var int * The image width */ this.imgW = this.img.width; /** * @var int * The image height */ this.imgH = this.img.height; $( this.north ).setStyle( { height: 0 } ); $( this.east ).setStyle( { width: 0, height: 0 } ); $( this.south ).setStyle( { height: 0 } ); $( this.west ).setStyle( { width: 0, height: 0 } ); // resize the container to fit the image $( this.imgWrap ).setStyle( { 'width': this.imgW + 'px', 'height': this.imgH + 'px' } ); // hide the select area $( this.selArea ).hide(); // setup the starting position of the select area var startCoords = { x1: 0, y1: 0, x2: 0, y2: 0 }, validCoordsSet = false; // display the select area if( this.options.onloadCoords !== null ) { // if we've being given some coordinates to startCoords = this.cloneCoords( this.options.onloadCoords ); validCoordsSet = true; } else if( this.options.ratioDim.x > 0 && this.options.ratioDim.y > 0 ) { // if there is a ratio limit applied and the then set it to initial ratio startCoords.x1 = Math.ceil( ( this.imgW - this.options.ratioDim.x ) / 2 ); startCoords.y1 = Math.ceil( ( this.imgH - this.options.ratioDim.y ) / 2 ); startCoords.x2 = startCoords.x1 + this.options.ratioDim.x; startCoords.y2 = startCoords.y1 + this.options.ratioDim.y; validCoordsSet = true; } this.setAreaCoords( startCoords, false, false, 1 ); if( this.options.displayOnInit && validCoordsSet ) { this.selArea.show(); this.drawArea(); this.endCrop(); } this.attached = true; }, /** * Removes the cropper * * @access public * @return void */ remove: function() { if( this.attached ) { this.attached = false; // remove the elements we inserted this.imgWrap.parentNode.insertBefore( this.img, this.imgWrap ); this.imgWrap.parentNode.removeChild( this.imgWrap ); // remove the event observers Event.stopObserving( this.dragArea, 'mousedown', this.startDragBind ); Event.stopObserving( document, 'mousemove', this.onDragBind ); Event.stopObserving( document, 'mouseup', this.endCropBind ); this.registerHandles( false ); if( this.options.captureKeys ) { Event.stopObserving( document, 'keypress', this.keysBind ); } } }, /** * Resets the cropper, can be used either after being removed or any time you wish * * @access public * @return void */ reset: function() { if( !this.attached ) { this.onLoad(); } else { this.setParams(); } this.endCrop(); }, /** * Handles the key functionality, currently just using arrow keys to move, if the user * presses shift then the area will move by 10 pixels */ handleKeys: function( e ) { var dir = { x: 0, y: 0 }; // direction to move it in & the amount in pixels if( !this.dragging ) { // catch the arrow keys switch( e.keyCode ) { case( 37 ) : // left dir.x = -1; break; case( 38 ) : // up dir.y = -1; break; case( 39 ) : // right dir.x = 1; break; case( 40 ) : // down dir.y = 1; break; } if( dir.x !== 0 || dir.y !== 0 ) { // if shift is pressed then move by 10 pixels if( e.shiftKey ) { dir.x *= 10; dir.y *= 10; } this.moveArea( [ this.areaCoords.x1 + dir.x, this.areaCoords.y1 + dir.y ] ); this.endCrop(); Event.stop( e ); } } }, /** * Calculates the width from the areaCoords * * @access private * @return int */ calcW: function() { return (this.areaCoords.x2 - this.areaCoords.x1); }, /** * Calculates the height from the areaCoords * * @access private * @return int */ calcH: function() { return (this.areaCoords.y2 - this.areaCoords.y1); }, /** * Moves the select area to the supplied point (assumes the point is x1 & y1 of the select area) * * @access public * @param array Point for x1 & y1 to move select area to * @return void */ moveArea: function( point ) { // dump( 'moveArea : ' + point[0] + ',' + point[1] + ',' + ( point[0] + ( this.areaCoords.x2 - this.areaCoords.x1 ) ) + ',' + ( point[1] + ( this.areaCoords.y2 - this.areaCoords.y1 ) ) + '\n' ); this.setAreaCoords( { x1: point[0], y1: point[1], x2: point[0] + this.calcW(), y2: point[1] + this.calcH() }, true, false ); this.drawArea(); }, /** * Clones a co-ordinates object, stops problems with handling them by reference * * @access private * @param obj Coordinate object x1, y1, x2, y2 * @return obj Coordinate object x1, y1, x2, y2 */ cloneCoords: function( coords ) { return { x1: coords.x1, y1: coords.y1, x2: coords.x2, y2: coords.y2 }; }, /** * Sets the select coords to those provided but ensures they don't go * outside the bounding box * * @access private * @param obj Coordinates x1, y1, x2, y2 * @param boolean Whether this is a move * @param boolean Whether to apply squaring * @param obj Direction of mouse along both axis x, y ( -1 = negative, 1 = positive ) only required when moving etc. * @param string The current resize handle || null * @return void */ setAreaCoords: function( coords, moving, square, direction, resizeHandle ) { // dump( 'setAreaCoords (in) : ' + coords.x1 + ',' + coords.y1 + ',' + coords.x2 + ',' + coords.y2 ); if( moving ) { // if moving var targW = coords.x2 - coords.x1, targH = coords.y2 - coords.y1; // ensure we're within the bounds if( coords.x1 < 0 ) { coords.x1 = 0; coords.x2 = targW; } if( coords.y1 < 0 ) { coords.y1 = 0; coords.y2 = targH; } if( coords.x2 > this.imgW ) { coords.x2 = this.imgW; coords.x1 = this.imgW - targW; } if( coords.y2 > this.imgH ) { coords.y2 = this.imgH; coords.y1 = this.imgH - targH; } } else { // ensure we're within the bounds if( coords.x1 < 0 ) { coords.x1 = 0; } if( coords.y1 < 0 ) { coords.y1 = 0; } if( coords.x2 > this.imgW ) { coords.x2 = this.imgW; } if( coords.y2 > this.imgH ) { coords.y2 = this.imgH; } // This is passed as null in onload if( direction !== null ) { // apply the ratio or squaring where appropriate if( this.ratioX > 0 ) { this.applyRatio( coords, { x: this.ratioX, y: this.ratioY }, direction, resizeHandle ); } else if( square ) { this.applyRatio( coords, { x: 1, y: 1 }, direction, resizeHandle ); } var mins = [ this.options.minWidth, this.options.minHeight ], // minimum dimensions [x,y] maxs = [ this.options.maxWidth, this.options.maxHeight ]; // maximum dimensions [x,y] // apply dimensions where appropriate if( mins[0] > 0 || mins[1] > 0 || maxs[0] > 0 || maxs[1] > 0) { var coordsTransX = { a1: coords.x1, a2: coords.x2 }, coordsTransY = { a1: coords.y1, a2: coords.y2 }, boundsX = { min: 0, max: this.imgW }, boundsY = { min: 0, max: this.imgH }; // handle squaring properly on single axis minimum dimensions if( (mins[0] !== 0 || mins[1] !== 0) && square ) { if( mins[0] > 0 ) { mins[1] = mins[0]; } else if( mins[1] > 0 ) { mins[0] = mins[1]; } } if( (maxs[0] !== 0 || maxs[0] !== 0) && square ) { // if we have a max x value & it is less than the max y value then we set the y max to the max x (so we don't go over the minimum maximum of one of the axes - if that makes sense) if( maxs[0] > 0 && maxs[0] <= maxs[1] ) { maxs[1] = maxs[0]; } else if( maxs[1] > 0 && maxs[1] <= maxs[0] ) { maxs[0] = maxs[1]; } } if( mins[0] > 0 ) { this.applyDimRestriction( coordsTransX, mins[0], direction.x, boundsX, 'min' ); } if( mins[1] > 1 ) { this.applyDimRestriction( coordsTransY, mins[1], direction.y, boundsY, 'min' ); } if( maxs[0] > 0 ) { this.applyDimRestriction( coordsTransX, maxs[0], direction.x, boundsX, 'max' ); } if( maxs[1] > 1 ) { this.applyDimRestriction( coordsTransY, maxs[1], direction.y, boundsY, 'max' ); } coords = { x1: coordsTransX.a1, y1: coordsTransY.a1, x2: coordsTransX.a2, y2: coordsTransY.a2 }; } } } // dump( 'setAreaCoords (out) : ' + coords.x1 + ',' + coords.y1 + ',' + coords.x2 + ',' + coords.y2 + '\n' ); this.areaCoords = coords; }, /** * Applies the supplied dimension restriction to the supplied coordinates along a single axis * * @access private * @param obj Single axis coordinates, a1, a2 (e.g. for the x axis a1 = x1 & a2 = x2) * @param int The restriction value * @param int The direction ( -1 = negative, 1 = positive ) * @param obj The bounds of the image ( for this axis ) * @param string The dimension restriction type ( 'min' | 'max' ) * @return void */ applyDimRestriction: function( coords, val, direction, bounds, type ) { var check; if( type == 'min' ) { check = ( ( coords.a2 - coords.a1 ) < val ); } else { check = ( ( coords.a2 - coords.a1 ) > val ); } if( check ) { if( direction == 1 ) { coords.a2 = coords.a1 + val; } else { coords.a1 = coords.a2 - val; } // make sure we're still in the bounds (not too pretty for the user, but needed) if( coords.a1 < bounds.min ) { coords.a1 = bounds.min; coords.a2 = val; } else if( coords.a2 > bounds.max ) { coords.a1 = bounds.max - val; coords.a2 = bounds.max; } } }, /** * Applies the supplied ratio to the supplied coordinates * * @access private * @param obj Coordinates, x1, y1, x2, y2 * @param obj Ratio, x, y * @param obj Direction of mouse, x & y : -1 == negative 1 == positive * @param string The current resize handle || null * @return void */ applyRatio : function( coords, ratio, direction, resizeHandle ) { // dump( 'direction.y : ' + direction.y + '\n'); var newCoords; if( resizeHandle == 'N' || resizeHandle == 'S' ) { // dump( 'north south \n'); // if moving on either the lone north & south handles apply the ratio on the y axis newCoords = this.applyRatioToAxis( { a1: coords.y1, b1: coords.x1, a2: coords.y2, b2: coords.x2 }, { a: ratio.y, b: ratio.x }, { a: direction.y, b: direction.x }, { min: 0, max: this.imgW } ); coords.x1 = newCoords.b1; coords.y1 = newCoords.a1; coords.x2 = newCoords.b2; coords.y2 = newCoords.a2; } else { // otherwise deal with it as if we're applying the ratio on the x axis newCoords = this.applyRatioToAxis( { a1: coords.x1, b1: coords.y1, a2: coords.x2, b2: coords.y2 }, { a: ratio.x, b: ratio.y }, { a: direction.x, b: direction.y }, { min: 0, max: this.imgH } ); coords.x1 = newCoords.a1; coords.y1 = newCoords.b1; coords.x2 = newCoords.a2; coords.y2 = newCoords.b2; } }, /** * Applies the provided ratio to the provided coordinates based on provided direction & bounds, * use to encapsulate functionality to make it easy to apply to either axis. This is probably * quite hard to visualise so see the x axis example within applyRatio() * * Example in parameter details & comments is for requesting applying ratio to x axis. * * @access private * @param obj Coords object (a1, b1, a2, b2) where a = x & b = y in example * @param obj Ratio object (a, b) where a = x & b = y in example * @param obj Direction object (a, b) where a = x & b = y in example * @param obj Bounds (min, max) * @return obj Coords object (a1, b1, a2, b2) where a = x & b = y in example */ applyRatioToAxis: function( coords, ratio, direction, bounds ) { var newCoords = Object.extend( coords, {} ), calcDimA = newCoords.a2 - newCoords.a1, // calculate dimension a (e.g. width) targDimB = Math.floor( calcDimA * ratio.b / ratio.a ), // the target dimension b (e.g. height) targB = null, // to hold target b (e.g. y value) targDimA = null, // to hold target dimension a (e.g. width) calcDimB = null; // to hold calculated dimension b (e.g. height) // dump( 'newCoords[0]: ' + newCoords.a1 + ',' + newCoords.b1 + ','+ newCoords.a2 + ',' + newCoords.b2 + '\n'); if( direction.b == 1 ) { // if travelling in a positive direction // make sure we're not going out of bounds targB = newCoords.b1 + targDimB; if( targB > bounds.max ) { targB = bounds.max; calcDimB = targB - newCoords.b1; // calcuate dimension b (e.g. height) } newCoords.b2 = targB; } else { // if travelling in a negative direction // make sure we're not going out of bounds targB = newCoords.b2 - targDimB; if( targB < bounds.min ) { targB = bounds.min; calcDimB = targB + newCoords.b2; // calcuate dimension b (e.g. height) } newCoords.b1 = targB; } // dump( 'newCoords[1]: ' + newCoords.a1 + ',' + newCoords.b1 + ','+ newCoords.a2 + ',' + newCoords.b2 + '\n'); // apply the calculated dimensions if( calcDimB !== null ) { targDimA = Math.floor( calcDimB * ratio.a / ratio.b ); if( direction.a == 1 ) { newCoords.a2 = newCoords.a1 + targDimA; } else { newCoords.a1 = newCoords.a1 = newCoords.a2 - targDimA; } } // dump( 'newCoords[2]: ' + newCoords.a1 + ',' + newCoords.b1 + ','+ newCoords.a2 + ',' + newCoords.b2 + '\n'); return newCoords; }, /** * Draws the select area * * @access private * @return void */ drawArea: function( ) { /* NOTE: I'm not using the Element.setStyle() shortcut as they make it quite sluggish on Mac based browsers */ // dump( 'drawArea : ' + this.areaCoords.x1 + ',' + this.areaCoords.y1 + ',' + this.areaCoords.x2 + ',' + this.areaCoords.y2 + '\n' ); var areaWidth = this.calcW(), areaHeight = this.calcH(); /* Calculate all the style strings before we use them, allows reuse & produces quicker rendering (especially noticable in Mac based browsers) */ var px = 'px', params = [ this.areaCoords.x1 + px, // the left of the selArea this.areaCoords.y1 + px, // the top of the selArea areaWidth + px, // width of the selArea areaHeight + px, // height of the selArea this.areaCoords.x2 + px, // bottom of the selArea this.areaCoords.y2 + px, // right of the selArea (this.img.width - this.areaCoords.x2) + px, // right edge of selArea (this.img.height - this.areaCoords.y2) + px // bottom edge of selArea ]; // do the select area var areaStyle = this.selArea.style; areaStyle.left = params[0]; areaStyle.top = params[1]; areaStyle.width = params[2]; areaStyle.height = params[3]; // position the north, east, south & west handles var horizHandlePos = Math.ceil( (areaWidth - 6) / 2 ) + px, vertHandlePos = Math.ceil( (areaHeight - 6) / 2 ) + px; this.handleN.style.left = horizHandlePos; this.handleE.style.top = vertHandlePos; this.handleS.style.left = horizHandlePos; this.handleW.style.top = vertHandlePos; // draw the four overlays this.north.style.height = params[1]; var eastStyle = this.east.style; eastStyle.top = params[1]; eastStyle.height = params[3]; eastStyle.left = params[4]; eastStyle.width = params[6]; var southStyle = this.south.style; southStyle.top = params[5]; southStyle.height = params[7]; var westStyle = this.west.style; westStyle.top = params[1]; westStyle.height = params[3]; westStyle.width = params[0]; // call the draw method on sub classes this.subDrawArea(); this.forceReRender(); }, /** * Force the re-rendering of the selArea element which fixes rendering issues in Safari * & IE PC, especially evident when re-sizing perfectly vertical using any of the south handles * * @access private * @return void */ forceReRender: function() { if( this.isIE || this.isWebKit) { var n = document.createTextNode(' '); var d,el,fixEL,i; if( this.isIE ) { fixEl = this.selArea; } else if( this.isWebKit ) { fixEl = document.getElementsByClassName( 'imgCrop_marqueeSouth', this.imgWrap )[0]; /* we have to be a bit more forceful for Safari, otherwise the the marquee & the south handles still don't move */ d = new Element( 'div' ); d.style.visibility = 'hidden'; var classList = ['SE','S','SW']; for( i = 0; i < classList.length; i++ ) { el = document.getElementsByClassName( 'imgCrop_handle' + classList[i], this.selArea )[0]; if( el.childNodes.length ) { el.removeChild( el.childNodes[0] ); } el.appendChild(d); } } fixEl.appendChild(n); fixEl.removeChild(n); } }, /** * Starts the resize * * @access private * @param obj Event * @return void */ startResize: function( e ) { this.startCoords = this.cloneCoords( this.areaCoords ); this.resizing = true; this.resizeHandle = Event.element( e ).classNames().toString().replace(/([^N|NE|E|SE|S|SW|W|NW])+/, ''); // dump( 'this.resizeHandle : ' + this.resizeHandle + '\n' ); Event.stop( e ); }, /** * Starts the drag * * @access private * @param obj Event * @return void */ startDrag: function( e ) { this.selArea.show(); this.clickCoords = this.getCurPos( e ); this.setAreaCoords( { x1: this.clickCoords.x, y1: this.clickCoords.y, x2: this.clickCoords.x, y2: this.clickCoords.y }, false, false, null ); this.dragging = true; this.onDrag( e ); // incase the user just clicks once after already making a selection Event.stop( e ); }, /** * Gets the current cursor position relative to the image * * @access private * @param obj Event * @return obj x,y pixels of the cursor */ getCurPos: function( e ) { // get the offsets for the wrapper within the document // get the offsets for the wrapper within the document var el = this.imgWrap, wrapOffsets = Element.cumulativeOffset( el ); // remove any scrolling that is applied to the wrapper (this may be buggy) - don't count the scroll on the body as that won't affect us while( el.nodeName != 'BODY' ) { wrapOffsets[1] -= el.scrollTop || 0; wrapOffsets[0] -= el.scrollLeft || 0; el = el.parentNode; } return { x: Event.pointerX(e) - wrapOffsets[0], y: Event.pointerY(e) - wrapOffsets[1] }; }, /** * Performs the drag for both resize & inital draw dragging * * @access private * @param obj Event * @return void */ onDrag: function( e ) { if( this.dragging || this.resizing ) { var resizeHandle = null, curPos = this.getCurPos( e ), newCoords = this.cloneCoords( this.areaCoords ), direction = { x: 1, y: 1 }; if( this.dragging ) { if( curPos.x < this.clickCoords.x ) { direction.x = -1; } if( curPos.y < this.clickCoords.y ) { direction.y = -1; } this.transformCoords( curPos.x, this.clickCoords.x, newCoords, 'x' ); this.transformCoords( curPos.y, this.clickCoords.y, newCoords, 'y' ); } else if( this.resizing ) { resizeHandle = this.resizeHandle; // do x movements first if( resizeHandle.match(/E/) ) { // if we're moving an east handle this.transformCoords( curPos.x, this.startCoords.x1, newCoords, 'x' ); if( curPos.x < this.startCoords.x1 ) { direction.x = -1; } } else if( resizeHandle.match(/W/) ) { // if we're moving an west handle this.transformCoords( curPos.x, this.startCoords.x2, newCoords, 'x' ); if( curPos.x < this.startCoords.x2 ) { direction.x = -1; } } // do y movements second if( resizeHandle.match(/N/) ) { // if we're moving an north handle this.transformCoords( curPos.y, this.startCoords.y2, newCoords, 'y' ); if( curPos.y < this.startCoords.y2 ) { direction.y = -1; } } else if( resizeHandle.match(/S/) ) { // if we're moving an south handle this.transformCoords( curPos.y, this.startCoords.y1, newCoords, 'y' ); if( curPos.y < this.startCoords.y1 ) { direction.y = -1; } } } this.setAreaCoords( newCoords, false, e.shiftKey, direction, resizeHandle ); this.drawArea(); Event.stop( e ); // stop the default event (selecting images & text) in Safari & IE PC } }, /** * Applies the appropriate transform to supplied co-ordinates, on the * defined axis, depending on the relationship of the supplied values * * @access private * @param int Current value of pointer * @param int Base value to compare current pointer val to * @param obj Coordinates to apply transformation on x1, x2, y1, y2 * @param string Axis to apply transformation on 'x' || 'y' * @return void */ transformCoords : function( curVal, baseVal, coords, axis ) { var newVals = [ curVal, baseVal ]; if( curVal > baseVal ) { newVals.reverse(); } coords[ axis + '1' ] = newVals[0]; coords[ axis + '2' ] = newVals[1]; }, /** * Ends the crop & passes the values of the select area on to the appropriate * callback function on completion of a crop * * @access private * @return void */ endCrop : function() { this.dragging = false; this.resizing = false; this.options.onEndCrop( this.areaCoords, { width: this.calcW(), height: this.calcH() } ); }, /** * Abstract method called on the end of initialization * * @access private * @abstract * @return void */ subInitialize: function() {}, /** * Abstract method called on the end of drawArea() * * @access private * @abstract * @return void */ subDrawArea: function() {} }); /** * Extend the Cropper.Img class to allow for presentation of a preview image of the resulting crop, * the option for displayOnInit is always overridden to true when displaying a preview image * * Usage: * @param obj Image element to attach to * @param obj Optional options: * - see Cropper.Img for base options * - previewWrap obj HTML element that will be used as a container for the preview image */ Cropper.ImgWithPreview = Class.create(Cropper.Img, { /** * Implements the abstract method from Cropper.Img to initialize preview image settings. * Will only attach a preview image is the previewWrap element is defined and the minWidth * & minHeight options are set. * * @see Croper.Img.subInitialize */ subInitialize: function() { /** * Whether or not we've attached a preview image * @var boolean */ this.hasPreviewImg = false; if( typeof(this.options.previewWrap) != 'undefined' && this.options.minWidth > 0 && this.options.minHeight > 0 ) { /** * The preview image wrapper element * @var obj HTML element */ this.previewWrap = $( this.options.previewWrap ); /** * The preview image element * @var obj HTML IMG element */ this.previewImg = this.img.cloneNode( false ); // set the ID of the preview image to be unique this.previewImg.id = 'imgCrop_' + this.previewImg.id; // set the displayOnInit option to true so we display the select area at the same time as the thumbnail this.options.displayOnInit = true; this.hasPreviewImg = true; this.previewWrap.addClassName( 'imgCrop_previewWrap' ); this.previewWrap.setStyle({ width: this.options.minWidth + 'px', height: this.options.minHeight + 'px' }); this.previewWrap.appendChild( this.previewImg ); } }, /** * Implements the abstract method from Cropper.Img to draw the preview image * * @see Croper.Img.subDrawArea */ subDrawArea: function() { if( this.hasPreviewImg ) { // get the ratio of the select area to the src image var calcWidth = this.calcW(), calcHeight = this.calcH(); // ratios for the dimensions of the preview image var dimRatio = { x: this.imgW / calcWidth, y: this.imgH / calcHeight }; //ratios for the positions within the preview var posRatio = { x: calcWidth / this.options.minWidth, y: calcHeight / this.options.minHeight }; // setting the positions in an obj before apply styles for rendering speed increase var calcPos = { w: Math.ceil( this.options.minWidth * dimRatio.x ) + 'px', h: Math.ceil( this.options.minHeight * dimRatio.y ) + 'px', x: '-' + Math.ceil( this.areaCoords.x1 / posRatio.x ) + 'px', y: '-' + Math.ceil( this.areaCoords.y1 / posRatio.y ) + 'px' }; var previewStyle = this.previewImg.style; previewStyle.width = calcPos.w; previewStyle.height= calcPos.h; previewStyle.left = calcPos.x; previewStyle.top = calcPos.y; } } }); jscropperui-1.2.2/licence.txt000066400000000000000000000030161173375244000162320ustar00rootroot00000000000000Copyright (c) 2006-2011, David Spurr (www.defusion.org.uk) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the David Spurr nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. http://www.opensource.org/licenses/bsd-license.phpjscropperui-1.2.2/marqueeHoriz.gif000066400000000000000000000021451173375244000172330ustar00rootroot00000000000000GIF89a ! NETSCAPE2.0! ,    "4xp À! , A"`A! , G@ Lxp`A! , G(h C! , ࿁ "4xp À! , A"`A! , @@ Lxp`A!,  @+h ;jscropperui-1.2.2/marqueeVert.gif000066400000000000000000000021651173375244000170620ustar00rootroot00000000000000GIF89a(! NETSCAPE2.0! ,(   "4xp Å! ,(A"`! ,(G@ Lxp` ! ,(G(h C! ,(࿁ "4xp Å! ,(A"`! ,(@@ Lxp` !,( @+h C;jscropperui-1.2.2/tests/000077500000000000000000000000001173375244000152315ustar00rootroot00000000000000jscropperui-1.2.2/tests/castle.jpg000066400000000000000000001031751173375244000172150ustar00rootroot00000000000000ExifMM*(12 &i"CanonCanon EOS 300D DIGITALHHAdobe Photoshop CS Windows2006-05-18T22:54:49Zlt'0221|  Ȓ  РMآ<2005-05-02T15:23:07Z2005-05-02T15:23:07Z*;^.|@SDucky !Adobed7 {   "#%#"--11--@@@@@@@@@@@@@@@##.!!.),%%%,)22..22??bW `&x(V+@Ts|̳]9:ܼhI!xF(TE 9GhRti$L}`2HY5KȟE DhXiv\wcJDȆv{@,!'iH CH"$yfI'eCus/R51>sc(]:o(2R/2aB@#@jNqugIv"Fl92M/HǾkl9Qiӥ&Я/5ʿq>~},r==іzӊ'!s "U&ļ8/ڧO7H^ʜ;|er=a٭ƹ{3;#n3'Mi.E媂o{*8<@Ntop{%^ui=䯿'Myѡ#=Efi|tޮ: NWP"4 ee{=~L!St14RU%k~o>־Ey6b0t0ʝ>.C].jՊ5jZՄqնE\Ѣ0&U^$f{O?o7@s" /s,ާQncyη XAW`+e^' 1#5$]o`;t̵=+ Fx!*Y0xx А`*xHѼVK4RרKxb"k} b,U*IJ ђE7&稗$,A^ZDz`:IUiVW/U$E\uDN~nVSDȯI/[ X~ F|iA^1{QU=KԿ[4<м9 R^n3,d?'sy^O5E b[T^G4O |~#)-&!$^ ^zĶ zJ::M/ZV#JD @`0ixOZ_s0{rplts޳w>:OY^=$w~꫸ /-W_o3ŽJOtyܴ,IkO_pʶïPmgŖY5U+9p"l==:caE=v[L!FEqry5"gMby-rtF_5jr^fMs†4rg=O\cf+DYr&59ô.ڗ7C,A6<:492[GzmFD_9! Ͳ뙫\v\nG TYcP#dRK K;6Ir=GrD=U*5TGQG{;/7WfF]:LV_ >U~^2;鷹nsdzDw司i&>d^M.c &h{GIrͦNoRĎ65CYDҞo#:zz܎ƵEiiiC.!u|WZFqV] 6Z >tEo=3+3Y[ZBxpᅯf:#︇:Oul>}@l}(di;Af< ak"^ x2*+=9b V#01B0ndJYcN 'sfs&VufԸEZEaVٛRL@g8Lk0:X]_?wg=*Mpm4ë4:y=,##`B,z a46^n[ lߙ1ڦ+Ebqb_m!+Zl^FTm!S3sݝ ]]H}ea6 /|D9kl>_%E,yѭql'ʑ`,uo b0826sk`V˫-9M-%sbfH,駰e[ Yvpy]+ln ϑ: Ib1sð '0Pvc#x[ *)\rpm*-I$\*5wNsӀ:.|fUUsKF3rs~RR/Y؈ʤ218u@lio; >{\bb= w+ O8l#9BI 츶$9gF4U0'~D|ֿwNv͇ Ek^prI 9¥sȔ uUƇDK(lְsL1[ r:V4`m}eaWnz~YxWPVP6,o3!YQU@ P7u6(+r$ IW4yn1F*}eT@'{ 1? q]S .tN[ZxXF7%dyy-bģ@'D#7u3Q0ȴLVL@G*1 ;-.o7N*43Xʸа[l3x{ ͳmb$TcD=~Kl`9k c֙pΪyF 1c8Ϣ3ᙁ  u%qb[ȣ=cƐg $LsѼF%| Ū⮈PsDYqS4@ck5ͅXDg"qT,@b~43C8V8#\k{?XAk xUl1)NjplXggf%Ҁ6o4sp6)V , Fc@O"S540ɼ`24p?i9h azbx o1ìF\h[lco~l$S, #P8hxqՃfMc.O%s$B O@#5phX?c1YUr4x6R>!`̠=vFumN]jiWN_S@ȬלXw"=13%ebMb`ʍK͟!<ı?c`h6*%C>ٮ >[j̪ULnUx3[x#»*6N94U\%+CM ㋬C hLJq+E@az(صBZТ%$ Z2oY5XG ÉRqUbUۺؽlLhWEmd<1aC"\YJX sqfYk5 (y*$BFF6ɉQ5; ZkQX>b0Un[UuUz C=uu"'#ॣU1˥o! c(8F;NT㨬b caElhW՚{ZnϢzx'sq8?GDʰ6£eF[,U@uq[K=1ץO2цPd~5B-~X}]@C$gq9UOiTm30m`0\fUj1ehs3зt{YčK!eVetE}lLЫ`DP8DY*Üsq' 0rUY`r2*qlUcN ߺwW&Qi2]TzkV+<%hSakS1BتĴjB׉JƫA^:8qF ),q[x,wBk)+l0S1Hai؆VHkq`ˡb%vdh% ;8Sr֔!6t樰OU%IAj&q¾hۆn"óo]ٻB^"{8`tlwfPZeSXD{%42.E<]<-T\e9qHҾ7 *%(r9< @vTu^/SLA-t5=tn^L32r[*ήݟg'UwY*$mElc~.q989 >Mrկ+T8 8' ZZꐬQ,nV]3)e*V@Fq D? /j(n-:X:ջY}ffUReW:"fZ$cc5+0)-WCS$<Ԯ*0Z "kC9]㴬=,j퇤}M؍< $@2h@ed6q'"Ҋ;HFD F,xA#4qkR0jVEf-R2wVebU#ThWfUT]6 NGzjĥousڧdB>J]Oq22v)_u;j_2: WVbIc49^dSַ%`Vh" j+b+T7bPM|I2sqLXZYxPqYRƱc^h,SjȑWI>FV1h~8@RYJ(cK0eęDm7 uzzU';.\ :*wUFfYx䒡Xϼ224|[4'/+mqE [;aQUjCq&IC5w%-OnK=%aP5VqJYR1Uv*U >)TcՍ,Hkܽ h]'դ_>Fs 2dhqmY ,'aٖN)&kX82N LjCbZmزaX@5\m)#fsM뺬VV'yUJVH+Pʑi64r~ʭ/ֵ$mk2}M ~֫䰬aB]b}ަ&OwNWK=8sfU[ 4J5pk#A"ځp>/UلWY׋zҳI&4M4񞣵-7q,sVg0xqvicX D:LQLFA$U$EwubeT Thж xdRY I$5 $8W8Nq9 1k&6AYTFU&҆Q;!ES0,FU+M D*5ZG&SHvrЮ4q+ϧ^f[u٣idXB$4KVPb8-W2*%LU_9e~iYqq6`2xxec(SC`-dVZjET\oV;F73‥~^XE6,Q&:a +,q䒌Jȱm^7/ʮK j14jVVR,FޥBϔl^ڱXTd,@8@ >Cypd2 !%Ոӈci4TBAf !1{XKREWqĪ6vf;R?` E"J9LYUdBfU$% )foqEJ0 Fp\0 'ifUN3g=Q1N]AEL"=58*bUAUS+/i g*NH0ΫP D譕a"TCj )HYlam4!aw,O{#+6{3)&{ sdlӿo$f6rg9cK_b0*9!q2燖:'PdcL̒̊ 1+,[0 DJ¥UFz:vo\ViCe[R8Tv%HdFjYCU$N1w0ֹ_lS9)<Ձyb8sq9Vb!]afSVdrqiBWcVP]cDCGZ=d!u Ej G!*H:S |8-BscXX9VU'+YW}b\ie*igd$#)YR {pM3Q8!e{%85e>\YM2X-aFYNǮx~|e *#lN/)ZUĚB:;[e)ʒ#1bqn9∈iqŀVEfaO+rg;R+LefF*aL[ʓK=[0ڻƤ/ҙ^YaKlaPqY,SqY Ji6L|QVvzv!i$o[쵊7Eaz]nK] /SR㮠'眧D+uz_꽏)zIv:R.6іni:NnvPd>y.Hdd,tzjb)HW'ْEb8{${7 X ,C3DkZl4-rĕeux恢9 ꦛӶ7Yq̑ڎ|AsGDja&*CcXj}S$/RP*FyM B/QQ[e`ٲ_R3ޖZFa*f|yedfqfVIÆR-cjX :=؎ڕ i;V[,\#R)=s:M&,]EJʚkvp^NǡMlW횯MS[G'jnk\ ˷bQZ{XN]bKT*-ש7eg}mQ[RػZ7z_\zBVٓԻ'[6vbYZ1 i٢+7{.hӃj9:Ki^)&$tDzQkOi[`WC$-NGJ62%ތW5/ӭWi:[0^nYgX>"MBvK#{mZZsu0 KńgFOݵ;Hk$ԚYZ̝TS7a=6f+33ZFG[UK~XeYZF·JB J=sTkVzծ{Z]*9{Jyרeuu&k~Dz:W F}g(:Xb;faRiI5!ؾwR%`>z}p0_pTg"Z*-7]wdGQjQ:#Q.Z-u|ќv)Q՚v]]cj)l@2UJ7Qdc,HFKUk%m}ZҲtV{]|e vV۷;o$P2ђi&*2^3zmNي%fױ"Iw!+V{Z?dTMkkOʹ#Ƭˬ:GUb++0+5TNǸI)ɖyӉRgٙn^#aBh7$TƟ.h1 AiNjzjlM^Oav_֒K}cRlq;UhDf?cr;eV%:7z Xr+h-;{kfPR*LeaճdGvjZip\U^ͯQJCrKrծXiJ5ؠ\~њJdG-%ksKs/5uNΝ=䕪7v=e)JCTTb&˵Q`̱XhIHxK|;*ByA޴STb!R!oeɥw445aIVVU,Bib*އN օib+ [P't^º|B.W0wT-ﻘbvSc Lc6c(V*t=/|Z>N[jϞا޵Wc2ĊnbYw.a$T"qAf:4o*ъ_/E*zPC1X֓)7fCWWX㪭f˖r]NI^<2 pbZKٯɖZhBREn2ܦ]~gpw_zunih{> $d"D7KjX+}qZa3=u,!V}d,*߁fM2ڣtzBeY̥TѷAyXXf­,phUV]uvR5eu 40%tDv^&h6e49c .5$RC/Z1!_}HFu)qUT+:,7_L9 biZ;ݬIV/h_zxBƥdHX1(U Y% KR44$H$84L~JQLfI#UĮbI)-!e9% m_|{>w^O| J#\޻ʚxoGǕn~'}^7[1.\'Ý>RМ0MǏu~'CocÅOaa-Ǵn>u+ݾ?kR/{~ھ̓_g_?ԧӡ (Pib`IWZ\ϥЕ< ]$)|D*x.Qz_IN`i2fy2 S>]n\-ۀ"$LÝDd!BĔsTorF#Ԥq 2!Ku$J<>hQہR"r_|Pq[hD%l6hH1+p MAMhUz حz 7Lv$Hm&H9u+f) .3b W zPW7*ɖ]+Le0ޖ)$p! *[Պb㠚G=- 3%UON$I3 U%] (Ujx#ѓSƒ H\lAVqo,ǸT]ONR\Kj%ZwI6PJ")X[~L0kJJۮEBU^LӋ4]gnJkNyz#g>l9`&w?i>웼G҃rOۻ%jc,s8dtԦ6BmVLqXJW$F*b8R[X`eUxd]So';>O8gn]$/L4;?RRUŏ1TY)a?&l9W,_qU\9Θ|{/HQ(Nptcs?ucKjS8 ?tYL7ثYڛe3Qxd/2D&JLr[3Y.(uُ]C:>EmQ' n6%tC#1r VKq1ܷPϬã]Xժ&r7f[b鹏sSlQ{w&Bl[I6򉛿d3;Y(5O[/9-17OIiphT Nq)b)XUFvPCžp?_:1O1㏪}-= ;F??3BJ)<ɱR*A$Ǫ(BmIUAvbDV%sEžIcښX "Gℨv5TQҊtvؖU"KO/4bYB>%x2ue1{yx(6__uOWŊirK-XTJIf C9Nqe4MzOt(WZҚƴ,ZT/%J LTԮ(m_QҞv6(#b1+bV ce):XbBx'Xz"4ݗ \I?3$%gMOpr"&z.qΠ[ a3?apA֠-p:T <-Jy}b@]Lh/2DQMzٱ0 U`Pɢ2j!v5~oRMCR"@&q^V32oS5hV6Xș>5,~ ժjT5bL"r OEd ZKcHُ)ֲeEP?m)N"C@hbk,y4B\F;^a$~Q^ZOaAD{1> G1S)I_108آfF"E$8) 'h.>x`$^~dhdADOO\|+&jb}4 7KV!h\}9 ZV o+1󭁃*ƔL:x,#@5j3Q&TQZ1EdRڐe5aB,04VcH* J9Vұ֋)^lwDG5{x2ԃn ơX2"}AAjT*#pje̪nHD23EPVGY(v?f{u?lTWd|+_+uSE/\CAP**(PO E^Uk%\H [<[ATrC ԩ=EdGArh6^X/oۙT bl@F87B($-/LVZc iS[ F<ʢƉ]nNJaZgf?EXM\W#?o˵JƤo8UTbfWƿx=v*h:SҘiS)H+v")IPGmJsjcİGV3<(@#hVUGLF&(_jh@ sev**~B,e{Qb< V0(4o‚E p"Tn "fmx^Cnt=o x#*I&Y3bQ<ƀSj>lKVqovk2|q^oR [FVҼUi &&ƴ(UQbTI *Qa71aI $Ԯ'JzJҽ5c?2ℜ(QWPz4_ROA^5Ddc;@#a2P/Dyr=} FEIS҇fRC)`&+'(ʕnSV8^HYQ`6iHS|GV3AToRIՉH@";Z"+"bZKJ&+s64Ğ)x$0=rirD%~n)J#)c%M8k?ƕkv$6u Ob@*AˤV vLOj'Ǝ,?X.:,h6 CI=VcXXwtI%HG $D̘bOac=&W$ޯ\Ԩ^ Qkn$̞H`~[!ts ?P 3rķ*7=.eGj2 zPJTjVV9ژH`HEh<Czf>tE-פ5anTjb$2ψ nEҘ1jP)y .E)ScY(ˆ'4H)umPNa~:QJ$7 icfʇ²v R@H Aou4 )Tp um@4Mc>7OA_̽k@ޠՇ$c`+3ڬ>aQ5Z$܎ IE LAM#D07B{TI<|%L]PU0d<\Cft$Pk͏ @i2V)0Wƺ˜%=mX<Uǰ`~ˋT>u*jh1j"4O&fTMO=(-Ԋ1Ȩ*ǟߚ|*VV*#6A ;HQŕ!H ܲ4qA< $$e[ETMF(G[hnYsHw#KgQވ+ RIu2 nz#(@3TA`̬'&bzJ N@b@MAE)Q nKkiVUSz+PoSߊ2keU+9SARLDV !Xdڲ  ݊%K/a[ЬʤiwcߦB0ÐEmعVPUSC!1Jډk(厕 AV(,A&*@D5JWaW**U]/OJdffDҤ:DOPH9=A- :Ҷ 9V= 6* xAnG rCфPrgk:  cy+$2I|+)cV E1Y W`CX 0$_ǽր Eow'aDƙ]arf+ 04<|+^`ye4XdDF@ 1DagF&Z?}zT_?}( 7= < "YfECIbHHPHh7$ maډSG$h2yRu*I9ddX'XL7ȟ0nV 4TP,Ai.&C!# /OCX@ऑa< 7\A-uRqK MW3A=Z\\AY;9k/^EA#gQz*keq'"~@LdWJOAֈ|aKLIIYTƉG!M[~4,L8L mحV o,bEcE߸^En2bExc@02(s0>5n iarYt֦K @Zr>kqr :+%ʒ#6 @+u^.D.GΉ""$M4M`-f-@C^$+EZoYVu9Tʛ5*<4  f4¡[ Xsԕ䘨f:zb7h4_ZYJAĩ`M1ܡ9$~q*0d#xF2QKkakkbU.4~][jJ Hnha-jF\Xl>S= b9 ,AD[Vz0 (.̻9Kݨ%t L k|.h0 Lj,XDZҫ3|LPݤY Gk^J5 qg6P6=in~"$ b )e,A'f5]X4 #l AY,t |~Se h3pc!,,rh,J0/HS"TޚF%c$ߊ![Y-qRon0|f(f dd`Ҡ&` 2e^bIA_F!u*%q*U]!"%XYu,Tq1?* X`Ĩ,`* ͊}&h['mGf]_)3/,$(Ċ!x@c֢.A0)UGnb,cҙ -bಏ(*@Q*Ʈ"n&T ju 4Z 9)z*ǗoLr&ƗbVU`b XW"ɲ7Aanr@44f&sղTYԫu0ʪo񭚎H_3pOO)]n=?}3謕(%gQ4ĩUfFf R. 36?a؁י3ڕI2< zD`QZ,zgX`)f]DXpCR#c2EӬ*@laSP*0@fy+43GٿK*F-#Ƙx' Dֿqc!R0#a  "+Vc@3lHʤ1me*]Ae*ߺ6pV `}'TieT R) f!)C3z cUbD6^/ӷ!#88Sī2ܓ؊;HPbZ&~Uk'bGϚ,V&D> kD BYs3FtRCQPn 4Yuys37`ǂ}rWⁿ {H_V0~FrX)oAX}W*X3)@̪4 *ԛz>5Bث|w"dj_kk RnX7Eů&f+[4ʬчշA%H뭰B b׽Er؀ [ѷ"׫)4+/Mٻ-o(ݯJ}\ٽReRPOA lړhMư S:o5Wڂ+b u11J޲7dq'RcU$ Rۼ{R2ARo6Vdb>Z,؊H cՏaJI,x{zXn~4n4{;_YSx~kc{h\Uz#xhęSQCQUYF@ :ՈSn>Z'j+Iӎ%\@okeŀRTg(`H@Srd1xZ>ѭZ,bԪrYP.mkbbەpcJo.6ʱ=dHz[cn EUAOCШ_QjX ׯǷ&;6'=e8R$*󨿘^4WR6\aj؛vvR܉8+* p{Q"0ch};bdz@">(ad2̸x$el(4x=WAVxYibDR3}aJ?udPOzqF`Y~lU݌La^x5X [On`!;fIaBYiȕ "@ȋP5lZ`ڽ-/_lT`@ xDk.@e6ޕ#"33yX7a'b(ͥT %`$VK6),un I5B#lIoKi!qX[{]Tf<&z-f\bU ~0ݭd PxVonK+7~?}*?RaaJ|kCYbף}/yΦ&Kv84erC1, 4 xF6Q` n] 8fX0?YnAMaw%U|S>f"@b1DDXRWQCC0־Z ͹>[l &V*TxMt.L}Q܎i6* Y+oOjX++)&tr,dU,” I(!rZ]fSrgM/0`#"$s{UAtMMY`obIiM>݁N*υ6κݔ*EZbcP>pVms0q=;c6 :ٗSyfDWYN@ {73r^T/74,bĴǬoLŎj̮L]7 {ȬJץc+Ao)`I YGS2!8s%UE{SAmS0_K7+%W$i].ηwKqέr-[ƕY@Ps^uF*N lnR5.z$5-[ʲf5?YE΃U'>imMkVo4pU?>BThڅ^QK|)PI,y+~Ч%fxQrsWbT؏ > 9~ǵ_ "LQ%z|-AN OUo$M'Ʋ0 ̏ox2,c3Lf{ \!f1ڇވ}xd e]m#c!OKS[Hk+lٿNf d,.—nQ.íCWeܷVދ>NXm63%S(o/%{|iuR0@"]r6ߊMUbEf#v!b rX۽k׽iҳd,/t>u /ul5'IegA;C2+[%b\4I TX¸4ƙ @MTYCc{GZVA.8t۰H8=Ot+* mk.j Q`٣hT]zN?Kߞ4tvi}UQnwY) WpS``b9&Y%C1jA9',70uPuVӱ|=,3±d2[?OkR^{fU.̑{ E4lUoZĶrȫAj]52{SJ{b,Sꀆ3VPcfx ]/e<=ang u QٽHg# Ŕuz]*I(2x:bKU0]Ti I ,%҃>Z`,C1Sd (P@rozg256X w2{IYuR͘Ql}%4}3^?'HU9"Nͷ^U `sƟ:(X!KbUsɄQ}fJ9}*D́a5Ne$o}$VOʂH,ojU;FR+ Zoiz{[Xka5ojߵݭ[S-[\"m:.أ < a]5 m#+s7'$95u{3VP=RA_3phuv0WZbPFBk*.mHdhnfYTO'+si+3?:4Ci\ATY|׊`*D>mlvQӯzﵬ#Gg}N?uLڶ ECN+pSl?/NcIbji*6' VGJMyYMp|h|cOcөjbwVRd4LAi\ ']XpA(i ̞+HvO /T6QxQVިa SؾfP_$S3x^ݱx Tkf2s)5(YS3iZǸ[d~ᇝO2XQb Fr)WoAdONCJE'i/LOq)Yj6NCd'鵩{E][=mjfg܌PaGShѽž w6%>mbۉ_lIȨ𠻘.UDl  4=T7u=2{wRԒQ2oғ L[7jȪ@w,qO{@|O;ԛbٛ,Ooƙ܆UB96-swŽ©CEpH5C{ZgkbNkMK \U{^HJJ(RҬl erJ AbC !>bØQj\Zbkc2͚!c*LjJhؼ c5 X78Ԭ b9= ٔċM AX&?P -A3lb: vieb>zunU!r<X$AХAyx⃨!FìSW1i| X|.^ 3UI;0ɥ7] ?8kK-oml9O42m,S)"<6KF=G tR[(*Ƶ v#kg lUđz x!y|* \RjRuJzARVR$7u7e`ui,~ś5}U}ًiIŔ0(kP[Q zI\gͽLF\~[}+Sl;һ f(jc1I* .L,s4X4|;3r$'Zԛk>5I17!T}(AڙLsP;e 9Q`_֟Kk[O+>ja^>^K[,Gȭbv46V1?־qNXSNض u5GK* @WYF#" nD sAO1?qZU$0|eqXXEV2 &h5蓋 ~4SbeLaȓXK# ;܋-O{pz)&*46a%r;|B)grI Z>`UYԪ.Fo6?jYGJ-@m H?HW]jVUW~>6{ʪHW2dT$?(-3_ƙ}3hP5 Sv 8> rZ9"H4!TŦ)ByA6"-Ҫo)nb.Nwl'o3f۴2c&&عmWe !e `s"Kr4UNLfD&LO'8c wS,HZr٭-z/64W7u-1 >u1Ao_p铏+l ` (;vM16S42EPBlТq_bciՓ<~`$a?C`\@VQ Ttkݱӫa)2VlT6p#YknMcUh"bjp PҦ?}7%ȉbԉ왶Ž6f1kߤմ !UX 5[0c[d/ VTބ-,ֹRfdԣO `lmAM)D*H_)_(7a{ d|ibC$~uJm[%^85 *62QɭGХO7L9V&ElI_ R$VV"if K a?5zTf,mL*K/bbb bV/֡#M4_ܸ 6εQ2֭gꂳ m[5nRp-`4}Fe)HSdx{eܥ=B 1:`;:TX  TDթAvcP Wy U(QYd@(c, hds<޲ bĈ>b 1*.zҒr~?RjemDُƂ*J0`\"ٿPUb1Cm)@OCЉU Xi*ph{ "h(#/ƏIŵIiT,4-+gڥv0s{+2 E.jh)\دH 2 'moǔ*O_zX21UT0i acE; 7'JpbǚS姍pT: !k"fWԑ1; yS(AT)*+ߵ܃_lvbORa ޣ7'Z5*lA\i1*_”y!yڰ,&fK*7MFtFBɸk^f6B/iiT,koPieV}L@cS,騍ga' ;#&7#V>zEH.Yas4n$Oyc29<@ފ?CGcHK23Gqc<hUe*ĴtܓIa"[k? Z3C($-[ڃG?uz$+%7ZMqD³AixWW'GF] lG^g_@zSOǛ A𙭬UƎ V~͞]sTicn\TTڶu|GIGY8XDޕzu РAe%Xڃ7Y<7{4ГuM(&8[C #QdR0%0G<~ra'zɭl*ʴL{W` Cc]9x`21MNR)|4? ̦YcS+5Ǡ)(PmDf?u'994zƒ`@mD*J"]KQX2*+q![ @$e"l#T IQ@y۰Xp![voPOS9hp(m:JIV@Z}sJp1sX1S jvnLb;ֵ\$׶pWPPf>N' K)&WvȈnM*J4kܒP)Ժ}ޖ܁D툏z@vǃ?SgdOy`vpZqK<q1uo~ZSۈ*KYqt"zYXV,U2>=ՏN a܋3pg񭻘؏cñkF&x!IR3Ұ|m{S0EjOƘp=G†(qMkR1`HWf-rDj? ̈́0~ RN9YF&}2ZUx-Q^a}$*A]F=&kA p)A$i$E gwiq")Ფp'p;NC~WW N"KmRR( jN$2)&K=A65HٽpTR: ]S[΍Tk MGψJ:e^U 4ZX@Gz,x|k&h?*Iw4Kn[r+KS)Rf G0J =R5P Jr)lS.X ' <GQ -YP;15 qL&'5O{VDLZ;'($\JqAa3jŁ_L6 yM` H qJJaOIb c(NjiNX)P<䩠5Ó P'MCě(tYԁ.B&&j4vSڽEln *|:@-i0@)bzKƥ*8bY e`bHI2"V)WP5ŽoYz4͋/+jf,3lSyMO"ET}F=aű>>43"MY6īGz:ܚ6-bȬ›fh%*(eݔQVOPzn((W&GZe3poO6U1eSc$ %zsI?OZւ MS{IPd 6<(!|{JX}lc2bDI>4']@|(c(Pgp;j/'ѓ}34g~QC <>?ݣGʵw&_ՉDM-?| @Rz}SI.?x&XA1yֹhw[}IoWigsR)qou7E/q=++WS^4p]x4q~>> އ>¼oLHqŖ|14=`uH›׌SF#<~h3zh~_ӞW(qHi#sWc(G'XhOx^#*8x"g+LqtWu],{"ОOAOMjscropperui-1.2.2/tests/castleMed.jpg000066400000000000000000001426301173375244000176420ustar00rootroot00000000000000JFIFddDucky!Adobed#uVHŖ   #%'%#//33//@@@@@@@@@@@@@@@&&0##0+.'''.+550055@@?@@@@@@@@@@@@"!1" A2#0B3$C4%!1AQa"q2 BR0#b3r@$Sc4!1AQ aq"02@BRbr# ZͨAM !Պ4JR'ZF){ U#[hp=O /愸/f %('RY2_fty=Yr*?BY\km'FKQ" :8|ف,,zt3>>gU:advDhӸH0-P| Wk:q<1cQ;@*9+['+_y M ׆A+Ζ.oKpUZLK fkgɣ,ku"/H2:x#:y<$y}j6L4`M Q "^׆ L ȩfА6"*!vGHOtu_Sm'͇ܫ/Ǯ0H:J-6`ɮ"3̧^wk+- 7 Ca嶺W+~[yRE*u+TLy]=Yj¼-VGt $R7 P$f5"x"f@cdlI&J2wF|=sǠKX̟D?#ާ1;>衡ϥݞԠ ֈsHu}aEff%|x}R8u\ ?՞u)ְk\k24EK [[ʅ_+>YDLOKр_7&>:59](hbiKexV-1t1jp:SjذfeNx^h"Jb2\cذnSk2Ԕ= %VR%I.>9* .eUQ}QRkla,$SFf{:ie1ZaᮔyR@'vx2A=&%-P{H%;j@E`\&¶52({iz ]]jX aY"6 @c~j3ŰN&V:LdbӥSagD?ƒ cp&yó6W=dJ-%!97>| ~m$TïZQ^ hEg˵\fV*`v nø?W^KG@Ytr"Q#U:zyg{Ww,2ڣ8'\[K yWTIC" r#5h6Fz]%5Nuo:lH+B>&:hsyG;,%,oLn'CHhBg[v2m; 4e-j4*IZU:Lb!k[RZts5+VQ<[Eu }ZţcE:kn\谫 @@MBZXLbnXdX=7_5;\;cmliU ѨqyM4^XT=IN iEzWB/ \S< &<-"(Ge-@:fuL#J_vGS5ERo_Z/С1JO4WLCcq!X* LJ6V/[euE* 4h0K>ڽ\: .r]Zb|71"KQM.䄚 6%Q^P[RKHW/*sKQ#Rd ӭz׆ũ3 g;'Eʉ$.9G u I= U%[K JAGVksN$5^20*af4iF|N*q%1^g]RHTfXƎѵok L1k1=V mԴ߇jWq{l- YҧŪfry{C = zœP<7-Ucs_C`ygdXT5}j%yUͶʶуcK {G~Vw)r^.ڪt)Z+!s{G$.nO4&ū6%M#-i$cj446j* PV|'ff+߆{xtEe̛$e4m>wSkQkv` l6zxki>w`rRM%DS]7RQZdz^FetCtq3o;_d_Q15ǼW9q 0 +ЍZv٥Ίx=6 y+9oʴ-=@zk'g⏤nu$?nyEKI>U{Ig8} a^Wq7nR-.X+}V&^خ'N}mgQ:yܿ9D3yW/qػ<|FMPq|yfY KGzx۞v5G8ߗ͝k7)0,f{0˹mKG5uIr]Fj66C<Ë 5L^Xlju(Z.ںi1-mo ,j#fIRΣuvt^iWf_E6R7)VA/RKaUmOvw./_'b+-s6F ָ/ipUG?[37r[Q(py!c),{CeM}5kz eId؋"keKγh pskQTUP!oZ_vX iaԫ6E:6UTvt[9Դu;sTKɑjvEW >ϙ5׮g͒ye?B]GPdFԱ:d0*h/R%,un[W)7mp2Ẕe޴0{cy$=d_N1+8BWZVID\%3}V+PW ܗhV{f1v,3iêL/fZli3v--Yk"jLΨZ /l4C!Jkg>i;^:Vr[c^OC5*ޭCl*-P]_#RQ'nvyYb-+asM Lk!elZ_P5Ȟb c\g2È:4~yjٺC$^WjIAi.sMkzZ]VbGkOc _;_?VIU}vǔr xI{Q[C(љ\KzT:e&:ڞlJ^2a+R^IÎ iS,0I 9 ݣjwRe;f84ri#SkLe1 (]ѝM9\yMb4*g̘ZOw_MkhN.Qfƹ8~l>vz3Jla0ŜHqttʩyhq4ϣʝwRr=E'΋-YBpnq6vvw(38t2qwT>ɲeOiݮrNEew{%|u&sJڔc'+݅ wie= !^<ػwTϟYWnu9Lk91?~`@b$* ?bgf ˃ 1<31F#q| [>E38?fxG$A#+9"g DN쐿8+zLfLX!&dcܗ:?NFfs1{%X ŵmoVe َS!1h 5ܢ{74r8+i'OceQyɭ^=d|f.Lۓ;43 3DOGgLG# ʛ 1hiRc׀Lg,f@< ī"$NIF*X19REr f Iee0> m84`0V'c=!8j۔#5A[c ~33)j kJQȩ,ؐ`"`O51$s&-a=~CA`L`sQ ؆ac3 1aW"1̭Uad+L9Yi#a03yAq LcÉ"bȰO{q9ZK0*f& Q? #,>3Q䖅Z"`=@< 9f'DBHXTN 1 Og3@ x#ĩ ILaCBͅx30VaD#EP&L Qf<pYT"r0f |ȖL^0APY@00!dɢ3F b ',0=&,30pqB#}x}!e6ZX Pʒӎ",i3Vr&Vr l'19i0'13`1 S} |12Xᔤ 838G >LN3EĬ`CSSOfy $uT%q-c9;C)qv` 0آrxBظ 32a'3͉! $`ff- 0pb,H)'laMF#?Ұ%lqlo8`| l}KppaLFXHCPA3Y\Ff8< FcEUl@@e_GpBI0W_JrBg W(gUO dc `\4rql"e\e W Ieե _G0 X:X9<[O7"/!߫O7wGo{smr_4oեO_K>""@5*W&?fLq8Oq$ʼn 30dja*G>8AZ b"2+CITa<@A&ahs0cLZ#(A ș )ZNu NEb?'slj|cg ~rr2 ' '1-o ؊N"qX|b3Lg6|  , d#A˘@}b?.܎bra d/9ŭZÙF 3"faZyF!PCVD0 1 Rg9ə3zDZxD'0a080VL8%L~1F# iS &5d.gV&? ̏GB+ "#c3,"`332g~ 0q'r$3`8f>39Lp9!r |qgo3 79d`xxǎl!qA"ri80 0<ϡL33 F2)Q 3p lɂRq>3@ɀ333c+&q3i8&q3L 0NsC?!g1~>ɇf NS9NSffraR&~I?OQ|Ly3e|AT4ja44kܭCό "&10c|}a0|dg302>>(6$B30L13̘Tqɧ3=ac0fq32~0sy3&rsL> L8#>&L!ȟYq fD>q$0#pό̘ʡ1A֩bd~% $`[3_xH`$2@pE>1K-*] "1 /ȌŌ`8? @%lp3S6TS<fp9yA`BT0%> <1_&1^9PnUg+g[ Xᬳ98'O9 ᾩ"1+ >"r"3yD39g#0Sf1Ocq?Aezʒ A?Q8I?8p $! x ʘ| 9-3>ƵfVb1xq31Na0XGxL 9`Ðf)17,f UFBL2-H/Vq䓔?y8e1,̘&! 9?N0g8~9f011ba\2cyV\AYhnR 뽮+]5;lweaX)S8 ╖/QCq'W`AV@̪ȰA`sLӰuVug;Vu/[X³813,#'Ab*0B cTZC#qDemZH - YZ* :8v}sSuzv^i^ʧaR'b*ʆUHe0u5#(Ne:]fq@HC LSUEV>kzk-t &&&&&&&'1㏐q : pTRpoF7hOQBTCn(&kljj:-~%"vgM)SRbYo2k+RƭU:h& +1111111~)m)YՖ&֥{TK &&&'NhԷZ3}>1N``CD!aGjCRVt*0g` !HǤgkI]t(\zD]Z^= 3k!$3g"aA_ Q fCnVp]ie8s n#uV\iXN!ٻnYmqL`339gH !8e+j"Zm%Ubè.'[(fSUfZ^ŊY*ך\E>Ãvcv)yk?=i#&)ET jD!.`@3f1a`LȘ0> 0`&yow$yۈv k_kX4vUد`B2T =kԸSӭ6ׯZAfkr94A5*ҭ*. RR1pekʘLBq] vGܯ>1 mY <f f @&g['uUVYvRj#}9]-m]"_3? y{Jkz[ڦxV;p,6 4,+ah șc[l06,nҾWbS$)o8(>X=O! c@LPL p"sm] @&}nmYl%4E )y'C.fv t\ Ο<=@h"u`q 33|Fx';w2TI$331f&`hm#u#zײϯM{bi@ASͭV *e,آP_jZ:}-0L˙}vM*Ę[m/ iٺ׮lhwWf-#<N*BעcUվjͯe(ZMueU*@䪧V& zۡ5-/hUR%U 몹kY,`BHռƪWOaad!0jޒXZ3Ka"=2U s[,ÒN[cqemN>)"P} eXO^Fpw`jiM}m_O}jj$_99T&B+#8k8Zj7SoJsORU}6L 5=5VjMa۔QQץ * 1lI eC]X+įG9b9$BHQ(c"SX,+ղ䈮\X"0'[Tj{C?u]WJ಑YPHƪݰzEؚlSZ" VS`jSaM5!2V"(0V.Sn]dJ+; \=nU b"2[‚ gc^ <1ũ=}^l皀l*Q絔0v0 cq_lSj+#k 1ȆKH[{".E5og]V{yֶ̫p][lXʅ0Tje-K%dİsO".:5.ըwv[y0`0~aCs=1m`+!o[/3\1A%EfrU\C4#ڤAPQT 6)jAJ Ͼ8jicZim)RJ]oK@T~5gŽATJKl lZewZ]f-YKWwt'cIj@TCZIjI6i(Р[jڶ4U4"a ى]9@Kd eL֩Z۬,캸iYbߢ, -|޺پUj7O&dDMWOOO[jw:uouZRѲ #dvG&5g62`V  L"bbc&VY, q?60F:.rZǝ+[r!PJ6#l`M515vuL28[ڂ\Z2!Ȃr#pA55?PX)jYle`Tǵַճ _X(˯TN1#0aY c $3>111111񉉈15kcU5!#.j_ `XMu{kآ)_-]ܳZS޷lk Y[ΥzPL"Bbe_(z-eyR%P̖Vx#%J}BؖYC˴Ok{Oɭ MN]SJ%+h=|Mz+L]6k"bqVAHk9a xD Jp $:Y+%Ku=5UoHg'ab 4;!5dF^=wieKi{ ب OXa`J܉b/mod<`J `|ƳAu,m5؞C 5ZRZr5~9ObbK b~B3f`haR;<գ!R'!6x0ܫ4m=Ȫʖs(r, xsG5Uiֱ],^MrT+1ZE/x R"CYʃBËfc MWX:euw1·pT=/U|rU|v}!ec}rgxʼnk7X]EePXjws]vYŞJ/Wov V6ru:{UVJ-Z0:ATֳԳҳҳ!OZ 8, BkZ͡I=F zLxJUٯ+s'ؠٹ(F{ g`U؋S$3`0(\ S9(ֲBV2DAPZXh@Bu!eu-\5=m|}VaPU[iUzQ붒ĵ fr(ZdgZwNP3Aal1HVչ \I"ХEe[~l*=VK%JA|EQVQ S֊%ЖҢAFAVUAS5r,2IbjPG7c^C)FFo` ՚k +Ymd%NM94,a&ri̙, S_^÷OO'2fLɊ[Z]ouŔTe*EEe!%/)g<{`ɲ{k9e6?[h~لNLGc1/ccAfo>-csG~" UNA[w[jjZ4ơnn}[f]m5w[KV*EvahݢaK` qU_Ӳ[PkʶF\)}]}6߭]eu:޽+ujSMCږP-Mj5O֯^5ߣF}>h sTl-N%6%V-VKͱ-Uf+jfɳ׽[k-{u[osD&ȵ1Vy1\֖2J?YKmޣgqv*-+nk-źvovzuֶZ6RgMc=,շ]b簫f/CKMz5).l,̥F֫l_[m&;J6uUVKouڻQbXkgYq`n-.N̳їsef5.F6Tk5;A+7i{vQּ/Wq_bְVEUu5 UJwSYMڻvPcn,UǬ`؍ê^?^~gJ:_eZ5-Ey׮C:V{uM]pHp5d-ޙ,}޾tU}]pQtEj+J lQ[{ϣ+٫gjͻױīdPwUunZJ.MnIZ;;-^zSboU빪fַ-~I1 ,;ob^kYWk]nnX=cmVǠ]C-(\u0v%6MVK5ZhOjnXQ}?erӴTU꭬.XG/٩ˣ)jiSZݦݫҙ[7 խ]zWBe6 Za:k{JZZږ=-I9$Iv7tnتdb~g@=AiGawUXkm.CNv%|oWkzn)^_vj'o·/4裰n46ƆnPQeHf68׬XŪ[_k),.]fX=Bۑ{YȬf־}t(4]־u粡PeI5QTc^tJ?^:=,%fQorWQٲjY5Ȧzj/4v]m]_]wnsCoNo{gkЇeHѵ/VƽuNZދZloz !pճZ+ݷ"m﮶Zѻrӡ_f]ilm۷y ~>a(CҲқyVΎ־~/mVli7SCVmz"fdgIm]G_[Clԕ]tUi3f%Jl١lUTմueSUzXw"vuM[hJT61^?O5jDԳOUsv1]UnFOR_Z /-U,a[ ,MMN=Vkn z[jS[w* bF,j '&iO]ްKV__nVka_ }oyܣs[Cgng5~9uɧe4rmVZuz,ZmekLgƹ,_IU(jl,+E jN\cŤ7\աWk&*żϨj66׫f]Yj_iz}cJKY ֺMZ+ׇmprKz^-6"Ҍ\^v[/mmgۧ`ݧguwFӠ{و՚o2oz4t[rM{ ,] 6Or:5ilmdج3.tMk)*Mpnam@M`m9~?wf~4UVsS n7HCdSizm95CZ:d}#+^-K:Ek!Rı !nWa26z5ZlklgYJB,V[j#W^ (*`,fݱְ5Yt/:ƫX;mm^mF潮o5ٱ4lP~c3Mvm.]{zPW4bN5Q/4}uPЂ¶G]3cZOwٰWQѿkƫaiIJϻַ_lmWj^n66syUmZS}45?G6V1CfV={VMLU6״65-Uf>+uZMfnp ѭ}u0ZcvG-~=p?l!w{G~׫CZZcM^P84Sɬ׸b*N ,d92ChTu&9 ^zܰ&Ө1UUn7zվ_R%&m|˵Xhj@sWtzXwX79%NYW_uj]i}m]zEڭr6uM6h>hcrj_wڦwZدex*Ji,K efa}fs7SWQ.J*c[a\$olӯoJ]?ֺۻ[Wm]WʆzL^ne]LVԀ`+-+pED Wr. UZݍu&f J_#U+2UIXأW6icD¬9zQqы?٭ 7~n~7Wϕ_>{hp:>˝sTGrɳ|MZܽqn&=?~_}}}z_+-־]Wcg;-o1/k G?ps{+?1,P난(KۺIn$*hP˔d4NeU0(A< MW*.\&`ep\+R# 9" Gw#l*q5W|F,,9E lR_B+rS2nJ.\…&gSqXEjMG((R|YrȬ藅 D|\"S2XԖ 0+t¸DDpJ#=HԤҢ*D\fP^#'(U\Ȇ',jKQE΅J:bس dB<^rQ[ISTS.+abļ(SBrn=CaA(% ҞdKD7j&TbI%k q5ܙ # ,(XU3S[[$yN <3bxJ&4e8g!tx2{~Si<i>MfkIYvnY pd:?4xLAx/%ʖu𭋒nmɗ"K(M T$fc[w~vIWԈfYDbQ6U_H rp$Fb%Yda+v. GB9ƒ9A ,$C}n 3h(ޥz}ܝi1Li)ג/G8iwn[ӔSt~ɛg.^:=PFB +}O7BDwg}.u0|Py-GҤrwixtމJ_/ /(Kowթ⟗y\}.n?6[N-4=nMnF©{щXy:-sL)C۸[6 C߹"r"Sb,9js׹ЋRPCܢy Zw"4#8\l|#ͻm"!s#gTrBږՠ՟2CSeڧZ)PE(mTI&ַFnHVF"Ňʌw/-\imݱmj[ʏ>1mn\jJW%G吮ؒ_!,5*6nz$l :ď#\ŃO*&n$Co Tx¾|G_]jGKGͱ 5$_-OsMϑ"VuLk"P yql׭1S!P]dDJbQNj?@s]iZ/x3bJO4nr7idDM2Q7i7U5tB)`.WNU|/'"{ꝺbW1J }Ľ;5#6nbۢ'3rtSBS^ܡsBNx?!N>t4}HuLiރ]~ot%HIv~ "oey)Eʍ߹o5Fh=StFZDo-s%˛ij9TdT[ k"Hʤ/qӭ(9ݳZ˺ةVx^RQK4/9eȈgx7vgQ'VnF}{v6ww݇~mɛGF;G] v3V##N#3m>L̾? +_ſ ?$bȡl-lI .(xԣ,WXQn ~ $"9$>8)0^0x(ʐW )b5c<$تv,)Ԗ*ظ!*TtV!_#"w~õ_L~7Ss?'jZcdԶ [Iw0=i**KIo֬xѩ7m?^ѷꊱkP $jXrDÕw !¯VlL*ǻI5sPjj9J"h깵@I/Hd%iDV ޏQ<~zxr fI*;[Q8CtEg֋.142,Z@(*b/WSz/F:B@k=j kݹeoD5v1lM#mnҦ`δ_p?r+pTP~|ƻ H7(b _oh(&Lgo D*ƿ%ka\> MNO젊ƀ o>,DLM}B ~&'E61kS3)Pu`Gu#]?[쏼LQ/EYtD2Q㆕*LQ+a֡P c!:^[\DUJR+J-CvjR X[욿PՉ5 wÝ vQE\AEq0*,}RtP.(+=Y, HКζƵe׉@^&Ti[Kr5(o^vQQZ$I V5ܢ3 ڛQu{+ps:Qǐ\hx[},~*"YqPpdPoOJ"$kG vJF߅|bx6*4'2%u>  K݆m@/ƤqPd)\WUj yQR5$VO78t@ޢ8k\ <+~4gP z߳7/U,/ʷs݂*BC*`Cx IEM&,7EZSbLpHBĝ~Q˝(PfF4%Lr[ m:u D,T5Ev}5j(Y?eo|uGՍ ɪ0/x[qWwjGЪq@yJTou5!ހ5{վ^Mkcb`j!4@<PV>(D jFXi_]]cj2,/'J`mJT;J47PPdim+&AËXT=kmH i4Qt5 yWT4&[?lOaBQ5s`dQd? 4odP$IҶ 宔!ݤ_Mk#dBn? ‰3PE  F AAVV53"zPSZP+Z'qDR&ohcUMLEpVm4T-i5Xf3ZĘ9E$oh$+&l.V,I({ukr# Y/CmE?om֤ :ژԚzTɵKH|4Yl9T~榹QoFSvZ89q[ikT6#NUjgʢ>dLOήKO[,`vڬHO'Y[#:cf|kۀ&$¤e:^8ZG?z* ~jf&-kZP "fh*Jm@I&OO^2-pVs4 ?o٥J E*3OOs4Mv8S:ƖLwwípʆ؊_!%b#n< \^Pѧ@hdfk֊OjUIBlngJ+A&nhƥAzmSµ:U(`UkVV&2xP"xEw6p*6:{TNT45h;c; WygסH34ckq/jv)"5hAЍ-Rᨠ7-ܧKV&-ݫ=iNs[? [rAGVO#(b[Z,@ \,~:hƯyS *Mt~j&*&j*z;Dm<6JTs"sA4tvkjZ cBk#޵.UPz} MN14w+'hZ@$&#4n?2J'4}aZ e2ukr)iD9bdP36CGԀln0܌Q @"nPPBCpܲu^vUYcȱh3W: c!QO‰8ΚG{`crxO춨R~BwbRLw?:׸TUtT6E$ Z VJyiS{Wr? 7ANmxdoFJ҉bw_@gTc 8#;\cWbyM"db45؇(Z64"i DpHaؔ$6ElĒNE>D9}E [^4XWJuȻX-Eb!h !TmE71!|[b{k<#dԪ3@V;MV7>1^kb"oʲpXW1D(5 *J>*@ܑcή`Tva5zۍw nB䎵zv*d*H4v:5{4LƿhiQ/ҽ΀q @#ŝ`ԩ i&&vBT*<|j.1F, [Q?UV{hQ:[ɱ-xy7$' ƓWPcoSwsWZk[H5!dT5 "ƄDv( Ύ7p?ezj^h?*"zTkZiT>8Vn"H5 YN!qB:G+r*DI'Z2zP#ԃ<*+qJmFx[RZ8PiX&RϬ#A^\ 1 pYoqD!z^7k;Lu"RGQ4@4b>T@y5%T6ƚQ n'O&hHz;LM351F :RNskrrOlB 230,?,Eh.}ݨI*S4(\xդh3X6}˥.,dpYV =r+$q/@DV?d5ܵ^իڄ 4٭Mi=h|hf+¤u@$.hEVռκ *˰n"5pe; ᴋz\hɰqlΔ;4YH=(n\'Cv&hș[JO6" ĩBH` {G۴, @ܩP`_KV9~TrPzD%gz({;d!w\k u^GһVר/[EC =i#h!#Sx[XG;#{` }"3&BK)`ɭωYI mAapONN6m H LōWemNxFf^EZV65?m& tja@ƗVu+ 8W Ov6>ad +d]u$kEtQTYt(5؛V<-@m1@*8rt[EOCih)"RDq246(:aDGi"G[ABMˏY49D=9Th ҫqva7=(cf ǭBډn ksD؈1}zV̀=o<;Bο F\ף[։ +}+antCt<(@+2qp`D YYOpC_%PNJvB^iƘ-8 h~U?e}ֵc mS¬u֤}U}5iZWo v6bF(R#KkL">DnqN`(3+IZ ¤1VbʋM^YHNһ8*C,X^mD F0G)r *fFˆJb![`B4%H$s&j1ৄT6ʶ–H~t6 K\U;iP<Ο*AGJd2t0jGzTF @lh8ܤ:qxhʂHؐ2Gzk469U*LD~ۜcuR2FTArDG (*c4J &wDu0L},xˋP$<֕sץfB 6<>4!AUA<&fBHaX0A>ֵҴֵkZVf[CZȢf80;r(`o"cQDYntW&@tL":$Dƿ Dkx l ꦔsCp[P&+I1WȻ8Q)*ʉP4 ?trQ XYLs[t?δQjCƠ}kfGlۉ5h]Ekv$h-NFMCC0d6A+ҽ̃kBxO:>.fś"DWB$ʃ @!Eߕ8ʢB"i"a˜?<9Lć !fyVvH69Rfᑄ+ ukTUOOiDH1jȄvG֭ZnET-M& DeYWh!o mЁE8.FQcT$FAQm5^}$\Gʾ`^h[ք q"~+?<+Q=(ѡCq}tV*nuh`@u 5p?*e7xXy0PP F7f$ \A*!Nҽ;ɸ*thPZTÀWaOTʀi ;<RJ 7oqŠ\GJ [hOhIȿuɍ# SVeջQ'e5d`վfmx 6bu|%JSƮ(0FpmD5}YEւEx b+Cq-Z8P*IC#VX:£_Z MccۡqFSukk01652yGk:m,O\ nF#C8V W5LKdا# ΢7JIFzUr$=iP8 CE23zӒCvSzpgipkr!\"㔋zcG**cSt*F|G?@݌ukZVD,$ߍ(`DDX td\XG(ye׭Y3c"`@$ ɽS0jޠ AHEF-,jkXDo9{lX K$7&(NMM}&N:Zi+q +o O_NETbpf>W!L{'A t֟^TU&rK m7Ҏ&xO*l9WUuaKJJI69kkre2GHa&>TKA} 1BNVJ m4s_jݺvTJUrHLNrbRI m2Rp (Ah0xYp'Z$IP&gS2UCk)ARvȑƊd 6XىL1PL+qMvtnY)U-i$WZ r/|GƗo5P$pdtjǁ4p<*UȊD@P@2§F)FF@KTn`АKH<=:Ѕ!91@En2OǷ:o<+g"ћq~EV$wkwAKf`z}>Ӧ[QßC!Xl?Xs\@ZiFoR'HZ·opRI;aL_2Ht4E:][h6iF)0cQ *iD3jT 6BP:PjD[I!'AYn'Z׵CZy$BЛI0nE+1IqGqDžAuWGlkcdڥmEݚ+.0wRZV.KPܳȍ( $\LVosG39׶_S^5,EUar #Sbu NAJ EK&ADxKbm=jDձۤT1ڵP C9Pר·(f~ĒG\覎2gn11•xԆGMfB٘f-^}mʱf YfgG16;H ܙNO-NosZ @!{Lkn v͈q7XmUګxI#/v_ToM)b {{1}zd˸De68S1"n.DdƪQ:r9祪py1MX9kܶn/X$MJęU]`yO&ɌZT ME$:E>W_w6cJ<_ v",6[siRs,"x5Y ݺV⏌FԢHXKUqj[Q(MM^b*H ΢ ^7}-\E`vãIѫrI aZNS&4laZ +?7*c/|hSzpĐۭΓ# $G\@LJE ){_1⅑?aCWٍfV<\!VO-@L뮔qتQ6 oĒ1.,y c\B!ȸ 08kn5+nlJEm\aVq")oʱ}&o 'Aڛ\x9⣏s&:+eHX!BĨ3X@<ƉmC6Ȋqi4!КUw%A$ ,ueG;I=:9JZ LX0y<~TDm'Cλ\.B#"'ȳ v=f ؛\^+|GHVqTjgzUVbufYZ#һd #QVI_)NEXNP P.&$I8 3,V&6zQ-"@$EԘwXZ `#bd ϻZ I:JtIB5 3c}V p44<}f$Z~ufb6ؠv6+V "(HcbNWo SŹiOa2&ƨF4u4l08/ CiqM8wmݼ~6,dy-x4g ei3œ1$/~V8Ah]޼| 5?+6<@Fobt)0𽩉O_Em:>&L.W71>6&;&8m7v6.A' qyE"WE;'wtɋ".QMqAe`ۉ&2&EܦC=KJs"RN10$_ր"cdVoq*w Pgq[|pE c¹w$VE|W8̈6*|^\D^F1fhY?ʙ&B*Μ?1vY(Z9Z\<&edehi9ӏ}xF)fDuЛޗ+' d7F¿DǥEHSȱh74c:}G}k&Ewuyǿ@?OD'ZAF\lwax]24Dɕ6ED L9J)]nOd3"Fr>ح`9Af͌o8 lH3Z_r3PT&Ukj )?gg>FP ^93"f pDFu*D4,%ri,C>\S`!mYq+ [9^", &[qZ~@o^bl/im?*!?x !͡xN;zq9E#בy& 5eLdI?ʻ :ʝUwMN=7IW* Y&t yvLC mI91[ng8c;f=),Բ$zv)PĹ&/|daJ*f?E hTQq#&IGVEϐ H;@) M'T} jTRdV_TJbE>?7h۴@ R1:Ʌ3Oo/AƷ &E,UOʳ'8)֏kDw9/6yx CB_&@7^p7n nlIX n'JUҰ?gV,X\hlذI&uNJ o#{ P>DŽW2[8;oa÷zlyOlhJ6,9Sr0W>LKW0Kn>ѕX; ˅(0ֶkI;<ݛhN~l|*ZQ6L 2؞9r;B}*>ԷJ;>0ց.w&EX.&|LO` n?c=T/$5ppP6`au|lP)5,(]'$w|VW貺Nx–@*O3vܛvy& d"Puo{N_d0eu ;n:tۛ qNQB̻5Ȳ̡D]>EyLژ;n=i3m 9LJ >)r@BTkb)&#"dLf=3mMh 0r"A]ܬA+Zc'hWaDZ@Tj4g%(UU 3f/@(1 v+)…I)*mv~ޛ1u2hc _1W*[! }|XfieLl! Uf,#Ym̘<)%Y nVېǭvAS:n2im2)r! 1r4|ۑT„0:_a̘ȣ_ꑷ`?TE^;5tRU^7''JoXj D  nBx~&~O%{ݳ`=vf\$HA zI2¨M..R1)LƱEDR8da.O AAv/9Yq_#d65(3cۏ3$_> /#cłG:_$ )ؘq/c/k;'ĆUO|iA_ҽ#i4PD'?rbX‡MjKmʼnI*,SY<7'_6QxdSb+PGj/fbCAO:K&o}_c?R 2U}5O0toGԿX|jUқ"$|˵!BӌduAaڣyݐFع05kT[|#{c*|ihy6<*੍oL"bt9${3 v`zG#1̳͜ s[{|` GѯKċd K dMu>sxUvϭ4L 9_( ck@ؤCJqQyC 6kb <ءNE $QL2Aψ7$ٔfX1r!-ֲ|+ AXm\[MxS?;܍ ⣧=1Y?V#wI&N6O(\Hߊ88lOU^mɜā^"x|i @tEɰ/[Ɂ53g’?Q+'(k>aD@8ePFʬl Z ] n6 ݾᠫ0$ G][^7n}- -hs,f7 PܓV1 Z*[Fw'ZOEuKߟѪXҏv:RlB $b4K0 JۇD TxBC(f.H\,aɍɌh$f5{x񁉔E3!Jc(\wm^ih)aq2fie0*.şN4>3VV`ѫuj=7pܸ?kL& 4F5'Ou64 .!*n5T1`ʦ7>KAŌi++ֿ"<f;e = c9$IeSmu"Ո =iO=z*c}˗`.W!i.H T:rsʲ71] j14xV3[Bqk%yڲ#~%Y&i| v4nAq΁@J! Gˆ}Wlex0`|+ ZE/1@Kn P1RDW0,G0~aRT>u)ݶ:+66OՍ2~d#Pk+/G%!tSyleuF3Mn\X eڠPW:br+=*}Q0HЏ_dz1fEF+oɌ5;iAEx2K UQrb xǕᅜHǝהQWwe7XX>TؖR' +[Z30k2IR? Fc6HBVc{ iIKe(:3Ƨ҆.2IU>Zk#I@~+ )3imڷ^kS/CE?q\Yxm7AO$ c`WqZID>8TpS `5jNJ>H& 4*,G8|;umxܡvl &{?6\cZGi\d|2,=A6II!4ӿB"`- zROr IRg5`/wF3㜩wޟ b͌p'~ #a唌Uxg͏n!8M7߇'s lBPƺuVLdv"ڕ" k.MD@>h@'iHhu7Sp$>m [Ԩ0w)xȱԵ@oY1cPW 0< m50,}(ƀCwҷjxް2Ko,sQEb­HODOʐ Ǝ۸A:t'v;p ҙu=Xbnve^&FWlWPp͏;"ʼn+>M-kbXgZo1 TA ) OJ#Q3S\StGf\ĶL-ksę'Be+OְyEˏ7k6a";Ñܑ;~4V=OT7ax߃ʿSdPqK͑;)s O;u&9uPGZ/0½+xGN\f}.m j@?(I0t7eS0,dNGՌH3qX˜]R&~U>t\<49>0]`(6 +»=iѯmrk&LD΁9֏ݷ+pTb+|ti^8L5>T@׭34bQOs`HF"Ab)a3ĝ>/:ZO{]nzŏ^}=5nA0'BkvucPdt=(;e3#1Rh0H?ʲbڇ֗.T-0PxSOh gSWPVRMā&pd?F6Cҷ$ͯCMd=ERڑ ZkD2.f?i &GLfGԯ9ɕλ;L4u8EʻZާnG`Nj$\ruʘ?r{@^G0IYH:67װF=ZX`f癯Dթ.C_eǥd]W|NULw~LB@}kM) ?LEN6&WX^@kNIt؁XLr6"ZFXT},R(ӘImJɞsRDJĤSlF-2O¼1*H3`y~,e=bgfFW GJGo*}FAoZ1*Q<X;6<(y9EF0}3@luIC탬#Zt+21i*$pMر|InAScr,iHY'~b\ b1N;DK!6<mq::s[OTHmMY2nlzxMjn4A09 ~TTJhc!+'CVq:<=ܝ+7Hi=*hZ:D,`[\jSAdXNM*xsN;9v0$0zn m`4 3o/Z  $N0U֠XnɊ܃vpXg` }-D:E#LE՗'j?tQ_Z#Il=4G};Af ^s=ǝT|&)/%‚;H;Ƹq('UA5f> 81ۊY{^?}eH(hOpXAШ}zS tֲbh'qǗ:SxݴVְ$.c^s\h. .1 )wc_!R"ʛ" ۝4"-K_J LXYsL.AX|U2)K!14^|+rrXsi[p-G Ȉ4MVntOe um1[wdoR8 \CQ$ =A@z/ʫ&']F݁3O*] LL A}@U#9O(<m]M3s&JD߼p8S/M&Y}|.̨0kdI\A:6mƾ1|#BMdWk)P~n5&E^XY$Ff(h"F*\ap4Ҕ&YjT" >׼Iq8`U"O3[Z,#"飍O: KLQL?L Xn\l@ ϖ@󣐿QC6Q }8h8R>H12z!% GɑB0uw 2-#eR$.!O. Ȣ4br5h*Fip Ҁ!v41aI!WjiwL>XvLtWۑRb42#&D̿TsNU؍4gi+~.w v(:&KwYb'c^ ňmUl~Q[n )M4Qax;`@#"$+ILڋf s_v&Th(.FDzk^@p< n0~hn([OuWsyQ4KTUY][dnS/Ɨa>*WCz| &ʋV4||VHQXZy&>dǥ/ktLFѠ$}i =OkcAX&m@z0c 5#͔QH0J:nb8AkR3˲M8Ihqm &mr"Bı1dIL@0[ Ⱦn6㵕@̚njll/dem=EM =+}xtiUKWRyqpq'V<+9&[dW;7J8 BYzT_U5,fo?Kۯcaэn[S`KLi4Dڂ&(/`?8-7<=(:ψL̴fM6B.GƷ b*B#9Wisr~\i,AHIZ\܃NUw$EY6@REm*G@,PX @DIeQEEHlز>uSYvxM]iQ~$NDY_# A'J TvS*~5Դ bb~T fH& hU64T1cX8q䨻SkOiZAQʛlȻNӓ _^ :װYvҦ>Єl5&C2{{q2A?DXPwVA4M2\Lk+V^! .rfM ^gOiP4mFg(uy(Q޿-)0F"u"(\[i.D0$ >FYxK78bx_@$*eO1ʃѓt2"AIBd'ҋ(ںonؘ9 o0,Zmzl^I!`qLv9 md𠭋 $=hnu?JgQqҡ 6SU'C+dlQEW]i6L6؞wd'bLXM*59r1z*Ps3;ұI]}FޛɏѬcK@&3e;Entw!fDZV[:rmĶΌy2l 1,.HG@VnKVE6qܿ l \Ȧ6mE9#YB i3{`TtփbBonh2 +EnBQQ޽hdP4ʀI":UZ`=MyLJTh<_E3łThc{f Ҡ`r8&N!]m@>Ai 4X~CV<ҶK{ oLgyԓcWN̘au֯gK Eeÿ"֡#Pi &.̧g:{Cֆ0ǡ[eQCMEDИ1V)~h(@!g"V<蠱h I9hXUD& Mw7JU;!H^C+E{ok~t1ͨڕ7ҍՒ4e-EmXL@qbC5* 6:,q$u0 ׍lS>BH֓rtTq4qs@VA5 RT*|rp5U(YaDۅƧ,Tе:)Xi:O:lΛC_dsnU.MO4uXՏ֋[EL9CZL*ibo߮xXk&?ghR޵(e |)vZO Xu1"Mxӹ@&Ŗ6aƷ~G}XM+$# Irj@=xPWed֣"u0hl]0dEbl]&֗vт kKR/Zs+y ^~5Z4^g))TtBmS8N#u4},$C/XT$PcOQP~T#@uSpMϤ=k\ܑv6QE;hc4$UcDbYt< ~Bmo{V"yԛ]4͇Bgmt S. VqKOʙ](nzSnxV/Ύ6U(xử{[-Ʊf1ӕ87lZu_vgl+s:[o*ѸT6mf5 ZʓY?god҆k^ﷹlt=ى1Ma$g4ixbLE7=&h֏O i黶kTZ<{\[AG塻NvVYlZ1IOo+57f:n;4~ݭ1"hGhmIΎ7T"9Q7޻mC{{:ţ6ŻoN{So"#wl+$i6廍[YeʎxR{rGʗڟr;=z?Mjscropperui-1.2.2/tests/example-Basic.htm000066400000000000000000000044611173375244000204220ustar00rootroot00000000000000 Basic cropper test

Basic cropper test

Some test content before the image

test image

jscropperui-1.2.2/tests/example-CSS-Absolute.htm000066400000000000000000000331251173375244000216040ustar00rootroot00000000000000 CSS - Absolute positioned (and draggable) test

CSS - Absolute positioned (and draggable) test

Some test content before the image

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque consequat risus cursus ipsum. Etiam libero. Integer vel mauris. Donec vulputate. In ut augue vitae nibh lobortis tempor. Aliquam hendrerit quam. Phasellus sed orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut sed urna. Donec nunc urna, porttitor a, feugiat pellentesque, varius id, justo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Sed sollicitudin. Integer enim. Aenean sollicitudin.

Integer lorem turpis, dapibus sed, vulputate nec, volutpat a, sem. Sed malesuada laoreet lorem. Duis mauris ipsum, fringilla nec, tristique vel, imperdiet vel, neque. Nulla vel purus. Fusce non lectus. Mauris pulvinar. Curabitur eget eros. Nunc ultrices, risus vitae adipiscing scelerisque, quam mi auctor lacus, non pellentesque augue sapien a magna. Etiam rutrum posuere tortor. Mauris rhoncus sagittis dolor. Donec sed quam. Vivamus vel diam id massa adipiscing bibendum. Suspendisse potenti. Integer arcu est, adipiscing sit amet, convallis eu, sollicitudin tincidunt, quam.

Etiam ligula lorem, imperdiet ac, luctus eget, ultrices at, odio. Vivamus malesuada, justo eu adipiscing semper, nisi dui tempus magna, quis ultrices nunc tellus id massa. Nullam lobortis auctor sapien. Quisque non nulla. Donec lobortis pellentesque nisl. Sed lacus sapien, viverra vitae, blandit ut, fermentum quis, leo. Morbi augue turpis, hendrerit non, feugiat vel, laoreet sed, est. Nunc velit. Praesent lobortis. Integer enim. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur faucibus lacus ac ante. Donec odio odio, tincidunt a, egestas nec, scelerisque nec, dui. Cras sollicitudin. Donec lacus enim, mollis sit amet, interdum quis, euismod et, nulla. Nunc sit amet dui eu magna dapibus mollis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla facilisi.

In hac habitasse platea dictumst. Nunc neque urna, dapibus ut, tristique ut, bibendum ac, felis. Donec dictum est ut dolor. Etiam accumsan, velit sit amet blandit vestibulum, turpis quam hendrerit risus, vel interdum eros orci in nunc. Curabitur tellus sapien, rutrum ac, euismod ac, malesuada nec, pede. Proin sit amet ipsum. Praesent quam nisl, adipiscing nec, tristique eget, fermentum sed, est. Praesent ac est sit amet orci facilisis placerat. Sed consequat, est sit amet consectetuer viverra, risus urna porttitor tellus, ut convallis nibh libero in lectus. Pellentesque molestie, erat non vehicula pretium, turpis nisi eleifend eros, sed scelerisque tortor odio non tellus. Nunc leo tellus, faucibus vitae, placerat a, accumsan vel, arcu. In et orci. Ut tristique euismod nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Sed nulla nunc, placerat vitae, pellentesque non, interdum non, sapien. Quisque faucibus, eros sed venenatis sagittis, leo risus rhoncus risus, in pretium sem purus a lacus. Aliquam aliquam leo et diam.

Nulla sagittis diam. Phasellus vitae enim tristique libero molestie tristique. Nam mauris sem, elementum nec, cursus in, fringilla ac, neque. Nunc metus nisi, dictum vel, vulputate quis, porttitor bibendum, tortor. Vestibulum vehicula. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla ac magna sed purus ultricies euismod. Aliquam dictum. Sed mauris. Suspendisse justo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi purus lorem, auctor non, porta ac, vehicula vel, orci. Morbi pharetra massa nec leo. Maecenas et mauris. Aliquam porttitor tincidunt nulla. Vestibulum pede.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque consequat risus cursus ipsum. Etiam libero. Integer vel mauris. Donec vulputate. In ut augue vitae nibh lobortis tempor. Aliquam hendrerit quam. Phasellus sed orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut sed urna. Donec nunc urna, porttitor a, feugiat pellentesque, varius id, justo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Sed sollicitudin. Integer enim. Aenean sollicitudin.

Integer lorem turpis, dapibus sed, vulputate nec, volutpat a, sem. Sed malesuada laoreet lorem. Duis mauris ipsum, fringilla nec, tristique vel, imperdiet vel, neque. Nulla vel purus. Fusce non lectus. Mauris pulvinar. Curabitur eget eros. Nunc ultrices, risus vitae adipiscing scelerisque, quam mi auctor lacus, non pellentesque augue sapien a magna. Etiam rutrum posuere tortor. Mauris rhoncus sagittis dolor. Donec sed quam. Vivamus vel diam id massa adipiscing bibendum. Suspendisse potenti. Integer arcu est, adipiscing sit amet, convallis eu, sollicitudin tincidunt, quam.

Etiam ligula lorem, imperdiet ac, luctus eget, ultrices at, odio. Vivamus malesuada, justo eu adipiscing semper, nisi dui tempus magna, quis ultrices nunc tellus id massa. Nullam lobortis auctor sapien. Quisque non nulla. Donec lobortis pellentesque nisl. Sed lacus sapien, viverra vitae, blandit ut, fermentum quis, leo. Morbi augue turpis, hendrerit non, feugiat vel, laoreet sed, est. Nunc velit. Praesent lobortis. Integer enim. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur faucibus lacus ac ante. Donec odio odio, tincidunt a, egestas nec, scelerisque nec, dui. Cras sollicitudin. Donec lacus enim, mollis sit amet, interdum quis, euismod et, nulla. Nunc sit amet dui eu magna dapibus mollis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla facilisi.

In hac habitasse platea dictumst. Nunc neque urna, dapibus ut, tristique ut, bibendum ac, felis. Donec dictum est ut dolor. Etiam accumsan, velit sit amet blandit vestibulum, turpis quam hendrerit risus, vel interdum eros orci in nunc. Curabitur tellus sapien, rutrum ac, euismod ac, malesuada nec, pede. Proin sit amet ipsum. Praesent quam nisl, adipiscing nec, tristique eget, fermentum sed, est. Praesent ac est sit amet orci facilisis placerat. Sed consequat, est sit amet consectetuer viverra, risus urna porttitor tellus, ut convallis nibh libero in lectus. Pellentesque molestie, erat non vehicula pretium, turpis nisi eleifend eros, sed scelerisque tortor odio non tellus. Nunc leo tellus, faucibus vitae, placerat a, accumsan vel, arcu. In et orci. Ut tristique euismod nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Sed nulla nunc, placerat vitae, pellentesque non, interdum non, sapien. Quisque faucibus, eros sed venenatis sagittis, leo risus rhoncus risus, in pretium sem purus a lacus. Aliquam aliquam leo et diam.

Nulla sagittis diam. Phasellus vitae enim tristique libero molestie tristique. Nam mauris sem, elementum nec, cursus in, fringilla ac, neque. Nunc metus nisi, dictum vel, vulputate quis, porttitor bibendum, tortor. Vestibulum vehicula. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla ac magna sed purus ultricies euismod. Aliquam dictum. Sed mauris. Suspendisse justo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi purus lorem, auctor non, porta ac, vehicula vel, orci. Morbi pharetra massa nec leo. Maecenas et mauris. Aliquam porttitor tincidunt nulla. Vestibulum pede.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque consequat risus cursus ipsum. Etiam libero. Integer vel mauris. Donec vulputate. In ut augue vitae nibh lobortis tempor. Aliquam hendrerit quam. Phasellus sed orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut sed urna. Donec nunc urna, porttitor a, feugiat pellentesque, varius id, justo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Sed sollicitudin. Integer enim. Aenean sollicitudin.

Integer lorem turpis, dapibus sed, vulputate nec, volutpat a, sem. Sed malesuada laoreet lorem. Duis mauris ipsum, fringilla nec, tristique vel, imperdiet vel, neque. Nulla vel purus. Fusce non lectus. Mauris pulvinar. Curabitur eget eros. Nunc ultrices, risus vitae adipiscing scelerisque, quam mi auctor lacus, non pellentesque augue sapien a magna. Etiam rutrum posuere tortor. Mauris rhoncus sagittis dolor. Donec sed quam. Vivamus vel diam id massa adipiscing bibendum. Suspendisse potenti. Integer arcu est, adipiscing sit amet, convallis eu, sollicitudin tincidunt, quam.

Etiam ligula lorem, imperdiet ac, luctus eget, ultrices at, odio. Vivamus malesuada, justo eu adipiscing semper, nisi dui tempus magna, quis ultrices nunc tellus id massa. Nullam lobortis auctor sapien. Quisque non nulla. Donec lobortis pellentesque nisl. Sed lacus sapien, viverra vitae, blandit ut, fermentum quis, leo. Morbi augue turpis, hendrerit non, feugiat vel, laoreet sed, est. Nunc velit. Praesent lobortis. Integer enim. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur faucibus lacus ac ante. Donec odio odio, tincidunt a, egestas nec, scelerisque nec, dui. Cras sollicitudin. Donec lacus enim, mollis sit amet, interdum quis, euismod et, nulla. Nunc sit amet dui eu magna dapibus mollis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla facilisi.

In hac habitasse platea dictumst. Nunc neque urna, dapibus ut, tristique ut, bibendum ac, felis. Donec dictum est ut dolor. Etiam accumsan, velit sit amet blandit vestibulum, turpis quam hendrerit risus, vel interdum eros orci in nunc. Curabitur tellus sapien, rutrum ac, euismod ac, malesuada nec, pede. Proin sit amet ipsum. Praesent quam nisl, adipiscing nec, tristique eget, fermentum sed, est. Praesent ac est sit amet orci facilisis placerat. Sed consequat, est sit amet consectetuer viverra, risus urna porttitor tellus, ut convallis nibh libero in lectus. Pellentesque molestie, erat non vehicula pretium, turpis nisi eleifend eros, sed scelerisque tortor odio non tellus. Nunc leo tellus, faucibus vitae, placerat a, accumsan vel, arcu. In et orci. Ut tristique euismod nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Sed nulla nunc, placerat vitae, pellentesque non, interdum non, sapien. Quisque faucibus, eros sed venenatis sagittis, leo risus rhoncus risus, in pretium sem purus a lacus. Aliquam aliquam leo et diam.

Nulla sagittis diam. Phasellus vitae enim tristique libero molestie tristique. Nam mauris sem, elementum nec, cursus in, fringilla ac, neque. Nunc metus nisi, dictum vel, vulputate quis, porttitor bibendum, tortor. Vestibulum vehicula. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla ac magna sed purus ultricies euismod. Aliquam dictum. Sed mauris. Suspendisse justo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi purus lorem, auctor non, porta ac, vehicula vel, orci. Morbi pharetra massa nec leo. Maecenas et mauris. Aliquam porttitor tincidunt nulla. Vestibulum pede.

Absolute test

test image

jscropperui-1.2.2/tests/example-CSS-Fixed.htm000066400000000000000000000326701173375244000210710ustar00rootroot00000000000000 CSS - Absolute positioned (and draggable) test

CSS - Fixed positioned (and draggable) test

Some test content before the image

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque consequat risus cursus ipsum. Etiam libero. Integer vel mauris. Donec vulputate. In ut augue vitae nibh lobortis tempor. Aliquam hendrerit quam. Phasellus sed orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut sed urna. Donec nunc urna, porttitor a, feugiat pellentesque, varius id, justo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Sed sollicitudin. Integer enim. Aenean sollicitudin.

Integer lorem turpis, dapibus sed, vulputate nec, volutpat a, sem. Sed malesuada laoreet lorem. Duis mauris ipsum, fringilla nec, tristique vel, imperdiet vel, neque. Nulla vel purus. Fusce non lectus. Mauris pulvinar. Curabitur eget eros. Nunc ultrices, risus vitae adipiscing scelerisque, quam mi auctor lacus, non pellentesque augue sapien a magna. Etiam rutrum posuere tortor. Mauris rhoncus sagittis dolor. Donec sed quam. Vivamus vel diam id massa adipiscing bibendum. Suspendisse potenti. Integer arcu est, adipiscing sit amet, convallis eu, sollicitudin tincidunt, quam.

Etiam ligula lorem, imperdiet ac, luctus eget, ultrices at, odio. Vivamus malesuada, justo eu adipiscing semper, nisi dui tempus magna, quis ultrices nunc tellus id massa. Nullam lobortis auctor sapien. Quisque non nulla. Donec lobortis pellentesque nisl. Sed lacus sapien, viverra vitae, blandit ut, fermentum quis, leo. Morbi augue turpis, hendrerit non, feugiat vel, laoreet sed, est. Nunc velit. Praesent lobortis. Integer enim. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur faucibus lacus ac ante. Donec odio odio, tincidunt a, egestas nec, scelerisque nec, dui. Cras sollicitudin. Donec lacus enim, mollis sit amet, interdum quis, euismod et, nulla. Nunc sit amet dui eu magna dapibus mollis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla facilisi.

In hac habitasse platea dictumst. Nunc neque urna, dapibus ut, tristique ut, bibendum ac, felis. Donec dictum est ut dolor. Etiam accumsan, velit sit amet blandit vestibulum, turpis quam hendrerit risus, vel interdum eros orci in nunc. Curabitur tellus sapien, rutrum ac, euismod ac, malesuada nec, pede. Proin sit amet ipsum. Praesent quam nisl, adipiscing nec, tristique eget, fermentum sed, est. Praesent ac est sit amet orci facilisis placerat. Sed consequat, est sit amet consectetuer viverra, risus urna porttitor tellus, ut convallis nibh libero in lectus. Pellentesque molestie, erat non vehicula pretium, turpis nisi eleifend eros, sed scelerisque tortor odio non tellus. Nunc leo tellus, faucibus vitae, placerat a, accumsan vel, arcu. In et orci. Ut tristique euismod nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Sed nulla nunc, placerat vitae, pellentesque non, interdum non, sapien. Quisque faucibus, eros sed venenatis sagittis, leo risus rhoncus risus, in pretium sem purus a lacus. Aliquam aliquam leo et diam.

Nulla sagittis diam. Phasellus vitae enim tristique libero molestie tristique. Nam mauris sem, elementum nec, cursus in, fringilla ac, neque. Nunc metus nisi, dictum vel, vulputate quis, porttitor bibendum, tortor. Vestibulum vehicula. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla ac magna sed purus ultricies euismod. Aliquam dictum. Sed mauris. Suspendisse justo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi purus lorem, auctor non, porta ac, vehicula vel, orci. Morbi pharetra massa nec leo. Maecenas et mauris. Aliquam porttitor tincidunt nulla. Vestibulum pede.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque consequat risus cursus ipsum. Etiam libero. Integer vel mauris. Donec vulputate. In ut augue vitae nibh lobortis tempor. Aliquam hendrerit quam. Phasellus sed orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut sed urna. Donec nunc urna, porttitor a, feugiat pellentesque, varius id, justo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Sed sollicitudin. Integer enim. Aenean sollicitudin.

Integer lorem turpis, dapibus sed, vulputate nec, volutpat a, sem. Sed malesuada laoreet lorem. Duis mauris ipsum, fringilla nec, tristique vel, imperdiet vel, neque. Nulla vel purus. Fusce non lectus. Mauris pulvinar. Curabitur eget eros. Nunc ultrices, risus vitae adipiscing scelerisque, quam mi auctor lacus, non pellentesque augue sapien a magna. Etiam rutrum posuere tortor. Mauris rhoncus sagittis dolor. Donec sed quam. Vivamus vel diam id massa adipiscing bibendum. Suspendisse potenti. Integer arcu est, adipiscing sit amet, convallis eu, sollicitudin tincidunt, quam.

Etiam ligula lorem, imperdiet ac, luctus eget, ultrices at, odio. Vivamus malesuada, justo eu adipiscing semper, nisi dui tempus magna, quis ultrices nunc tellus id massa. Nullam lobortis auctor sapien. Quisque non nulla. Donec lobortis pellentesque nisl. Sed lacus sapien, viverra vitae, blandit ut, fermentum quis, leo. Morbi augue turpis, hendrerit non, feugiat vel, laoreet sed, est. Nunc velit. Praesent lobortis. Integer enim. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur faucibus lacus ac ante. Donec odio odio, tincidunt a, egestas nec, scelerisque nec, dui. Cras sollicitudin. Donec lacus enim, mollis sit amet, interdum quis, euismod et, nulla. Nunc sit amet dui eu magna dapibus mollis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla facilisi.

In hac habitasse platea dictumst. Nunc neque urna, dapibus ut, tristique ut, bibendum ac, felis. Donec dictum est ut dolor. Etiam accumsan, velit sit amet blandit vestibulum, turpis quam hendrerit risus, vel interdum eros orci in nunc. Curabitur tellus sapien, rutrum ac, euismod ac, malesuada nec, pede. Proin sit amet ipsum. Praesent quam nisl, adipiscing nec, tristique eget, fermentum sed, est. Praesent ac est sit amet orci facilisis placerat. Sed consequat, est sit amet consectetuer viverra, risus urna porttitor tellus, ut convallis nibh libero in lectus. Pellentesque molestie, erat non vehicula pretium, turpis nisi eleifend eros, sed scelerisque tortor odio non tellus. Nunc leo tellus, faucibus vitae, placerat a, accumsan vel, arcu. In et orci. Ut tristique euismod nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Sed nulla nunc, placerat vitae, pellentesque non, interdum non, sapien. Quisque faucibus, eros sed venenatis sagittis, leo risus rhoncus risus, in pretium sem purus a lacus. Aliquam aliquam leo et diam.

Nulla sagittis diam. Phasellus vitae enim tristique libero molestie tristique. Nam mauris sem, elementum nec, cursus in, fringilla ac, neque. Nunc metus nisi, dictum vel, vulputate quis, porttitor bibendum, tortor. Vestibulum vehicula. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla ac magna sed purus ultricies euismod. Aliquam dictum. Sed mauris. Suspendisse justo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi purus lorem, auctor non, porta ac, vehicula vel, orci. Morbi pharetra massa nec leo. Maecenas et mauris. Aliquam porttitor tincidunt nulla. Vestibulum pede.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque consequat risus cursus ipsum. Etiam libero. Integer vel mauris. Donec vulputate. In ut augue vitae nibh lobortis tempor. Aliquam hendrerit quam. Phasellus sed orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut sed urna. Donec nunc urna, porttitor a, feugiat pellentesque, varius id, justo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Sed sollicitudin. Integer enim. Aenean sollicitudin.

Integer lorem turpis, dapibus sed, vulputate nec, volutpat a, sem. Sed malesuada laoreet lorem. Duis mauris ipsum, fringilla nec, tristique vel, imperdiet vel, neque. Nulla vel purus. Fusce non lectus. Mauris pulvinar. Curabitur eget eros. Nunc ultrices, risus vitae adipiscing scelerisque, quam mi auctor lacus, non pellentesque augue sapien a magna. Etiam rutrum posuere tortor. Mauris rhoncus sagittis dolor. Donec sed quam. Vivamus vel diam id massa adipiscing bibendum. Suspendisse potenti. Integer arcu est, adipiscing sit amet, convallis eu, sollicitudin tincidunt, quam.

Etiam ligula lorem, imperdiet ac, luctus eget, ultrices at, odio. Vivamus malesuada, justo eu adipiscing semper, nisi dui tempus magna, quis ultrices nunc tellus id massa. Nullam lobortis auctor sapien. Quisque non nulla. Donec lobortis pellentesque nisl. Sed lacus sapien, viverra vitae, blandit ut, fermentum quis, leo. Morbi augue turpis, hendrerit non, feugiat vel, laoreet sed, est. Nunc velit. Praesent lobortis. Integer enim. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur faucibus lacus ac ante. Donec odio odio, tincidunt a, egestas nec, scelerisque nec, dui. Cras sollicitudin. Donec lacus enim, mollis sit amet, interdum quis, euismod et, nulla. Nunc sit amet dui eu magna dapibus mollis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla facilisi.

In hac habitasse platea dictumst. Nunc neque urna, dapibus ut, tristique ut, bibendum ac, felis. Donec dictum est ut dolor. Etiam accumsan, velit sit amet blandit vestibulum, turpis quam hendrerit risus, vel interdum eros orci in nunc. Curabitur tellus sapien, rutrum ac, euismod ac, malesuada nec, pede. Proin sit amet ipsum. Praesent quam nisl, adipiscing nec, tristique eget, fermentum sed, est. Praesent ac est sit amet orci facilisis placerat. Sed consequat, est sit amet consectetuer viverra, risus urna porttitor tellus, ut convallis nibh libero in lectus. Pellentesque molestie, erat non vehicula pretium, turpis nisi eleifend eros, sed scelerisque tortor odio non tellus. Nunc leo tellus, faucibus vitae, placerat a, accumsan vel, arcu. In et orci. Ut tristique euismod nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Sed nulla nunc, placerat vitae, pellentesque non, interdum non, sapien. Quisque faucibus, eros sed venenatis sagittis, leo risus rhoncus risus, in pretium sem purus a lacus. Aliquam aliquam leo et diam.

Nulla sagittis diam. Phasellus vitae enim tristique libero molestie tristique. Nam mauris sem, elementum nec, cursus in, fringilla ac, neque. Nunc metus nisi, dictum vel, vulputate quis, porttitor bibendum, tortor. Vestibulum vehicula. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla ac magna sed purus ultricies euismod. Aliquam dictum. Sed mauris. Suspendisse justo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi purus lorem, auctor non, porta ac, vehicula vel, orci. Morbi pharetra massa nec leo. Maecenas et mauris. Aliquam porttitor tincidunt nulla. Vestibulum pede.

Fixed test

test image

jscropperui-1.2.2/tests/example-CSS-Float.htm000066400000000000000000000056371173375244000211020ustar00rootroot00000000000000 CSS - Float test

Test page with floating wrapper

Some test content before the image

Float test

test image

jscropperui-1.2.2/tests/example-CSS-Relative.htm000066400000000000000000000050261173375244000216000ustar00rootroot00000000000000 CSS - Relative test

Test page with relatively positioned wrapper

Some test content before the image

Relative test

test image

jscropperui-1.2.2/tests/example-CoordsOnLoad.htm000066400000000000000000000047541173375244000217340ustar00rootroot00000000000000 Loading & displaying co-ordinates of crop area on attachment test

Loading & displaying co-ordinates of crop area on attachment test

Some test content before the image

test image

jscropperui-1.2.2/tests/example-CoordsOnLoadWithRatio.htm000066400000000000000000000050571173375244000235640ustar00rootroot00000000000000 Loading & displaying co-ordinates (with ratio) of crop area on attachment test<

Loading & displaying co-ordinates (with ratio) of crop area on attachment test

Some test content before the image

test image

jscropperui-1.2.2/tests/example-Dimensions.htm000066400000000000000000000121241173375244000215040ustar00rootroot00000000000000 Different dimensions test

Multiple dimensions tests

Test of applying different dimension restrictions to the cropper

Set the cropper with the following dimension restrictions:

test image

jscropperui-1.2.2/tests/example-DynamicImage.htm000066400000000000000000000116261173375244000217310ustar00rootroot00000000000000 Dynamic image test

Dynamic image test

Test of dynamically changing images or removing & re-applying the cropper

test image

jscropperui-1.2.2/tests/example-FixedRatio.htm000066400000000000000000000045051173375244000214360ustar00rootroot00000000000000 Fixed ratio test

Fixed ratio test

Test of applying a fixed ratio to the cropper


test image

jscropperui-1.2.2/tests/example-Frameset-TopFrame.htm000066400000000000000000000004421173375244000226550ustar00rootroot00000000000000 Testing the basic example within a frameset jscropperui-1.2.2/tests/example-Frameset.htm000066400000000000000000000007631173375244000211500ustar00rootroot00000000000000 Testing basic example in frame To be viewed properly, this page requires frames. jscropperui-1.2.2/tests/example-MinimumDimensions.htm000066400000000000000000000046051173375244000230450ustar00rootroot00000000000000 Min dimensions test

Minimum (both axes ) dimension test

Test of applying a minimum dimension to both axes to the cropper


test image

jscropperui-1.2.2/tests/example-MinimumWidth.htm000066400000000000000000000046401173375244000220130ustar00rootroot00000000000000 Min (single axis) dimensions test

Minimum (single axis) dimension test

Test of applying a minimum dimension to only one axis (width in this case) to the cropper




test image

jscropperui-1.2.2/tests/example-Preview.htm000066400000000000000000000051211173375244000210140ustar00rootroot00000000000000

test image

jscropperui-1.2.2/tests/example-iFrame.htm000066400000000000000000000005121173375244000205750ustar00rootroot00000000000000 Testing in iFrame jscropperui-1.2.2/tests/poppy.jpg000066400000000000000000000436421173375244000171130ustar00rootroot00000000000000ExifMM*(12 Si"CanonCanon EOS 350D DIGITALHHAdobe Photoshop CS Windows2006-05-18T22:30:59Z "'0221(> T\ d  l7Ңt| P 2006-05-02T14:25:15Z2006-05-02T14:25:15Z d#(F4jDucky-!Adobed k-G       ,+++,1111111111 !!!!))())11111111117"!1 0"2A4@#35BpC$%PE6!1AQaq" 2BR#0@r3bCPScs!10AQq a"2pBRPb!1AQaq 0@Pp` }zA 0` ibpmiLbibU$`N0iM,`cm0,Gc`Lc, 8!iLm0,0ê m0q#iM 0` cX@ 4 6Қq 0H L"[L`}V 10 44% h 400#L`Ӊp00 K` 0 0i-:$i` AH ``A-:$i` L``0F0:$hb`p`%0`%04@טN'ٮU݁N` ٯ:010b`J~-ݠÙLX1M 'p=Ϝ\߿pޘc@4iǒr3 =6:Sm}.ުp9܌}͝a4]<tK|x,mh0% 0G?=Uӓjꝲ#sF~> tF}eK7nf֯\P_$` o 0"@%U*h ycy?U!#%?VS䬘<]dέ|_;"W6^Z@Lj&3$1VpQoTS5_+7x<ˆ/6֞{oo1{mWWVT3B{& Lh7edD5h9sڱ/VX|m:z2fH,WvϞZ|>pihCZ#Vswc*VN؉j`j]}fi6}Qz64Y7*{< G ~ VODǤatn] 5Ex^=[ېyvPw ON{hxU'ɱz<>G ^䇛|68byUVjZ4mʜW:Qr]U?u ~_G?1<J=GOkV|w}sбzyEk&;}reQdRs}:O"UU۸Qo[vWWn:ji_>}kVkO7_#kyO^BNmzB5"5F -[ŃFMg"dQv&I7uLp佛=M][ylU)As\uV##-T-M}uTῦSBo|U?}Woz? -5` vA 8҃-oу *Q7/jȃ~y!}~d}lu_>|<"A ,HOK1GHA,NFKxLt\}#兞㐗#1:v_}$Aļ%Fr<߄ǯ9"x2' RI ! Abzdd y_fCGL3B5ȁO3?W,'=Vxw_ G89ޣ<x 9NC"y))'(˞A!DBxǜ<1$L< wXD2Ϯ!wqH KQ)$0 $ypïi`p)JB"<Oc5P$KzGŞ 6s<t}!8W^Xpr^x%dX@Ȣ*G#1 `=9Ýz^~>pz !&ȓy>bdLiz5F0w80rKrC>HY2eHt/(K!8Wg=A y~d:`sp6T $|#񏜼#Ctr]TѴMTծz箏eyvV6G7X%d¦Cy$?m8Vعvaۿf/'71V% ;YV3142CAĞ82g?kH3ڕ=ߎe޻\26POġ᫏w6i= z3iMH1ptX< ,"'650K;eIJ0;Z=~d )*pOp$b%"8@#&VbZ[+XY݂y d"MlH1eKai\><JI{7*)@xlgGV.OSGm?gkVbx#@Hٝ%Jҵ֒M^][cn 9wD%q XYO*8+a† ƙ0g."V#(R lb]v~^1|$% fB?>{X/afx1cSe!fYjL쀜o^Կ W(DZ%U6[!ͧyR"6>W<ߦ mwɆR:/nZ:/øuZNo-PPq~Ly1`^ɵ_"DtZwe7-3 =:׳v~l>lk'?3b]jWŝ} BȢͤW]߷? m+Z/m^'f۰O^&^11y22=bհRN$ӜD#WED?|=&W}yx/Y z-cEJcql9J4~BH1V kr2)a[h]N¡^W5p?3eӣdٱ+:6Yw`}[m-c-U bm7 oɌdt찚4?8i5^G[kmNwLމɍ/J݋̯Z oI>#v~fJ.Uhх F5M? zwl!%-fkYM]띜9R~tƶ+BPןAb؃|6!BlC_e"K2&rfNyD/|~ȝxGTWһob=5.LuPh0";㞼 P%)KҺiC{ 6){IwLMXb%vۯRu| Jϸ*EN2%k;_t [ N1dKaLD#W`@_)oE(=W`r:!3J܁ՕFװgjE>v^/e6.թXn[Va?amkʫZOr%OT&Y_$d-k;հc֠#1×0};i"Uq3rRe8ga~ߟ5atQ{5jL`uʭײZ;jݠ_Ui-x;Kih/*{smkqvjP+uc ,Ӣziӎ_#_NG0̘vJL&AlR? 7٣XŐSgjNՕ,5z:`R0nͯǧe)]nIrȫ{QY1W_k;!;uN{m:dD4O>;kK[hg^icloI`_g3u_/Gg%?]tF'񙞋)'x N WqELz@ h(^!C#-X'5b()tM-q-5dlnеԣh!}/4 z|jcuu^[y!5fKR> e_kISvBh(.>WC5V$  ?:%9LgyIC9!5Ic3up g4'=H]ev0[ X+fJMޫ^r*\~3^OqH[|2_H]O1㤮0??k~-hW9Oaz+T`P=`Lm]`4QP"tX?;.Gl3S<ܳ%A}yB@,^h)P~Nۭ2V {h#f s .]e@r؜&~Mmw @4 rA0Osn38!n"P  ":ѓvE4!@(ܣ#l@Uv7/W#C}F-& ܵ4Ed0^,ggcrYOi`#v1@"Dr!r-V3=K@aCN; ){I]UGNtMCvN{-|@cQ*ߟe@x#iR"b|rkp1ޚ)W$95Y=F0|īj0{ N(Nh0@&@TB%Hia4N}!8(bD}NMIk| D"9:EB9)d8+{WNECA;pϸ1DB?g@hSRlLH++r hs~hn!x c7GjCeQ4lN'0QmgE H !g:A i9-19AOnfU78;wr0KcBW5S.uZ4d`kK(|$ou dxv|1;KKf nZ}#5-a[dkrKJkZPl8Fmeh5B=D6"4fIig̀ZNAQ5L0#uP NH5Q!5GƩ Ę/U`L :7_7Br a_FX3t:P$?ۖ`g8~c=ȑ0]3LkcߙW-i>RW F@Oe4yrZخGZP1Zӏa+;l:1mn ZnV NߩrۢL~Huao[fᰑW^xotbxmVosJ@`sD\q^=H_l?;S\ !_ɔb Ӄ&I" E\'T w??Pdw-x]ّh]&:hMI;o7l:)mbKL+8!yQ@c4F@6Xۂ1A3b6)& J xGPvhປ , d"AqOvsuπoӈN%l&jvC%i] X[#:ܠ wiQxI;sI Lۭ mpZTtB4! RX'xBS1> ־i\#|X{C1E6tz6XEdo"Q"P+@W&UapD{tn?r-ԣ=Nh^kƤzn``rNvހW7شF*  7 i n4:QQ4E:\yLӄ= x~`E .Zشh7`o` W| h$6f4Cf9\4ӣW4ˬypy' Lrq^ w⃘uf~R:3}.WniDS/bsG,rª˴^ 0  q*@Ѫ8bE19I51]u F &9 x6NcܟZigW?R()i5V߱)\V_> +ܺjP8?ICa]E|8'S ]5ovJhxw+^?~.JNt_?nkJy v~dp!_[),<{\,ud fARt%ۘx R S<S6-:)'XV_`%g()ߙCm,yYhy :} `$raw9Ie&5d3ED+j\r1Bpxr~ އ;Ek%k,pi#9e΂ 2pf|q[,qgAH Tֹ" %&+7TaC*A b<>Jl #]Z#b}Պ쪹KT~eѮ7x.N p;=n`LL +8es I >|㠹#)`ze^&(4Foī]",187W̵8=eZx$rRXk] +x[f0f0[VC,ҎԶs0Njk]d1zcq VM80βl9px$v;n%db_+hbjacPLfAB7ĦYf@%`}6U >&KQ*2"*e1( J" Q*1@]! i9\&AeU|^F&?R%9 Q<S!zL5Kxv:5*FN@(j.C`i|󸋒@GN%k rW٫1IiljÊ" Q~3HSA/T_UHE دJ[0EA-} YnɹBU#8:0=ϔ~؝pX:ƞtl/-XW8uPHʳ%CICpEU T%US:UgK`lJaU,0:2Y_ihHo8 ?(C쉧?쫕kLE_Rs$/(:Qc WoZ-!Z ZYA笠"/mI,p`?BxO6)s?#NOh%Gz,Qg$AnT%3IbNLZ1u;[q\?e?DPAߧ>R[xYW]9^"Ck h\M>04Ҋ^"nl:nR+ \ZXT;dcz"dX?YD`4/ UhidϳPF{19L&UAmY4+{0p; ]SQf po.T5kO} k.D ,Nx괹{!~T,T(qϮt& F y%EϘ>~hM%p5 Fjo jWz̷ 00luq%8%AH |JU0"jMen>Tt= 6e Sdl7:D}p9na!Z n&ʚOp'dn9D 0{g)yYA b2G%Fȳrl[e%(SSkS; fIS?FhkUy׀9@Wl.:7hA.(Ñ zew/}( E?p v:={KXSCo.f.q56(:յ|@&?8l7MҠ=ᷟ?m0i<ͽ?g?B9Y9Ӕ::KuTp>!SlBgK!t.P~"݈@6.c\ xoxXMބ;X1ї]e H"E"))M쁐^x4(6K0S#Ju 8')dc(jjg)NWt: pTP.6|pe]]!v(:ygîXTTSYJ(X +1C HbW4ba@ ǭLJsE6cmU-@42vbmPykG0T`b͠#`nXxr`t8ieftcy.a0BaUic# (:}[Ig05 H]hC&M*fK<;,FCdJ zklB@x4`K< wQB)$rb;1aīDZlcOu(V47uكrXEk$[KEt\Y8TCpe/!rH Ԣ[p?W F oUNhhR}s3sUCWE5z?)"CILVqiQ6uN3b7*?:,F\Qn}\!Տ" Z= QAL!qs DD0(B(s Brj+k!Z$lOkSИ4*@\[/ )\*wAI}[0YhsC^n`%`PP$@4é)ˤVg@Bv몼M97{#{/l]b7DߑzVT*MAYK`] S٘TMK8_hi#7v4cmqLKbj|Qvna3PXne-.F꭮UL*(W^4+w`RC!߫R‘m"K4pdȦ[ض*wGKGPh^O NU diGJuӆꟳ,w!r<кx`6 H"rűQLEa@P5`@ C Xf]t"^ƀk53!~vBpum8'ѓgy$X{H9 ^J.KgYn`kމ~MA{@ΥO7 5Zhwb;rJmk\V\/lLT1P֣Z:pYAk&+P |}$k pe^%.-Uڌ+XGjM$t=Ȭ+ hKarQq˰U0;לK (J{nzIu#U[=/]s`(p# QUUUq-yb1ȨeJ{3KP=Cl2 ĠfB嗚3u=∮6Nfhi*4tѢdfmA G 2〳ѵd+,~`Ѝ-E&׳6QiZPt!ӽ}|rN9Ȩs`~ҰyVlvkLRKSX7t;HlVPDMf,{ʋrϐByg{1SFA]J6ţT q[IJqֽ'i^1#Zro N5f!WWo6v6ˈ-[ %RS;q+[!0a'+@ƦP3n?00[0xg" wP~&vo3'}߄t;OwgOz?cS_}ww>Oi}v/SG||M> _|^?~jscropperui-1.2.2/tests/staticHTMLStructure.htm000066400000000000000000000130251173375244000216410ustar00rootroot00000000000000

test image

Preview:

test image