{“version”:3,“sources”:[“../../src/openseadragon.js”,“../../src/fullscreen.js”,“../../src/eventsource.js”,“../../src/mousetracker.js”,“../../src/control.js”,“../../src/controldock.js”,“../../src/placement.js”,“../../src/viewer.js”,“../../src/navigator.js”,“../../src/strings.js”,“../../src/point.js”,“../../src/tilesource.js”,“../../src/dzitilesource.js”,“../../src/iiiftilesource.js”,“../../src/osmtilesource.js”,“../../src/tmstilesource.js”,“../../src/zoomifytilesource.js”,“../../src/legacytilesource.js”,“../../src/imagetilesource.js”,“../../src/tilesourcecollection.js”,“../../src/button.js”,“../../src/buttongroup.js”,“../../src/rectangle.js”,“../../src/referencestrip.js”,“../../src/displayrectangle.js”,“../../src/spring.js”,“../../src/imageloader.js”,“../../src/tile.js”,“../../src/overlay.js”,“../../src/drawer.js”,“../../src/viewport.js”,“../../src/tiledimage.js”,“../../src/tilecache.js”,“../../src/world.js”],“names”:[“OpenSeadragon”,“options”,“Viewer”,“$”,“version”,“versionStr”,“major”,“parseInt”,“minor”,“revision”,“class2type”,“[object Boolean]”,“[object Number]”,“[object String]”,“[object Function]”,“[object Array]”,“[object Date]”,“[object RegExp]”,“[object Object]”,“toString”,“Object”,“prototype”,“hasOwn”,“hasOwnProperty”,“isFunction”,“obj”,“type”,“isArray”,“Array”,“isWindow”,“undefined”,“String”,“call”,“isPlainObject”,“nodeType”,“constructor”,“lastKey”,“key”,“isEmptyObject”,“name”,“freezeObject”,“freeze”,“supportsCanvas”,“canvasElement”,“document”,“createElement”,“getContext”,“isCanvasTainted”,“canvas”,“isTainted”,“getImageData”,“e”,“pixelDensityRatio”,“context”,“devicePixelRatio”,“window”,“backingStoreRatio”,“webkitBackingStorePixelRatio”,“mozBackingStorePixelRatio”,“msBackingStorePixelRatio”,“oBackingStorePixelRatio”,“backingStorePixelRatio”,“Math”,“max”,“extend”,“src”,“copy”,“copyIsArray”,“clone”,“target”,“arguments”,“length”,“deep”,“i”,“this”,“isIOSDevice”,“navigator”,“userAgent”,“indexOf”,“DEFAULT_SETTINGS”,“xmlPath”,“tileSources”,“tileHost”,“initialPage”,“crossOriginPolicy”,“ajaxWithCredentials”,“loadTilesWithAjax”,“ajaxHeaders”,“panHorizontal”,“panVertical”,“constrainDuringPan”,“wrapHorizontal”,“wrapVertical”,“visibilityRatio”,“minPixelRatio”,“defaultZoomLevel”,“minZoomLevel”,“maxZoomLevel”,“homeFillsViewer”,“clickTimeThreshold”,“clickDistThreshold”,“dblClickTimeThreshold”,“dblClickDistThreshold”,“springStiffness”,“animationTime”,“gestureSettingsMouse”,“scrollToZoom”,“clickToZoom”,“dblClickToZoom”,“pinchToZoom”,“zoomToRefPoint”,“flickEnabled”,“flickMinSpeed”,“flickMomentum”,“pinchRotate”,“gestureSettingsTouch”,“gestureSettingsPen”,“gestureSettingsUnknown”,“zoomPerClick”,“zoomPerScroll”,“zoomPerSecond”,“blendTime”,“alwaysBlend”,“autoHideControls”,“immediateRender”,“minZoomImageRatio”,“maxZoomPixelRatio”,“smoothTileEdgesMinZoom”,“iOSDevice”,“pixelsPerWheelLine”,“pixelsPerArrowPress”,“autoResize”,“preserveImageSizeOnResize”,“minScrollDeltaTime”,“showSequenceControl”,“sequenceControlAnchor”,“preserveViewport”,“preserveOverlays”,“navPrevNextWrap”,“showNavigationControl”,“navigationControlAnchor”,“showZoomControl”,“showHomeControl”,“showFullPageControl”,“showRotationControl”,“showFlipControl”,“controlsFadeDelay”,“controlsFadeLength”,“mouseNavEnabled”,“showNavigator”,“navigatorId”,“navigatorPosition”,“navigatorSizeRatio”,“navigatorMaintainSizeRatio”,“navigatorTop”,“navigatorLeft”,“navigatorHeight”,“navigatorWidth”,“navigatorAutoResize”,“navigatorAutoFade”,“navigatorRotate”,“navigatorBackground”,“navigatorOpacity”,“navigatorBorderColor”,“navigatorDisplayRegionColor”,“degrees”,“flipped”,“opacity”,“preload”,“compositeOperation”,“placeholderFillStyle”,“showReferenceStrip”,“referenceStripScroll”,“referenceStripElement”,“referenceStripHeight”,“referenceStripWidth”,“referenceStripPosition”,“referenceStripSizeRatio”,“collectionRows”,“collectionColumns”,“collectionLayout”,“collectionMode”,“collectionTileSize”,“collectionTileMargin”,“imageLoaderLimit”,“maxImageCacheCount”,“timeout”,“useCanvas”,“prefixUrl”,“navImages”,“zoomIn”,“REST”,“GROUP”,“HOVER”,“DOWN”,“zoomOut”,“home”,“fullpage”,“rotateleft”,“rotateright”,“flip”,“previous”,“next”,“debugMode”,“debugGridColor”,“SIGNAL”,“delegate”,“object”,“method”,“args”,“apply”,“BROWSERS”,“UNKNOWN”,“IE”,“FIREFOX”,“SAFARI”,“CHROME”,“OPERA”,“getElement”,“element”,“getElementById”,“getElementPosition”,“isFixed”,“offsetParent”,“result”,“Point”,“getOffsetParent”,“getElementStyle”,“position”,“x”,“offsetLeft”,“y”,“offsetTop”,“plus”,“getPageScroll”,“getElementOffset”,“docElement”,“win”,“doc”,“ownerDocument”,“boundingRect”,“top”,“left”,“documentElement”,“getBoundingClientRect”,“defaultView”,“parentWindow”,“pageXOffset”,“scrollLeft”,“clientLeft”,“pageYOffset”,“scrollTop”,“clientTop”,“getElementSize”,“clientWidth”,“clientHeight”,“currentStyle”,“getComputedStyle”,“getCssPropertyWithVendorPrefix”,“property”,“memo”,“style”,“prefixes”,“suffix”,“capitalizeFirstLetter”,“prop”,“string”,“charAt”,“toUpperCase”,“slice”,“positiveModulo”,“number”,“modulo”,“pointInElement”,“point”,“offset”,“size”,“getEvent”,“event”,“getMousePosition”,“pageX”,“pageY”,“Error”,“clientX”,“body”,“clientY”,“setPageScroll”,“scroll”,“scrollTo”,“originalScroll”,“currentScroll”,“getWindowSize”,“innerWidth”,“innerHeight”,“makeCenteredNode”,“wrappers”,“makeNeutralElement”,“display”,“height”,“width”,“verticalAlign”,“textAlign”,“appendChild”,“tagName”,“background”,“border”,“margin”,“padding”,“now”,“Date”,“getTime”,“makeTransparentImage”,“img”,“Browser”,“vendor”,“onload”,“filter”,“setElementOpacity”,“usesAlpha”,“ieFilter”,“alpha”,“round”,“setElementTouchActionNone”,“touchAction”,“msTouchAction”,“addClass”,“className”,“array”,“searchElement”,“fromIndex”,“pivot”,“TypeError”,“abs”,“removeClass”,“oldClasses”,“newClasses”,“split”,“push”,“join”,“addEvent”,“addEventListener”,“eventName”,“handler”,“useCapture”,“attachEvent”,“removeEvent”,“removeEventListener”,“detachEvent”,“cancelEvent”,“preventDefault”,“cancel”,“returnValue”,“stopEvent”,“stopPropagation”,“cancelBubble”,“createCallback”,“initialArgs”,“concat”,“getUrlParameter”,“value”,“URLPARAMS”,“getUrlProtocol”,“url”,“match”,“location”,“protocol”,“toLowerCase”,“createAjaxRequest”,“local”,“supportActiveX”,“ActiveXObject”,“XMLHttpRequest”,“makeAjaxRequest”,“onSuccess”,“onError”,“withCredentials”,“headers”,“responseType”,“success”,“error”,“request”,“onreadystatechange”,“readyState”,“status”,“console”,“log”,“open”,“headerName”,“setRequestHeader”,“send”,“msg”,“message”,“XDomainRequest”,“xdr”,“responseText”,“statusText”,“onerror”,“e2”,“jsonp”,“script”,“head”,“getElementsByTagName”,“jsonpCallback”,“callbackName”,“replace”,“callbackParam”,“param”,“callback”,“test”,“response”,“async”,“scriptCharset”,“charset”,“_”,“isAbort”,“parentNode”,“removeChild”,“insertBefore”,“firstChild”,“createFromDZI”,“parseXml”,“DOMParser”,“parseFromString”,“xmlDoc”,“loadXML”,“parseJSON”,“JSON”,“parse”,“eval”,“imageFormatSupported”,“extension”,“FILEFORMATS”,“bmp”,“jpeg”,“jpg”,“png”,“tif”,“wdp”,“ver”,“appVersion”,“ua”,“appName”,“parseFloat”,“substring”,“lastIndexOf”,“RegExp”,“exec”,“$1”,“part”,“sep”,“parts”,“search”,“decodeURIComponent”,“nullfunction”,“debug”,“info”,“warn”,“assert”,“w”,“requestAnimationFrame”,“mozRequestAnimationFrame”,“webkitRequestAnimationFrame”,“msRequestAnimationFrame”,“cancelAnimationFrame”,“mozCancelAnimationFrame”,“webkitCancelAnimationFrame”,“msCancelAnimationFrame”,“iIntervalId”,“aAnimQueue”,“processing”,“iRequestId”,“setInterval”,“time”,“temp”,“shift”,“clearInterval”,“requestId”,“j”,“splice”,“root”,“factory”,“define”,“amd”,“module”,“exports”,“fullScreenApi”,“supportsFullScreen”,“isFullScreen”,“getFullScreenElement”,“requestFullScreen”,“exitFullScreen”,“cancelFullScreen”,“fullScreenEventName”,“fullScreenErrorEventName”,“exitFullscreen”,“fullscreenElement”,“requestFullscreen”,“msExitFullscreen”,“msFullscreenElement”,“msRequestFullscreen”,“webkitExitFullscreen”,“webkitFullscreenElement”,“webkitRequestFullscreen”,“webkitCancelFullScreen”,“webkitCurrentFullScreenElement”,“webkitRequestFullScreen”,“mozCancelFullScreen”,“mozFullScreenElement”,“mozRequestFullScreen”,“EventSource”,“events”,“addOnceHandler”,“userData”,“times”,“self”,“count”,“onceHandler”,“removeHandler”,“addHandler”,“handlers”,“removeAllHandlers”,“eventType”,“getHandler”,“source”,“eventSource”,“raiseEvent”,“eventArgs”,“MOUSETRACKERS”,“THIS”,“MouseTracker”,“hash”,“random”,“stopDelay”,“enterHandler”,“exitHandler”,“pressHandler”,“nonPrimaryPressHandler”,“releaseHandler”,“nonPrimaryReleaseHandler”,“moveHandler”,“scrollHandler”,“clickHandler”,“dblClickHandler”,“dragHandler”,“dragEndHandler”,“pinchHandler”,“stopHandler”,“keyDownHandler”,“keyUpHandler”,“keyHandler”,“focusHandler”,“blurHandler”,“_this”,“click”,“dblclick”,“keydown”,“tracker”,“keyCode”,“charCode”,“ctrl”,“ctrlKey”,“shiftKey”,“alt”,“altKey”,“meta”,“metaKey”,“originalEvent”,“preventDefaultAction”,“onKeyDown”,“keyup”,“onKeyUp”,“keypress”,“onKeyPress”,“focus”,“onFocus”,“blur”,“onBlur”,“wheel”,“handleWheelEvent”,“mousewheel”,“onMouseWheel”,“DOMMouseScroll”,“MozMousePixelScroll”,“mouseenter”,“handleMouseEnter”,“onMouseEnter”,“mouseleave”,“handleMouseExit”,“onMouseLeave”,“mouseover”,“currentTarget”,“relatedTarget”,“isParentChild”,“onMouseOver”,“mouseout”,“onMouseOut”,“mousedown”,“gPoint”,“id”,“mousePointerId”,“isPrimary”,“currentPos”,“getMouseAbsolute”,“currentTime”,“updatePointersDown”,“getStandardizedButton”,“button”,“capturePointer”,“onMouseDown”,“mouseup”,“handleMouseUp”,“mouseupcaptured”,“onMouseUpCaptured”,“mousemove”,“handleMouseMove”,“mousemovecaptured”,“onMouseMoveCaptured”,“touchstart”,“parentGPoints”,“touchCount”,“changedTouches”,“gPoints”,“pointsList”,“getActivePointersListByType”,“getLength”,“touches”,“abortContacts”,“identifier”,“updatePointersEnter”,“isTracking”,“onTouchStart”,“touchend”,“handleTouchEnd”,“touchendcaptured”,“onTouchEndCaptured”,“touchmove”,“handleTouchMove”,“touchmovecaptured”,“onTouchMoveCaptured”,“touchcancel”,“onTouchCancel”,“gesturestart”,“onGestureStart”,“gesturechange”,“onGestureChange”,“pointerover”,“onPointerOver”,“MSPointerOver”,“pointerout”,“onPointerOut”,“MSPointerOut”,“pointerdown”,“onPointerDown”,“MSPointerDown”,“pointerup”,“onPointerUp”,“MSPointerUp”,“pointermove”,“onPointerMove”,“MSPointerMove”,“pointercancel”,“onPointerCancel”,“MSPointerCancel”,“pointerupcaptured”,“getPointerType”,“getById”,“pointerId”,“handlePointerUp”,“onPointerUpCaptured”,“pointermovecaptured”,“handlePointerMove”,“onPointerMoveCaptured”,“tracking”,“activePointersLists”,“lastClickPos”,“dblClickTimeOut”,“pinchGPoints”,“lastPinchDist”,“currentPinchDist”,“lastPinchCenter”,“currentPinchCenter”,“startDisabled”,“setTracking”,“destroy”,“stopTracking”,“track”,“subscribeEvents”,“clearTrackedPointers”,“startTracking”,“getActivePointersListsExceptType”,“listArray”,“list”,“len”,“GesturePointList”,“getActivePointerCount”,“resetAllMouseTrackers”,“gesturePointVelocityTracker”,“trackerPoints”,“intervalId”,“lastTime”,“_generateGuid”,“_doTracking”,“trackPoint”,“elapsedTime”,“distance”,“speed”,“direction”,“atan2”,“lastPos”,“distanceTo”,“addPoint”,“guid”,“removePoint”,“captureElement”,“wheelEventName”,“onmousewheel”,“supportsMouseCapture”,“divElement”,“setCapture”,“releaseCapture”,“PointerEvent”,“pointerEnabled”,“havePointerEvents”,“unprefixedPointerEvents”,“maxTouchPoints”,“haveMouseEnter”,“MSPointerEvent”,“msPointerEnabled”,“msMaxTouchPoints”,“_gPoints”,“buttons”,“contacts”,“clicks”,“captureCount”,“asArray”,“add”,“gp”,“removeById”,“getByIndex”,“index”,“getPrimary”,“addContact”,“removeContact”,“pointerListCount”,“pop”,“getCaptureEventParams”,“pointerType”,“upName”,“upHandler”,“moveName”,“pointerCount”,“eventParams”,“isInIframe”,“canAccessEvents”,“releasePointer”,“pointerTypeStr”,“getMouseRelative”,“getPointRelativeToAbsolute”,“minus”,“getCenterPoint”,“point1”,“point2”,“simulatedEvent”,“srcElement”,“deltaMode”,“deltaX”,“deltaZ”,“deltaY”,“wheelDelta”,“detail”,“nDelta”,“isTouchEvent”,“parent”,“child”,“updatePointersExit”,“updatePointersUp”,“updatePointersMove”,“gPointCount”,“abortGPoints”,“updatePointersCancel”,“startTrackingPointer”,“contactPos”,“contactTime”,“stopTrackingPointer”,“listLength”,“primaryPoint”,“curGPoint”,“updateGPoint”,“insideElement”,“captured”,“insideElementPressed”,“pointers”,“buttonDownAny”,“buttonChanged”,“otherPointsLists”,“releasePoint”,“releaseTime”,“quick”,“wasCaptured”,“insideElementReleased”,“equals”,“setTimeout”,“clearTimeout”,“gPointArray”,“delta”,“stopTimeOut”,“originalMoveEvent”,“gesturePoints”,“lastCenter”,“center”,“lastDistance”,“ControlAnchor”,“NONE”,“TOP_LEFT”,“TOP_RIGHT”,“BOTTOM_RIGHT”,“BOTTOM_LEFT”,“ABSOLUTE”,“Control”,“container”,“anchor”,“attachToViewer”,“autoFade”,“wrapper”,“isVisible”,“setVisible”,“visible”,“setOpacity”,“ControlDock”,“layout”,“layouts”,“floor”,“controls”,“onsubmit”,“right”,“bottom”,“topleft”,“topright”,“bottomright”,“bottomleft”,“addControl”,“controlOptions”,“div”,“getControlIndex”,“paddingRight”,“paddingTop”,“paddingBottom”,“paddingLeft”,“removeControl”,“clearControls”,“areControlsEnabled”,“setControlsEnabled”,“enabled”,“dock”,“Placement”,“CENTER”,“TOP”,“RIGHT”,“BOTTOM”,“LEFT”,“properties”,“0”,“isLeft”,“isHorizontallyCentered”,“isRight”,“isTop”,“isVerticallyCentered”,“isBottom”,“1”,“2”,“3”,“4”,“5”,“6”,“7”,“8”,“nextHash”,“overlays”,“config”,“overlaysContainer”,“previousBody”,“customControls”,“drawer”,“world”,“viewport”,“collectionViewport”,“collectionDrawer”,“profiler”,“fsBoundsDelta”,“prevContainerSize”,“animating”,“forceRedraw”,“mouseInside”,“group”,“zooming”,“zoomFactor”,“lastZoomTime”,“fullPage”,“onfullscreenchange”,“_sequenceIndex”,“_firstOpen”,“_updateRequestId”,“_loadQueue”,“currentOverlays”,“_lastScrollTime”,“getString”,“_showMessage”,“overflow”,“tabIndex”,“bodyWidth”,“bodyHeight”,“bodyOverflow”,“docOverflow”,“innerTracker”,“onCanvasKeyDown”,“onCanvasKeyPress”,“onCanvasClick”,“onCanvasDblClick”,“onCanvasDrag”,“onCanvasDragEnd”,“onCanvasEnter”,“onCanvasExit”,“onCanvasPress”,“onCanvasRelease”,“onCanvasNonPrimaryPress”,“onCanvasNonPrimaryRelease”,“onCanvasScroll”,“onCanvasPinch”,“outerTracker”,“onContainerEnter”,“onContainerExit”,“toolbar”,“bindStandardControls”,“_getSafeElemSize”,“World”,“viewer”,“getItemAt”,“scheduleUpdate”,“updateMulti”,“getItemCount”,“_setContentBounds”,“getHomeBounds”,“getContentFactor”,“Viewport”,“containerSize”,“margins”,“viewportMargins”,“imageLoader”,“ImageLoader”,“jobLimit”,“tileCache”,“TileCache”,“Drawer”,“canRotate”,“rotateLeft”,“rotateRight”,“Navigator”,“sizeRatio”,“maintainSizeRatio”,“borderColor”,“displayRegionColor”,“sequenceMode”,“bindSequenceControls”,“beginControlsAutoHide”,“isOpen”,“openDzi”,“dzi”,“openTileSource”,“tileSource”,“close”,“referenceStrip”,“isNaN”,“min”,“addReferenceStrip”,“_updateSequenceButtons”,“_opening”,“expected”,“successes”,“failures”,“failEvent”,“checkCompletion”,“goHome”,“update”,“getOverlayObject”,“_drawOverlays”,“doOne”,“collectionImmediately”,“originalSuccess”,“addOverlay”,“originalError”,“addTiledImage”,“clearOverlays”,“innerHTML”,“removeAll”,“clear”,“isMouseNavEnabled”,“setMouseNavEnabled”,“isVisibile”,“abortControlsAutoHide”,“setDebugMode”,“isFullPage”,“setFullPage”,“nodes”,“bodyStyle”,“docStyle”,“fullPageEventArgs”,“elementSize”,“pageScroll”,“elementMargin”,“elementPadding”,“bodyMargin”,“docMargin”,“bodyPadding”,“docPadding”,“docWidth”,“docHeight”,“prevElementParent”,“prevNextSibling”,“nextSibling”,“prevElementWidth”,“prevElementHeight”,“childNodes”,“restoreScrollCounter”,“restoreScroll”,“setFullScreen”,“fullScreen”,“fullScreeEventArgs”,“fullPageStyleWidth”,“fullPageStyleHeight”,“onFullScreenChange”,“visibility”,“replaceItem”,“_hideMessage”,“myQueueItem”,“raiseAddItemFailed”,“refreshWorld”,“theItem”,“arrange”,“immediately”,“rows”,“columns”,“tileSize”,“tileMargin”,“setAutoRefigureSizes”,“imgOptions”,“successCallback”,“failCallback”,“tileSourceJ”,“waitUntilReady”,“originalTileSource”,“ready”,“TileSource”,“getTileUrl”,“customTileSource”,“$TileSource”,“determineType”,“configure”,“getTileSourceImplementation”,“processReadyItems”,“queueItem”,“tiledImage”,“optionsClone”,“newIndex”,“getIndexOfItem”,“removeItem”,“TiledImage”,“fitBounds”,“fitBoundsPlacement”,“clip”,“addItem”,“originalTiledImage”,“item”,“addSimpleImage”,“opts”,“addLayer”,“getLayerAtLevel”,“level”,“getLevelOfLayer”,“getLayersCount”,“setLayerLevel”,“setItemIndex”,“removeLayer”,“onFocusHandler”,“onBlurHandler”,“onNextHandler”,“onNext”,“onPreviousHandler”,“onPrevious”,“useGroup”,“previousButton”,“nextButton”,“Button”,“tooltip”,“srcRest”,“resolveUrl”,“srcGroup”,“srcHover”,“srcDown”,“onRelease”,“disable”,“paging”,“ButtonGroup”,“pagingControl”,“beginZoomingInHandler”,“beginZoomingIn”,“endZoomingHandler”,“endZooming”,“doSingleZoomInHandler”,“doSingleZoomIn”,“beginZoomingOutHandler”,“beginZoomingOut”,“doSingleZoomOutHandler”,“doSingleZoomOut”,“onHomeHandler”,“onHome”,“onFullScreenHandler”,“onFullScreen”,“onRotateLeftHandler”,“onRotateLeft”,“onRotateRightHandler”,“onRotateRight”,“onFlipHandler”,“onFlip”,“zoomInButton”,“zoomOutButton”,“homeButton”,“fullPageButton”,“rotateLeftButton”,“rotateRightButton”,“flipButton”,“onPress”,“onClick”,“onEnter”,“onExit”,“navControl”,“lightUp”,“currentPage”,“goToPage”,“page”,“setFocus”,“placement”,“onDraw”,“getOverlayIndex”,“overlay”,“drawHTML”,“updateOverlay”,“removeOverlay”,“getOverlayById”,“enable”,“createTextNode”,“messageDiv”,“gestureSettingsByDeviceType”,“_cancelPendingImages”,“removeReferenceStrip”,“ReferenceStrip”,“oElement”,“Overlay”,“href”,“px”,“rect”,“imageToViewportRectangle”,“Rect”,“py”,“checkResize”,“rotationMode”,“updateFunc”,“scheduleControlsFade”,“deltaTime”,“controlsShouldFade”,“controlsFadeBeginTime”,“updateControlsFade”,“canvasKeyDownEventArgs”,“preventVerticalPan”,“preventHorizontalPan”,“zoomBy”,“panBy”,“deltaPointsFromPixels”,“applyConstraints”,“canvasKeyPressEventArgs”,“setRotation”,“toggleFlip”,“gestureSettings”,“activeElement”,“getContainerSize”,“canvasClickEventArgs”,“pointFromPixel”,“canvasDblClickEventArgs”,“canvasDragEventArgs”,“negate”,“centerSpringX”,“centerSpringY”,“bounds”,“getBounds”,“constrainedBounds”,“getConstrainedBounds”,“amplitudeX”,“cos”,“amplitudeY”,“sin”,“pixelFromPoint”,“getCenter”,“panTo”,“centerPt”,“panByPt”,“angle1”,“angle2”,“getRotation”,“PI”,“factor”,“thisScrollTime”,“pow”,“resizeRatio”,“zoom”,“getZoom”,“resize”,“zoomTo”,“oldBounds”,“fitBoundsWithConstraints”,“viewportChange”,“animated”,“needsDraw”,“draw”,“drawWorld”,“updateOnce”,“prefix”,“scheduleZoom”,“doZoom”,“adjustedFactor”,“emulateEnter”,“emulateExit”,“currRotation”,“viewerSize”,“navigatorSize”,“borderWidth”,“fudge”,“totalBorderWidths”,“displayRegion”,“fontSize”,“cssFloat”,“styleFloat”,“zIndex”,“cursor”,“displayRegionContainer”,“_resizeWithViewer”,“oldViewerSize”,“elementArea”,“oldContainerSize”,“rotate”,“_setTransformRotate”,“previousIndex”,“theirItem”,“myItem”,“_getMatchingItem”,“updateSize”,“setFlip”,“state”,“setDisplayTransform”,“getFlip”,“rule”,“setElementTransform”,“newWidth”,“newHeight”,“sqrt”,“getBoundsNoRotate”,“pixelFromPointNoRotate”,“getTopLeft”,“getBottomRight”,“original”,“_originalForNavigator”,“_matchBounds”,“matchBounds”,“_matchOpacity”,“_matchCompositeOperation”,“setPosition”,“setWidth”,“setClip”,“getClip”,“setCompositeOperation”,“webkitTransform”,“mozTransform”,“msTransform”,“oTransform”,“transform”,“I18N”,“Errors”,“Dzc”,“Dzi”,“Xml”,“ImageFormat”,“Security”,“Status”,“OpenFailed”,“Tooltips”,“FullPage”,“Home”,“ZoomIn”,“ZoomOut”,“NextPage”,“PreviousPage”,“RotateLeft”,“RotateRight”,“Flip”,“props”,“capture”,“setString”,“divide”,“squaredDistanceTo”,“func”,“angle”,“tileOverlap”,“minLevel”,“maxLevel”,“aspectRatio”,“dimensions”,“_tileWidth”,“_tileHeight”,“getImageInfo”,“tileWidth”,“tileHeight”,“ceil”,“getTileSize”,“getTileWidth”,“getTileHeight”,“getLevelScale”,“levelScaleCache”,“_level”,“getNumTiles”,“scale”,“getPixelRatio”,“imageSizeScaled”,“rx”,“ry”,“getClosestLevel”,“tiles”,“getTileAtPoint”,“validPoint”,“widthScaled”,“pixelX”,“pixelY”,“getTileBounds”,“isSource”,“dimensionsScaled”,“sx”,“sy”,“readySource”,“urlParts”,“filename”,“lastDot”,“data”,“xhr”,“responseXML”,“processResponse”,“exc”,“formattedExc”,“supports”,“getTileAjaxHeaders”,“tileExists”,“numTiles”,“DziTileSource”,“tilesUrl”,“fileFormat”,“displayRects”,“_levelRects”,“ns”,“Image”,“xmlns”,“localName”,“namespaceURI”,“configureFromObject”,“dispRectNodes”,“dispRectNode”,“rectNode”,“sizeNode”,“rootName”,“configuration”,“getElementsByTagNameNS”,“Url”,“getAttribute”,“Format”,“DisplayRect”,“Overlap”,“TileSize”,“Size”,“Height”,“Width”,“X”,“Y”,“MinLevel”,“MaxLevel”,“messageNode”,“nodeValue”,“configureFromXML”,“queryParams”,“xMin”,“yMin”,“xMax”,“yMax”,“rects”,“rectData”,“imageData”,“sizeData”,“dispRectData”,“IIIFTileSource”,“tileSizePerScaleFactor”,“tile_width”,“tile_height”,“scale_factors”,“scaleFactors”,“t”,“sf”,“scaleFactor”,“profile”,“shortDim”,“tileOptions”,“smallerTiles”,“c”,“sizes”,“emulateLegacyImagePyramid”,“levels”,“sort”,“a”,“b”,“constructLevels”,“maxScaleFactor”,“LOG2E”,“Number”,“parseXML10”,“node”,“trim”,“nodeName”,“configureFromXml10”,“levelScale”,“NaN”,“iiifTileSizeWidth”,“iiifTileSizeHeight”,“iiifRegion”,“iiifTileX”,“iiifTileY”,“iiifTileW”,“iiifTileH”,“iiifSize”,“iiifQuality”,“levelWidth”,“levelHeight”,“OsmTileSource”,“TmsTileSource”,“bufferedWidth”,“bufferedHeight”,“yTiles”,“ZoomifyTileSource”,“currentImageSize”,“imageSizes”,“gridSize”,“_getGridSize”,“reverse”,“_calculateAbsoluteTileNumber”,“num”,“z”,“LegacyTileSource”,“files”,“file”,“filtered”,“filterFiles”,“dataUrl”,“conf”,“ImageTileSource”,“buildPyramid”,“image”,“_image”,“crossOrigin”,“useCredentials”,“naturalWidth”,“naturalHeight”,“_buildLevels”,“getContext2D”,“context2D”,“currentWidth”,“currentHeight”,“bigCanvas”,“bigContext”,“drawImage”,“smallCanvas”,“smallContext”,“TileSourceCollection”,“ButtonState”,“fadeDelay”,“fadeLength”,“imgRest”,“imgGroup”,“imgHover”,“imgDown”,“currentState”,“fadeBeginTime”,“shouldFade”,“title”,“inTo”,“outTo”,“notifyGroupEnter”,“notifyGroupExit”,“disabled”,“scheduleFade”,“updateFade”,“newState”,“stopFading”,“beginFading”,“labelText”,“label”,“newTopLeft”,“getTopRight”,“getBottomLeft”,“fromSummits”,“topLeft”,“topRight”,“bottomLeft”,“diff”,“radians”,“atan”,“getAspectRatio”,“getSize”,“other”,“translate”,“union”,“thisBoundingBox”,“getBoundingBox”,“otherBoundingBox”,“intersection”,“EPSILON”,“intersectionPoints”,“thisTopLeft”,“containsPoint”,“thisTopRight”,“thisBottomLeft”,“thisBottomRight”,“rectTopLeft”,“rectTopRight”,“rectBottomLeft”,“rectBottomRight”,“thisSegments”,“_getSegments”,“rectSegments”,“thisSegment”,“rectSegment”,“intersect”,“getIntersection”,“d”,“abVector”,“cdVector”,“denom”,“s”,“minX”,“maxX”,“minY”,“maxY”,“k”,“bottomRight”,“getIntegerBoundingBox”,“boundingBox”,“epsilon”,“topDiff”,“leftDiff”,“marginTop”,“marginRight”,“marginBottom”,“marginLeft”,“onStripDrag”,“onStripScroll”,“onStripEnter”,“onStripExit”,“panelWidth”,“panelHeight”,“panels”,“miniViewers”,“float”,“dragging”,“activePanel”,“loadPanels”,“scrollWidth”,“scrollHeight”,“currentSelected”,“strip”,“panelSize”,“activePanelsStart”,“activePanelsEnd”,“miniViewer”,“miniTileSource”,“referenceStripThumbnailUrl”,“Spring”,“initial”,“exponential”,“_exponential”,“current”,“start”,“_logValue”,“resetTo”,“springTo”,“shiftBy”,“setExponential”,“startValue”,“targetValue”,“currentValue”,“stiffness”,“exp”,“oldValue”,“isAtTargetValue”,“ImageJob”,“jobId”,“errorMsg”,“selfAbort”,“abort”,“finish”,“onabort”,“loadWithAjax”,“blb”,“Blob”,“BlobBuilder”,“WebKitBlobBuilder”,“MozBlobBuilder”,“MSBlobBuilder”,“bb”,“append”,“getBlob”,“URL”,“webkitURL”,“createObjectURL”,“successful”,“jobQueue”,“jobsInProgress”,“addJob”,“newJob”,“job”,“loader”,“completeJob”,“Tile”,“exists”,“sourceBounds”,“cacheKey”,“stringify”,“loaded”,“loading”,“imgElement”,“blendStart”,“squaredDistance”,“beingDrawn”,“lastTouchTime”,“isRightMost”,“isBottomMost”,“_hasTransparencyChannel”,“cacheImageRecord”,“getImage”,“cloneNode”,“msInterpolationMode”,“drawCanvas”,“drawingHandler”,“rendered”,“getRenderedContext”,“save”,“globalAlpha”,“clearRect”,“tile”,“sourceWidth”,“sourceHeight”,“restore”,“getScaleForEdgeSmoothing”,“getTranslationForEdgeSmoothing”,“canvasSize”,“sketchCanvasSize”,“unload”,“OverlayPlacement”,“OverlayRotationMode”,“NO_ROTATION”,“EXACT”,“BOUNDING_BOX”,“_init”,“scales”,“adjust”,“transformOriginProp”,“transformProp”,“positionAndSize”,“_getOverlayPositionAndSize”,“_getTransformOrigin”,“_getSizeInPixels”,“_getBoundingBox”,“scaledSize”,“deltaPixelsFromPointsNoRotate”,“eltSize”,“refPoint”,“_getPlacementPoint”,“deltaPointsFromPixelsNoRotate”,“_adjustBoundsForRotation”,“viewerElementToViewportRectangle”,“sketchCanvas”,“sketchContext”,“dir”,“viewportSize”,“_calculateCanvasSize”,“getOpacity”,“maxOpacity”,“needsUpdate”,“numTilesLoaded”,“reset”,“resetItems”,“_calculateSketchCanvasSize”,“_clear”,“useSketch”,“_getContext”,“viewportToDrawerRectangle”,“rectangle”,“drawTile”,“resizeSketchCanvas”,“saveContext”,“restoreContext”,“beginPath”,“drawRectangle”,“fillStyle”,“fillRect”,“blendSketch”,“globalCompositeOperation”,“widthExt”,“heightExt”,“widthDiff”,“heightDiff”,“drawDebugInfo”,“colorIndex”,“lineWidth”,“font”,“strokeStyle”,“_offsetForRotation”,“_flip”,“_getRotationPoint”,“strokeRect”,“tileCenterX”,“tileCenterY”,“fillText”,“_restoreRotationChanges”,“debugRect”,“getCanvasSize”,“sketch”,“getCanvasCenter”,“contentSize”,“_margins”,“zoomPoint”,“_updateContainerInnerSize”,“zoomSpring”,“_oldCenterX”,“_oldCenterY”,“_oldZoom”,“resetContentSize”,“setHomeBounds”,“contentFactor”,“_contentBoundsNoRotate”,“_contentSizeNoRotate”,“_contentBounds”,“_contentSize”,“_contentAspectRatio”,“homeBounds”,“contentBounds”,“getHomeZoom”,“aspectFactor”,“getHomeBoundsNoRotate”,“getMinZoom”,“homeZoom”,“getMaxZoom”,“_containerInnerSize”,“getMargins”,“setMargins”,“getBoundsWithMargins”,“getBoundsNoRotateWithMargins”,“oldZoomPixel”,“deltaZoomPoints”,“centerCurrent”,“centerTarget”,“_pixelFromPoint”,“_applyZoomConstraints”,“_applyBoundaryConstraints”,“newBounds”,“horizontalThreshold”,“boundsRight”,“contentRight”,“leftDx”,“rightDx”,“verticalThreshold”,“boundsBottom”,“contentBottom”,“topDy”,“bottomDy”,“_raiseConstraintsEvent”,“actualZoom”,“constrainedZoom”,“ensureVisible”,“_fitBounds”,“constraints”,“aspect”,“newZoom”,“newBoundsAspectRatio”,“newConstrainedZoom”,“oldZoom”,“referencePoint”,“fitVertically”,“box”,“fitHorizontally”,“_adjustCenterSpringsForZoomPoint”,“newContainerSize”,“maintain”,“widthDeltaFactor”,“changed”,“zoomSpringHandler”,“deltaZoomPixels”,“deltaPoints”,“deltaPixelsFromPoints”,“deltaPixels”,“_pixelFromPointNoRotate”,“pointFromPixelNoRotate”,“pixel”,“_viewportToImageDelta”,“viewerX”,“viewerY”,“viewportToImageCoordinates”,“_imageToViewportDelta”,“imageX”,“imageY”,“imageToViewportCoordinates”,“pixelWidth”,“pixelHeight”,“coordA”,“coordB”,“viewportToImageRectangle”,“pointWidth”,“pointHeight”,“viewerElementToImageCoordinates”,“imageToViewerElementCoordinates”,“windowToImageCoordinates”,“viewerCoordinates”,“imageToWindowCoordinates”,“viewerElementToViewportCoordinates”,“viewportToViewerElementCoordinates”,“viewportToViewerElementRectangle”,“windowToViewportCoordinates”,“viewportToWindowCoordinates”,“viewportToImageZoom”,“viewportZoom”,“imageWidth”,“imageToViewportZoom”,“imageZoom”,“_tileCache”,“_drawer”,“_imageLoader”,“_clip”,“normHeight”,“contentAspectX”,“tilesMatrix”,“coverage”,“loadingCoverage”,“lastDrawn”,“lastResetTime”,“_midDraw”,“_needsDraw”,“_hasOpaqueTile”,“_tilesLoading”,“_preload”,“_fullyLoaded”,“_xSpring”,“_ySpring”,“_scaleSpring”,“_degreesSpring”,“_updateForScale”,“_drawingHandler”,“getFullyLoaded”,“_setFullyLoaded”,“flag”,“fullyLoaded”,“clearTilesFor”,“xUpdated”,“yUpdated”,“scaleUpdated”,“degreesUpdated”,“_updateViewport”,“_worldWidthCurrent”,“_worldHeightCurrent”,“_worldWidthTarget”,“_worldHeightTarget”,“getWorldBounds”,“getClippedBounds”,“ratio”,“getContentSize”,“_viewportToTiledImageRectangle”,“sameTarget”,“_raiseBoundsChange”,“_setScale”,“setHeight”,“anchorProperties”,“xOffset”,“yOffset”,“displayedWidthRatio”,“displayedHeightRatio”,“newClip”,“getPreload”,“setPreload”,“getCompositeOperation”,“_isBottomItem”,“_getLevelsInterval”,“lowestLevel”,“currentZeroRatio”,“highestLevel”,“drawArea”,“tiledImageBounds”,“levelsInterval”,“bestTile”,“haveDrawn”,“drawLevel”,“currentRenderPixelRatio”,“targetRenderPixelRatio”,“targetZeroRatio”,“optimalRatio”,“updateLevel”,“providesCoverage”,“sketchScale”,“sketchTranslate”,“usedClip”,“clipRect”,“placeholderRect”,“drawTiles”,“tileRequest”,“cutoff”,“setTileLoaded”,“onTileLoad”,“loadTile”,“_getCornerTiles”,“topLeftBound”,“bottomRightBound”,“leftX”,“rightX”,“topY”,“bottomY”,“topLeftTile”,“bottomRightTile”,“levelOpacity”,“levelVisibility”,“best”,“havedrawn”,“currenttime”,“resetCoverage”,“cornerTiles”,“numberOfTiles”,“viewportCenter”,“tileBounds”,“updateTile”,“worldWidth”,“worldHeight”,“xMod”,“yMod”,“getTile”,“setCoverage”,“isCovered”,“overlap”,“boundsTL”,“boundsSize”,“positionC”,“positionT”,“sizeC”,“sizeT”,“tileCenter”,“tileSquaredDistance”,“positionTile”,“imageRecord”,“getImageRecord”,“blendTimeMillis”,“blendTile”,“previousBest”,“compareTiles”,“increment”,“getCompletionCallback”,“completionCallback”,“cacheTile”,“cols”,“covers”,“ImageRecord”,“_tiles”,“_renderedContext”,“setRenderedContext”,“renderedContext”,“addTile”,“removeTile”,“getTileCount”,“_maxImageCacheCount”,“_tilesLoaded”,“_imagesLoaded”,“_imagesLoadedCount”,“insertionIndex”,“worstTile”,“worstTileIndex”,“worstTileRecord”,“prevTile”,“worstTime”,“worstLevel”,“prevTime”,“prevLevel”,“prevTileRecord”,“_unloadTile”,“tileRecord”,“_items”,“_autoRefigureSizes”,“_needsSizesFigured”,“_delegatedFigureSizes”,“_figureSizes”,“oldIndex”,“_raiseRemoveItem”,“removedItems”,“_homeBounds”,“_contentFactor”,“wrap”,“oldHomeBounds”,“oldContentSize”,“oldContentFactor”,“clippedBounds”],“mappings”:“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”,“file”:“openseadragon.min.js”,“sourcesContent”:[“/*n * OpenSeadragonn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn/*n * Portions of this source file taken from jQuery:n *n * Copyright 2011 John Resign *n * Permission is hereby granted, free of charge, to any person obtainingn * a copy of this software and associated documentation files (then * "Software"), to deal in the Software without restriction, includingn * without limitation the rights to use, copy, modify, merge, publish,n * distribute, sublicense, and/or sell copies of the Software, and ton * permit persons to whom the Software is furnished to do so, subject ton * the following conditions:n *n * The above copyright notice and this permission notice shall ben * included in all copies or substantial portions of the Software.n *n * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OFn * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE ANDn * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BEn * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTIONn * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTIONn * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.n */nn/*n * Portions of this source file taken from mattsnider.com:n *n * Copyright © 2006-2013 Matt Snidern *n * Permission is hereby granted, free of charge, to any person obtaining an * copy of this software and associated documentation files (the "Software"),n * to deal in the Software without restriction, including without limitationn * the rights to use, copy, modify, merge, publish, distribute, sublicense,n * and/or sell copies of the Software, and to permit persons to whom then * Software is furnished to do so, subject to the following conditions:n *n * The above copyright notice and this permission notice shall be includedn * in all copies or substantial portions of the Software.n *n * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSn * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OFn * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANYn * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORTn * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE ORn * THE USE OR OTHER DEALINGS IN THE SOFTWARE.n */nnn/**n * @namespace OpenSeadragonn * @version openseadragon 2.4.0n * @classdesc The root namespace for OpenSeadragon. All utility methodsn * and classes are defined on or below this namespace.n *n */nnn// Typedefsnn /**n * All required and optional settings for instantiating a new instance of an OpenSeadragon image viewer.n *n * @typedef {Object} Optionsn * @memberof OpenSeadragonn *n * @property {String} idn * Id of the element to append the viewer’s container element to. If not provided, the ‘element’ property must be provided.n * If both the element and id properties are specified, the viewer is appended to the element provided in the element property.n *n * @property {Element} elementn * The element to append the viewer’s container element to. If not provided, the ‘id’ property must be provided.n * If both the element and id properties are specified, the viewer is appended to the element provided in the element property.n *n * @property {Array|String|Function|Object} [tileSources=null]n * Tile source(s) to open initially. This is a complex parameter; seen * {@link OpenSeadragon.Viewer#open} for details.n *n * @property {Number} [tabIndex=0]n * Tabbing order index to assign to the viewer element. Positive values are selected in increasing order. When tabIndex is 0n * source order is used. A negative value omits the viewer from the tabbing order.n *n * @property {Array} overlays Array of objects defining permanent overlays ofn * the viewer. The overlays added via this option and later removed withn * {@link OpenSeadragon.Viewer#removeOverlay} will be added back when a newn * image is opened.n * To add overlays which can be definitively removed, one must usen * {@link OpenSeadragon.Viewer#addOverlay}n * If displaying a sequence of images, the overlays can be associatedn * with a specific page by passing the overlays array to the page’sn * tile source configuration.n * Expected properties:n * * x, y, (or px, py for pixel coordinates) to define the location.n * * width, height in point if using x,y or in pixels if using px,py. If widthn * and height are specified, the overlay size is adjusted when zooming,n * otherwise the size stays the size of the content (or the size defined by CSS).n * * className to associate a class to the overlayn * * id to set the overlay element. If an element with this id already exists,n * it is reused, otherwise it is created. If not specified, a new element isn * created.n * * placement a string to define the relative position to the viewport.n * Only used if no width and height are specified. Default: ‘TOP_LEFT’.n * See {@link OpenSeadragon.Placement} for possible values.n *n * @property {String} [xmlPath=null]n * DEPRECATED. A relative path to load a DZI file from the server.n * Prefer the newer Options.tileSources.n *n * @property {String} [prefixUrl=‘/images/’]n * Prepends the prefixUrl to navImages paths, which is very usefuln * since the default paths are rarely useful for productionn * environments.n *n * @property {OpenSeadragon.NavImages} [navImages]n * An object with a property for each button or other built-in navigationn * control, eg the current ‘zoomIn’, ‘zoomOut’, ‘home’, and ‘fullpage’.n * Each of those in turn provides an image path for each state of the buttonn * or navigation control, eg ‘REST’, ‘GROUP’, ‘HOVER’, ‘PRESS’. Finally then * image paths, by default assume there is a folder on the servers root pathn * called ‘/images’, eg ‘/images/zoomin_rest.png’. If you need to adjustn * these paths, prefer setting the option.prefixUrl rather than overridingn * every image path directly through this setting.n *n * @property {Boolean} [debugMode=false]n * TODO: provide an in-screen panel providing event detail feedback.n *n * @property {String} [debugGridColor=[‘#437AB2’, ‘#1B9E77’, ‘#D95F02’, ‘#7570B3’, ‘#E7298A’, ‘#66A61E’, ‘#E6AB02’, ‘#A6761D’, ‘#666666’]]n * The colors of grids in debug mode. Each tiled image’s grid uses a consecutive color.n * If there are more tiled images than provided colors, the color vector is recycled.n *n * @property {Number} [blendTime=0]n * Specifies the duration of animation as higher or lower level tiles aren * replacing the existing tile.n *n * @property {Boolean} [alwaysBlend=false]n * Forces the tile to always blend. By default the tiles skip blendingn * when the blendTime is surpassed and the current animation frame wouldn * not complete the blend.n *n * @property {Boolean} [autoHideControls=true]n * If the user stops interacting with the viewport, fade the navigationn * controls. Useful for presentation since the controls are by defaultn * floated on top of the image the user is viewing.n *n * @property {Boolean} [immediateRender=false]n * Render the best closest level first, ignoring the lowering levels whichn * provide the effect of very blurry to sharp. It is recommended to changen * setting to true for mobile devices.n *n * @property {Number} [defaultZoomLevel=0]n * Zoom level to use when image is first opened or the home button is clicked.n * If 0, adjusts to fit viewer.n *n * @property {Number} [opacity=1]n * Default proportional opacity of the tiled images (1=opaque, 0=hidden)n * Hidden images do not draw and only load when preloading is allowed.n *n * @property {Boolean} [preload=false]n * Default switch for loading hidden images (true loads, false blocks)n *n * @property {String} [compositeOperation=null]n * Valid values are ‘source-over’, ‘source-atop’, ‘source-in’, ‘source-out’,n * ‘destination-over’, ‘destination-atop’, ‘destination-in’,n * ‘destination-out’, ‘lighter’, ‘copy’ or ‘xor’n *n * @property {String|CanvasGradient|CanvasPattern|Function} [placeholderFillStyle=null]n * Draws a colored rectangle behind the tile if it is not loaded yet.n * You can pass a CSS color value like "#FF8800".n * When passing a function the tiledImage and canvas context are available as argument which is useful when you draw a gradient or pattern.n *n * @property {Number} [degrees=0]n * Initial rotation.n *n * @property {Boolean} [flipped=false]n * Initial flip state.n *n * @property {Number} [minZoomLevel=null]n *n * @property {Number} [maxZoomLevel=null]n *n * @property {Boolean} [homeFillsViewer=false]n * Make the ‘home’ button fill the viewer and clip the image, insteadn * of fitting the image to the viewer and letterboxing.n *n * @property {Boolean} [panHorizontal=true]n * Allow horizontal pan.n *n * @property {Boolean} [panVertical=true]n * Allow vertical pan.n *n * @property {Boolean} [constrainDuringPan=false]n *n * @property {Boolean} [wrapHorizontal=false]n * Set to true to force the image to wrap horizontally within the viewport.n * Useful for maps or images representing the surface of a sphere or cylinder.n *n * @property {Boolean} [wrapVertical=false]n * Set to true to force the image to wrap vertically within the viewport.n * Useful for maps or images representing the surface of a sphere or cylinder.n *n * @property {Number} [minZoomImageRatio=0.9]n * The minimum percentage ( expressed as a number between 0 and 1 ) ofn * the viewport height or width at which the zoom out will be constrained.n * Setting it to 0, for example will allow you to zoom out infinity.n *n * @property {Number} [maxZoomPixelRatio=1.1]n * The maximum ratio to allow a zoom-in to affect the highest level pixeln * ratio. This can be set to Infinity to allow ‘infinite’ zooming into then * image though it is less effective visually if the HTML5 Canvas is notn * availble on the viewing device.n *n * @property {Number} [smoothTileEdgesMinZoom=1.1]n * A zoom percentage ( where 1 is 100% ) of the highest resolution level.n * When zoomed in beyond this value alternative compositing will be used ton * smooth out the edges between tiles. This will have a performance impact.n * Can be set to Infinity to turn it off.n * Note: This setting is ignored on iOS devices due to a known bug (See {@link https://github.com/openseadragon/openseadragon/issues/952})n *n * @property {Boolean} [iOSDevice=?]n * True if running on an iOS device, false otherwise.n * Used to disable certain features that behave differently on iOS devices.n *n * @property {Boolean} [autoResize=true]n * Set to false to prevent polling for viewer size changes. Useful for providing custom resize behavior.n *n * @property {Boolean} [preserveImageSizeOnResize=false]n * Set to true to have the image size preserved when the viewer is resized. This requires autoResize=true (default).n *n * @property {Number} [minScrollDeltaTime=50]n * Number of milliseconds between canvas-scroll events. This value helps normalize the rate of canvas-scrolln * events between different devices, causing the faster devices to slow down enough to make the zoom controln * more manageable.n *n * @property {Number} [pixelsPerWheelLine=40]n * For pixel-resolution scrolling devices, the number of pixels equal to one scroll line.n *n * @property {Number} [pixelsPerArrowPress=40]n * The number of pixels viewport moves when an arrow key is pressed.n *n * @property {Number} [visibilityRatio=0.5]n * The percentage ( as a number from 0 to 1 ) of the source image whichn * must be kept within the viewport. If the image is dragged beyond thatn * limit, it will ‘bounce’ back until the minimum visibility ratio isn * achieved. Setting this to 0 and wrapHorizontal ( or wrapVertical ) ton * true will provide the effect of an infinitely scrolling viewport.n *n * @property {Object} [viewportMargins={}]n * Pushes the "home" region in from the sides by the specified amounts.n * Possible subproperties (Numbers, in screen coordinates): left, top, right, bottom.n *n * @property {Number} [imageLoaderLimit=0]n * The maximum number of image requests to make concurrently. By defaultn * it is set to 0 allowing the browser to make the maximum number ofn * image requests in parallel as allowed by the browsers policy.n *n * @property {Number} [clickTimeThreshold=300]n * The number of milliseconds within which a pointer down-up event combinationn * will be treated as a click gesture.n *n * @property {Number} [clickDistThreshold=5]n * The maximum distance allowed between a pointer down event and a pointer up eventn * to be treated as a click gesture.n *n * @property {Number} [dblClickTimeThreshold=300]n * The number of milliseconds within which two pointer down-up event combinationsn * will be treated as a double-click gesture.n *n * @property {Number} [dblClickDistThreshold=20]n * The maximum distance allowed between two pointer click eventsn * to be treated as a double-click gesture.n *n * @property {Number} [springStiffness=6.5]n *n * @property {Number} [animationTime=1.2]n * Specifies the animation duration per each {@link OpenSeadragon.Spring}n * which occur when the image is dragged or zoomed.n *n * @property {OpenSeadragon.GestureSettings} [gestureSettingsMouse]n * Settings for gestures generated by a mouse pointer device. (See {@link OpenSeadragon.GestureSettings})n * @property {Boolean} [gestureSettingsMouse.scrollToZoom=true] - Zoom on scroll gesturen * @property {Boolean} [gestureSettingsMouse.clickToZoom=true] - Zoom on click gesturen * @property {Boolean} [gestureSettingsMouse.dblClickToZoom=false] - Zoom on double-click gesture. Note: If set to truen * then clickToZoom should be set to false to prevent multiple zooms.n * @property {Boolean} [gestureSettingsMouse.pinchToZoom=false] - Zoom on pinch gesturen * @property {Boolean} [gestureSettingsMouse.zoomToRefPoint=true] - If zoomToRefPoint is true, the zoom is centered at the pointer position. Otherwise,n * the zoom is centered at the canvas center.n * @property {Boolean} [gestureSettingsMouse.flickEnabled=false] - Enable flick gesturen * @property {Number} [gestureSettingsMouse.flickMinSpeed=120] - If flickEnabled is true, the minimum speed to initiate a flick gesture (pixels-per-second)n * @property {Number} [gestureSettingsMouse.flickMomentum=0.25] - If flickEnabled is true, the momentum factor for the flick gesturen * @property {Boolean} [gestureSettingsMouse.pinchRotate=false] - If pinchRotate is true, the user will have the ability to rotate the image using their fingers.n *n * @property {OpenSeadragon.GestureSettings} [gestureSettingsTouch]n * Settings for gestures generated by a touch pointer device. (See {@link OpenSeadragon.GestureSettings})n * @property {Boolean} [gestureSettingsTouch.scrollToZoom=false] - Zoom on scroll gesturen * @property {Boolean} [gestureSettingsTouch.clickToZoom=false] - Zoom on click gesturen * @property {Boolean} [gestureSettingsTouch.dblClickToZoom=true] - Zoom on double-click gesture. Note: If set to truen * then clickToZoom should be set to false to prevent multiple zooms.n * @property {Boolean} [gestureSettingsTouch.pinchToZoom=true] - Zoom on pinch gesturen * @property {Boolean} [gestureSettingsTouch.zoomToRefPoint=true] - If zoomToRefPoint is true, the zoom is centered at the pointer position. Otherwise,n * the zoom is centered at the canvas center.n * @property {Boolean} [gestureSettingsTouch.flickEnabled=true] - Enable flick gesturen * @property {Number} [gestureSettingsTouch.flickMinSpeed=120] - If flickEnabled is true, the minimum speed to initiate a flick gesture (pixels-per-second)n * @property {Number} [gestureSettingsTouch.flickMomentum=0.25] - If flickEnabled is true, the momentum factor for the flick gesturen * @property {Boolean} [gestureSettingsTouch.pinchRotate=false] - If pinchRotate is true, the user will have the ability to rotate the image using their fingers.n *n * @property {OpenSeadragon.GestureSettings} [gestureSettingsPen]n * Settings for gestures generated by a pen pointer device. (See {@link OpenSeadragon.GestureSettings})n * @property {Boolean} [gestureSettingsPen.scrollToZoom=false] - Zoom on scroll gesturen * @property {Boolean} [gestureSettingsPen.clickToZoom=true] - Zoom on click gesturen * @property {Boolean} [gestureSettingsPen.dblClickToZoom=false] - Zoom on double-click gesture. Note: If set to truen * then clickToZoom should be set to false to prevent multiple zooms.n * @property {Boolean} [gestureSettingsPen.pinchToZoom=false] - Zoom on pinch gesturen * @property {Boolean} [gestureSettingsPan.zoomToRefPoint=true] - If zoomToRefPoint is true, the zoom is centered at the pointer position. Otherwise,n * the zoom is centered at the canvas center.n * @property {Boolean} [gestureSettingsPen.flickEnabled=false] - Enable flick gesturen * @property {Number} [gestureSettingsPen.flickMinSpeed=120] - If flickEnabled is true, the minimum speed to initiate a flick gesture (pixels-per-second)n * @property {Number} [gestureSettingsPen.flickMomentum=0.25] - If flickEnabled is true, the momentum factor for the flick gesturen * @property {Boolean} [gestureSettingsPen.pinchRotate=false] - If pinchRotate is true, the user will have the ability to rotate the image using their fingers.n *n * @property {OpenSeadragon.GestureSettings} [gestureSettingsUnknown]n * Settings for gestures generated by unknown pointer devices. (See {@link OpenSeadragon.GestureSettings})n * @property {Boolean} [gestureSettingsUnknown.scrollToZoom=true] - Zoom on scroll gesturen * @property {Boolean} [gestureSettingsUnknown.clickToZoom=false] - Zoom on click gesturen * @property {Boolean} [gestureSettingsUnknown.dblClickToZoom=true] - Zoom on double-click gesture. Note: If set to truen * then clickToZoom should be set to false to prevent multiple zooms.n * @property {Boolean} [gestureSettingsUnknown.pinchToZoom=true] - Zoom on pinch gesturen * @property {Boolean} [gestureSettingsUnknown.zoomToRefPoint=true] - If zoomToRefPoint is true, the zoom is centered at the pointer position. Otherwise,n * the zoom is centered at the canvas center.n * @property {Boolean} [gestureSettingsUnknown.flickEnabled=true] - Enable flick gesturen * @property {Number} [gestureSettingsUnknown.flickMinSpeed=120] - If flickEnabled is true, the minimum speed to initiate a flick gesture (pixels-per-second)n * @property {Number} [gestureSettingsUnknown.flickMomentum=0.25] - If flickEnabled is true, the momentum factor for the flick gesturen * @property {Boolean} [gestureSettingsUnknown.pinchRotate=false] - If pinchRotate is true, the user will have the ability to rotate the image using their fingers.n *n * @property {Number} [zoomPerClick=2.0]n * The "zoom distance" per mouse click or touch tap. <strong>Note:</strong> Setting this to 1.0 effectively disables the click-to-zoom feature (also see gestureSettings[Mouse|Touch|Pen].clickToZoom/dblClickToZoom).n *n * @property {Number} [zoomPerScroll=1.2]n * The "zoom distance" per mouse scroll or touch pinch. <strong>Note:</strong> Setting this to 1.0 effectively disables the mouse-wheel zoom feature (also see gestureSettings[Mouse|Touch|Pen].scrollToZoom}).n *n * @property {Number} [zoomPerSecond=1.0]n * The number of seconds to animate a single zoom event over.n *n * @property {Boolean} [showNavigator=false]n * Set to true to make the navigator minimap appear.n *n * @property {String} [navigatorId=navigator-GENERATED DATE]n * The ID of a div to hold the navigator minimap.n * If an ID is specified, the navigatorPosition, navigatorSizeRatio, navigatorMaintainSizeRatio, navigator[Top|Left|Height|Width] and navigatorAutoFade options will be ignored.n * If an ID is not specified, a div element will be generated and placed on top of the main image.n *n * @property {String} [navigatorPosition=‘TOP_RIGHT’]n * Valid values are ‘TOP_LEFT’, ‘TOP_RIGHT’, ‘BOTTOM_LEFT’, ‘BOTTOM_RIGHT’, or ‘ABSOLUTE’.
n * If ‘ABSOLUTE’ is specified, then navigator[Top|Left|Height|Width] determines the size and position of the navigator minimap in the viewer, and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.
n * For ‘TOP_LEFT’, ‘TOP_RIGHT’, ‘BOTTOM_LEFT’, and ‘BOTTOM_RIGHT’, the navigatorSizeRatio or navigator[Height|Width] values determine the size of the navigator minimap.n *n * @property {Number} [navigatorSizeRatio=0.2]n * Ratio of navigator size to viewer size. Ignored if navigator[Height|Width] are specified.n *n * @property {Boolean} [navigatorMaintainSizeRatio=false]n * If true, the navigator minimap is resized (using navigatorSizeRatio) when the viewer size changes.n *n * @property {Number|String} [navigatorTop=null]n * Specifies the location of the navigator minimap (see navigatorPosition).n *n * @property {Number|String} [navigatorLeft=null]n * Specifies the location of the navigator minimap (see navigatorPosition).n *n * @property {Number|String} [navigatorHeight=null]n * Specifies the size of the navigator minimap (see navigatorPosition).n * If specified, navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.n *n * @property {Number|String} [navigatorWidth=null]n * Specifies the size of the navigator minimap (see navigatorPosition).n * If specified, navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.n *n * @property {Boolean} [navigatorAutoResize=true]n * Set to false to prevent polling for navigator size changes. Useful for providing custom resize behavior.n * Setting to false can also improve performance when the navigator is configured to a fixed size.n *n * @property {Boolean} [navigatorAutoFade=true]n * If the user stops interacting with the viewport, fade the navigator minimap.n * Setting to false will make the navigator minimap always visible.n *n * @property {Boolean} [navigatorRotate=true]n * If true, the navigator will be rotated together with the viewer.n *n * @property {String} [navigatorBackground=‘#000’]n * Specifies the background color of the navigator minimapn *n * @property {Number} [navigatorOpacity=0.8]n * Specifies the opacity of the navigator minimap.n *n * @property {String} [navigatorBorderColor=‘#555’]n * Specifies the border color of the navigator minimapn *n * @property {String} [navigatorDisplayRegionColor=‘#900’]n * Specifies the border color of the display region rectangle of the navigator minimapn *n * @property {Number} [controlsFadeDelay=2000]n * The number of milliseconds to wait once the user has stopped interactingn * with the interface before begining to fade the controls. Assumesn * showNavigationControl and autoHideControls are both true.n *n * @property {Number} [controlsFadeLength=1500]n * The number of milliseconds to animate the controls fading out.n *n * @property {Number} [maxImageCacheCount=200]n * The max number of images we should keep in memory (per drawer).n *n * @property {Number} [timeout=30000]n * The max number of milliseconds that an image job may take to complete.n *n * @property {Boolean} [useCanvas=true]n * Set to false to not use an HTML canvas element for image rendering even if canvas is supported.n *n * @property {Number} [minPixelRatio=0.5]n * The higher the minPixelRatio, the lower the quality of the image thatn * is considered sufficient to stop rendering a given zoom level. Forn * example, if you are targeting mobile devices with less bandwith you mayn * try setting this to 1.5 or higher.n *n * @property {Boolean} [mouseNavEnabled=true]n * Is the user able to interact with the image via mouse or touch. Defaultn * interactions include draging the image in a plane, and zooming in towardn * and away from the image.n *n * @property {Boolean} [showNavigationControl=true]n * Set to false to prevent the appearance of the default navigation controls.
n * Note that if set to false, the customs buttons set by the optionsn * zoomInButton, zoomOutButton etc, are rendered inactive.n *n * @property {OpenSeadragon.ControlAnchor} [navigationControlAnchor=TOP_LEFT]n * Placement of the default navigation controls.n * To set the placement of the sequence controls, see then * sequenceControlAnchor option.n *n * @property {Boolean} [showZoomControl=true]n * If true then + and - buttons to zoom in and out are displayed.
n * Note: {@link OpenSeadragon.Options.showNavigationControl} is overridingn * this setting when set to false.n *n * @property {Boolean} [showHomeControl=true]n * If true then the ‘Go home’ button is displayed to go back to the originaln * zoom and pan.
n * Note: {@link OpenSeadragon.Options.showNavigationControl} is overridingn * this setting when set to false.n *n * @property {Boolean} [showFullPageControl=true]n * If true then the ‘Toggle full page’ button is displayed to switchn * between full page and normal mode.
n * Note: {@link OpenSeadragon.Options.showNavigationControl} is overridingn * this setting when set to false.n *n * @property {Boolean} [showRotationControl=false]n * If true then the rotate left/right controls will be displayed as part of then * standard controls. This is also subject to the browser support for rotaten * (e.g. viewer.drawer.canRotate()).
n * Note: {@link OpenSeadragon.Options.showNavigationControl} is overridingn * this setting when set to false.n *n * @property {Boolean} [showFlipControl=false]n * If true then the flip controls will be displayed as part of then * standard controls.n *n * @property {Boolean} [showSequenceControl=true]n * If sequenceMode is true, then provide buttons for navigating forward andn * backward through the images.n *n * @property {OpenSeadragon.ControlAnchor} [sequenceControlAnchor=TOP_LEFT]n * Placement of the default sequence controls.n *n * @property {Boolean} [navPrevNextWrap=false]n * If true then the ‘previous’ button will wrap to the last image whenn * viewing the first image and the ‘next’ button will wrap to the firstn * image when viewing the last image.n *n * @property {String} zoomInButtonn * Set the id of the custom ‘Zoom in’ button to use.n * This is useful to have a custom button anywhere in the web page.
n * To only change the button images, consider usingn * {@link OpenSeadragon.Options.navImages}n *n * @property {String} zoomOutButtonn * Set the id of the custom ‘Zoom out’ button to use.n * This is useful to have a custom button anywhere in the web page.
n * To only change the button images, consider usingn * {@link OpenSeadragon.Options.navImages}n *n * @property {String} homeButtonn * Set the id of the custom ‘Go home’ button to use.n * This is useful to have a custom button anywhere in the web page.
n * To only change the button images, consider usingn * {@link OpenSeadragon.Options.navImages}n *n * @property {String} fullPageButtonn * Set the id of the custom ‘Toggle full page’ button to use.n * This is useful to have a custom button anywhere in the web page.
n * To only change the button images, consider usingn * {@link OpenSeadragon.Options.navImages}n *n * @property {String} rotateLeftButtonn * Set the id of the custom ‘Rotate left’ button to use.n * This is useful to have a custom button anywhere in the web page.
n * To only change the button images, consider usingn * {@link OpenSeadragon.Options.navImages}n *n * @property {String} rotateRightButtonn * Set the id of the custom ‘Rotate right’ button to use.n * This is useful to have a custom button anywhere in the web page.
n * To only change the button images, consider usingn * {@link OpenSeadragon.Options.navImages}n *n * @property {String} previousButtonn * Set the id of the custom ‘Previous page’ button to use.n * This is useful to have a custom button anywhere in the web page.
n * To only change the button images, consider usingn * {@link OpenSeadragon.Options.navImages}n *n * @property {String} nextButtonn * Set the id of the custom ‘Next page’ button to use.n * This is useful to have a custom button anywhere in the web page.
n * To only change the button images, consider usingn * {@link OpenSeadragon.Options.navImages}n *n * @property {Boolean} [sequenceMode=false]n * Set to true to have the viewer treat your tilesources as a sequence of images ton * be opened one at a time rather than all at once.n *n * @property {Number} [initialPage=0]n * If sequenceMode is true, display this page initially.n *n * @property {Boolean} [preserveViewport=false]n * If sequenceMode is true, then normally navigating through each image resets then * viewport to ‘home’ position. If preserveViewport is set to true, then the viewportn * position is preserved when navigating between images in the sequence.n *n * @property {Boolean} [preserveOverlays=false]n * If sequenceMode is true, then normally navigating through each imagen * resets the overlays.n * If preserveOverlays is set to true, then the overlays added with {@link OpenSeadragon.Viewer#addOverlay}n * are preserved when navigating between images in the sequence.n * Note: setting preserveOverlays overrides any overlays specified in the globaln * "overlays" option for the Viewer. It’s also not compatible with specifyingn * per-tileSource overlays via the options, as those overlays will persistn * even after the tileSource is closed.n *n * @property {Boolean} [showReferenceStrip=false]n * If sequenceMode is true, then display a scrolling strip of image thumbnails forn * navigating through the images.n *n * @property {String} [referenceStripScroll=‘horizontal’]n *n * @property {Element} [referenceStripElement=null]n *n * @property {Number} [referenceStripHeight=null]n *n * @property {Number} [referenceStripWidth=null]n *n * @property {String} [referenceStripPosition=‘BOTTOM_LEFT’]n *n * @property {Number} [referenceStripSizeRatio=0.2]n *n * @property {Boolean} [collectionMode=false]n * Set to true to have the viewer arrange your TiledImages in a grid or line.n *n * @property {Number} [collectionRows=3]n * If collectionMode is true, specifies how many rows the grid should have. Use 1 to make a line.n * If collectionLayout is ‘vertical’, specifies how many columns instead.n *n * @property {Number} [collectionColumns=0]n * If collectionMode is true, specifies how many columns the grid should have. Use 1 to make a line.n * If collectionLayout is ‘vertical’, specifies how many rows instead. Ignored if collectionRows is not set to a falsy value.n *n * @property {String} [collectionLayout=‘horizontal’]n * If collectionMode is true, specifies whether to arrange vertically or horizontally.n *n * @property {Number} [collectionTileSize=800]n * If collectionMode is true, specifies the size, in viewport coordinates, for each TiledImage to fit into.n * The TiledImage will be centered within a square of the specified size.n *n * @property {Number} [collectionTileMargin=80]n * If collectionMode is true, specifies the margin, in viewport coordinates, between each TiledImage.n *n * @property {String|Boolean} [crossOriginPolicy=false]n * Valid values are ‘Anonymous’, ‘use-credentials’, and false. If false, canvas requests willn * not use CORS, and the canvas will be tainted.n *n * @property {Boolean} [ajaxWithCredentials=false]n * Whether to set the withCredentials XHR flag for AJAX requests.n * Note that this can be overridden at the {@link OpenSeadragon.TileSource} level.n *n * @property {Boolean} [loadTilesWithAjax=false]n * Whether to load tile data using AJAX requests.n * Note that this can be overridden at the {@link OpenSeadragon.TileSource} level.n *n * @property {Object} [ajaxHeaders={}]n * A set of headers to include when making AJAX requests for tile sources or tiles.n *n */nn /**n * Settings for gestures generated by a pointer device.n *n * @typedef {Object} GestureSettingsn * @memberof OpenSeadragonn *n * @property {Boolean} scrollToZoomn * Set to false to disable zooming on scroll gestures.n *n * @property {Boolean} clickToZoomn * Set to false to disable zooming on click gestures.n *n * @property {Boolean} dblClickToZoomn * Set to false to disable zooming on double-click gestures. Note: If set to truen * then clickToZoom should be set to false to prevent multiple zooms.n *n * @property {Boolean} pinchToZoomn * Set to false to disable zooming on pinch gestures.n *n * @property {Boolean} flickEnabledn * Set to false to disable the kinetic panning effect (flick) at the end of a drag gesture.n *n * @property {Number} flickMinSpeedn * If flickEnabled is true, the minimum speed (in pixels-per-second) required to cause the kinetic panning effect (flick) at the end of a drag gesture.n *n * @property {Number} flickMomentumn * If flickEnabled is true, a constant multiplied by the velocity to determine the distance of the kinetic panning effect (flick) at the end of a drag gesture.n * A larger value will make the flick feel "lighter", while a smaller value will make the flick feel "heavier".n * Note: springStiffness and animationTime also affect the "spring" used to stop the flick animation.n *n */nn/**n * The names for the image resources used for the image navigation buttons.n *n * @typedef {Object} NavImagesn * @memberof OpenSeadragonn *n * @property {Object} zoomIn - Images for the zoom-in button.n * @property {String} zoomIn.RESTn * @property {String} zoomIn.GROUPn * @property {String} zoomIn.HOVERn * @property {String} zoomIn.DOWNn *n * @property {Object} zoomOut - Images for the zoom-out button.n * @property {String} zoomOut.RESTn * @property {String} zoomOut.GROUPn * @property {String} zoomOut.HOVERn * @property {String} zoomOut.DOWNn *n * @property {Object} home - Images for the home button.n * @property {String} home.RESTn * @property {String} home.GROUPn * @property {String} home.HOVERn * @property {String} home.DOWNn *n * @property {Object} fullpage - Images for the full-page button.n * @property {String} fullpage.RESTn * @property {String} fullpage.GROUPn * @property {String} fullpage.HOVERn * @property {String} fullpage.DOWNn *n * @property {Object} rotateleft - Images for the rotate left button.n * @property {String} rotateleft.RESTn * @property {String} rotateleft.GROUPn * @property {String} rotateleft.HOVERn * @property {String} rotateleft.DOWNn *n * @property {Object} rotateright - Images for the rotate right button.n * @property {String} rotateright.RESTn * @property {String} rotateright.GROUPn * @property {String} rotateright.HOVERn * @property {String} rotateright.DOWNn *n * @property {Object} flip - Images for the flip button.n * @property {String} flip.RESTn * @property {String} flip.GROUPn * @property {String} flip.HOVERn * @property {String} flip.DOWNn *n * @property {Object} previous - Images for the previous button.n * @property {String} previous.RESTn * @property {String} previous.GROUPn * @property {String} previous.HOVERn * @property {String} previous.DOWNn *n * @property {Object} next - Images for the next button.n * @property {String} next.RESTn * @property {String} next.GROUPn * @property {String} next.HOVERn * @property {String} next.DOWNn *n */nnnfunction OpenSeadragon( options ){n return new OpenSeadragon.Viewer( options );n}nn(function( $ ){nnn /**n * The OpenSeadragon version.n *n * @member {Object} OpenSeadragon.versionn * @property {String} versionStr - The version number as a string (‘major.minor.revision’).n * @property {Number} major - The major version number.n * @property {Number} minor - The minor version number.n * @property {Number} revision - The revision number.n * @since 1.0.0n */n $.version = {n versionStr: ‘2.4.0’,n major: parseInt(‘2’, 10),n minor: parseInt(‘4’, 10),n revision: parseInt(‘0’, 10)n };nnn /**n * Taken from jquery 1.6.1n * [[Class]] -> type pairsn * @privaten */n var class2type = {n ‘[object Boolean]’: ‘boolean’,n ‘[object Number]’: ‘number’,n ‘[object String]’: ‘string’,n ‘[object Function]’: ‘function’,n ‘[object Array]’: ‘array’,n ‘[object Date]’: ‘date’,n ‘[object RegExp]’: ‘regexp’,n ‘[object Object]’: ‘object’n },n // Save a reference to some core methodsn toString = Object.prototype.toString,n hasOwn = Object.prototype.hasOwnProperty;nn /**n * Taken from jQuery 1.6.1n * @function isFunctionn * @memberof OpenSeadragonn * @see {@link http://www.jquery.com/ jQuery}n */n $.isFunction = function( obj ) {n return $.type(obj) === "function";n };nnn /**n * Taken from jQuery 1.6.1n * @function isArrayn * @memberof OpenSeadragonn * @see {@link http://www.jquery.com/ jQuery}n */n $.isArray = Array.isArray || function( obj ) {n return $.type(obj) === "array";n };nnn /**n * A crude way of determining if an object is a window.n * Taken from jQuery 1.6.1n * @function isWindown * @memberof OpenSeadragonn * @see {@link http://www.jquery.com/ jQuery}n */n $.isWindow = function( obj ) {n return obj && typeof obj === "object" && "setInterval" in obj;n };nnn /**n * Taken from jQuery 1.6.1n * @function typen * @memberof OpenSeadragonn * @see {@link http://www.jquery.com/ jQuery}n */n $.type = function( obj ) {n return ( obj === null ) || ( obj === undefined ) ?n String( obj ) :n class2type[ toString.call(obj) ] || "object";n };nnn /**n * Taken from jQuery 1.6.1n * @function isPlainObjectn * @memberof OpenSeadragonn * @see {@link http://www.jquery.com/ jQuery}n */n $.isPlainObject = function( obj ) {n // Must be an Object.n // Because of IE, we also have to check the presence of the constructor property.n // Make sure that DOM nodes and window objects don’t pass through, as welln if ( !obj || OpenSeadragon.type(obj) !== "object" || obj.nodeType || $.isWindow( obj ) ) {n return false;n }nn // Not own constructor property must be Objectn if ( obj.constructor &&n !hasOwn.call(obj, "constructor") &&n !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {n return false;n }nn // Own properties are enumerated firstly, so to speed up,n // if last one is own, then all properties are own.nn var lastKey;n for (var key in obj ) {n lastKey = key;n }nn return lastKey === undefined || hasOwn.call( obj, lastKey );n };nnn /**n * Taken from jQuery 1.6.1n * @function isEmptyObjectn * @memberof OpenSeadragonn * @see {@link http://www.jquery.com/ jQuery}n */n $.isEmptyObject = function( obj ) {n for ( var name in obj ) {n return false;n }n return true;n };nn /**n * Shim around Object.freeze. Does nothing if Object.freeze is not supported.n * @param {Object} obj The object to freeze.n * @return {Object} obj The frozen object.n */n $.freezeObject = function(obj) {n if (Object.freeze) {n $.freezeObject = Object.freeze;n } else {n $.freezeObject = function(obj) {n return obj;n };n }n return $.freezeObject(obj);n };nn /**n * True if the browser supports the HTML5 canvas elementn * @member {Boolean} supportsCanvasn * @memberof OpenSeadragonn */n $.supportsCanvas = (function () {n var canvasElement = document.createElement( ‘canvas’ );n return !!( $.isFunction( canvasElement.getContext ) &&n canvasElement.getContext( ‘2d’ ) );n }());nn /**n * Test whether the submitted canvas is tainted or not.n * @argument {Canvas} canvas The canvas to test.n * @returns {Boolean} True if the canvas is tainted.n */n $.isCanvasTainted = function(canvas) {n var isTainted = false;n try {n // We test if the canvas is tainted by retrieving data from it.n // An exception will be raised if the canvas is tainted.n canvas.getContext(‘2d’).getImageData(0, 0, 1, 1);n } catch (e) {n isTainted = true;n }n return isTainted;n };nn /**n * A ratio comparing the device screen’s pixel density to the canvas’s backing store pixel density,n * clamped to a minimum of 1. Defaults to 1 if canvas isn’t supported by the browser.n * @member {Number} pixelDensityRation * @memberof OpenSeadragonn */n $.pixelDensityRatio = (function () {n if ( $.supportsCanvas ) {n var context = document.createElement(‘canvas’).getContext(‘2d’);n var devicePixelRatio = window.devicePixelRatio || 1;n var backingStoreRatio = context.webkitBackingStorePixelRatio ||n context.mozBackingStorePixelRatio ||n context.msBackingStorePixelRatio ||n context.oBackingStorePixelRatio ||n context.backingStorePixelRatio || 1;n return Math.max(devicePixelRatio, 1) / backingStoreRatio;n } else {n return 1;n }n }());nn}( OpenSeadragon ));nn/**n * This closure defines all static methods available to the OpenSeadragonn * namespace. Many, if not most, are taked directly from jQuery for usen * to simplify and reduce common programming patterns. More static methodsn * from jQuery may eventually make their way into this though we aren * attempting to avoid an explicit dependency on jQuery only becausen * OpenSeadragon is a broadly useful code base and would be made less broadn * by requiring jQuery fully.n *n * Some static methods have also been refactored from the original OpenSeadragonn * project.n */n(function( $ ){nn /**n * Taken from jQuery 1.6.1n * @function extendn * @memberof OpenSeadragonn * @see {@link http://www.jquery.com/ jQuery}n */n $.extend = function() {n var options,n name,n src,n copy,n copyIsArray,n clone,n target = arguments[ 0 ] || {},n length = arguments.length,n deep = false,n i = 1;nn // Handle a deep copy situationn if ( typeof target === "boolean" ) {n deep = target;n target = arguments[ 1 ] || {};n // skip the boolean and the targetn i = 2;n }nn // Handle case when target is a string or something (possible in deep copy)n if ( typeof target !== "object" && !OpenSeadragon.isFunction( target ) ) {n target = {};n }nn // extend jQuery itself if only one argument is passedn if ( length === i ) {n target = this;n –i;n }nn for ( ; i < length; i++ ) {\n // Only deal with non-null/undefined values\n options = arguments[ i ];\n if ( options !== null || options !== undefined ) {\n // Extend the base object\n for ( name in options ) {\n src = target[ name ];\n copy = options[ name ];\n\n // Prevent never-ending loop\n if ( target === copy ) {\n continue;\n }\n\n // Recurse if we're merging plain objects or arrays\n if ( deep && copy && ( OpenSeadragon.isPlainObject( copy ) || ( copyIsArray = OpenSeadragon.isArray( copy ) ) ) ) {\n if ( copyIsArray ) {\n copyIsArray = false;\n clone = src && OpenSeadragon.isArray( src ) ? src : [];\n\n } else {\n clone = src && OpenSeadragon.isPlainObject( src ) ? src : {};\n }\n\n // Never move original objects, clone them\n target[ name ] = OpenSeadragon.extend( deep, clone, copy );\n\n // Don't bring in undefined values\n } else if ( copy !== undefined ) {\n target[ name ] = copy;\n }\n }\n }\n }\n\n // Return the modified object\n return target;\n };\n\n var isIOSDevice = function () {\n if (typeof navigator !== 'object') {\n return false;\n }\n var userAgent = navigator.userAgent;\n if (typeof userAgent !== 'string') {\n return false;\n }\n return userAgent.indexOf('iPhone') !== -1 ||\n userAgent.indexOf('iPad') !== -1 ||\n userAgent.indexOf('iPod') !== -1;\n };\n\n $.extend( $, /** @lends OpenSeadragon */{\n /**\n * The default values for the optional settings documented at {@link OpenSeadragon.Options}.\n * @static\n * @type {Object}\n */\n DEFAULT_SETTINGS: {\n //DATA SOURCE DETAILS\n xmlPath: null,\n tileSources: null,\n tileHost: null,\n initialPage: 0,\n crossOriginPolicy: false,\n ajaxWithCredentials: false,\n loadTilesWithAjax: false,\n ajaxHeaders: {},\n\n //PAN AND ZOOM SETTINGS AND CONSTRAINTS\n panHorizontal: true,\n panVertical: true,\n constrainDuringPan: false,\n wrapHorizontal: false,\n wrapVertical: false,\n visibilityRatio: 0.5, //-> how much of the viewer can be negative spacen minPixelRatio: 0.5, //->closer to 0 draws tiles meant for a higher zoom at this zoomn defaultZoomLevel: 0,n minZoomLevel: null,n maxZoomLevel: null,n homeFillsViewer: false,nn //UI RESPONSIVENESS AND FEELn clickTimeThreshold: 300,n clickDistThreshold: 5,n dblClickTimeThreshold: 300,n dblClickDistThreshold: 20,n springStiffness: 6.5,n animationTime: 1.2,n gestureSettingsMouse: {n scrollToZoom: true,n clickToZoom: true,n dblClickToZoom: false,n pinchToZoom: false,n zoomToRefPoint: true,n flickEnabled: false,n flickMinSpeed: 120,n flickMomentum: 0.25,n pinchRotate: falsen },n gestureSettingsTouch: {n scrollToZoom: false,n clickToZoom: false,n dblClickToZoom: true,n pinchToZoom: true,n zoomToRefPoint: true,n flickEnabled: true,n flickMinSpeed: 120,n flickMomentum: 0.25,n pinchRotate: falsen },n gestureSettingsPen: {n scrollToZoom: false,n clickToZoom: true,n dblClickToZoom: false,n pinchToZoom: false,n zoomToRefPoint: true,n flickEnabled: false,n flickMinSpeed: 120,n flickMomentum: 0.25,n pinchRotate: falsen },n gestureSettingsUnknown: {n scrollToZoom: false,n clickToZoom: false,n dblClickToZoom: true,n pinchToZoom: true,n zoomToRefPoint: true,n flickEnabled: true,n flickMinSpeed: 120,n flickMomentum: 0.25,n pinchRotate: falsen },n zoomPerClick: 2,n zoomPerScroll: 1.2,n zoomPerSecond: 1.0,n blendTime: 0,n alwaysBlend: false,n autoHideControls: true,n immediateRender: false,n minZoomImageRatio: 0.9, //-> closer to 0 allows zoom out to infinityn maxZoomPixelRatio: 1.1, //-> higher allows ‘over zoom’ into pixelsn smoothTileEdgesMinZoom: 1.1, //-> higher than maxZoomPixelRatio disables itn iOSDevice: isIOSDevice(),n pixelsPerWheelLine: 40,n pixelsPerArrowPress: 40,n autoResize: true,n preserveImageSizeOnResize: false, // requires autoResize=truen minScrollDeltaTime: 50,nn //DEFAULT CONTROL SETTINGSn showSequenceControl: true, //SEQUENCEn sequenceControlAnchor: null, //SEQUENCEn preserveViewport: false, //SEQUENCEn preserveOverlays: false, //SEQUENCEn navPrevNextWrap: false, //SEQUENCEn showNavigationControl: true, //ZOOM/HOME/FULL/ROTATIONn navigationControlAnchor: null, //ZOOM/HOME/FULL/ROTATIONn showZoomControl: true, //ZOOMn showHomeControl: true, //HOMEn showFullPageControl: true, //FULLn showRotationControl: false, //ROTATIONn showFlipControl: false, //FLIPn controlsFadeDelay: 2000, //ZOOM/HOME/FULL/SEQUENCEn controlsFadeLength: 1500, //ZOOM/HOME/FULL/SEQUENCEn mouseNavEnabled: true, //GENERAL MOUSE INTERACTIVITYnn //VIEWPORT NAVIGATOR SETTINGSn showNavigator: false,n navigatorId: null,n navigatorPosition: null,n navigatorSizeRatio: 0.2,n navigatorMaintainSizeRatio: false,n navigatorTop: null,n navigatorLeft: null,n navigatorHeight: null,n navigatorWidth: null,n navigatorAutoResize: true,n navigatorAutoFade: true,n navigatorRotate: true,n navigatorBackground: ‘#000’,n navigatorOpacity: 0.8,n navigatorBorderColor: ‘#555’,n navigatorDisplayRegionColor: ‘#900’,nn // INITIAL ROTATIONn degrees: 0,nn // INITIAL FLIP STATEn flipped: false,nn // APPEARANCEn opacity: 1,n preload: false,n compositeOperation: null,n placeholderFillStyle: null,nn //REFERENCE STRIP SETTINGSn showReferenceStrip: false,n referenceStripScroll: ‘horizontal’,n referenceStripElement: null,n referenceStripHeight: null,n referenceStripWidth: null,n referenceStripPosition: ‘BOTTOM_LEFT’,n referenceStripSizeRatio: 0.2,nn //COLLECTION VISUALIZATION SETTINGSn collectionRows: 3, //or columns depending on layoutn collectionColumns: 0, //columns in horizontal layout, rows in vertical layoutn collectionLayout: ‘horizontal’, //verticaln collectionMode: false,n collectionTileSize: 800,n collectionTileMargin: 80,nn //PERFORMANCE SETTINGSn imageLoaderLimit: 0,n maxImageCacheCount: 200,n timeout: 30000,n useCanvas: true, // Use canvas element for drawing if availablenn //INTERFACE RESOURCE SETTINGSn prefixUrl: "/images/",n navImages: {n zoomIn: {n REST: ‘zoomin_rest.png’,n GROUP: ‘zoomin_grouphover.png’,n HOVER: ‘zoomin_hover.png’,n DOWN: ‘zoomin_pressed.png’n },n zoomOut: {n REST: ‘zoomout_rest.png’,n GROUP: ‘zoomout_grouphover.png’,n HOVER: ‘zoomout_hover.png’,n DOWN: ‘zoomout_pressed.png’n },n home: {n REST: ‘home_rest.png’,n GROUP: ‘home_grouphover.png’,n HOVER: ‘home_hover.png’,n DOWN: ‘home_pressed.png’n },n fullpage: {n REST: ‘fullpage_rest.png’,n GROUP: ‘fullpage_grouphover.png’,n HOVER: ‘fullpage_hover.png’,n DOWN: ‘fullpage_pressed.png’n },n rotateleft: {n REST: ‘rotateleft_rest.png’,n GROUP: ‘rotateleft_grouphover.png’,n HOVER: ‘rotateleft_hover.png’,n DOWN: ‘rotateleft_pressed.png’n },n rotateright: {n REST: ‘rotateright_rest.png’,n GROUP: ‘rotateright_grouphover.png’,n HOVER: ‘rotateright_hover.png’,n DOWN: ‘rotateright_pressed.png’n },n flip: { // Flip icon designed by Yaroslav Samoylov from the Noun Project and modified by Nelson Campos ncampos@criteriamarathon.com, https://thenounproject.com/term/flip/136289/n REST: ‘flip_rest.png’,n GROUP: ‘flip_grouphover.png’,n HOVER: ‘flip_hover.png’,n DOWN: ‘flip_pressed.png’n },n previous: {n REST: ‘previous_rest.png’,n GROUP: ‘previous_grouphover.png’,n HOVER: ‘previous_hover.png’,n DOWN: ‘previous_pressed.png’n },n next: {n REST: ‘next_rest.png’,n GROUP: ‘next_grouphover.png’,n HOVER: ‘next_hover.png’,n DOWN: ‘next_pressed.png’n }n },nn //DEVELOPER SETTINGSn debugMode: false,n debugGridColor: [‘#437AB2’, ‘#1B9E77’, ‘#D95F02’, ‘#7570B3’, ‘#E7298A’, ‘#66A61E’, ‘#E6AB02’, ‘#A6761D’, ‘#666666’]n },nnn /**n * TODO: get rid of this. I can’t see how it’s required at all. Looksn * like an early legacy code artifact.n * @staticn * @ignoren */n SIGNAL: "—-seadragon—-",nnn /**n * Returns a function which invokes the method as if it were a method belonging to the object.n * @functionn * @param {Object} objectn * @param {Function} methodn * @returns {Function}n */n delegate: function( object, method ) {n return function(){n var args = arguments;n if ( args === undefined ){n args = [];n }n return method.apply( object, args );n };n },nnn /**n * An enumeration of Browser vendors.n * @staticn * @type {Object}n * @property {Number} UNKNOWNn * @property {Number} IEn * @property {Number} FIREFOXn * @property {Number} SAFARIn * @property {Number} CHROMEn * @property {Number} OPERAn */n BROWSERS: {n UNKNOWN: 0,n IE: 1,n FIREFOX: 2,n SAFARI: 3,n CHROME: 4,n OPERA: 5n },nnn /**n * Returns a DOM Element for the given id or element.n * @functionn * @param {String|Element} element Accepts an id or element.n * @returns {Element} The element with the given id, null, or the element itself.n */n getElement: function( element ) {n if ( typeof ( element ) == "string" ) {n element = document.getElementById( element );n }n return element;n },nnn /**n * Determines the position of the upper-left corner of the element.n * @functionn * @param {Element|String} element - the elemenet we want the position for.n * @returns {OpenSeadragon.Point} - the position of the upper left corner of the element.n */n getElementPosition: function( element ) {n var result = new $.Point(),n isFixed,n offsetParent;nn element = $.getElement( element );n isFixed = $.getElementStyle( element ).position == "fixed";n offsetParent = getOffsetParent( element, isFixed );nn while ( offsetParent ) {nn result.x += element.offsetLeft;n result.y += element.offsetTop;nn if ( isFixed ) {n result = result.plus( $.getPageScroll() );n }nn element = offsetParent;n isFixed = $.getElementStyle( element ).position == "fixed";n offsetParent = getOffsetParent( element, isFixed );n }nn return result;n },nnn /**n * Determines the position of the upper-left corner of the element adjusted for current page and/or element scroll.n * @functionn * @param {Element|String} element - the element we want the position for.n * @returns {OpenSeadragon.Point} - the position of the upper left corner of the element adjusted for current page and/or element scroll.n */n getElementOffset: function( element ) {n element = $.getElement( element );nn var doc = element && element.ownerDocument,n docElement,n win,n boundingRect = { top: 0, left: 0 };nn if ( !doc ) {n return new $.Point();n }nn docElement = doc.documentElement;nn if ( typeof element.getBoundingClientRect !== typeof undefined ) {n boundingRect = element.getBoundingClientRect();n }nn win = ( doc == doc.window ) ?n doc :n ( doc.nodeType === 9 ) ?n doc.defaultView || doc.parentWindow :n false;nn return new $.Point(n boundingRect.left + ( win.pageXOffset || docElement.scrollLeft ) - ( docElement.clientLeft || 0 ),n boundingRect.top + ( win.pageYOffset || docElement.scrollTop ) - ( docElement.clientTop || 0 )n );n },nnn /**n * Determines the height and width of the given element.n * @functionn * @param {Element|String} elementn * @returns {OpenSeadragon.Point}n */n getElementSize: function( element ) {n element = $.getElement( element );nn return new $.Point(n element.clientWidth,n element.clientHeightn );n },nnn /**n * Returns the CSSStyle object for the given element.n * @functionn * @param {Element|String} elementn * @returns {CSSStyle}n */n getElementStyle:n document.documentElement.currentStyle ?n function( element ) {n element = $.getElement( element );n return element.currentStyle;n } :n function( element ) {n element = $.getElement( element );n return window.getComputedStyle( element, "" );n },nn /**n * Returns the property with the correct vendor prefix appended.n * @param {String} property the property namen * @returns {String} the property with the correct prefix or null if notn * supported.n */n getCssPropertyWithVendorPrefix: function(property) {n var memo = {};nn $.getCssPropertyWithVendorPrefix = function(property) {n if (memo[property] !== undefined) {n return memo[property];n }n var style = document.createElement(‘div’).style;n var result = null;n if (style[property] !== undefined) {n result = property;n } else {n var prefixes = [‘Webkit’, ‘Moz’, ‘MS’, ‘O’,n ‘webkit’, ‘moz’, ‘ms’, ‘o’];n var suffix = $.capitalizeFirstLetter(property);n for (var i = 0; i < prefixes.length; i++) {\n var prop = prefixes[i] + suffix;\n if (style[prop] !== undefined) {\n result = prop;\n break;\n }\n }\n }\n memo[property] = result;\n return result;\n };\n return $.getCssPropertyWithVendorPrefix(property);\n },\n\n /**\n * Capitalizes the first letter of a string\n * @param {String} string\n * @returns {String} The string with the first letter capitalized\n */\n capitalizeFirstLetter: function(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n },\n\n /**\n * Compute the modulo of a number but makes sure to always return\n * a positive value.\n * @param {Number} number the number to computes the modulo of\n * @param {Number} modulo the modulo\n * @returns {Number} the result of the modulo of number\n */\n positiveModulo: function(number, modulo) {\n var result = number % modulo;\n if (result < 0) {\n result += modulo;\n }\n return result;\n },\n\n /**\n * Determines if a point is within the bounding rectangle of the given element (hit-test).\n * @function\n * @param {Element|String} element\n * @param {OpenSeadragon.Point} point\n * @returns {Boolean}\n */\n pointInElement: function( element, point ) {\n element = $.getElement( element );\n var offset = $.getElementOffset( element ),\n size = $.getElementSize( element );\n return point.x >= offset.x && point.x < offset.x + size.x && point.y < offset.y + size.y && point.y >= offset.y;n },nnn /**n * Gets the latest event, really only useful internally since itsn * specific to IE behavior.n * @functionn * @param {Event} [event]n * @returns {Event}n * @deprecated For internal use onlyn * @privaten */n getEvent: function( event ) {n if( event ){n $.getEvent = function( event ) {n return event;n };n } else {n $.getEvent = function() {n return window.event;n };n }n return $.getEvent( event );n },nnn /**n * Gets the position of the mouse on the screen for a given event.n * @functionn * @param {Event} [event]n * @returns {OpenSeadragon.Point}n */n getMousePosition: function( event ) {nn if ( typeof ( event.pageX ) == "number" ) {n $.getMousePosition = function( event ){n var result = new $.Point();nn event = $.getEvent( event );n result.x = event.pageX;n result.y = event.pageY;nn return result;n };n } else if ( typeof ( event.clientX ) == "number" ) {n $.getMousePosition = function( event ){n var result = new $.Point();nn event = $.getEvent( event );n result.x =n event.clientX +n document.body.scrollLeft +n document.documentElement.scrollLeft;n result.y =n event.clientY +n document.body.scrollTop +n document.documentElement.scrollTop;nn return result;n };n } else {n throw new Error(n "Unknown event mouse position, no known technique."n );n }nn return $.getMousePosition( event );n },nnn /**n * Determines the page’s current scroll position.n * @functionn * @returns {OpenSeadragon.Point}n */n getPageScroll: function() {n var docElement = document.documentElement || {},n body = document.body || {};nn if ( typeof ( window.pageXOffset ) == "number" ) {n $.getPageScroll = function(){n return new $.Point(n window.pageXOffset,n window.pageYOffsetn );n };n } else if ( body.scrollLeft || body.scrollTop ) {n $.getPageScroll = function(){n return new $.Point(n document.body.scrollLeft,n document.body.scrollTopn );n };n } else if ( docElement.scrollLeft || docElement.scrollTop ) {n $.getPageScroll = function(){n return new $.Point(n document.documentElement.scrollLeft,n document.documentElement.scrollTopn );n };n } else {n // We can’t reassign the function yet, as there was no scroll.n return new $.Point(0, 0);n }nn return $.getPageScroll();n },nn /**n * Set the page scroll position.n * @functionn * @returns {OpenSeadragon.Point}n */n setPageScroll: function( scroll ) {n if ( typeof ( window.scrollTo ) !== "undefined" ) {n $.setPageScroll = function( scroll ) {n window.scrollTo( scroll.x, scroll.y );n };n } else {n var originalScroll = $.getPageScroll();n if ( originalScroll.x === scroll.x &&n originalScroll.y === scroll.y ) {n // We are already correctly positioned and theren // is no way to detect the correct method.n return;n }nn document.body.scrollLeft = scroll.x;n document.body.scrollTop = scroll.y;n var currentScroll = $.getPageScroll();n if ( currentScroll.x !== originalScroll.x &&n currentScroll.y !== originalScroll.y ) {n $.setPageScroll = function( scroll ) {n document.body.scrollLeft = scroll.x;n document.body.scrollTop = scroll.y;n };n return;n }nn document.documentElement.scrollLeft = scroll.x;n document.documentElement.scrollTop = scroll.y;n currentScroll = $.getPageScroll();n if ( currentScroll.x !== originalScroll.x &&n currentScroll.y !== originalScroll.y ) {n $.setPageScroll = function( scroll ) {n document.documentElement.scrollLeft = scroll.x;n document.documentElement.scrollTop = scroll.y;n };n return;n }nn // We can’t find anything working, so we do nothing.n $.setPageScroll = function( scroll ) {n };n }nn return $.setPageScroll( scroll );n },nn /**n * Determines the size of the browsers window.n * @functionn * @returns {OpenSeadragon.Point}n */n getWindowSize: function() {n var docElement = document.documentElement || {},n body = document.body || {};nn if ( typeof ( window.innerWidth ) == ‘number’ ) {n $.getWindowSize = function(){n return new $.Point(n window.innerWidth,n window.innerHeightn );n };n } else if ( docElement.clientWidth || docElement.clientHeight ) {n $.getWindowSize = function(){n return new $.Point(n document.documentElement.clientWidth,n document.documentElement.clientHeightn );n };n } else if ( body.clientWidth || body.clientHeight ) {n $.getWindowSize = function(){n return new $.Point(n document.body.clientWidth,n document.body.clientHeightn );n };n } else {n throw new Error("Unknown window size, no known technique.");n }nn return $.getWindowSize();n },nnn /**n * Wraps the given element in a nest of divs so that the element cann * be easily centered using CSS tablesn * @functionn * @param {Element|String} elementn * @returns {Element} outermost wrapper elementn */n makeCenteredNode: function( element ) {n // Convert a possible ID to an actual HTMLElementn element = $.getElement( element );nn /*n CSS tables require you to have a display:table/row/cell hierarchy so we need to createn three nested wrapper divs:n */nn var wrappers = [n $.makeNeutralElement( ‘div’ ),n $.makeNeutralElement( ‘div’ ),n $.makeNeutralElement( ‘div’ )n ];nn // It feels like we should be able to pass style dicts to makeNeutralElement:n $.extend(wrappers[0].style, {n display: "table",n height: "100%",n width: "100%"n });nn $.extend(wrappers[1].style, {n display: "table-row"n });nn $.extend(wrappers[2].style, {n display: "table-cell",n verticalAlign: "middle",n textAlign: "center"n });nn wrappers[0].appendChild(wrappers[1]);n wrappers[1].appendChild(wrappers[2]);n wrappers[2].appendChild(element);nn return wrappers[0];n },nnn /**n * Creates an easily positionable element of the given type that thereforn * serves as an excellent container element.n * @functionn * @param {String} tagNamen * @returns {Element}n */n makeNeutralElement: function( tagName ) {n var element = document.createElement( tagName ),n style = element.style;nn style.background = "transparent none";n style.border = "none";n style.margin = "0px";n style.padding = "0px";n style.position = "static";nn return element;n },nnn /**n * Returns the current milliseconds, using Date.now() if availablen * @functionn */n now: function( ) {n if (Date.now) {n $.now = Date.now;n } else {n $.now = function() {n return new Date().getTime();n };n }nn return $.now();n },nnn /**n * Ensures an image is loaded correctly to support alpha transparency.n * Generally only IE has issues doing this correctly for formats liken * png.n * @functionn * @param {String} srcn * @returns {Element}n */n makeTransparentImage: function( src ) {nn $.makeTransparentImage = function( src ){n var img = $.makeNeutralElement( "img" );nn img.src = src;nn return img;n };nn if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 7 ) {\n\n $.makeTransparentImage = function( src ){\n var img = $.makeNeutralElement( \"img\" ),\n element = null;\n\n element = $.makeNeutralElement(\"span\");\n element.style.display = \"inline-block\";\n\n img.onload = function() {\n element.style.width = element.style.width || img.width + \"px\";\n element.style.height = element.style.height || img.height + \"px\";\n\n img.onload = null;\n img = null; // to prevent memory leaks in IE\n };\n\n img.src = src;\n element.style.filter =\n \"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='\" +\n src +\n \"', sizingMethod='scale')\";\n\n return element;\n };\n\n }\n\n return $.makeTransparentImage( src );\n },\n\n\n /**\n * Sets the opacity of the specified element.\n * @function\n * @param {Element|String} element\n * @param {Number} opacity\n * @param {Boolean} [usesAlpha]\n */\n setElementOpacity: function( element, opacity, usesAlpha ) {\n\n var ieOpacity,\n ieFilter;\n\n element = $.getElement( element );\n\n if ( usesAlpha && !$.Browser.alpha ) {\n opacity = Math.round( opacity );\n }\n\n if ( $.Browser.opacity ) {\n element.style.opacity = opacity < 1 ? opacity : \"\";\n } else {\n if ( opacity < 1 ) {\n ieOpacity = Math.round( 100 * opacity );\n ieFilter = \"alpha(opacity=\" + ieOpacity + \")\";\n element.style.filter = ieFilter;\n } else {\n element.style.filter = \"\";\n }\n }\n },\n\n\n /**\n * Sets the specified element's touch-action style attribute to 'none'.\n * @function\n * @param {Element|String} element\n */\n setElementTouchActionNone: function( element ) {\n element = $.getElement( element );\n if ( typeof element.style.touchAction !== 'undefined' ) {\n element.style.touchAction = 'none';\n } else if ( typeof element.style.msTouchAction !== 'undefined' ) {\n element.style.msTouchAction = 'none';\n }\n },\n\n\n /**\n * Add the specified CSS class to the element if not present.\n * @function\n * @param {Element|String} element\n * @param {String} className\n */\n addClass: function( element, className ) {\n element = $.getElement( element );\n\n if (!element.className) {\n element.className = className;\n } else if ( ( ' ' + element.className + ' ' ).\n indexOf( ' ' + className + ' ' ) === -1 ) {\n element.className += ' ' + className;\n }\n },\n\n /**\n * Find the first index at which an element is found in an array or -1\n * if not present.\n *\n * Code taken and adapted from\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf#Compatibility\n *\n * @function\n * @param {Array} array The array from which to find the element\n * @param {Object} searchElement The element to find\n * @param {Number} [fromIndex=0] Index to start research.\n * @returns {Number} The index of the element in the array.\n */\n indexOf: function( array, searchElement, fromIndex ) {\n if ( Array.prototype.indexOf ) {\n this.indexOf = function( array, searchElement, fromIndex ) {\n return array.indexOf( searchElement, fromIndex );\n };\n } else {\n this.indexOf = function( array, searchElement, fromIndex ) {\n var i,\n pivot = ( fromIndex ) ? fromIndex : 0,\n length;\n if ( !array ) {\n throw new TypeError( );\n }\n\n length = array.length;\n if ( length === 0 || pivot >= length ) {n return -1;n }nn if ( pivot < 0 ) {\n pivot = length - Math.abs( pivot );\n }\n\n for ( i = pivot; i < length; i++ ) {\n if ( array[i] === searchElement ) {\n return i;\n }\n }\n return -1;\n };\n }\n return this.indexOf( array, searchElement, fromIndex );\n },\n\n /**\n * Remove the specified CSS class from the element.\n * @function\n * @param {Element|String} element\n * @param {String} className\n */\n removeClass: function( element, className ) {\n var oldClasses,\n newClasses = [],\n i;\n\n element = $.getElement( element );\n oldClasses = element.className.split( /\\s+/ );\n for ( i = 0; i < oldClasses.length; i++ ) {\n if ( oldClasses[ i ] && oldClasses[ i ] !== className ) {\n newClasses.push( oldClasses[ i ] );\n }\n }\n element.className = newClasses.join(' ');\n },\n\n\n /**\n * Adds an event listener for the given element, eventName and handler.\n * @function\n * @param {Element|String} element\n * @param {String} eventName\n * @param {Function} handler\n * @param {Boolean} [useCapture]\n */\n addEvent: (function () {\n if ( window.addEventListener ) {\n return function ( element, eventName, handler, useCapture ) {\n element = $.getElement( element );\n element.addEventListener( eventName, handler, useCapture );\n };\n } else if ( window.attachEvent ) {\n return function ( element, eventName, handler, useCapture ) {\n element = $.getElement( element );\n element.attachEvent( 'on' + eventName, handler );\n };\n } else {\n throw new Error( \"No known event model.\" );\n }\n }()),\n\n\n /**\n * Remove a given event listener for the given element, event type and\n * handler.\n * @function\n * @param {Element|String} element\n * @param {String} eventName\n * @param {Function} handler\n * @param {Boolean} [useCapture]\n */\n removeEvent: (function () {\n if ( window.removeEventListener ) {\n return function ( element, eventName, handler, useCapture ) {\n element = $.getElement( element );\n element.removeEventListener( eventName, handler, useCapture );\n };\n } else if ( window.detachEvent ) {\n return function( element, eventName, handler, useCapture ) {\n element = $.getElement( element );\n element.detachEvent( 'on' + eventName, handler );\n };\n } else {\n throw new Error( \"No known event model.\" );\n }\n }()),\n\n\n /**\n * Cancels the default browser behavior had the event propagated all\n * the way up the DOM to the window object.\n * @function\n * @param {Event} [event]\n */\n cancelEvent: function( event ) {\n event = $.getEvent( event );\n\n if ( event.preventDefault ) {\n $.cancelEvent = function( event ){\n // W3C for preventing default\n event.preventDefault();\n };\n } else {\n $.cancelEvent = function( event ){\n event = $.getEvent( event );\n // legacy for preventing default\n event.cancel = true;\n // IE for preventing default\n event.returnValue = false;\n };\n }\n $.cancelEvent( event );\n },\n\n\n /**\n * Stops the propagation of the event up the DOM.\n * @function\n * @param {Event} [event]\n */\n stopEvent: function( event ) {\n event = $.getEvent( event );\n\n if ( event.stopPropagation ) {\n // W3C for stopping propagation\n $.stopEvent = function( event ){\n event.stopPropagation();\n };\n } else {\n // IE for stopping propagation\n $.stopEvent = function( event ){\n event = $.getEvent( event );\n event.cancelBubble = true;\n };\n\n }\n\n $.stopEvent( event );\n },\n\n\n /**\n * Similar to OpenSeadragon.delegate, but it does not immediately call\n * the method on the object, returning a function which can be called\n * repeatedly to delegate the method. It also allows additonal arguments\n * to be passed during construction which will be added during each\n * invocation, and each invocation can add additional arguments as well.\n *\n * @function\n * @param {Object} object\n * @param {Function} method\n * @param [args] any additional arguments are passed as arguments to the\n * created callback\n * @returns {Function}\n */\n createCallback: function( object, method ) {\n //TODO: This pattern is painful to use and debug. It's much cleaner\n // to use pinning plus anonymous functions. Get rid of this\n // pattern!\n var initialArgs = [],\n i;\n for ( i = 2; i < arguments.length; i++ ) {\n initialArgs.push( arguments[ i ] );\n }\n\n return function() {\n var args = initialArgs.concat( [] ),\n i;\n for ( i = 0; i < arguments.length; i++ ) {\n args.push( arguments[ i ] );\n }\n\n return method.apply( object, args );\n };\n },\n\n\n /**\n * Retreives the value of a url parameter from the window.location string.\n * @function\n * @param {String} key\n * @returns {String} The value of the url parameter or null if no param matches.\n */\n getUrlParameter: function( key ) {\n // eslint-disable-next-line no-use-before-define\n var value = URLPARAMS[ key ];\n return value ? value : null;\n },\n\n /**\n * Retrieves the protocol used by the url. The url can either be absolute\n * or relative.\n * @function\n * @private\n * @param {String} url The url to retrieve the protocol from.\n * @return {String} The protocol (http:, https:, file:, ftp: ...)\n */\n getUrlProtocol: function( url ) {\n var match = url.match(/^([a-z]+:)\\/\\//i);\n if ( match === null ) {\n // Relative URL, retrive the protocol from window.location\n return window.location.protocol;\n }\n return match[1].toLowerCase();\n },\n\n /**\n * Create an XHR object\n * @private\n * @param {type} [local] If set to true, the XHR will be file: protocol\n * compatible if possible (but may raise a warning in the browser).\n * @returns {XMLHttpRequest}\n */\n createAjaxRequest: function( local ) {\n // IE11 does not support window.ActiveXObject so we just try to\n // create one to see if it is supported.\n // See: http://msdn.microsoft.com/en-us/library/ie/dn423948%28v=vs.85%29.aspx\n var supportActiveX;\n try {\n /* global ActiveXObject:true */\n supportActiveX = !!new ActiveXObject( \"Microsoft.XMLHTTP\" );\n } catch( e ) {\n supportActiveX = false;\n }\n\n if ( supportActiveX ) {\n if ( window.XMLHttpRequest ) {\n $.createAjaxRequest = function( local ) {\n if ( local ) {\n return new ActiveXObject( \"Microsoft.XMLHTTP\" );\n }\n return new XMLHttpRequest();\n };\n } else {\n $.createAjaxRequest = function() {\n return new ActiveXObject( \"Microsoft.XMLHTTP\" );\n };\n }\n } else if ( window.XMLHttpRequest ) {\n $.createAjaxRequest = function() {\n return new XMLHttpRequest();\n };\n } else {\n throw new Error( \"Browser doesn't support XMLHttpRequest.\" );\n }\n return $.createAjaxRequest( local );\n },\n\n /**\n * Makes an AJAX request.\n * @param {Object} options\n * @param {String} options.url - the url to request\n * @param {Function} options.success - a function to call on a successful response\n * @param {Function} options.error - a function to call on when an error occurs\n * @param {Object} options.headers - headers to add to the AJAX request\n * @param {String} options.responseType - the response type of the the AJAX request\n * @param {Boolean} [options.withCredentials=false] - whether to set the XHR's withCredentials\n * @throws {Error}\n * @returns {XMLHttpRequest}\n */\n makeAjaxRequest: function( url, onSuccess, onError ) {\n var withCredentials;\n var headers;\n var responseType;\n\n // Note that our preferred API is that you pass in a single object; the named\n // arguments are for legacy support.\n if( $.isPlainObject( url ) ){\n onSuccess = url.success;\n onError = url.error;\n withCredentials = url.withCredentials;\n headers = url.headers;\n responseType = url.responseType || null;\n url = url.url;\n }\n\n var protocol = $.getUrlProtocol( url );\n var request = $.createAjaxRequest( protocol === \"file:\" );\n\n if ( !$.isFunction( onSuccess ) ) {\n throw new Error( \"makeAjaxRequest requires a success callback\" );\n }\n\n request.onreadystatechange = function() {\n // 4 = DONE (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#Properties)\n if ( request.readyState == 4 ) {\n request.onreadystatechange = function(){};\n\n // With protocols other than http/https, a successful request status is in\n // the 200's on Firefox and 0 on other browsers\n if ( (request.status >= 200 && request.status < 300) ||\n ( request.status === 0 &&\n protocol !== \"http:\" &&\n protocol !== \"https:\" )) {\n onSuccess( request );\n } else {\n $.console.log( \"AJAX request returned %d: %s\", request.status, url );\n\n if ( $.isFunction( onError ) ) {\n onError( request );\n }\n }\n }\n };\n\n try {\n request.open( \"GET\", url, true );\n\n if (responseType) {\n request.responseType = responseType;\n }\n\n if (headers) {\n for (var headerName in headers) {\n if (headers.hasOwnProperty(headerName) && headers[headerName]) {\n request.setRequestHeader(headerName, headers[headerName]);\n }\n }\n }\n\n if (withCredentials) {\n request.withCredentials = true;\n }\n\n request.send(null);\n } catch (e) {\n var msg = e.message;\n\n /*\n IE < 10 does not support CORS and an XHR request to a different origin will fail as soon\n as send() is called. This is particularly easy to miss during development and appear in\n production if you use a CDN or domain sharding and the security policy is likely to break\n exception handlers since any attempt to access a property of the request object will\n raise an access denied TypeError inside the catch block.\n\n To be friendlier, we'll check for this specific error and add a documentation pointer\n to point developers in the right direction. We test the exception number because IE's\n error messages are localized.\n */\n var oldIE = $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 10;\n if ( oldIE && typeof ( e.number ) != \"undefined\" && e.number == -2147024891 ) {\n msg += \"\\nSee http://msdn.microsoft.com/en-us/library/ms537505(v=vs.85).aspx#xdomain\";\n }\n\n $.console.log( \"%s while making AJAX request: %s\", e.name, msg );\n\n request.onreadystatechange = function(){};\n\n if (window.XDomainRequest) { // IE9 or IE8 might as well try to use XDomainRequest\n var xdr = new XDomainRequest();\n if (xdr) {\n xdr.onload = function (e) {\n if ( $.isFunction( onSuccess ) ) {\n onSuccess({ // Faking an xhr object\n responseText: xdr.responseText,\n status: 200, // XDomainRequest doesn't support status codes, so we just fake one! :/\n statusText: 'OK'\n });\n }\n };\n xdr.onerror = function (e) {\n if ($.isFunction(onError)) {\n onError({ // Faking an xhr object\n responseText: xdr.responseText,\n status: 444, // 444 No Response\n statusText: 'An error happened. Due to an XDomainRequest deficiency we can not extract any information about this error. Upgrade your browser.'\n });\n }\n };\n try {\n xdr.open('GET', url);\n xdr.send();\n } catch (e2) {\n if ( $.isFunction( onError ) ) {\n onError( request, e );\n }\n }\n }\n } else {\n if ( $.isFunction( onError ) ) {\n onError( request, e );\n }\n }\n }\n\n return request;\n },\n\n /**\n * Taken from jQuery 1.6.1\n * @function\n * @param {Object} options\n * @param {String} options.url\n * @param {Function} options.callback\n * @param {String} [options.param='callback'] The name of the url parameter\n * to request the jsonp provider with.\n * @param {String} [options.callbackName=] The name of the callback to\n * request the jsonp provider with.\n */\n jsonp: function( options ){\n var script,\n url = options.url,\n head = document.head ||\n document.getElementsByTagName( \"head\" )[ 0 ] ||\n document.documentElement,\n jsonpCallback = options.callbackName || 'openseadragon' + $.now(),\n previous = window[ jsonpCallback ],\n replace = \"$1\" + jsonpCallback + \"$2\",\n callbackParam = options.param || 'callback',\n callback = options.callback;\n\n url = url.replace( /(\\=)\\?(&|$)|\\?\\?/i, replace );\n // Add callback manually\n url += (/\\?/.test( url ) ? \"&\" : \"?\") + callbackParam + \"=\" + jsonpCallback;\n\n // Install callback\n window[ jsonpCallback ] = function( response ) {\n if ( !previous ){\n try{\n delete window[ jsonpCallback ];\n }catch(e){\n //swallow\n }\n } else {\n window[ jsonpCallback ] = previous;\n }\n if( callback && $.isFunction( callback ) ){\n callback( response );\n }\n };\n\n script = document.createElement( \"script\" );\n\n //TODO: having an issue with async info requests\n if( undefined !== options.async || false !== options.async ){\n script.async = \"async\";\n }\n\n if ( options.scriptCharset ) {\n script.charset = options.scriptCharset;\n }\n\n script.src = url;\n\n // Attach handlers for all browsers\n script.onload = script.onreadystatechange = function( _, isAbort ) {\n\n if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n // Handle memory leak in IE\n script.onload = script.onreadystatechange = null;\n\n // Remove the script\n if ( head && script.parentNode ) {\n head.removeChild( script );\n }\n\n // Dereference the script\n script = undefined;\n }\n };\n // Use insertBefore instead of appendChild to circumvent an IE6 bug.\n // This arises when a base node is used (#2709 and #4378).\n head.insertBefore( script, head.firstChild );\n\n },\n\n\n /**\n * Fully deprecated. Will throw an error.\n * @function\n * @deprecated use {@link OpenSeadragon.Viewer#open}\n */\n createFromDZI: function() {\n throw \"OpenSeadragon.createFromDZI is deprecated, use Viewer.open.\";\n },\n\n /**\n * Parses an XML string into a DOM Document.\n * @function\n * @param {String} string\n * @returns {Document}\n */\n parseXml: function( string ) {\n if ( window.DOMParser ) {\n\n $.parseXml = function( string ) {\n var xmlDoc = null,\n parser;\n\n parser = new DOMParser();\n xmlDoc = parser.parseFromString( string, \"text/xml\" );\n return xmlDoc;\n };\n\n } else if ( window.ActiveXObject ) {\n\n $.parseXml = function( string ) {\n var xmlDoc = null;\n\n xmlDoc = new ActiveXObject( \"Microsoft.XMLDOM\" );\n xmlDoc.async = false;\n xmlDoc.loadXML( string );\n return xmlDoc;\n };\n\n } else {\n throw new Error( \"Browser doesn't support XML DOM.\" );\n }\n\n return $.parseXml( string );\n },\n\n /**\n * Parses a JSON string into a Javascript object.\n * @function\n * @param {String} string\n * @returns {Object}\n */\n parseJSON: function(string) {\n if (window.JSON && window.JSON.parse) {\n $.parseJSON = window.JSON.parse;\n } else {\n // Should only be used by IE8 in non standards mode\n $.parseJSON = function(string) {\n /*jshint evil:true*/\n //eslint-disable-next-line no-eval\n return eval('(' + string + ')');\n };\n }\n return $.parseJSON(string);\n },\n\n /**\n * Reports whether the image format is supported for tiling in this\n * version.\n * @function\n * @param {String} [extension]\n * @returns {Boolean}\n */\n imageFormatSupported: function( extension ) {\n extension = extension ? extension : \"\";\n // eslint-disable-next-line no-use-before-define\n return !!FILEFORMATS[ extension.toLowerCase() ];\n }\n\n });\n\n\n /**\n * The current browser vendor, version, and related information regarding detected features.\n * @member {Object} Browser\n * @memberof OpenSeadragon\n * @static\n * @type {Object}\n * @property {OpenSeadragon.BROWSERS} vendor - One of the {@link OpenSeadragon.BROWSERS} enumeration values.\n * @property {Number} version\n * @property {Boolean} alpha - Does the browser support image alpha transparency.\n */\n $.Browser = {\n vendor: $.BROWSERS.UNKNOWN,\n version: 0,\n alpha: true\n };\n\n\n var FILEFORMATS = {\n \"bmp\": false,\n \"jpeg\": true,\n \"jpg\": true,\n \"png\": true,\n \"tif\": false,\n \"wdp\": false\n },\n URLPARAMS = {};\n\n (function() {\n //A small auto-executing routine to determine the browser vendor,\n //version and supporting feature sets.\n var ver = navigator.appVersion,\n ua = navigator.userAgent,\n regex;\n\n //console.error( 'appName: ' + navigator.appName );\n //console.error( 'appVersion: ' + navigator.appVersion );\n //console.error( 'userAgent: ' + navigator.userAgent );\n\n switch( navigator.appName ){\n case \"Microsoft Internet Explorer\":\n if( !!window.attachEvent &&\n !!window.ActiveXObject ) {\n\n $.Browser.vendor = $.BROWSERS.IE;\n $.Browser.version = parseFloat(\n ua.substring(\n ua.indexOf( \"MSIE\" ) + 5,\n ua.indexOf( \";\", ua.indexOf( \"MSIE\" ) ) )\n );\n }\n break;\n case \"Netscape\":\n if (window.addEventListener) {\n if ( ua.indexOf( \"Firefox\" ) >= 0 ) {n $.Browser.vendor = $.BROWSERS.FIREFOX;n $.Browser.version = parseFloat(n ua.substring( ua.indexOf( "Firefox" ) + 8 )n );n } else if ( ua.indexOf( "Safari" ) >= 0 ) {n $.Browser.vendor = ua.indexOf( "Chrome" ) >= 0 ?n $.BROWSERS.CHROME :n $.BROWSERS.SAFARI;n $.Browser.version = parseFloat(n ua.substring(n ua.substring( 0, ua.indexOf( "Safari" ) ).lastIndexOf( "/" ) + 1,n ua.indexOf( "Safari" )n )n );n } else {n regex = new RegExp( "Trident/.*rv:([0-9]{1,}[.0-9]{0,})");n if ( regex.exec( ua ) !== null ) {n $.Browser.vendor = $.BROWSERS.IE;n $.Browser.version = parseFloat( RegExp.$1 );n }n }n }n break;n case "Opera":n $.Browser.vendor = $.BROWSERS.OPERA;n $.Browser.version = parseFloat( ver );n break;n }nn // ignore '?' portion of query stringn var query = window.location.search.substring( 1 ),n parts = query.split('&'),n part,n sep,n i;nn for ( i = 0; i < parts.length; i++ ) {n part = parts[ i ];n sep = part.indexOf( '=' );nn if ( sep > 0 ) {n URLPARAMS[ part.substring( 0, sep ) ] =n decodeURIComponent( part.substring( sep + 1 ) );n }n }nn //determine if this browser supports image alpha transparencyn $.Browser.alpha = !(n (n $.Browser.vendor == $.BROWSERS.IE &&n $.Browser.version < 9n ) || (n $.Browser.vendor == $.BROWSERS.CHROME &&n $.Browser.version < 2n )n );nn //determine if this browser supports element.style.opacityn $.Browser.opacity = !(n $.Browser.vendor == $.BROWSERS.IE &&n $.Browser.version < 9n );nn })();nnn //TODO: $.console is often used inside a try/catch block which generallyn // prevents allowings errors to occur with detection until a debuggern // is attached. Although I've been guilty of the same anti-patternn // I eventually was convinced that errors should naturally propogate inn // all but the most special cases.n /**n * A convenient alias for console when available, and a simple nulln * function when console is unavailable.n * @staticn * @privaten */n var nullfunction = function( msg ){n //document.location.hash = msg;n };nn $.console = window.console || {n log: nullfunction,n debug: nullfunction,n info: nullfunction,n warn: nullfunction,n error: nullfunction,n assert: nullfunctionn };nnn // Adding support for HTML5's requestAnimationFrame as suggested by acdha.n // Implementation taken from matt synder's post here:n // mattsnider.com/cross-browser-and-legacy-supported-requestframeanimation/n (function( w ) {nn // most browsers have an implementationn var requestAnimationFrame = w.requestAnimationFrame ||n w.mozRequestAnimationFrame ||n w.webkitRequestAnimationFrame ||n w.msRequestAnimationFrame;nn var cancelAnimationFrame = w.cancelAnimationFrame ||n w.mozCancelAnimationFrame ||n w.webkitCancelAnimationFrame ||n w.msCancelAnimationFrame;nn // polyfill, when necessaryn if ( requestAnimationFrame && cancelAnimationFrame ) {n // We can't assign these window methods directly to $ because theyn // expect their "this" to be "window", so we call them in wrappers.n $.requestAnimationFrame = function(){n return requestAnimationFrame.apply( w, arguments );n };n $.cancelAnimationFrame = function(){n return cancelAnimationFrame.apply( w, arguments );n };n } else {n var aAnimQueue = [],n processing = [],n iRequestId = 0,n iIntervalId;nn // create a mock requestAnimationFrame functionn $.requestAnimationFrame = function( callback ) {n aAnimQueue.push( [ ++iRequestId, callback ] );nn if ( !iIntervalId ) {n iIntervalId = setInterval( function() {n if ( aAnimQueue.length ) {n var time = $.now();n // Process all of the currently outstanding framen // requests, but none that get added during then // processing.n // Swap the arrays so we don't have to create a newn // array every frame.n var temp = processing;n processing = aAnimQueue;n aAnimQueue = temp;n while ( processing.length ) {n processing.shift()[ 1 ]( time );n }n } else {n // don't continue the interval, if unnecessaryn clearInterval( iIntervalId );n iIntervalId = undefined;n }n }, 1000 / 50); // estimating support for 50 frames per secondn }nn return iRequestId;n };nn // create a mock cancelAnimationFrame functionn $.cancelAnimationFrame = function( requestId ) {n // find the request ID and remove itn var i, j;n for ( i = 0, j = aAnimQueue.length; i < j; i += 1 ) {n if ( aAnimQueue[ i ][ 0 ] === requestId ) {n aAnimQueue.splice( i, 1 );n return;n }n }nn // If it's not in the queue, it may be in the set we're currentlyn // processing (if cancelAnimationFrame is called from within an // requestAnimationFrame callback).n for ( i = 0, j = processing.length; i < j; i += 1 ) {n if ( processing[ i ][ 0 ] === requestId ) {n processing.splice( i, 1 );n return;n }n }n };n }n })( window );nn /**n * @privaten * @innern * @functionn * @param {Element} elementn * @param {Boolean} [isFixed]n * @returns {Element}n */n function getOffsetParent( element, isFixed ) {n if ( isFixed && element != document.body ) {n return document.body;n } else {n return element.offsetParent;n }n }nn}(OpenSeadragon));nnn// Universal Module Definition, supports CommonJS, AMD and simple script tagn(function (root, factory) {n if (typeof define === 'function' && define.amd) {n // expose as amd modulen define([], factory);n } else if (typeof module === 'object' && module.exports) {n // expose as commonjs modulen module.exports = factory();n } else {n // expose as window.OpenSeadragonn root.OpenSeadragon = factory();n }n}(this, function () {n return OpenSeadragon;n}));n”,“/*n * OpenSeadragon - full-screen support functionsn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ) {n /**n * Determine native full screen support we can get from the browser.n * @member fullScreenApin * @memberof OpenSeadragonn * @type {object}n * @property {Boolean} supportsFullScreen Return true if full screen API is supported.n * @property {Function} isFullScreen Return true if currently in full screen mode.n * @property {Function} getFullScreenElement Return the element currently in full screen mode.n * @property {Function} requestFullScreen Make a request to go in full screen mode.n * @property {Function} exitFullScreen Make a request to exit full screen mode.n * @property {Function} cancelFullScreen Deprecated, use exitFullScreen instead.n * @property {String} fullScreenEventName Event fired when the full screen mode change.n * @property {String} fullScreenErrorEventName Event fired when a request to gon * in full screen mode failed.n */n var fullScreenApi = {n supportsFullScreen: false,n isFullScreen: function() { return false; },n getFullScreenElement: function() { return null; },n requestFullScreen: function() {},n exitFullScreen: function() {},n cancelFullScreen: function() {},n fullScreenEventName: '',n fullScreenErrorEventName: ''n };nn // check for native supportn if ( document.exitFullscreen ) {n // W3C standardn fullScreenApi.supportsFullScreen = true;n fullScreenApi.getFullScreenElement = function() {n return document.fullscreenElement;n };n fullScreenApi.requestFullScreen = function( element ) {n return element.requestFullscreen();n };n fullScreenApi.exitFullScreen = function() {n document.exitFullscreen();n };n fullScreenApi.fullScreenEventName = "fullscreenchange";n fullScreenApi.fullScreenErrorEventName = "fullscreenerror";n } else if ( document.msExitFullscreen ) {n // IE 11n fullScreenApi.supportsFullScreen = true;n fullScreenApi.getFullScreenElement = function() {n return document.msFullscreenElement;n };n fullScreenApi.requestFullScreen = function( element ) {n return element.msRequestFullscreen();n };n fullScreenApi.exitFullScreen = function() {n document.msExitFullscreen();n };n fullScreenApi.fullScreenEventName = "MSFullscreenChange";n fullScreenApi.fullScreenErrorEventName = "MSFullscreenError";n } else if ( document.webkitExitFullscreen ) {n // Recent webkitn fullScreenApi.supportsFullScreen = true;n fullScreenApi.getFullScreenElement = function() {n return document.webkitFullscreenElement;n };n fullScreenApi.requestFullScreen = function( element ) {n return element.webkitRequestFullscreen();n };n fullScreenApi.exitFullScreen = function() {n document.webkitExitFullscreen();n };n fullScreenApi.fullScreenEventName = "webkitfullscreenchange";n fullScreenApi.fullScreenErrorEventName = "webkitfullscreenerror";n } else if ( document.webkitCancelFullScreen ) {n // Old webkitn fullScreenApi.supportsFullScreen = true;n fullScreenApi.getFullScreenElement = function() {n return document.webkitCurrentFullScreenElement;n };n fullScreenApi.requestFullScreen = function( element ) {n return element.webkitRequestFullScreen();n };n fullScreenApi.exitFullScreen = function() {n document.webkitCancelFullScreen();n };n fullScreenApi.fullScreenEventName = "webkitfullscreenchange";n fullScreenApi.fullScreenErrorEventName = "webkitfullscreenerror";n } else if ( document.mozCancelFullScreen ) {n // Firefoxn fullScreenApi.supportsFullScreen = true;n fullScreenApi.getFullScreenElement = function() {n return document.mozFullScreenElement;n };n fullScreenApi.requestFullScreen = function( element ) {n return element.mozRequestFullScreen();n };n fullScreenApi.exitFullScreen = function() {n document.mozCancelFullScreen();n };n fullScreenApi.fullScreenEventName = "mozfullscreenchange";n fullScreenApi.fullScreenErrorEventName = "mozfullscreenerror";n }n fullScreenApi.isFullScreen = function() {n return fullScreenApi.getFullScreenElement() !== null;n };n fullScreenApi.cancelFullScreen = function() {n $.console.error("cancelFullScreen is deprecated. Use exitFullScreen instead.");n fullScreenApi.exitFullScreen();n };nn // export apin $.extend( $, fullScreenApi );nn})( OpenSeadragon );n”,“/*n * OpenSeadragon - EventSourcen *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function($){nn/**n * Event handler method signature used by all OpenSeadragon events.n *n * @callback EventHandlern * @memberof OpenSeadragonn * @param {Object} event - See individual events for event-specific properties.n */nnn/**n * @class EventSourcen * @classdesc For use by classes which want to support custom, non-browser events.n *n * @memberof OpenSeadragonn */n$.EventSource = function() {n this.events = {};n};nn/** @lends OpenSeadragon.EventSource.prototype */n$.EventSource.prototype = {nn /**n * Add an event handler to be triggered only once (or a given number of times)n * for a given event.n * @functionn * @param {String} eventName - Name of event to register.n * @param {OpenSeadragon.EventHandler} handler - Function to call when eventn * is triggered.n * @param {Object} [userData=null] - Arbitrary object to be passed unchangedn * to the handler.n * @param {Number} [times=1] - The number of times to handle the eventn * before removing it.n */n addOnceHandler: function(eventName, handler, userData, times) {n var self = this;n times = times || 1;n var count = 0;n var onceHandler = function(event) {n count++;n if (count === times) {n self.removeHandler(eventName, onceHandler);n }n handler(event);n };n this.addHandler(eventName, onceHandler, userData);n },nn /**n * Add an event handler for a given event.n * @functionn * @param {String} eventName - Name of event to register.n * @param {OpenSeadragon.EventHandler} handler - Function to call when event is triggered.n * @param {Object} [userData=null] - Arbitrary object to be passed unchanged to the handler.n */n addHandler: function ( eventName, handler, userData ) {n var events = this.events[ eventName ];n if ( !events ) {n this.events[ eventName ] = events = [];n }n if ( handler && $.isFunction( handler ) ) {n events[ events.length ] = { handler: handler, userData: userData || null };n }n },nn /**n * Remove a specific event handler for a given event.n * @functionn * @param {String} eventName - Name of event for which the handler is to be removed.n * @param {OpenSeadragon.EventHandler} handler - Function to be removed.n */n removeHandler: function ( eventName, handler ) {n var events = this.events[ eventName ],n handlers = [],n i;n if ( !events ) {n return;n }n if ( $.isArray( events ) ) {n for ( i = 0; i < events.length; i++ ) {n if ( events.handler !== handler ) {n handlers.push( events[ i ] );n }n }n this.events[ eventName ] = handlers;n }n },nnn /**n * Remove all event handlers for a given event type. If no type is given alln * event handlers for every event type are removed.n * @functionn * @param {String} eventName - Name of event for which all handlers are to be removed.n */n removeAllHandlers: function( eventName ) {n if ( eventName ){n this.events[ eventName ] = [];n } else{n for ( var eventType in this.events ) {n this.events[ eventType ] = [];n }n }n },nn /**n * Get a function which iterates the list of all handlers registered for a given event, calling the handler for each.n * @functionn * @param {String} eventName - Name of event to get handlers for.n */n getHandler: function ( eventName ) {n var events = this.events[ eventName ];n if ( !events || !events.length ) {n return null;n }n events = events.length === 1 ?n [ events[ 0 ] ] :n Array.apply( null, events );n return function ( source, args ) {n var i,n length = events.length;n for ( i = 0; i < length; i++ ) {n if ( events[ i ] ) {n args.eventSource = source;n args.userData = events[ i ].userData;n events[ i ].handler( args );n }n }n };n },nn /**n * Trigger an event, optionally passing additional information.n * @functionn * @param {String} eventName - Name of event to register.n * @param {Object} eventArgs - Event-specific data.n */n raiseEvent: function( eventName, eventArgs ) {n //uncomment if you want to get a log of all eventsn //$.console.log( eventName );n var handler = this.getHandler( eventName );nn if ( handler ) {n if ( !eventArgs ) {n eventArgs = {};n }nn handler( this, eventArgs );n }n }n};nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - MouseTrackern *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function ( $ ) {nn // All MouseTracker instancesn var MOUSETRACKERS = [];nn // dictionary from hash to private propertiesn var THIS = {};nnn /**n * @class MouseTrackern * @classdesc Provides simplified handling of common pointer device (mouse, touch, pen, etc.) gesturesn * and keyboard events on a specified element.n * @memberof OpenSeadragonn * @param {Object} optionsn * Allows configurable properties to be entirely specified by passingn * an options object to the constructor. The constructor also supportsn * the original positional arguments 'element', 'clickTimeThreshold',n * and 'clickDistThreshold' in that order.n * @param {Element|String} options.elementn * A reference to an element or an element id for which the pointer/keyn * events will be monitored.n * @param {Boolean} [options.startDisabled=false]n * If true, event tracking on the element will not start untiln * {@link OpenSeadragon.MouseTracker.setTracking|setTracking} is called.n * @param {Number} options.clickTimeThresholdn * The number of milliseconds within which a pointer down-up event combinationn * will be treated as a click gesture.n * @param {Number} options.clickDistThresholdn * The maximum distance allowed between a pointer down event and a pointer up eventn * to be treated as a click gesture.n * @param {Number} options.dblClickTimeThresholdn * The number of milliseconds within which two pointer down-up event combinationsn * will be treated as a double-click gesture.n * @param {Number} options.dblClickDistThresholdn * The maximum distance allowed between two pointer click eventsn * to be treated as a click gesture.n * @param {Number} [options.stopDelay=50]n * The number of milliseconds without pointer move before the stopn * event is fired.n * @param {OpenSeadragon.EventHandler} [options.enterHandler=null]n * An optional handler for pointer enter.n * @param {OpenSeadragon.EventHandler} [options.exitHandler=null]n * An optional handler for pointer exit.n * @param {OpenSeadragon.EventHandler} [options.pressHandler=null]n * An optional handler for pointer press.n * @param {OpenSeadragon.EventHandler} [options.nonPrimaryPressHandler=null]n * An optional handler for pointer non-primary button press.n * @param {OpenSeadragon.EventHandler} [options.releaseHandler=null]n * An optional handler for pointer release.n * @param {OpenSeadragon.EventHandler} [options.nonPrimaryReleaseHandler=null]n * An optional handler for pointer non-primary button release.n * @param {OpenSeadragon.EventHandler} [options.moveHandler=null]n * An optional handler for pointer move.n * @param {OpenSeadragon.EventHandler} [options.scrollHandler=null]n * An optional handler for mouse wheel scroll.n * @param {OpenSeadragon.EventHandler} [options.clickHandler=null]n * An optional handler for pointer click.n * @param {OpenSeadragon.EventHandler} [options.dblClickHandler=null]n * An optional handler for pointer double-click.n * @param {OpenSeadragon.EventHandler} [options.dragHandler=null]n * An optional handler for the drag gesture.n * @param {OpenSeadragon.EventHandler} [options.dragEndHandler=null]n * An optional handler for after a drag gesture.n * @param {OpenSeadragon.EventHandler} [options.pinchHandler=null]n * An optional handler for the pinch gesture.n * @param {OpenSeadragon.EventHandler} [options.keyDownHandler=null]n * An optional handler for keydown.n * @param {OpenSeadragon.EventHandler} [options.keyUpHandler=null]n * An optional handler for keyup.n * @param {OpenSeadragon.EventHandler} [options.keyHandler=null]n * An optional handler for keypress.n * @param {OpenSeadragon.EventHandler} [options.focusHandler=null]n * An optional handler for focus.n * @param {OpenSeadragon.EventHandler} [options.blurHandler=null]n * An optional handler for blur.n * @param {Object} [options.userData=null]n * Arbitrary object to be passed unchanged to any attached handler methods.n */n $.MouseTracker = function ( options ) {nn MOUSETRACKERS.push( this );nn var args = arguments;nn if ( !$.isPlainObject( options ) ) {n options = {n element: args[ 0 ],n clickTimeThreshold: args[ 1 ],n clickDistThreshold: args[ 2 ]n };n }nn this.hash = Math.random(); // An unique hash for this tracker.n /**n * The element for which pointer events are being monitored.n * @member {Element} elementn * @memberof OpenSeadragon.MouseTracker#n */n this.element = $.getElement( options.element );n /**n * The number of milliseconds within which a pointer down-up event combinationn * will be treated as a click gesture.n * @member {Number} clickTimeThresholdn * @memberof OpenSeadragon.MouseTracker#n */n this.clickTimeThreshold = options.clickTimeThreshold || $.DEFAULT_SETTINGS.clickTimeThreshold;n /**n * The maximum distance allowed between a pointer down event and a pointer up eventn * to be treated as a click gesture.n * @member {Number} clickDistThresholdn * @memberof OpenSeadragon.MouseTracker#n */n this.clickDistThreshold = options.clickDistThreshold || $.DEFAULT_SETTINGS.clickDistThreshold;n /**n * The number of milliseconds within which two pointer down-up event combinationsn * will be treated as a double-click gesture.n * @member {Number} dblClickTimeThresholdn * @memberof OpenSeadragon.MouseTracker#n */n this.dblClickTimeThreshold = options.dblClickTimeThreshold || $.DEFAULT_SETTINGS.dblClickTimeThreshold;n /**n * The maximum distance allowed between two pointer click eventsn * to be treated as a click gesture.n * @member {Number} clickDistThresholdn * @memberof OpenSeadragon.MouseTracker#n */n this.dblClickDistThreshold = options.dblClickDistThreshold || $.DEFAULT_SETTINGS.dblClickDistThreshold;n /*eslint-disable no-multi-spaces*/n this.userData = options.userData || null;n this.stopDelay = options.stopDelay || 50;nn this.enterHandler = options.enterHandler || null;n this.exitHandler = options.exitHandler || null;n this.pressHandler = options.pressHandler || null;n this.nonPrimaryPressHandler = options.nonPrimaryPressHandler || null;n this.releaseHandler = options.releaseHandler || null;n this.nonPrimaryReleaseHandler = options.nonPrimaryReleaseHandler || null;n this.moveHandler = options.moveHandler || null;n this.scrollHandler = options.scrollHandler || null;n this.clickHandler = options.clickHandler || null;n this.dblClickHandler = options.dblClickHandler || null;n this.dragHandler = options.dragHandler || null;n this.dragEndHandler = options.dragEndHandler || null;n this.pinchHandler = options.pinchHandler || null;n this.stopHandler = options.stopHandler || null;n this.keyDownHandler = options.keyDownHandler || null;n this.keyUpHandler = options.keyUpHandler || null;n this.keyHandler = options.keyHandler || null;n this.focusHandler = options.focusHandler || null;n this.blurHandler = options.blurHandler || null;n /*eslint-enable no-multi-spaces*/nn //Store private properties in a scope sealed hash mapn var _this = this;nn /**n * @privaten * @property {Boolean} trackingn * Are we currently tracking pointer events for this element.n */n THIS[ this.hash ] = {n click: function ( event ) { onClick( _this, event ); },n dblclick: function ( event ) { onDblClick( _this, event ); },n keydown: function ( event ) { onKeyDown( _this, event ); },n keyup: function ( event ) { onKeyUp( _this, event ); },n keypress: function ( event ) { onKeyPress( _this, event ); },n focus: function ( event ) { onFocus( _this, event ); },n blur: function ( event ) { onBlur( _this, event ); },nn wheel: function ( event ) { onWheel( _this, event ); },n mousewheel: function ( event ) { onMouseWheel( _this, event ); },n DOMMouseScroll: function ( event ) { onMouseWheel( _this, event ); },n MozMousePixelScroll: function ( event ) { onMouseWheel( _this, event ); },nn mouseenter: function ( event ) { onMouseEnter( _this, event ); }, // Used on IE8 onlyn mouseleave: function ( event ) { onMouseLeave( _this, event ); }, // Used on IE8 onlyn mouseover: function ( event ) { onMouseOver( _this, event ); },n mouseout: function ( event ) { onMouseOut( _this, event ); },n mousedown: function ( event ) { onMouseDown( _this, event ); },n mouseup: function ( event ) { onMouseUp( _this, event ); },n mouseupcaptured: function ( event ) { onMouseUpCaptured( _this, event ); },n mousemove: function ( event ) { onMouseMove( _this, event ); },n mousemovecaptured: function ( event ) { onMouseMoveCaptured( _this, event ); },nn touchstart: function ( event ) { onTouchStart( _this, event ); },n touchend: function ( event ) { onTouchEnd( _this, event ); },n touchendcaptured: function ( event ) { onTouchEndCaptured( _this, event ); },n touchmove: function ( event ) { onTouchMove( _this, event ); },n touchmovecaptured: function ( event ) { onTouchMoveCaptured( _this, event ); },n touchcancel: function ( event ) { onTouchCancel( _this, event ); },nn gesturestart: function ( event ) { onGestureStart( _this, event ); },n gesturechange: function ( event ) { onGestureChange( _this, event ); },nn pointerover: function ( event ) { onPointerOver( _this, event ); },n MSPointerOver: function ( event ) { onPointerOver( _this, event ); },n pointerout: function ( event ) { onPointerOut( _this, event ); },n MSPointerOut: function ( event ) { onPointerOut( _this, event ); },n pointerdown: function ( event ) { onPointerDown( _this, event ); },n MSPointerDown: function ( event ) { onPointerDown( _this, event ); },n pointerup: function ( event ) { onPointerUp( _this, event ); },n MSPointerUp: function ( event ) { onPointerUp( _this, event ); },n pointermove: function ( event ) { onPointerMove( _this, event ); },n MSPointerMove: function ( event ) { onPointerMove( _this, event ); },n pointercancel: function ( event ) { onPointerCancel( _this, event ); },n MSPointerCancel: function ( event ) { onPointerCancel( _this, event ); },n pointerupcaptured: function ( event ) { onPointerUpCaptured( _this, event ); },n pointermovecaptured: function ( event ) { onPointerMoveCaptured( _this, event ); },nn tracking: false,nn // Active pointers lists. Array of GesturePointList objects, one for each pointer device type.n // GesturePointList objects are added each time a pointer is tracked by a new pointer device type (see getActivePointersListByType()).n // Active pointers are any pointer being tracked for this element which are in the hit-test arean // of the element (for hover-capable devices) and/or have contact or a button press initiated in the element.n activePointersLists: [],nn // Tracking for double-click gesturen lastClickPos: null,n dblClickTimeOut: null,nn // Tracking for pinch gesturen pinchGPoints: [],n lastPinchDist: 0,n currentPinchDist: 0,n lastPinchCenter: null,n currentPinchCenter: nulln };nn if ( !options.startDisabled ) {n this.setTracking( true );n }n };nn /** @lends OpenSeadragon.MouseTracker.prototype */n $.MouseTracker.prototype = {nn /**n * Clean up any events or objects created by the tracker.n * @functionn */n destroy: function () {n var i;nn stopTracking( this );n this.element = null;nn for ( i = 0; i < MOUSETRACKERS.length; i++ ) {n if ( MOUSETRACKERS[ i ] === this ) {n MOUSETRACKERS.splice( i, 1 );n break;n }n }nn THIS[ this.hash ] = null;n delete THIS[ this.hash ];n },nn /**n * Are we currently tracking events on this element.n * @deprecated Just use this.trackingn * @functionn * @returns {Boolean} Are we currently tracking events on this element.n */n isTracking: function () {n return THIS[ this.hash ].tracking;n },nn /**n * Enable or disable whether or not we are tracking events on this element.n * @functionn * @param {Boolean} track True to start tracking, false to stop tracking.n * @returns {OpenSeadragon.MouseTracker} Chainable.n */n setTracking: function ( track ) {n if ( track ) {n startTracking( this );n } else {n stopTracking( this );n }n //chainn return this;n },nn /**n * Returns the {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} for all but the given pointer device type.n * @functionn * @param {String} type - The pointer device type: "mouse", "touch", "pen", etc.n * @returns {Array.<OpenSeadragon.MouseTracker.GesturePointList>}n */n getActivePointersListsExceptType: function ( type ) {n var delegate = THIS[ this.hash ];n var listArray = [];nn for (var i = 0; i < delegate.activePointersLists.length; ++i) {n if (delegate.activePointersLists.type !== type) {n listArray.push(delegate.activePointersLists);n }n }nn return listArray;n },nn /**n * Returns the {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} for the given pointer device type,n * creating and caching a new {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} if one doesn't already exist for the type.n * @functionn * @param {String} type - The pointer device type: "mouse", "touch", "pen", etc.n * @returns {OpenSeadragon.MouseTracker.GesturePointList}n */n getActivePointersListByType: function ( type ) {n var delegate = THIS[ this.hash ],n i,n len = delegate.activePointersLists.length,n list;nn for ( i = 0; i < len; i++ ) {n if ( delegate.activePointersLists[ i ].type === type ) {n return delegate.activePointersLists[ i ];n }n }nn list = new $.MouseTracker.GesturePointList( type );n delegate.activePointersLists.push( list );n return list;n },nn /**n * Returns the total number of pointers currently active on the tracked element.n * @functionn * @returns {Number}n */n getActivePointerCount: function () {n var delegate = THIS[ this.hash ],n i,n len = delegate.activePointersLists.length,n count = 0;nn for ( i = 0; i < len; i++ ) {n count += delegate.activePointersLists[ i ].getLength();n }nn return count;n },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Number} event.buttonsn * Current buttons pressed.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @param {Number} event.pointersn * Number of pointers (all types) active in the tracked element.n * @param {Boolean} event.insideElementPressedn * True if the left mouse button is currently being pressed and wasn * initiated inside the tracked element, otherwise false.n * @param {Boolean} event.buttonDownAnyn * Was the button down anywhere in the screen during the event. <span style="color:red;">Deprecated. Use buttons instead.</span>n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n enterHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Number} event.buttonsn * Current buttons pressed.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @param {Number} event.pointersn * Number of pointers (all types) active in the tracked element.n * @param {Boolean} event.insideElementPressedn * True if the left mouse button is currently being pressed and wasn * initiated inside the tracked element, otherwise false.n * @param {Boolean} event.buttonDownAnyn * Was the button down anywhere in the screen during the event. <span style="color:red;">Deprecated. Use buttons instead.</span>n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n exitHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Number} event.buttonsn * Current buttons pressed.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n pressHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Number} event.buttonn * Button which caused the event.n * -1: none, 0: primary/left, 1: aux/middle, 2: secondary/right, 3: X1/back, 4: X2/forward, 5: pen eraser.n * @param {Number} event.buttonsn * Current buttons pressed.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n nonPrimaryPressHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Number} event.buttonsn * Current buttons pressed.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @param {Boolean} event.insideElementPressedn * True if the left mouse button is currently being pressed and wasn * initiated inside the tracked element, otherwise false.n * @param {Boolean} event.insideElementReleasedn * True if the cursor inside the tracked element when the button was released.n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n releaseHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Number} event.buttonn * Button which caused the event.n * -1: none, 0: primary/left, 1: aux/middle, 2: secondary/right, 3: X1/back, 4: X2/forward, 5: pen eraser.n * @param {Number} event.buttonsn * Current buttons pressed.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n nonPrimaryReleaseHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Number} event.buttonsn * Current buttons pressed.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n moveHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Number} event.scrolln * The scroll delta for the event.n * @param {Boolean} event.shiftn * True if the shift key was pressed during this event.n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead. Touch devices no longer generate scroll event.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n scrollHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Boolean} event.quickn * True only if the clickDistThreshold and clickTimeThreshold are both passed. Useful for ignoring drag events.n * @param {Boolean} event.shiftn * True if the shift key was pressed during this event.n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n clickHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Boolean} event.shiftn * True if the shift key was pressed during this event.n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n dblClickHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Number} event.buttonsn * Current buttons pressed.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @param {OpenSeadragon.Point} event.deltan * The x,y components of the difference between the current position and the last drag event position. Useful for ignoring or weighting the events.n * @param {Number} event.speedn * Current computed speed, in pixels per second.n * @param {Number} event.directionn * Current computed direction, expressed as an angle counterclockwise relative to the positive X axis (-pi to pi, in radians). Only valid if speed > 0.n * @param {Boolean} event.shiftn * True if the shift key was pressed during this event.n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n dragHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Number} event.speedn * Speed at the end of a drag gesture, in pixels per second.n * @param {Number} event.directionn * Direction at the end of a drag gesture, expressed as an angle counterclockwise relative to the positive X axis (-pi to pi, in radians). Only valid if speed > 0.n * @param {Boolean} event.shiftn * True if the shift key was pressed during this event.n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n dragEndHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {Array.<OpenSeadragon.MouseTracker.GesturePoint>} event.gesturePointsn * Gesture points associated with the gesture. Velocity data can be found here.n * @param {OpenSeadragon.Point} event.lastCentern * The previous center point of the two pinch contact points relative to the tracked element.n * @param {OpenSeadragon.Point} event.centern * The center point of the two pinch contact points relative to the tracked element.n * @param {Number} event.lastDistancen * The previous distance between the two pinch contact points in CSS pixels.n * @param {Number} event.distancen * The distance between the two pinch contact points in CSS pixels.n * @param {Boolean} event.shiftn * True if the shift key was pressed during this event.n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n pinchHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {String} event.pointerTypen * "mouse", "touch", "pen", etc.n * @param {OpenSeadragon.Point} event.positionn * The position of the event relative to the tracked element.n * @param {Number} event.buttonsn * Current buttons pressed.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @param {Boolean} event.isTouchEventn * True if the original event is a touch event, otherwise false. <span style="color:red;">Deprecated. Use pointerType and/or originalEvent instead.</span>n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n stopHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {Number} event.keyCoden * The key code that was pressed.n * @param {Boolean} event.ctrln * True if the ctrl key was pressed during this event.n * @param {Boolean} event.shiftn * True if the shift key was pressed during this event.n * @param {Boolean} event.altn * True if the alt key was pressed during this event.n * @param {Boolean} event.metan * True if the meta key was pressed during this event.n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n keyDownHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {Number} event.keyCoden * The key code that was pressed.n * @param {Boolean} event.ctrln * True if the ctrl key was pressed during this event.n * @param {Boolean} event.shiftn * True if the shift key was pressed during this event.n * @param {Boolean} event.altn * True if the alt key was pressed during this event.n * @param {Boolean} event.metan * True if the meta key was pressed during this event.n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n keyUpHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {Number} event.keyCoden * The key code that was pressed.n * @param {Boolean} event.ctrln * True if the ctrl key was pressed during this event.n * @param {Boolean} event.shiftn * True if the shift key was pressed during this event.n * @param {Boolean} event.altn * True if the alt key was pressed during this event.n * @param {Boolean} event.metan * True if the meta key was pressed during this event.n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n keyHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n focusHandler: function () { },nn /**n * Implement or assign implementation to these handlers during or aftern * calling the constructor.n * @functionn * @param {Object} eventn * @param {OpenSeadragon.MouseTracker} event.eventSourcen * A reference to the tracker instance.n * @param {Object} event.originalEventn * The original event object.n * @param {Boolean} event.preventDefaultActionn * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.n * @param {Object} event.userDatan * Arbitrary user-defined object.n */n blurHandler: function () { }n };nn /**n * Resets all active mousetrakers. (Added to patch issue #697 "Mouse up outside map will cause "canvas-drag" event to stick")n *n * @privaten * @member resetAllMouseTrackersn * @memberof OpenSeadragon.MouseTrackern */n $.MouseTracker.resetAllMouseTrackers = function(){n for(var i = 0; i < MOUSETRACKERS.length; i++){n if (MOUSETRACKERS.isTracking()){n MOUSETRACKERS.setTracking(false);n MOUSETRACKERS.setTracking(true);n }n }n };nn /**n * Provides continuous computation of velocity (speed and direction) of active pointers.n * This is a singleton, used by all MouseTracker instances, as it is unlikely there will ever be more thann * two active gesture pointers at a time.n *n * @privaten * @member gesturePointVelocityTrackern * @memberof OpenSeadragon.MouseTrackern */n $.MouseTracker.gesturePointVelocityTracker = (function () {n var trackerPoints = [],n intervalId = 0,n lastTime = 0;nn // Generates a unique identifier for a tracked gesture pointn var _generateGuid = function ( tracker, gPoint ) {n return tracker.hash.toString() + gPoint.type + gPoint.id.toString();n };nn // Interval timer callback. Computes velocity for all tracked gesture points.n var _doTracking = function () {n var i,n len = trackerPoints.length,n trackPoint,n gPoint,n now = $.now(),n elapsedTime,n distance,n speed;nn elapsedTime = now - lastTime;n lastTime = now;nn for ( i = 0; i < len; i++ ) {n trackPoint = trackerPoints[ i ];n gPoint = trackPoint.gPoint;n // Math.atan2 gives us just what we need for a velocity vector, as we can simplyn // use cos()/sin() to extract the x/y velocity components.n gPoint.direction = Math.atan2( gPoint.currentPos.y - trackPoint.lastPos.y, gPoint.currentPos.x - trackPoint.lastPos.x );n // speed = distance / elapsed timen distance = trackPoint.lastPos.distanceTo( gPoint.currentPos );n trackPoint.lastPos = gPoint.currentPos;n speed = 1000 * distance / ( elapsedTime + 1 );n // Simple biased average, favors the most recent speed computation. Smooths out erratic gestures a bit.n gPoint.speed = 0.75 * speed + 0.25 * gPoint.speed;n }n };nn // Public. Add a gesture point to be trackedn var addPoint = function ( tracker, gPoint ) {n var guid = _generateGuid( tracker, gPoint );nn trackerPoints.push(n {n guid: guid,n gPoint: gPoint,n lastPos: gPoint.currentPosn } );nn // Only fire up the interval timer when there's gesture pointers to trackn if ( trackerPoints.length === 1 ) {n lastTime = $.now();n intervalId = window.setInterval( _doTracking, 50 );n }n };nn // Public. Stop tracking a gesture pointn var removePoint = function ( tracker, gPoint ) {n var guid = _generateGuid( tracker, gPoint ),n i,n len = trackerPoints.length;n for ( i = 0; i < len; i++ ) {n if ( trackerPoints[ i ].guid === guid ) {n trackerPoints.splice( i, 1 );n // Only run the interval timer if theres gesture pointers to trackn len–;n if ( len === 0 ) {n window.clearInterval( intervalId );n }n break;n }n }n };nn return {n addPoint: addPoint,n removePoint: removePointn };n } )();nnn///////////////////////////////////////////////////////////////////////////////n// Pointer event model and feature detectionn///////////////////////////////////////////////////////////////////////////////nn $.MouseTracker.captureElement = document;nn /**n * Detect available mouse wheel event name.n */n $.MouseTracker.wheelEventName = ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version > 8 ) ||n ( 'onwheel' in document.createElement( 'div' ) ) ? 'wheel' : // Modern browsers support 'wheel'n document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least 'mousewheel'n 'DOMMouseScroll'; // Assume old Firefoxnn /**n * Detect legacy mouse capture support.n */n $.MouseTracker.supportsMouseCapture = (function () {n var divElement = document.createElement( 'div' );n return $.isFunction( divElement.setCapture ) && $.isFunction( divElement.releaseCapture );n }());nn /**n * Detect browser pointer device event model(s) and build appropriate list of events to subscribe to.n */n $.MouseTracker.subscribeEvents = [ "click", "dblclick", "keydown", "keyup", "keypress", "focus", "blur", $.MouseTracker.wheelEventName ];nn if( $.MouseTracker.wheelEventName == "DOMMouseScroll" ) {n // Older Firefoxn $.MouseTracker.subscribeEvents.push( "MozMousePixelScroll" );n }nn // Note: window.navigator.pointerEnable is deprecated on IE 11 and not part of W3C spec.n if ( window.PointerEvent && ( window.navigator.pointerEnabled || $.Browser.vendor !== $.BROWSERS.IE ) ) {n // IE11 and other W3C Pointer Event implementations (see www.w3.org/TR/pointerevents)n $.MouseTracker.havePointerEvents = true;n $.MouseTracker.subscribeEvents.push( "pointerover", "pointerout", "pointerdown", "pointerup", "pointermove", "pointercancel" );n $.MouseTracker.unprefixedPointerEvents = true;n if( navigator.maxTouchPoints ) {n $.MouseTracker.maxTouchPoints = navigator.maxTouchPoints;n } else {n $.MouseTracker.maxTouchPoints = 0;n }n $.MouseTracker.haveMouseEnter = false;n } else if ( window.MSPointerEvent && window.navigator.msPointerEnabled ) {n // IE10n $.MouseTracker.havePointerEvents = true;n $.MouseTracker.subscribeEvents.push( "MSPointerOver", "MSPointerOut", "MSPointerDown", "MSPointerUp", "MSPointerMove", "MSPointerCancel" );n $.MouseTracker.unprefixedPointerEvents = false;n if( navigator.msMaxTouchPoints ) {n $.MouseTracker.maxTouchPoints = navigator.msMaxTouchPoints;n } else {n $.MouseTracker.maxTouchPoints = 0;n }n $.MouseTracker.haveMouseEnter = false;n } else {n // Legacy W3C mouse eventsn $.MouseTracker.havePointerEvents = false;n if ( $.Browser.vendor === $.BROWSERS.IE && $.Browser.version < 9 ) {n $.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" );n $.MouseTracker.haveMouseEnter = true;n } else {n $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" );n $.MouseTracker.haveMouseEnter = false;n }n $.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" );n if ( 'ontouchstart' in window ) {n // iOS, Android, and other W3c Touch Event implementationsn // (see www.w3.org/TR/touch-events/)n // (see developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html)n // (see developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html)n $.MouseTracker.subscribeEvents.push( "touchstart", "touchend", "touchmove", "touchcancel" );n }n if ( 'ongesturestart' in window ) {n // iOS (see developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html)n // Subscribe to these to prevent default gesture handlingn $.MouseTracker.subscribeEvents.push( "gesturestart", "gesturechange" );n }n $.MouseTracker.mousePointerId = "legacy-mouse";n $.MouseTracker.maxTouchPoints = 10;n }nnn///////////////////////////////////////////////////////////////////////////////n// Classes and typedefsn///////////////////////////////////////////////////////////////////////////////nn /**n * Represents a point of contact on the screen made by a mouse cursor, pen, touch, or other pointer device.n *n * @typedef {Object} GesturePointn * @memberof OpenSeadragon.MouseTrackern *n * @property {Number} idn * Identifier unique from all other active GesturePoints for a given pointer device.n * @property {String} typen * The pointer device type: "mouse", "touch", "pen", etc.n * @property {Boolean} capturedn * True if events for the gesture point are captured to the tracked element.n * @property {Boolean} isPrimaryn * True if the gesture point is a master pointer amongst the set of active pointers for each pointer type. True for mouse and primary (first) touch/pen pointers.n * @property {Boolean} insideElementPressedn * True if button pressed or contact point initiated inside the screen area of the tracked element.n * @property {Boolean} insideElementn * True if pointer or contact point is currently inside the bounds of the tracked element.n * @property {Number} speedn * Current computed speed, in pixels per second.n * @property {Number} directionn * Current computed direction, expressed as an angle counterclockwise relative to the positive X axis (-pi to pi, in radians). Only valid if speed > 0.n * @property {OpenSeadragon.Point} contactPosn * The initial pointer contact position, relative to the page including any scrolling. Only valid if the pointer has contact (pressed, touch contact, pen contact).n * @property {Number} contactTimen * The initial pointer contact time, in milliseconds. Only valid if the pointer has contact (pressed, touch contact, pen contact).n * @property {OpenSeadragon.Point} lastPosn * The last pointer position, relative to the page including any scrolling.n * @property {Number} lastTimen * The last pointer contact time, in milliseconds.n * @property {OpenSeadragon.Point} currentPosn * The current pointer position, relative to the page including any scrolling.n * @property {Number} currentTimen * The current pointer contact time, in milliseconds.n */nnn /**n * @class GesturePointListn * @classdesc Provides an abstraction for a set of active {@link OpenSeadragon.MouseTracker.GesturePoint|GesturePoint} objects for a given pointer device type.n * Active pointers are any pointer being tracked for this element which are in the hit-test arean * of the element (for hover-capable devices) and/or have contact or a button press initiated in the element.n * @memberof OpenSeadragon.MouseTrackern * @param {String} type - The pointer device type: "mouse", "touch", "pen", etc.n */n $.MouseTracker.GesturePointList = function ( type ) {n this._gPoints = [];n /**n * The pointer device type: "mouse", "touch", "pen", etc.n * @member {String} typen * @memberof OpenSeadragon.MouseTracker.GesturePointList#n */n this.type = type;n /**n * Current buttons pressed for the device.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @member {Number} buttonsn * @memberof OpenSeadragon.MouseTracker.GesturePointList#n */n this.buttons = 0;n /**n * Current number of contact points (touch points, mouse down, etc.) for the device.n * @member {Number} contactsn * @memberof OpenSeadragon.MouseTracker.GesturePointList#n */n this.contacts = 0;n /**n * Current number of clicks for the device. Used for multiple click gesture tracking.n * @member {Number} clicksn * @memberof OpenSeadragon.MouseTracker.GesturePointList#n */n this.clicks = 0;n /**n * Current number of captured pointers for the device.n * @member {Number} captureCountn * @memberof OpenSeadragon.MouseTracker.GesturePointList#n */n this.captureCount = 0;n };nn /** @lends OpenSeadragon.MouseTracker.GesturePointList.prototype */n $.MouseTracker.GesturePointList.prototype = {n /**n * @functionn * @returns {Number} Number of gesture points in the list.n */n getLength: function () {n return this._gPoints.length;n },n /**n * @functionn * @returns {Array.<OpenSeadragon.MouseTracker.GesturePoint>} The list of gesture points in the list as an array (read-only).n */n asArray: function () {n return this._gPoints;n },n /**n * @functionn * @param {OpenSeadragon.MouseTracker.GesturePoint} gesturePoint - A gesture point to add to the list.n * @returns {Number} Number of gesture points in the list.n */n add: function ( gp ) {n return this._gPoints.push( gp );n },n /**n * @functionn * @param {Number} id - The id of the gesture point to remove from the list.n * @returns {Number} Number of gesture points in the list.n */n removeById: function ( id ) {n var i,n len = this._gPoints.length;n for ( i = 0; i < len; i++ ) {n if ( this._gPoints[ i ].id === id ) {n this._gPoints.splice( i, 1 );n break;n }n }n return this._gPoints.length;n },n /**n * @functionn * @param {Number} index - The index of the gesture point to retrieve from the list.n * @returns {OpenSeadragon.MouseTracker.GesturePoint|null} The gesture point at the given index, or null if not found.n */n getByIndex: function ( index ) {n if ( index < this._gPoints.length) {n return this._gPoints[ index ];n }nn return null;n },n /**n * @functionn * @param {Number} id - The id of the gesture point to retrieve from the list.n * @returns {OpenSeadragon.MouseTracker.GesturePoint|null} The gesture point with the given id, or null if not found.n */n getById: function ( id ) {n var i,n len = this._gPoints.length;n for ( i = 0; i < len; i++ ) {n if ( this._gPoints[ i ].id === id ) {n return this._gPoints[ i ];n }n }n return null;n },n /**n * @functionn * @returns {OpenSeadragon.MouseTracker.GesturePoint|null} The primary gesture point in the list, or null if not found.n */n getPrimary: function ( id ) {n var i,n len = this._gPoints.length;n for ( i = 0; i < len; i++ ) {n if ( this._gPoints[ i ].isPrimary ) {n return this._gPoints[ i ];n }n }n return null;n },nn /**n * Increment this pointer's contact count.n * It will evaluate whether this pointer type is allowed to have multiple contacts.n * @functionn */n addContact: function() {n ++this.contacts;nn if (this.contacts > 1 && (this.type === "mouse" || this.type === "pen")) {n this.contacts = 1;n }n },nn /**n * Decrement this pointer's contact count.n * It will make sure the count does not go below 0.n * @functionn */n removeContact: function() {n –this.contacts;nn if (this.contacts < 0) {n this.contacts = 0;n }n }n };nnn///////////////////////////////////////////////////////////////////////////////n// Utility functionsn///////////////////////////////////////////////////////////////////////////////nn /**n * Removes all tracked pointers.n * @privaten * @innern */n function clearTrackedPointers( tracker ) {n var delegate = THIS[ tracker.hash ],n i,n pointerListCount = delegate.activePointersLists.length;nn for ( i = 0; i < pointerListCount; i++ ) {n if ( delegate.activePointersLists[ i ].captureCount > 0 ) {n $.removeEvent(n $.MouseTracker.captureElement,n 'mousemove',n delegate.mousemovecaptured,n truen );n $.removeEvent(n $.MouseTracker.captureElement,n 'mouseup',n delegate.mouseupcaptured,n truen );n $.removeEvent(n $.MouseTracker.captureElement,n $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove',n delegate.pointermovecaptured,n truen );n $.removeEvent(n $.MouseTracker.captureElement,n $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp',n delegate.pointerupcaptured,n truen );n $.removeEvent(n $.MouseTracker.captureElement,n 'touchmove',n delegate.touchmovecaptured,n truen );n $.removeEvent(n $.MouseTracker.captureElement,n 'touchend',n delegate.touchendcaptured,n truen );nn delegate.activePointersLists[ i ].captureCount = 0;n }n }nn for ( i = 0; i < pointerListCount; i++ ) {n delegate.activePointersLists.pop();n }n }nn /**n * Starts tracking pointer events on the tracked element.n * @privaten * @innern */n function startTracking( tracker ) {n var delegate = THIS[ tracker.hash ],n event,n i;nn if ( !delegate.tracking ) {n for ( i = 0; i < $.MouseTracker.subscribeEvents.length; i++ ) {n event = $.MouseTracker.subscribeEvents[ i ];n $.addEvent(n tracker.element,n event,n delegate[ event ],n falsen );n }nn clearTrackedPointers( tracker );nn delegate.tracking = true;n }n }nn /**n * Stops tracking pointer events on the tracked element.n * @privaten * @innern */n function stopTracking( tracker ) {n var delegate = THIS[ tracker.hash ],n event,n i;nn if ( delegate.tracking ) {n for ( i = 0; i < $.MouseTracker.subscribeEvents.length; i++ ) {n event = $.MouseTracker.subscribeEvents[ i ];n $.removeEvent(n tracker.element,n event,n delegate[ event ],n falsen );n }nn clearTrackedPointers( tracker );nn delegate.tracking = false;n }n }nn /**n * @privaten * @innern */n function getCaptureEventParams( tracker, pointerType ) {n var delegate = THIS[ tracker.hash ];nn if ( pointerType === 'pointerevent' ) {n return {n upName: $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp',n upHandler: delegate.pointerupcaptured,n moveName: $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove',n moveHandler: delegate.pointermovecapturedn };n } else if ( pointerType === 'mouse' ) {n return {n upName: 'mouseup',n upHandler: delegate.mouseupcaptured,n moveName: 'mousemove',n moveHandler: delegate.mousemovecapturedn };n } else if ( pointerType === 'touch' ) {n return {n upName: 'touchend',n upHandler: delegate.touchendcaptured,n moveName: 'touchmove',n moveHandler: delegate.touchmovecapturedn };n } else {n throw new Error( "MouseTracker.getCaptureEventParams: Unknown pointer type." );n }n }nn /**n * Begin capturing pointer events to the tracked element.n * @privaten * @innern */n function capturePointer( tracker, pointerType, pointerCount ) {n var pointsList = tracker.getActivePointersListByType( pointerType ),n eventParams;nn pointsList.captureCount += (pointerCount || 1);nn if ( pointsList.captureCount === 1 ) {n if ( $.Browser.vendor === $.BROWSERS.IE && $.Browser.version < 9 ) {n tracker.element.setCapture( true );n } else {n eventParams = getCaptureEventParams( tracker, $.MouseTracker.havePointerEvents ? 'pointerevent' : pointerType );n // We emulate mouse capture by hanging listeners on the document object.n // (Note we listen on the capture phase so the captured handlers will get called first)n // eslint-disable-next-line no-use-before-definen if (isInIframe && canAccessEvents(window.top)) {n $.addEvent(n window.top,n eventParams.upName,n eventParams.upHandler,n truen );n }n $.addEvent(n $.MouseTracker.captureElement,n eventParams.upName,n eventParams.upHandler,n truen );n $.addEvent(n $.MouseTracker.captureElement,n eventParams.moveName,n eventParams.moveHandler,n truen );n }n }n }nnn /**n * Stop capturing pointer events to the tracked element.n * @privaten * @innern */n function releasePointer( tracker, pointerType, pointerCount ) {n var pointsList = tracker.getActivePointersListByType( pointerType ),n eventParams;nn pointsList.captureCount -= (pointerCount || 1);nn if ( pointsList.captureCount === 0 ) {n if ( $.Browser.vendor === $.BROWSERS.IE && $.Browser.version < 9 ) {n tracker.element.releaseCapture();n } else {n eventParams = getCaptureEventParams( tracker, $.MouseTracker.havePointerEvents ? 'pointerevent' : pointerType );n // We emulate mouse capture by hanging listeners on the document object.n // (Note we listen on the capture phase so the captured handlers will get called first)n // eslint-disable-next-line no-use-before-definen if (isInIframe && canAccessEvents(window.top)) {n $.removeEvent(n window.top,n eventParams.upName,n eventParams.upHandler,n truen );n }n $.removeEvent(n $.MouseTracker.captureElement,n eventParams.moveName,n eventParams.moveHandler,n truen );n $.removeEvent(n $.MouseTracker.captureElement,n eventParams.upName,n eventParams.upHandler,n truen );n }n }n }nnn /**n * Gets a W3C Pointer Events model compatible pointer type string from a DOM pointer event.n * IE10 used a long integer value, but the W3C specification (and IE11+) use a string "mouse", "touch", "pen", etc.n * @privaten * @innern */n function getPointerType( event ) {n var pointerTypeStr;n if ( $.MouseTracker.unprefixedPointerEvents ) {n pointerTypeStr = event.pointerType;n } else {n // IE10n // MSPOINTER_TYPE_TOUCH: 0x00000002n // MSPOINTER_TYPE_PEN: 0x00000003n // MSPOINTER_TYPE_MOUSE: 0x00000004n switch( event.pointerType )n {n case 0x00000002:n pointerTypeStr = 'touch';n break;n case 0x00000003:n pointerTypeStr = 'pen';n break;n case 0x00000004:n pointerTypeStr = 'mouse';n break;n default:n pointerTypeStr = '';n }n }n return pointerTypeStr;n }nnn /**n * @privaten * @innern */n function getMouseAbsolute( event ) {n return $.getMousePosition( event );n }nn /**n * @privaten * @innern */n function getMouseRelative( event, element ) {n return getPointRelativeToAbsolute( getMouseAbsolute( event ), element );n }nn /**n * @privaten * @innern */n function getPointRelativeToAbsolute( point, element ) {n var offset = $.getElementOffset( element );n return point.minus( offset );n }nn /**n * @privaten * @innern */n function getCenterPoint( point1, point2 ) {n return new $.Point( ( point1.x + point2.x ) / 2, ( point1.y + point2.y ) / 2 );n }nnn///////////////////////////////////////////////////////////////////////////////n// Device-specific DOM event handlersn///////////////////////////////////////////////////////////////////////////////nn /**n * @privaten * @innern */n function onClick( tracker, event ) {n if ( tracker.clickHandler ) {n $.cancelEvent( event );n }n }nnn /**n * @privaten * @innern */n function onDblClick( tracker, event ) {n if ( tracker.dblClickHandler ) {n $.cancelEvent( event );n }n }nnn /**n * @privaten * @innern */n function onKeyDown( tracker, event ) {n //$.console.log( "keydown %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey );n var propagate;n if ( tracker.keyDownHandler ) {n event = $.getEvent( event );n propagate = tracker.keyDownHandler(n {n eventSource: tracker,n keyCode: event.keyCode ? event.keyCode : event.charCode,n ctrl: event.ctrlKey,n shift: event.shiftKey,n alt: event.altKey,n meta: event.metaKey,n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( !propagate ) {n $.cancelEvent( event );n }n }n }nnn /**n * @privaten * @innern */n function onKeyUp( tracker, event ) {n //$.console.log( "keyup %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey );n var propagate;n if ( tracker.keyUpHandler ) {n event = $.getEvent( event );n propagate = tracker.keyUpHandler(n {n eventSource: tracker,n keyCode: event.keyCode ? event.keyCode : event.charCode,n ctrl: event.ctrlKey,n shift: event.shiftKey,n alt: event.altKey,n meta: event.metaKey,n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( !propagate ) {n $.cancelEvent( event );n }n }n }nnn /**n * @privaten * @innern */n function onKeyPress( tracker, event ) {n //$.console.log( "keypress %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey );n var propagate;n if ( tracker.keyHandler ) {n event = $.getEvent( event );n propagate = tracker.keyHandler(n {n eventSource: tracker,n keyCode: event.keyCode ? event.keyCode : event.charCode,n ctrl: event.ctrlKey,n shift: event.shiftKey,n alt: event.altKey,n meta: event.metaKey,n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( !propagate ) {n $.cancelEvent( event );n }n }n }nnn /**n * @privaten * @innern */n function onFocus( tracker, event ) {n //console.log( "focus %s", event );n var propagate;n if ( tracker.focusHandler ) {n event = $.getEvent( event );n propagate = tracker.focusHandler(n {n eventSource: tracker,n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }n }nnn /**n * @privaten * @innern */n function onBlur( tracker, event ) {n //console.log( "blur %s", event );n var propagate;n if ( tracker.blurHandler ) {n event = $.getEvent( event );n propagate = tracker.blurHandler(n {n eventSource: tracker,n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }n }nnn /**n * Handler for 'wheel' eventsn *n * @privaten * @innern */n function onWheel( tracker, event ) {n handleWheelEvent( tracker, event, event );n }nnn /**n * Handler for 'mousewheel', 'DOMMouseScroll', and 'MozMousePixelScroll' eventsn *n * @privaten * @innern */n function onMouseWheel( tracker, event ) {n event = $.getEvent( event );nn // Simulate a 'wheel' eventn var simulatedEvent = {n target: event.target || event.srcElement,n type: "wheel",n shiftKey: event.shiftKey || false,n clientX: event.clientX,n clientY: event.clientY,n pageX: event.pageX ? event.pageX : event.clientX,n pageY: event.pageY ? event.pageY : event.clientY,n deltaMode: event.type == "MozMousePixelScroll" ? 0 : 1, // 0=pixel, 1=line, 2=pagen deltaX: 0,n deltaZ: 0n };nn // Calculate deltaYn if ( $.MouseTracker.wheelEventName == "mousewheel" ) {n simulatedEvent.deltaY = -event.wheelDelta / $.DEFAULT_SETTINGS.pixelsPerWheelLine;n } else {n simulatedEvent.deltaY = event.detail;n }nn handleWheelEvent( tracker, simulatedEvent, event );n }nnn /**n * Handles 'wheel' events.n * The event may be simulated by the legacy mouse wheel event handler (onMouseWheel()).n *n * @privaten * @innern */n function handleWheelEvent( tracker, event, originalEvent ) {n var nDelta = 0,n propagate;nn // The nDelta variable is gated to provide smooth z-index scrollingn // since the mouse wheel allows for substantial deltas meant for rapidn // y-index scrolling.n // event.deltaMode: 0=pixel, 1=line, 2=pagen // TODO: Deltas in pixel mode should be accumulated then a scroll value computed after $.DEFAULT_SETTINGS.pixelsPerWheelLine threshold reachedn nDelta = event.deltaY < 0 ? 1 : -1;nn if ( tracker.scrollHandler ) {n propagate = tracker.scrollHandler(n {n eventSource: tracker,n pointerType: 'mouse',n position: getMouseRelative( event, tracker.element ),n scroll: nDelta,n shift: event.shiftKey,n isTouchEvent: false,n originalEvent: originalEvent,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( originalEvent );n }n }n }nnn /**n * @privaten * @innern */n function isParentChild( parent, child )n {n if ( parent === child ) {n return false;n }n while ( child && child !== parent ) {n child = child.parentNode;n }n return child === parent;n }nnn /**n * Only used on IE 8n *n * @privaten * @innern */n function onMouseEnter( tracker, event ) {n event = $.getEvent( event );nn handleMouseEnter( tracker, event );n }nnn /**n * @privaten * @innern */n function onMouseOver( tracker, event ) {n event = $.getEvent( event );nn if ( event.currentTarget === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) {n return;n }nn handleMouseEnter( tracker, event );n }nnn /**n * @privaten * @innern */n function handleMouseEnter( tracker, event ) {n var gPoint = {n id: $.MouseTracker.mousePointerId,n type: 'mouse',n isPrimary: true,n currentPos: getMouseAbsolute( event ),n currentTime: $.now()n };nn updatePointersEnter( tracker, event, [ gPoint ] );n }nnn /**n * Only used on IE 8n *n * @privaten * @innern */n function onMouseLeave( tracker, event ) {n event = $.getEvent( event );nn handleMouseExit( tracker, event );n }nnn /**n * @privaten * @innern */n function onMouseOut( tracker, event ) {n event = $.getEvent( event );nn if ( event.currentTarget === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) {n return;n }nn handleMouseExit( tracker, event );n }nnn /**n * @privaten * @innern */n function handleMouseExit( tracker, event ) {n var gPoint = {n id: $.MouseTracker.mousePointerId,n type: 'mouse',n isPrimary: true,n currentPos: getMouseAbsolute( event ),n currentTime: $.now()n };nn updatePointersExit( tracker, event, [ gPoint ] );n }nnn /**n * Returns a W3C DOM level 3 standard button value given an event.button property:n * -1 == none, 0 == primary/left, 1 == middle, 2 == secondary/right, 3 == X1/back, 4 == X2/forward, 5 == eraser (pen)n * @privaten * @innern */n function getStandardizedButton( button ) {n if ( $.Browser.vendor === $.BROWSERS.IE && $.Browser.version < 9 ) {n // On IE 8, 0 == none, 1 == left, 2 == right, 3 == left and right, 4 == middle, 5 == left and middle, 6 == right and middle, 7 == all threen // TODO: Support chorded (multiple) button presses on IE 8?n if ( button === 1 ) {n return 0;n } else if ( button === 2 ) {n return 2;n } else if ( button === 4 ) {n return 1;n } else {n return -1;n }n } else {n return button;n }n }nnn /**n * @privaten * @innern */n function onMouseDown( tracker, event ) {n var gPoint;nn event = $.getEvent( event );nn gPoint = {n id: $.MouseTracker.mousePointerId,n type: 'mouse',n isPrimary: true,n currentPos: getMouseAbsolute( event ),n currentTime: $.now()n };nn if ( updatePointersDown( tracker, event, [ gPoint ], getStandardizedButton( event.button ) ) ) {n $.stopEvent( event );n capturePointer( tracker, 'mouse' );n }nn if ( tracker.clickHandler || tracker.dblClickHandler || tracker.pressHandler || tracker.dragHandler || tracker.dragEndHandler ) {n $.cancelEvent( event );n }n }nnn /**n * @privaten * @innern */n function onMouseUp( tracker, event ) {n handleMouseUp( tracker, event );n }nn /**n * This handler is attached to the window object (on the capture phase) to emulate mouse capture.n * onMouseUp is still attached to the tracked element, so stop propagation to avoid processing twice.n *n * @privaten * @innern */n function onMouseUpCaptured( tracker, event ) {n handleMouseUp( tracker, event );n $.stopEvent( event );n }nnn /**n * @privaten * @innern */n function handleMouseUp( tracker, event ) {n var gPoint;nn event = $.getEvent( event );nn gPoint = {n id: $.MouseTracker.mousePointerId,n type: 'mouse',n isPrimary: true,n currentPos: getMouseAbsolute( event ),n currentTime: $.now()n };nn if ( updatePointersUp( tracker, event, [ gPoint ], getStandardizedButton( event.button ) ) ) {n releasePointer( tracker, 'mouse' );n }n }nnn /**n * @privaten * @innern */n function onMouseMove( tracker, event ) {n handleMouseMove( tracker, event );n }nnn /**n * This handler is attached to the window object (on the capture phase) to emulate mouse capture.n * onMouseMove is still attached to the tracked element, so stop propagation to avoid processing twice.n *n * @privaten * @innern */n function onMouseMoveCaptured( tracker, event ) {n handleMouseMove( tracker, event );n $.stopEvent( event );n }nnn /**n * @privaten * @innern */n function handleMouseMove( tracker, event ) {n var gPoint;nn event = $.getEvent( event );nn gPoint = {n id: $.MouseTracker.mousePointerId,n type: 'mouse',n isPrimary: true,n currentPos: getMouseAbsolute( event ),n currentTime: $.now()n };nn updatePointersMove( tracker, event, [ gPoint ] );n }nnn /**n * @privaten * @innern */n function abortContacts( tracker, event, pointsList ) {n var i,n gPointCount = pointsList.getLength(),n abortGPoints = [];nn // Check contact count for hoverable pointer types before abortingn if (pointsList.type === 'touch' || pointsList.contacts > 0) {n for ( i = 0; i < gPointCount; i++ ) {n abortGPoints.push( pointsList.getByIndex( i ) );n }nn if ( abortGPoints.length > 0 ) {n // simulate touchend/mouseupn updatePointersUp( tracker, event, abortGPoints, 0 ); // 0 means primary button press/release or touch contactn // release pointer capturen pointsList.captureCount = 1;n releasePointer( tracker, pointsList.type );n // simulate touchleave/mouseoutn updatePointersExit( tracker, event, abortGPoints );n }n }n }nnn /**n * @privaten * @innern */n function onTouchStart( tracker, event ) {n var time,n i,n j,n touchCount = event.changedTouches.length,n gPoints = [],n parentGPoints,n pointsList = tracker.getActivePointersListByType( 'touch' );nn time = $.now();nn if ( pointsList.getLength() > event.touches.length - touchCount ) {n $.console.warn('Tracked touch contact count doesn\'t match event.touches.length. Removing all tracked touch pointers.');n abortContacts( tracker, event, pointsList );n }nn for ( i = 0; i < touchCount; i++ ) {n gPoints.push( {n id: event.changedTouches[ i ].identifier,n type: 'touch',n // isPrimary not set - let the updatePointers functions determine itn currentPos: getMouseAbsolute( event.changedTouches[ i ] ),n currentTime: timen } );n }nn // simulate touchenter on our tracked elementn updatePointersEnter( tracker, event, gPoints );nn // simulate touchenter on our tracked element's tracked ancestor elementsn for ( i = 0; i < MOUSETRACKERS.length; i++ ) {n if ( MOUSETRACKERS[ i ] !== tracker && MOUSETRACKERS[ i ].isTracking() && isParentChild( MOUSETRACKERS[ i ].element, tracker.element ) ) {n parentGPoints = [];n for ( j = 0; j < touchCount; j++ ) {n parentGPoints.push( {n id: event.changedTouches[ j ].identifier,n type: 'touch',n // isPrimary not set - let the updatePointers functions determine itn currentPos: getMouseAbsolute( event.changedTouches[ j ] ),n currentTime: timen } );n }n updatePointersEnter( MOUSETRACKERS[ i ], event, parentGPoints );n }n }nn if ( updatePointersDown( tracker, event, gPoints, 0 ) ) { // 0 means primary button press/release or touch contactn $.stopEvent( event );n capturePointer( tracker, 'touch', touchCount );n }nn $.cancelEvent( event );n }nnn /**n * @privaten * @innern */n function onTouchEnd( tracker, event ) {n handleTouchEnd( tracker, event );n }nnn /**n * This handler is attached to the window object (on the capture phase) to emulate pointer capture.n * onTouchEnd is still attached to the tracked element, so stop propagation to avoid processing twice.n *n * @privaten * @innern */n function onTouchEndCaptured( tracker, event ) {n handleTouchEnd( tracker, event );n $.stopEvent( event );n }nnn /**n * @privaten * @innern */n function handleTouchEnd( tracker, event ) {n var time,n i,n j,n touchCount = event.changedTouches.length,n gPoints = [],n parentGPoints;nn time = $.now();nn for ( i = 0; i < touchCount; i++ ) {n gPoints.push( {n id: event.changedTouches[ i ].identifier,n type: 'touch',n // isPrimary not set - let the updatePointers functions determine itn currentPos: getMouseAbsolute( event.changedTouches[ i ] ),n currentTime: timen } );n }nn if ( updatePointersUp( tracker, event, gPoints, 0 ) ) {n releasePointer( tracker, 'touch', touchCount );n }nn // simulate touchleave on our tracked elementn updatePointersExit( tracker, event, gPoints );nn // simulate touchleave on our tracked element's tracked ancestor elementsn for ( i = 0; i < MOUSETRACKERS.length; i++ ) {n if ( MOUSETRACKERS[ i ] !== tracker && MOUSETRACKERS[ i ].isTracking() && isParentChild( MOUSETRACKERS[ i ].element, tracker.element ) ) {n parentGPoints = [];n for ( j = 0; j < touchCount; j++ ) {n parentGPoints.push( {n id: event.changedTouches[ j ].identifier,n type: 'touch',n // isPrimary not set - let the updatePointers functions determine itn currentPos: getMouseAbsolute( event.changedTouches[ j ] ),n currentTime: timen } );n }n updatePointersExit( MOUSETRACKERS[ i ], event, parentGPoints );n }n }nn $.cancelEvent( event );n }nnn /**n * @privaten * @innern */n function onTouchMove( tracker, event ) {n handleTouchMove( tracker, event );n }nnn /**n * This handler is attached to the window object (on the capture phase) to emulate pointer capture.n * onTouchMove is still attached to the tracked element, so stop propagation to avoid processing twice.n *n * @privaten * @innern */n function onTouchMoveCaptured( tracker, event ) {n handleTouchMove( tracker, event );n $.stopEvent( event );n }nnn /**n * @privaten * @innern */n function handleTouchMove( tracker, event ) {n var i,n touchCount = event.changedTouches.length,n gPoints = [];nn for ( i = 0; i < touchCount; i++ ) {n gPoints.push( {n id: event.changedTouches[ i ].identifier,n type: 'touch',n // isPrimary not set - let the updatePointers functions determine itn currentPos: getMouseAbsolute( event.changedTouches[ i ] ),n currentTime: $.now()n } );n }nn updatePointersMove( tracker, event, gPoints );nn $.cancelEvent( event );n }nnn /**n * @privaten * @innern */n function onTouchCancel( tracker, event ) {n var pointsList = tracker.getActivePointersListByType('touch');nn abortContacts( tracker, event, pointsList );n }nnn /**n * @privaten * @innern */n function onGestureStart( tracker, event ) {n event.stopPropagation();n event.preventDefault();n return false;n }nnn /**n * @privaten * @innern */n function onGestureChange( tracker, event ) {n event.stopPropagation();n event.preventDefault();n return false;n }nnn /**n * @privaten * @innern */n function onPointerOver( tracker, event ) {n var gPoint;nn if ( event.currentTarget === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) {n return;n }nn gPoint = {n id: event.pointerId,n type: getPointerType( event ),n isPrimary: event.isPrimary,n currentPos: getMouseAbsolute( event ),n currentTime: $.now()n };nn updatePointersEnter( tracker, event, [ gPoint ] );n }nnn /**n * @privaten * @innern */n function onPointerOut( tracker, event ) {n var gPoint;nn if ( event.currentTarget === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) {n return;n }nn gPoint = {n id: event.pointerId,n type: getPointerType( event ),n isPrimary: event.isPrimary,n currentPos: getMouseAbsolute( event ),n currentTime: $.now()n };nn updatePointersExit( tracker, event, [ gPoint ] );n }nnn /**n * @privaten * @innern */n function onPointerDown( tracker, event ) {n var gPoint;nn gPoint = {n id: event.pointerId,n type: getPointerType( event ),n isPrimary: event.isPrimary,n currentPos: getMouseAbsolute( event ),n currentTime: $.now()n };nn if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) {n $.stopEvent( event );n capturePointer( tracker, gPoint.type );n }nn if ( tracker.clickHandler || tracker.dblClickHandler || tracker.pressHandler || tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {n $.cancelEvent( event );n }n }nnn /**n * @privaten * @innern */n function onPointerUp( tracker, event ) {n handlePointerUp( tracker, event );n }nnn /**n * This handler is attached to the window object (on the capture phase) to emulate mouse capture.n * onPointerUp is still attached to the tracked element, so stop propagation to avoid processing twice.n *n * @privaten * @innern */n function onPointerUpCaptured( tracker, event ) {n var pointsList = tracker.getActivePointersListByType( getPointerType( event ) );n if ( pointsList.getById( event.pointerId ) ) {n handlePointerUp( tracker, event );n }n $.stopEvent( event );n }nnn /**n * @privaten * @innern */n function handlePointerUp( tracker, event ) {n var gPoint;nn gPoint = {n id: event.pointerId,n type: getPointerType( event ),n isPrimary: event.isPrimary,n currentPos: getMouseAbsolute( event ),n currentTime: $.now()n };nn if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) {n releasePointer( tracker, gPoint.type );n }n }nnn /**n * @privaten * @innern */n function onPointerMove( tracker, event ) {n handlePointerMove( tracker, event );n }nnn /**n * This handler is attached to the window object (on the capture phase) to emulate mouse capture.n * onPointerMove is still attached to the tracked element, so stop propagation to avoid processing twice.n *n * @privaten * @innern */n function onPointerMoveCaptured( tracker, event ) {n var pointsList = tracker.getActivePointersListByType( getPointerType( event ) );n if ( pointsList.getById( event.pointerId ) ) {n handlePointerMove( tracker, event );n }n $.stopEvent( event );n }nnn /**n * @privaten * @innern */n function handlePointerMove( tracker, event ) {n // Pointer changed coordinates, button state, pressure, tilt, or contact geometry (e.g. width and height)n var gPoint;nn gPoint = {n id: event.pointerId,n type: getPointerType( event ),n isPrimary: event.isPrimary,n currentPos: getMouseAbsolute( event ),n currentTime: $.now()n };nn updatePointersMove( tracker, event, [ gPoint ] );n }nnn /**n * @privaten * @innern */n function onPointerCancel( tracker, event ) {n var gPoint;nn gPoint = {n id: event.pointerId,n type: getPointerType( event )n };nn updatePointersCancel( tracker, event, [ gPoint ] );n }nnn///////////////////////////////////////////////////////////////////////////////n// Device-agnostic DOM event handlersn///////////////////////////////////////////////////////////////////////////////nn /**n * @functionn * @privaten * @innern * @param {OpenSeadragon.MouseTracker.GesturePointList} pointsListn * The GesturePointList to track the pointer in.n * @param {OpenSeadragon.MouseTracker.GesturePoint} gPointn * Gesture point to track.n * @returns {Number} Number of gesture points in pointsList.n */n function startTrackingPointer( pointsList, gPoint ) {nn // If isPrimary is not known for the pointer then set it according to our rules:n // true if the first pointer in the gesture, otherwise falsen if ( !gPoint.hasOwnProperty( 'isPrimary' ) ) {n if ( pointsList.getLength() === 0 ) {n gPoint.isPrimary = true;n } else {n gPoint.isPrimary = false;n }n }n gPoint.speed = 0;n gPoint.direction = 0;n gPoint.contactPos = gPoint.currentPos;n gPoint.contactTime = gPoint.currentTime;n gPoint.lastPos = gPoint.currentPos;n gPoint.lastTime = gPoint.currentTime;nn return pointsList.add( gPoint );n }nnn /**n * @functionn * @privaten * @innern * @param {OpenSeadragon.MouseTracker.GesturePointList} pointsListn * The GesturePointList to stop tracking the pointer on.n * @param {OpenSeadragon.MouseTracker.GesturePoint} gPointn * Gesture point to stop tracking.n * @returns {Number} Number of gesture points in pointsList.n */n function stopTrackingPointer( pointsList, gPoint ) {n var listLength,n primaryPoint;nn if ( pointsList.getById( gPoint.id ) ) {n listLength = pointsList.removeById( gPoint.id );nn // If isPrimary is not known for the pointer and we just removed the primary pointer from the list then we need to set another pointer as primaryn if ( !gPoint.hasOwnProperty( 'isPrimary' ) ) {n primaryPoint = pointsList.getPrimary();n if ( !primaryPoint ) {n primaryPoint = pointsList.getByIndex( 0 );n if ( primaryPoint ) {n primaryPoint.isPrimary = true;n }n }n }n } else {n listLength = pointsList.getLength();n }nn return listLength;n }nnn /**n * @functionn * @privaten * @innern * @param {OpenSeadragon.MouseTracker} trackern * A reference to the MouseTracker instance.n * @param {Object} eventn * A reference to the originating DOM event.n * @param {Array.<OpenSeadragon.MouseTracker.GesturePoint>} gPointsn * Gesture points associated with the event.n */n function updatePointersEnter( tracker, event, gPoints ) {n var pointsList = tracker.getActivePointersListByType( gPoints[ 0 ].type ),n i,n gPointCount = gPoints.length,n curGPoint,n updateGPoint,n propagate;nn for ( i = 0; i < gPointCount; i++ ) {n curGPoint = gPoints[ i ];n updateGPoint = pointsList.getById( curGPoint.id );nn if ( updateGPoint ) {n // Already tracking the pointer…update itn updateGPoint.insideElement = true;n updateGPoint.lastPos = updateGPoint.currentPos;n updateGPoint.lastTime = updateGPoint.currentTime;n updateGPoint.currentPos = curGPoint.currentPos;n updateGPoint.currentTime = curGPoint.currentTime;nn curGPoint = updateGPoint;n } else {n // Initialize for tracking and add to the tracking listn curGPoint.captured = false;n curGPoint.insideElementPressed = false;n curGPoint.insideElement = true;n startTrackingPointer( pointsList, curGPoint );n }nn // Entern if ( tracker.enterHandler ) {n propagate = tracker.enterHandler(n {n eventSource: tracker,n pointerType: curGPoint.type,n position: getPointRelativeToAbsolute( curGPoint.currentPos, tracker.element ),n buttons: pointsList.buttons,n pointers: tracker.getActivePointerCount(),n insideElementPressed: curGPoint.insideElementPressed,n buttonDownAny: pointsList.buttons !== 0,n isTouchEvent: curGPoint.type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }n }n }nnn /**n * @functionn * @privaten * @innern * @param {OpenSeadragon.MouseTracker} trackern * A reference to the MouseTracker instance.n * @param {Object} eventn * A reference to the originating DOM event.n * @param {Array.<OpenSeadragon.MouseTracker.GesturePoint>} gPointsn * Gesture points associated with the event.n */n function updatePointersExit( tracker, event, gPoints ) {n var pointsList = tracker.getActivePointersListByType(gPoints.type),n i,n gPointCount = gPoints.length,n curGPoint,n updateGPoint,n propagate;nn for ( i = 0; i < gPointCount; i++ ) {n curGPoint = gPoints[ i ];n updateGPoint = pointsList.getById( curGPoint.id );nn if ( updateGPoint ) {n // Already tracking the pointer. If captured then update it, else stop tracking itn if ( updateGPoint.captured ) {n updateGPoint.insideElement = false;n updateGPoint.lastPos = updateGPoint.currentPos;n updateGPoint.lastTime = updateGPoint.currentTime;n updateGPoint.currentPos = curGPoint.currentPos;n updateGPoint.currentTime = curGPoint.currentTime;n } else {n stopTrackingPointer( pointsList, updateGPoint );n }nn curGPoint = updateGPoint;n }nn // Exitn if ( tracker.exitHandler ) {n propagate = tracker.exitHandler(n {n eventSource: tracker,n pointerType: curGPoint.type,n position: getPointRelativeToAbsolute( curGPoint.currentPos, tracker.element ),n buttons: pointsList.buttons,n pointers: tracker.getActivePointerCount(),n insideElementPressed: updateGPoint ? updateGPoint.insideElementPressed : false,n buttonDownAny: pointsList.buttons !== 0,n isTouchEvent: curGPoint.type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );nn if ( propagate === false ) {n $.cancelEvent( event );n }n }n }n }nnn /**n * @functionn * @privaten * @innern * @param {OpenSeadragon.MouseTracker} trackern * A reference to the MouseTracker instance.n * @param {Object} eventn * A reference to the originating DOM event.n * @param {Array.<OpenSeadragon.MouseTracker.GesturePoint>} gPointsn * Gesture points associated with the event.n * @param {Number} buttonChangedn * The button involved in the event: -1: none, 0: primary/left, 1: aux/middle, 2: secondary/right, 3: X1/back, 4: X2/forward, 5: pen eraser.n * Note on chorded button presses (a button pressed when another button is already pressed): In the W3C Pointer Events model,n * only one pointerdown/pointerup event combo is fired. Chorded button state changes instead fire pointermove events.n *n * @returns {Boolean} True if pointers should be captured to the tracked element, otherwise false.n */n function updatePointersDown( tracker, event, gPoints, buttonChanged ) {n var delegate = THIS[ tracker.hash ],n propagate,n pointsList = tracker.getActivePointersListByType( gPoints[ 0 ].type ),n i,n gPointCount = gPoints.length,n curGPoint,n updateGPoint;nn if ( typeof event.buttons !== 'undefined' ) {n pointsList.buttons = event.buttons;n } else {n if ( $.Browser.vendor === $.BROWSERS.IE && $.Browser.version < 9 ) {n if ( buttonChanged === 0 ) {n // Primaryn pointsList.buttons += 1;n } else if ( buttonChanged === 1 ) {n // Auxn pointsList.buttons += 4;n } else if ( buttonChanged === 2 ) {n // Secondaryn pointsList.buttons += 2;n } else if ( buttonChanged === 3 ) {n // X1 (Back)n pointsList.buttons += 8;n } else if ( buttonChanged === 4 ) {n // X2 (Forward)n pointsList.buttons += 16;n } else if ( buttonChanged === 5 ) {n // Pen Erasern pointsList.buttons += 32;n }n } else {n if ( buttonChanged === 0 ) {n // Primaryn pointsList.buttons |= 1;n } else if ( buttonChanged === 1 ) {n // Auxn pointsList.buttons |= 4;n } else if ( buttonChanged === 2 ) {n // Secondaryn pointsList.buttons |= 2;n } else if ( buttonChanged === 3 ) {n // X1 (Back)n pointsList.buttons |= 8;n } else if ( buttonChanged === 4 ) {n // X2 (Forward)n pointsList.buttons |= 16;n } else if ( buttonChanged === 5 ) {n // Pen Erasern pointsList.buttons |= 32;n }n }n }nn // Some pointers may steal control from another pointer without firing the appropriate release eventsn // e.g. Touching a screen while click-dragging with certain mice.n var otherPointsLists = tracker.getActivePointersListsExceptType(gPoints[ 0 ].type);n for (i = 0; i < otherPointsLists.length; i++) {n //If another pointer has contact, simulate the releasen abortContacts(tracker, event, otherPointsLists); // No-op if no active pointern }nn // Only capture and track primary button, pen, and touch contactsn if ( buttonChanged !== 0 ) {n // Aux Pressn if ( tracker.nonPrimaryPressHandler ) {n propagate = tracker.nonPrimaryPressHandler(n {n eventSource: tracker,n pointerType: gPoints[ 0 ].type,n position: getPointRelativeToAbsolute( gPoints[ 0 ].currentPos, tracker.element ),n button: buttonChanged,n buttons: pointsList.buttons,n isTouchEvent: gPoints[ 0 ].type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }nn return false;n }nn for ( i = 0; i < gPointCount; i++ ) {n curGPoint = gPoints[ i ];n updateGPoint = pointsList.getById( curGPoint.id );nn if ( updateGPoint ) {n // Already tracking the pointer…update itn updateGPoint.captured = true;n updateGPoint.insideElementPressed = true;n updateGPoint.insideElement = true;n updateGPoint.contactPos = curGPoint.currentPos;n updateGPoint.contactTime = curGPoint.currentTime;n updateGPoint.lastPos = updateGPoint.currentPos;n updateGPoint.lastTime = updateGPoint.currentTime;n updateGPoint.currentPos = curGPoint.currentPos;n updateGPoint.currentTime = curGPoint.currentTime;nn curGPoint = updateGPoint;n } else {n // Initialize for tracking and add to the tracking list (no pointerover or pointermove event occurred before this)n curGPoint.captured = true;n curGPoint.insideElementPressed = true;n curGPoint.insideElement = true;n startTrackingPointer( pointsList, curGPoint );n }nn pointsList.addContact();n //$.console.log('contacts++ ', pointsList.contacts);nn if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {n $.MouseTracker.gesturePointVelocityTracker.addPoint( tracker, curGPoint );n }nn if ( pointsList.contacts === 1 ) {n // Pressn if ( tracker.pressHandler ) {n propagate = tracker.pressHandler(n {n eventSource: tracker,n pointerType: curGPoint.type,n position: getPointRelativeToAbsolute( curGPoint.contactPos, tracker.element ),n buttons: pointsList.buttons,n isTouchEvent: curGPoint.type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }n } else if ( pointsList.contacts === 2 ) {n if ( tracker.pinchHandler && curGPoint.type === 'touch' ) {n // Initialize for pinchn delegate.pinchGPoints = pointsList.asArray();n delegate.lastPinchDist = delegate.currentPinchDist = delegate.pinchGPoints[ 0 ].currentPos.distanceTo( delegate.pinchGPoints[ 1 ].currentPos );n delegate.lastPinchCenter = delegate.currentPinchCenter = getCenterPoint( delegate.pinchGPoints[ 0 ].currentPos, delegate.pinchGPoints[ 1 ].currentPos );n }n }n }nn return true;n }nnn /**n * @functionn * @privaten * @innern * @param {OpenSeadragon.MouseTracker} trackern * A reference to the MouseTracker instance.n * @param {Object} eventn * A reference to the originating DOM event.n * @param {Array.<OpenSeadragon.MouseTracker.GesturePoint>} gPointsn * Gesture points associated with the event.n * @param {Number} buttonChangedn * The button involved in the event: -1: none, 0: primary/left, 1: aux/middle, 2: secondary/right, 3: X1/back, 4: X2/forward, 5: pen eraser.n * Note on chorded button presses (a button pressed when another button is already pressed): In the W3C Pointer Events model,n * only one pointerdown/pointerup event combo is fired. Chorded button state changes instead fire pointermove events.n *n * @returns {Boolean} True if pointer capture should be released from the tracked element, otherwise false.n */n function updatePointersUp( tracker, event, gPoints, buttonChanged ) {n var delegate = THIS[ tracker.hash ],n pointsList = tracker.getActivePointersListByType( gPoints[ 0 ].type ),n propagate,n releasePoint,n releaseTime,n i,n gPointCount = gPoints.length,n curGPoint,n updateGPoint,n releaseCapture = false,n wasCaptured = false,n quick;nn if ( typeof event.buttons !== 'undefined' ) {n pointsList.buttons = event.buttons;n } else {n if ( $.Browser.vendor === $.BROWSERS.IE && $.Browser.version < 9 ) {n if ( buttonChanged === 0 ) {n // Primaryn pointsList.buttons -= 1;n } else if ( buttonChanged === 1 ) {n // Auxn pointsList.buttons -= 4;n } else if ( buttonChanged === 2 ) {n // Secondaryn pointsList.buttons -= 2;n } else if ( buttonChanged === 3 ) {n // X1 (Back)n pointsList.buttons -= 8;n } else if ( buttonChanged === 4 ) {n // X2 (Forward)n pointsList.buttons -= 16;n } else if ( buttonChanged === 5 ) {n // Pen Erasern pointsList.buttons -= 32;n }n } else {n if ( buttonChanged === 0 ) {n // Primaryn pointsList.buttons ^= ~1;n } else if ( buttonChanged === 1 ) {n // Auxn pointsList.buttons ^= ~4;n } else if ( buttonChanged === 2 ) {n // Secondaryn pointsList.buttons ^= ~2;n } else if ( buttonChanged === 3 ) {n // X1 (Back)n pointsList.buttons ^= ~8;n } else if ( buttonChanged === 4 ) {n // X2 (Forward)n pointsList.buttons ^= ~16;n } else if ( buttonChanged === 5 ) {n // Pen Erasern pointsList.buttons ^= ~32;n }n }n }nn // Only capture and track primary button, pen, and touch contactsn if ( buttonChanged !== 0 ) {n // Aux Releasen if ( tracker.nonPrimaryReleaseHandler ) {n propagate = tracker.nonPrimaryReleaseHandler(n {n eventSource: tracker,n pointerType: gPoints[ 0 ].type,n position: getPointRelativeToAbsolute(gPoints.currentPos, tracker.element),n button: buttonChanged,n buttons: pointsList.buttons,n isTouchEvent: gPoints[ 0 ].type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }nn // A primary mouse button may have been released while the non-primary button was downn var otherPointsList = tracker.getActivePointersListByType("mouse");n // Stop tracking the mouse; see github.com/openseadragon/openseadragon/pull/1223n abortContacts(tracker, event, otherPointsList); // No-op if no active pointernn return false;n }nn for ( i = 0; i < gPointCount; i++ ) {n curGPoint = gPoints[ i ];n updateGPoint = pointsList.getById( curGPoint.id );nn if ( updateGPoint ) {n // Update the pointer, stop tracking it if not still in this elementn if ( updateGPoint.captured ) {n updateGPoint.captured = false;n releaseCapture = true;n wasCaptured = true;n }n updateGPoint.lastPos = updateGPoint.currentPos;n updateGPoint.lastTime = updateGPoint.currentTime;n updateGPoint.currentPos = curGPoint.currentPos;n updateGPoint.currentTime = curGPoint.currentTime;n if ( !updateGPoint.insideElement ) {n stopTrackingPointer( pointsList, updateGPoint );n }nn releasePoint = updateGPoint.currentPos;n releaseTime = updateGPoint.currentTime;nn if ( wasCaptured ) {n // Pointer was activated in our element but could have been removed in any element since events are captured to our elementnn pointsList.removeContact();n //$.console.log('contacts– ', pointsList.contacts);nn if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {n $.MouseTracker.gesturePointVelocityTracker.removePoint( tracker, updateGPoint );n }nn if ( pointsList.contacts === 0 ) {nn // Release (pressed in our element)n if ( tracker.releaseHandler ) {n propagate = tracker.releaseHandler(n {n eventSource: tracker,n pointerType: updateGPoint.type,n position: getPointRelativeToAbsolute( releasePoint, tracker.element ),n buttons: pointsList.buttons,n insideElementPressed: updateGPoint.insideElementPressed,n insideElementReleased: updateGPoint.insideElement,n isTouchEvent: updateGPoint.type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }nn // Drag Endn if ( tracker.dragEndHandler && !updateGPoint.currentPos.equals( updateGPoint.contactPos ) ) {n propagate = tracker.dragEndHandler(n {n eventSource: tracker,n pointerType: updateGPoint.type,n position: getPointRelativeToAbsolute( updateGPoint.currentPos, tracker.element ),n speed: updateGPoint.speed,n direction: updateGPoint.direction,n shift: event.shiftKey,n isTouchEvent: updateGPoint.type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }nn // Click / Double-Clickn if ( ( tracker.clickHandler || tracker.dblClickHandler ) && updateGPoint.insideElement ) {n quick = releaseTime - updateGPoint.contactTime <= tracker.clickTimeThreshold &&n updateGPoint.contactPos.distanceTo( releasePoint ) <= tracker.clickDistThreshold;nn // Clickn if ( tracker.clickHandler ) {n propagate = tracker.clickHandler(n {n eventSource: tracker,n pointerType: updateGPoint.type,n position: getPointRelativeToAbsolute( updateGPoint.currentPos, tracker.element ),n quick: quick,n shift: event.shiftKey,n isTouchEvent: updateGPoint.type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }nn // Double-Clickn if ( tracker.dblClickHandler && quick ) {n pointsList.clicks++;n if ( pointsList.clicks === 1 ) {n delegate.lastClickPos = releasePoint;n /*jshint loopfunc:true*/n delegate.dblClickTimeOut = setTimeout( function() {n pointsList.clicks = 0;n }, tracker.dblClickTimeThreshold );n /*jshint loopfunc:false*/n } else if ( pointsList.clicks === 2 ) {n clearTimeout( delegate.dblClickTimeOut );n pointsList.clicks = 0;n if ( delegate.lastClickPos.distanceTo( releasePoint ) <= tracker.dblClickDistThreshold ) {n propagate = tracker.dblClickHandler(n {n eventSource: tracker,n pointerType: updateGPoint.type,n position: getPointRelativeToAbsolute( updateGPoint.currentPos, tracker.element ),n shift: event.shiftKey,n isTouchEvent: updateGPoint.type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }n delegate.lastClickPos = null;n }n }n }n } else if ( pointsList.contacts === 2 ) {n if ( tracker.pinchHandler && updateGPoint.type === 'touch' ) {n // Reset for pinchn delegate.pinchGPoints = pointsList.asArray();n delegate.lastPinchDist = delegate.currentPinchDist = delegate.pinchGPoints[ 0 ].currentPos.distanceTo( delegate.pinchGPoints[ 1 ].currentPos );n delegate.lastPinchCenter = delegate.currentPinchCenter = getCenterPoint( delegate.pinchGPoints[ 0 ].currentPos, delegate.pinchGPoints[ 1 ].currentPos );n }n }n } else {n // Pointer was activated in another element but removed in our elementnn // Release (pressed in another element)n if ( tracker.releaseHandler ) {n propagate = tracker.releaseHandler(n {n eventSource: tracker,n pointerType: updateGPoint.type,n position: getPointRelativeToAbsolute( releasePoint, tracker.element ),n buttons: pointsList.buttons,n insideElementPressed: updateGPoint.insideElementPressed,n insideElementReleased: updateGPoint.insideElement,n isTouchEvent: updateGPoint.type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }n }n }n }nn return releaseCapture;n }nnn /**n * Call when pointer(s) change coordinates, button state, pressure, tilt, or contact geometry (e.g. width and height)n *n * @functionn * @privaten * @innern * @param {OpenSeadragon.MouseTracker} trackern * A reference to the MouseTracker instance.n * @param {Object} eventn * A reference to the originating DOM event.n * @param {Array.<OpenSeadragon.MouseTracker.GesturePoint>} gPointsn * Gesture points associated with the event.n */n function updatePointersMove( tracker, event, gPoints ) {n var delegate = THIS[ tracker.hash ],n pointsList = tracker.getActivePointersListByType( gPoints[ 0 ].type ),n i,n gPointCount = gPoints.length,n curGPoint,n updateGPoint,n gPointArray,n delta,n propagate;nn if ( typeof event.buttons !== 'undefined' ) {n pointsList.buttons = event.buttons;n }nn for ( i = 0; i < gPointCount; i++ ) {n curGPoint = gPoints[ i ];n updateGPoint = pointsList.getById( curGPoint.id );nn if ( updateGPoint ) {n // Already tracking the pointer…update itn if ( curGPoint.hasOwnProperty( 'isPrimary' ) ) {n updateGPoint.isPrimary = curGPoint.isPrimary;n }n updateGPoint.lastPos = updateGPoint.currentPos;n updateGPoint.lastTime = updateGPoint.currentTime;n updateGPoint.currentPos = curGPoint.currentPos;n updateGPoint.currentTime = curGPoint.currentTime;n } else {n // Initialize for tracking and add to the tracking list (no pointerover or pointerdown event occurred before this)n curGPoint.captured = false;n curGPoint.insideElementPressed = false;n curGPoint.insideElement = true;n startTrackingPointer( pointsList, curGPoint );n }n }nn // Stop (mouse only)n if ( tracker.stopHandler && gPoints[ 0 ].type === 'mouse' ) {n clearTimeout( tracker.stopTimeOut );n tracker.stopTimeOut = setTimeout( function() {n handlePointerStop( tracker, event, gPoints[ 0 ].type );n }, tracker.stopDelay );n }nn if ( pointsList.contacts === 0 ) {n // Move (no contacts: hovering mouse or other hover-capable device)n if ( tracker.moveHandler ) {n propagate = tracker.moveHandler(n {n eventSource: tracker,n pointerType: gPoints[ 0 ].type,n position: getPointRelativeToAbsolute( gPoints[ 0 ].currentPos, tracker.element ),n buttons: pointsList.buttons,n isTouchEvent: gPoints[ 0 ].type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }n } else if ( pointsList.contacts === 1 ) {n // Move (1 contact)n if ( tracker.moveHandler ) {n updateGPoint = pointsList.asArray()[ 0 ];n propagate = tracker.moveHandler(n {n eventSource: tracker,n pointerType: updateGPoint.type,n position: getPointRelativeToAbsolute( updateGPoint.currentPos, tracker.element ),n buttons: pointsList.buttons,n isTouchEvent: updateGPoint.type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }nn // Dragn if ( tracker.dragHandler ) {n updateGPoint = pointsList.asArray()[ 0 ];n delta = updateGPoint.currentPos.minus( updateGPoint.lastPos );n propagate = tracker.dragHandler(n {n eventSource: tracker,n pointerType: updateGPoint.type,n position: getPointRelativeToAbsolute( updateGPoint.currentPos, tracker.element ),n buttons: pointsList.buttons,n delta: delta,n speed: updateGPoint.speed,n direction: updateGPoint.direction,n shift: event.shiftKey,n isTouchEvent: updateGPoint.type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }n } else if ( pointsList.contacts === 2 ) {n // Move (2 contacts, use center)n if ( tracker.moveHandler ) {n gPointArray = pointsList.asArray();n propagate = tracker.moveHandler(n {n eventSource: tracker,n pointerType: gPointArray[ 0 ].type,n position: getPointRelativeToAbsolute( getCenterPoint( gPointArray[ 0 ].currentPos, gPointArray[ 1 ].currentPos ), tracker.element ),n buttons: pointsList.buttons,n isTouchEvent: gPointArray[ 0 ].type === 'touch',n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }nn // Pinchn if ( tracker.pinchHandler && gPoints[ 0 ].type === 'touch' ) {n delta = delegate.pinchGPoints[ 0 ].currentPos.distanceTo( delegate.pinchGPoints[ 1 ].currentPos );n if ( delta != delegate.currentPinchDist ) {n delegate.lastPinchDist = delegate.currentPinchDist;n delegate.currentPinchDist = delta;n delegate.lastPinchCenter = delegate.currentPinchCenter;n delegate.currentPinchCenter = getCenterPoint( delegate.pinchGPoints[ 0 ].currentPos, delegate.pinchGPoints[ 1 ].currentPos );n propagate = tracker.pinchHandler(n {n eventSource: tracker,n pointerType: 'touch',n gesturePoints: delegate.pinchGPoints,n lastCenter: getPointRelativeToAbsolute( delegate.lastPinchCenter, tracker.element ),n center: getPointRelativeToAbsolute( delegate.currentPinchCenter, tracker.element ),n lastDistance: delegate.lastPinchDist,n distance: delegate.currentPinchDist,n shift: event.shiftKey,n originalEvent: event,n preventDefaultAction: false,n userData: tracker.userDatan }n );n if ( propagate === false ) {n $.cancelEvent( event );n }n }n }n }n }nnn /**n * @functionn * @privaten * @innern * @param {OpenSeadragon.MouseTracker} trackern * A reference to the MouseTracker instance.n * @param {Object} eventn * A reference to the originating DOM event.n * @param {Array.<OpenSeadragon.MouseTracker.GesturePoint>} gPointsn * Gesture points associated with the event.n */n function updatePointersCancel( tracker, event, gPoints ) {n updatePointersUp( tracker, event, gPoints, 0 );n updatePointersExit( tracker, event, gPoints );n }nnn /**n * @privaten * @innern */n function handlePointerStop( tracker, originalMoveEvent, pointerType ) {n if ( tracker.stopHandler ) {n tracker.stopHandler( {n eventSource: tracker,n pointerType: pointerType,n position: getMouseRelative( originalMoveEvent, tracker.element ),n buttons: tracker.getActivePointersListByType( pointerType ).buttons,n isTouchEvent: pointerType === 'touch',n originalEvent: originalMoveEvent,n preventDefaultAction: false,n userData: tracker.userDatan } );n }n }nn /**n * True if inside an iframe, otherwise false.n * @member {Boolean} isInIframen * @privaten * @innern */n var isInIframe = (function() {n try {n return window.self !== window.top;n } catch (e) {n return true;n }n })();nn /**n * @functionn * @privaten * @innern * @returns {Boolean} True if the target has access rights to events, otherwise false.n */n function canAccessEvents (target) {n try {n return target.addEventListener && target.removeEventListener;n } catch (e) {n return false;n }n }nn}(OpenSeadragon));n”,“/*n * OpenSeadragon - Controln *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * An enumeration of supported locations where controls can be anchored.n * The anchoring is always relative to the container.n * @member ControlAnchorn * @memberof OpenSeadragonn * @staticn * @type {Object}n * @property {Number} NONEn * @property {Number} TOP_LEFTn * @property {Number} TOP_RIGHTn * @property {Number} BOTTOM_LEFTn * @property {Number} BOTTOM_RIGHTn * @property {Number} ABSOLUTEn */n$.ControlAnchor = {n NONE: 0,n TOP_LEFT: 1,n TOP_RIGHT: 2,n BOTTOM_RIGHT: 3,n BOTTOM_LEFT: 4,n ABSOLUTE: 5n};nn/**n * @class Controln * @classdesc A Control represents any interface element which is meant to allow the usern * to interact with the zoomable interface. Any control can be anchored to anyn * element.n *n * @memberof OpenSeadragonn * @param {Element} element - the control element to be anchored in the container.n * @param {Object } options - All required and optional settings for configuring a control element.n * @param {OpenSeadragon.ControlAnchor} [options.anchor=OpenSeadragon.ControlAnchor.NONE] - the position of the controln * relative to the container.n * @param {Boolean} [options.attachToViewer=true] - Whether the control should be added directly to the viewer, orn * directly to the containern * @param {Boolean} [options.autoFade=true] - Whether the control should have the autofade behaviorn * @param {Element} container - the element to control will be anchored too.n */n$.Control = function ( element, options, container ) {n var parent = element.parentNode;n if (typeof options === 'number')n {n $.console.error("Passing an anchor directly into the OpenSeadragon.Control constructor is deprecated; " +n "please use an options object instead. " +n "Support for this deprecated variant is scheduled for removal in December 2013");n options = {anchor: options};n }n options.attachToViewer = (typeof options.attachToViewer === 'undefined') ? true : options.attachToViewer;n /**n * True if the control should have autofade behavior.n * @member {Boolean} autoFaden * @memberof OpenSeadragon.Control#n */n this.autoFade = (typeof options.autoFade === 'undefined') ? true : options.autoFade;n /**n * The element providing the user interface with some type of control (e.g. a zoom-in button).n * @member {Element} elementn * @memberof OpenSeadragon.Control#n */n this.element = element;n /**n * The position of the Control relative to its container.n * @member {OpenSeadragon.ControlAnchor} anchorn * @memberof OpenSeadragon.Control#n */n this.anchor = options.anchor;n /**n * The Control's containing element.n * @member {Element} containern * @memberof OpenSeadragon.Control#n */n this.container = container;n /**n * A neutral element surrounding the control element.n * @member {Element} wrappern * @memberof OpenSeadragon.Control#n */n if ( this.anchor == $.ControlAnchor.ABSOLUTE ) {n this.wrapper = $.makeNeutralElement( "div" );n this.wrapper.style.position = "absolute";n this.wrapper.style.top = typeof (options.top) == "number" ? (options.top + 'px') : options.top;n this.wrapper.style.left = typeof (options.left) == "number" ? (options.left + 'px') : options.left;n this.wrapper.style.height = typeof (options.height) == "number" ? (options.height + 'px') : options.height;n this.wrapper.style.width = typeof (options.width) == "number" ? (options.width + 'px') : options.width;n this.wrapper.style.margin = "0px";n this.wrapper.style.padding = "0px";nn this.element.style.position = "relative";n this.element.style.top = "0px";n this.element.style.left = "0px";n this.element.style.height = "100%";n this.element.style.width = "100%";n } else {n this.wrapper = $.makeNeutralElement( "div" );n this.wrapper.style.display = "inline-block";n if ( this.anchor == $.ControlAnchor.NONE ) {n // IE6 fixn this.wrapper.style.width = this.wrapper.style.height = "100%";n }n }n this.wrapper.appendChild( this.element );nn if (options.attachToViewer ) {n if ( this.anchor == $.ControlAnchor.TOP_RIGHT ||n this.anchor == $.ControlAnchor.BOTTOM_RIGHT ) {n this.container.insertBefore(n this.wrapper,n this.container.firstChildn );n } else {n this.container.appendChild( this.wrapper );n }n } else {n parent.appendChild( this.wrapper );n }n};nn/** @lends OpenSeadragon.Control.prototype */n$.Control.prototype = {nn /**n * Removes the control from the container.n * @functionn */n destroy: function() {n this.wrapper.removeChild( this.element );n this.container.removeChild( this.wrapper );n },nn /**n * Determines if the control is currently visible.n * @functionn * @return {Boolean} true if currenly visible, false otherwise.n */n isVisible: function() {n return this.wrapper.style.display != "none";n },nn /**n * Toggles the visibility of the control.n * @functionn * @param {Boolean} visible - true to make visible, false to hide.n */n setVisible: function( visible ) {n this.wrapper.style.display = visible ?n ( this.anchor == $.ControlAnchor.ABSOLUTE ? 'block' : 'inline-block' ) :n "none";n },nn /**n * Sets the opacity level for the control.n * @functionn * @param {Number} opactiy - a value between 1 and 0 inclusively.n */n setOpacity: function( opacity ) {n if ( this.element[ $.SIGNAL ] && $.Browser.vendor == $.BROWSERS.IE ) {n $.setElementOpacity( this.element, opacity, true );n } else {n $.setElementOpacity( this.wrapper, opacity, true );n }n }n};nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - ControlDockn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){n /**n * @class ControlDockn * @classdesc Provides a container element (a &lt;form&gt; element) with support for the layout of control elements.n *n * @memberof OpenSeadragonn */n $.ControlDock = function( options ){n var layouts = [ 'topleft', 'topright', 'bottomright', 'bottomleft'],n layout,n i;nn $.extend( true, this, {n id: 'controldock-' + $.now() + '-' + Math.floor(Math.random() * 1000000),n container: $.makeNeutralElement( 'div' ),n controls: []n }, options );nn // Disable the form's submit; otherwise button clicks and return keysn // can trigger it.n this.container.onsubmit = function() {n return false;n };nn if( this.element ){n this.element = $.getElement( this.element );n this.element.appendChild( this.container );n this.element.style.position = 'relative';n this.container.style.width = '100%';n this.container.style.height = '100%';n }nn for( i = 0; i < layouts.length; i++ ){n layout = layouts[ i ];n this.controls[ layout ] = $.makeNeutralElement( "div" );n this.controls[ layout ].style.position = 'absolute';n if ( layout.match( 'left' ) ){n this.controls[ layout ].style.left = '0px';n }n if ( layout.match( 'right' ) ){n this.controls[ layout ].style.right = '0px';n }n if ( layout.match( 'top' ) ){n this.controls[ layout ].style.top = '0px';n }n if ( layout.match( 'bottom' ) ){n this.controls[ layout ].style.bottom = '0px';n }n }nn this.container.appendChild( this.controls.topleft );n this.container.appendChild( this.controls.topright );n this.container.appendChild( this.controls.bottomright );n this.container.appendChild( this.controls.bottomleft );n };nn /** @lends OpenSeadragon.ControlDock.prototype */n $.ControlDock.prototype = {nn /**n * @functionn */n addControl: function ( element, controlOptions ) {n element = $.getElement( element );n var div = null;nn if ( getControlIndex( this, element ) >= 0 ) {n return; // they're trying to add a duplicate controln }nn switch ( controlOptions.anchor ) {n case $.ControlAnchor.TOP_RIGHT:n div = this.controls.topright;n element.style.position = "relative";n element.style.paddingRight = "0px";n element.style.paddingTop = "0px";n break;n case $.ControlAnchor.BOTTOM_RIGHT:n div = this.controls.bottomright;n element.style.position = "relative";n element.style.paddingRight = "0px";n element.style.paddingBottom = "0px";n break;n case $.ControlAnchor.BOTTOM_LEFT:n div = this.controls.bottomleft;n element.style.position = "relative";n element.style.paddingLeft = "0px";n element.style.paddingBottom = "0px";n break;n case $.ControlAnchor.TOP_LEFT:n div = this.controls.topleft;n element.style.position = "relative";n element.style.paddingLeft = "0px";n element.style.paddingTop = "0px";n break;n case $.ControlAnchor.ABSOLUTE:n div = this.container;n element.style.margin = "0px";n element.style.padding = "0px";n break;n default:n case $.ControlAnchor.NONE:n div = this.container;n element.style.margin = "0px";n element.style.padding = "0px";n break;n }nn this.controls.push(n new $.Control( element, controlOptions, div )n );n element.style.display = "inline-block";n },nnn /**n * @functionn * @return {OpenSeadragon.ControlDock} Chainable.n */n removeControl: function ( element ) {n element = $.getElement( element );n var i = getControlIndex( this, element );nn if ( i >= 0 ) {n this.controls[ i ].destroy();n this.controls.splice( i, 1 );n }nn return this;n },nn /**n * @functionn * @return {OpenSeadragon.ControlDock} Chainable.n */n clearControls: function () {n while ( this.controls.length > 0 ) {n this.controls.pop().destroy();n }nn return this;n },nnn /**n * @functionn * @return {Boolean}n */n areControlsEnabled: function () {n var i;nn for ( i = this.controls.length - 1; i >= 0; i– ) {n if ( this.controls[ i ].isVisible() ) {n return true;n }n }nn return false;n },nnn /**n * @functionn * @return {OpenSeadragon.ControlDock} Chainable.n */n setControlsEnabled: function( enabled ) {n var i;nn for ( i = this.controls.length - 1; i >= 0; i– ) {n this.controls[ i ].setVisible( enabled );n }nn return this;n }nn };nnn ///////////////////////////////////////////////////////////////////////////////n // Utility methodsn ///////////////////////////////////////////////////////////////////////////////n function getControlIndex( dock, element ) {n var controls = dock.controls,n i;nn for ( i = controls.length - 1; i >= 0; i– ) {n if ( controls[ i ].element == element ) {n return i;n }n }nn return -1;n }nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - Placementn *n * Copyright (C) 2010-2016 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function($) {nn /**n * An enumeration of positions to anchor an element.n * @member Placementn * @memberOf OpenSeadragonn * @staticn * @readonlyn * @property {OpenSeadragon.Placement} CENTERn * @property {OpenSeadragon.Placement} TOP_LEFTn * @property {OpenSeadragon.Placement} TOPn * @property {OpenSeadragon.Placement} TOP_RIGHTn * @property {OpenSeadragon.Placement} RIGHTn * @property {OpenSeadragon.Placement} BOTTOM_RIGHTn * @property {OpenSeadragon.Placement} BOTTOMn * @property {OpenSeadragon.Placement} BOTTOM_LEFTn * @property {OpenSeadragon.Placement} LEFTn */n $.Placement = $.freezeObject({n CENTER: 0,n TOP_LEFT: 1,n TOP: 2,n TOP_RIGHT: 3,n RIGHT: 4,n BOTTOM_RIGHT: 5,n BOTTOM: 6,n BOTTOM_LEFT: 7,n LEFT: 8,n properties: {n 0: {n isLeft: false,n isHorizontallyCentered: true,n isRight: false,n isTop: false,n isVerticallyCentered: true,n isBottom: falsen },n 1: {n isLeft: true,n isHorizontallyCentered: false,n isRight: false,n isTop: true,n isVerticallyCentered: false,n isBottom: falsen },n 2: {n isLeft: false,n isHorizontallyCentered: true,n isRight: false,n isTop: true,n isVerticallyCentered: false,n isBottom: falsen },n 3: {n isLeft: false,n isHorizontallyCentered: false,n isRight: true,n isTop: true,n isVerticallyCentered: false,n isBottom: falsen },n 4: {n isLeft: false,n isHorizontallyCentered: false,n isRight: true,n isTop: false,n isVerticallyCentered: true,n isBottom: falsen },n 5: {n isLeft: false,n isHorizontallyCentered: false,n isRight: true,n isTop: false,n isVerticallyCentered: false,n isBottom: truen },n 6: {n isLeft: false,n isHorizontallyCentered: true,n isRight: false,n isTop: false,n isVerticallyCentered: false,n isBottom: truen },n 7: {n isLeft: true,n isHorizontallyCentered: false,n isRight: false,n isTop: false,n isVerticallyCentered: false,n isBottom: truen },n 8: {n isLeft: true,n isHorizontallyCentered: false,n isRight: false,n isTop: false,n isVerticallyCentered: true,n isBottom: falsen }n }n });nn}(OpenSeadragon));n”,“/*n * OpenSeadragon - Viewern *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn// dictionary from hash to private propertiesnvar THIS = {};nvar nextHash = 1;nn/**n *n * The main point of entry into creating a zoomable image on the page.
n *
n * We have provided an idiomatic javascript constructor which takesn * a single object, but still support the legacy positional arguments.
n *
n * The options below are given in order that they appeared in the constructorn * as arguments and we translate a positional call into an idiomatic call.
n *
n * To create a viewer, you can use either of this methods:
n * <ul>n * <li>var viewer = new OpenSeadragon.Viewer(options);</li>n * <li>var viewer = OpenSeadragon(options);</li>n * </ul>n * @class Viewern * @classdesc The main OpenSeadragon viewer class.n *n * @memberof OpenSeadragonn * @extends OpenSeadragon.EventSourcen * @extends OpenSeadragon.ControlDockn * @param {OpenSeadragon.Options} options - Viewer options.n *n **/n$.Viewer = function( options ) {nn var args = arguments,n _this = this,n i;nnn //backward compatibility for positional args while prefering moren //idiomatic javascript options object as the only argumentn if( !$.isPlainObject( options ) ){n options = {n id: args[ 0 ],n xmlPath: args.length > 1 ? args[ 1 ] : undefined,n prefixUrl: args.length > 2 ? args[ 2 ] : undefined,n controls: args.length > 3 ? args[ 3 ] : undefined,n overlays: args.length > 4 ? args[ 4 ] : undefinedn };n }nn //options.config and the general config argument are deprecatedn //in favor of the more direct specification of optional settingsn //being pass directly on the options objectn if ( options.config ){n $.extend( true, options, options.config );n delete options.config;n }nn //Public propertiesn //Allow the options object to override global defaultsn $.extend( true, this, {nn //internal state and dom identifiersn id: options.id,n hash: options.hash || nextHash++,n /**n * Index for page to be shown first next time open() is called (only used in sequenceMode).n * @member {Number} initialPagen * @memberof OpenSeadragon.Viewer#n */n initialPage: 0,nn //dom nodesn /**n * The parent element of this Viewer instance, passed in when the Viewer was created.n * @member {Element} elementn * @memberof OpenSeadragon.Viewer#n */n element: null,n /**n * A &lt;div&gt; element (provided by {@link OpenSeadragon.ControlDock}), the base element of this Viewer instance.
n * Child element of {@link OpenSeadragon.Viewer#element}.n * @member {Element} containern * @memberof OpenSeadragon.Viewer#n */n container: null,n /**n * A &lt;div&gt; element, the element where user-input events are handled for panning and zooming.
n * Child element of {@link OpenSeadragon.Viewer#container},n * positioned on top of {@link OpenSeadragon.Viewer#keyboardCommandArea}.
n * The parent of {@link OpenSeadragon.Drawer#canvas} instances.n * @member {Element} canvasn * @memberof OpenSeadragon.Viewer#n */n canvas: null,nn // Overlays list. An overlay allows to add html on top of the viewer.n overlays: [],n // Container inside the canvas where overlays are drawn.n overlaysContainer: null,nn //private state propertiesn previousBody: [],nn //This was originally initialized in the constructor and so could nevern //have anything in it. now it can because we allow it to be specifiedn //in the options and is only empty by default if not specified. Alson //this array was returned from get_controls which I find confusingn //since this object has a controls property which is treated in othern //functions like clearControls. I'm removing the accessors.n customControls: [],nn //These are originally not part options but declared as membersn //in initialize. It's still considered idiomatic to put them heren //source is here for backwards compatibility. It is not an officialn //part of the API and should not be relied upon.n source: null,n /**n * Handles rendering of tiles in the viewer. Created for each TileSource opened.n * @member {OpenSeadragon.Drawer} drawern * @memberof OpenSeadragon.Viewer#n */n drawer: null,n /**n * Keeps track of all of the tiled images in the scene.n * @member {OpenSeadragon.Drawer} worldn * @memberof OpenSeadragon.Viewer#n */n world: null,n /**n * Handles coordinate-related functionality - zoom, pan, rotation, etc. Created for each TileSource opened.n * @member {OpenSeadragon.Viewport} viewportn * @memberof OpenSeadragon.Viewer#n */n viewport: null,n /**n * @member {OpenSeadragon.Navigator} navigatorn * @memberof OpenSeadragon.Viewer#n */n navigator: null,nn //A collection viewport is a separate viewport used to providen //simultaneous rendering of sets of tilesn collectionViewport: null,n collectionDrawer: null,nn //UI image resourcesn //TODO: rename navImages to uiImagesn navImages: null,nn //interface button controlsn buttons: null,nn //TODO: this is defunct so safely remove itn profiler: nullnn }, $.DEFAULT_SETTINGS, options );nn if ( typeof ( this.hash) === "undefined" ) {n throw new Error("A hash must be defined, either by specifying options.id or options.hash.");n }n if ( typeof ( THIS[ this.hash ] ) !== "undefined" ) {n // We don't want to throw an error here, as the user might have discardedn // the previous viewer with the same hash and now want to recreate it.n $.console.warn("Hash " + this.hash + " has already been used.");n }nn //Private state propertiesn THIS[ this.hash ] = {n "fsBoundsDelta": new $.Point( 1, 1 ),n "prevContainerSize": null,n "animating": false,n "forceRedraw": false,n "mouseInside": false,n "group": null,n // whether we should be continuously zoomingn "zooming": false,n // how much we should be continuously zooming byn "zoomFactor": null,n "lastZoomTime": null,n "fullPage": false,n "onfullscreenchange": nulln };nn this._sequenceIndex = 0;n this._firstOpen = true;n this._updateRequestId = null;n this._loadQueue = [];n this.currentOverlays = [];nn this._lastScrollTime = $.now(); // variable used to help normalize the scroll event speed of different devicesnn //Inherit some behaviors and propertiesn $.EventSource.call( this );nn this.addHandler( 'open-failed', function ( event ) {n var msg = $.getString( "Errors.OpenFailed", event.eventSource, event.message);n _this._showMessage( msg );n });nn $.ControlDock.call( this, options );nn //Deal with tile sourcesn if (this.xmlPath) {n //Deprecated option. Now it is preferred to use the tileSources optionn this.tileSources = [ this.xmlPath ];n }nn this.element = this.element || document.getElementById( this.id );n this.canvas = $.makeNeutralElement( "div" );nn this.canvas.className = "openseadragon-canvas";n (function( style ){n style.width = "100%";n style.height = "100%";n style.overflow = "hidden";n style.position = "absolute";n style.top = "0px";n style.left = "0px";n }(this.canvas.style));n $.setElementTouchActionNone( this.canvas );n if (options.tabIndex !== "") {n this.canvas.tabIndex = (options.tabIndex === undefined ? 0 : options.tabIndex);n }nn //the container is created through applying the ControlDock constructor aboven this.container.className = "openseadragon-container";n (function( style ){n style.width = "100%";n style.height = "100%";n style.position = "relative";n style.overflow = "hidden";n style.left = "0px";n style.top = "0px";n style.textAlign = "left"; // needed to protect againstn }( this.container.style ));nn this.container.insertBefore( this.canvas, this.container.firstChild );n this.element.appendChild( this.container );nn //Used for toggling between fullscreen and default container sizen //TODO: these can be closure private and shared across Viewern // instances.n this.bodyWidth = document.body.style.width;n this.bodyHeight = document.body.style.height;n this.bodyOverflow = document.body.style.overflow;n this.docOverflow = document.documentElement.style.overflow;nn this.innerTracker = new $.MouseTracker({n element: this.canvas,n startDisabled: !this.mouseNavEnabled,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n dblClickTimeThreshold: this.dblClickTimeThreshold,n dblClickDistThreshold: this.dblClickDistThreshold,n keyDownHandler: $.delegate( this, onCanvasKeyDown ),n keyHandler: $.delegate( this, onCanvasKeyPress ),n clickHandler: $.delegate( this, onCanvasClick ),n dblClickHandler: $.delegate( this, onCanvasDblClick ),n dragHandler: $.delegate( this, onCanvasDrag ),n dragEndHandler: $.delegate( this, onCanvasDragEnd ),n enterHandler: $.delegate( this, onCanvasEnter ),n exitHandler: $.delegate( this, onCanvasExit ),n pressHandler: $.delegate( this, onCanvasPress ),n releaseHandler: $.delegate( this, onCanvasRelease ),n nonPrimaryPressHandler: $.delegate( this, onCanvasNonPrimaryPress ),n nonPrimaryReleaseHandler: $.delegate( this, onCanvasNonPrimaryRelease ),n scrollHandler: $.delegate( this, onCanvasScroll ),n pinchHandler: $.delegate( this, onCanvasPinch )n });nn this.outerTracker = new $.MouseTracker({n element: this.container,n startDisabled: !this.mouseNavEnabled,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n dblClickTimeThreshold: this.dblClickTimeThreshold,n dblClickDistThreshold: this.dblClickDistThreshold,n enterHandler: $.delegate( this, onContainerEnter ),n exitHandler: $.delegate( this, onContainerExit )n });nn if( this.toolbar ){n this.toolbar = new $.ControlDock({ element: this.toolbar });n }nn this.bindStandardControls();nn THIS[ this.hash ].prevContainerSize = _getSafeElemSize( this.container );nn // Create the worldn this.world = new $.World({n viewer: thisn });nn this.world.addHandler('add-item', function(event) {n // For backwards compatibility, we maintain the source propertyn _this.source = _this.world.getItemAt(0).source;nn THIS[ _this.hash ].forceRedraw = true;nn if (!_this._updateRequestId) {n _this._updateRequestId = scheduleUpdate( _this, updateMulti );n }n });nn this.world.addHandler('remove-item', function(event) {n // For backwards compatibility, we maintain the source propertyn if (_this.world.getItemCount()) {n _this.source = _this.world.getItemAt(0).source;n } else {n _this.source = null;n }nn THIS[ _this.hash ].forceRedraw = true;n });nn this.world.addHandler('metrics-change', function(event) {n if (_this.viewport) {n _this.viewport._setContentBounds(_this.world.getHomeBounds(), _this.world.getContentFactor());n }n });nn this.world.addHandler('item-index-change', function(event) {n // For backwards compatibility, we maintain the source propertyn _this.source = _this.world.getItemAt(0).source;n });nn // Create the viewportn this.viewport = new $.Viewport({n containerSize: THIS[ this.hash ].prevContainerSize,n springStiffness: this.springStiffness,n animationTime: this.animationTime,n minZoomImageRatio: this.minZoomImageRatio,n maxZoomPixelRatio: this.maxZoomPixelRatio,n visibilityRatio: this.visibilityRatio,n wrapHorizontal: this.wrapHorizontal,n wrapVertical: this.wrapVertical,n defaultZoomLevel: this.defaultZoomLevel,n minZoomLevel: this.minZoomLevel,n maxZoomLevel: this.maxZoomLevel,n viewer: this,n degrees: this.degrees,n flipped: this.flipped,n navigatorRotate: this.navigatorRotate,n homeFillsViewer: this.homeFillsViewer,n margins: this.viewportMarginsn });nn this.viewport._setContentBounds(this.world.getHomeBounds(), this.world.getContentFactor());nn // Create the image loadern this.imageLoader = new $.ImageLoader({n jobLimit: this.imageLoaderLimit,n timeout: options.timeoutn });nn // Create the tile cachen this.tileCache = new $.TileCache({n maxImageCacheCount: this.maxImageCacheCountn });nn // Create the drawern this.drawer = new $.Drawer({n viewer: this,n viewport: this.viewport,n element: this.canvas,n debugGridColor: this.debugGridColorn });nn // Overlay containern this.overlaysContainer = $.makeNeutralElement( "div" );n this.canvas.appendChild( this.overlaysContainer );nn // Now that we have a drawer, see if it supports rotate. If not we need to remove the rotate buttonsn if (!this.drawer.canRotate()) {n // Disable/remove the rotate left/right buttons since they aren't supportedn if (this.rotateLeft) {n i = this.buttons.buttons.indexOf(this.rotateLeft);n this.buttons.buttons.splice(i, 1);n this.buttons.element.removeChild(this.rotateLeft.element);n }n if (this.rotateRight) {n i = this.buttons.buttons.indexOf(this.rotateRight);n this.buttons.buttons.splice(i, 1);n this.buttons.element.removeChild(this.rotateRight.element);n }n }nn //Instantiate a navigator if configuredn if ( this.showNavigator){n this.navigator = new $.Navigator({n id: this.navigatorId,n position: this.navigatorPosition,n sizeRatio: this.navigatorSizeRatio,n maintainSizeRatio: this.navigatorMaintainSizeRatio,n top: this.navigatorTop,n left: this.navigatorLeft,n width: this.navigatorWidth,n height: this.navigatorHeight,n autoResize: this.navigatorAutoResize,n autoFade: this.navigatorAutoFade,n prefixUrl: this.prefixUrl,n viewer: this,n navigatorRotate: this.navigatorRotate,n background: this.navigatorBackground,n opacity: this.navigatorOpacity,n borderColor: this.navigatorBorderColor,n displayRegionColor: this.navigatorDisplayRegionColor,n crossOriginPolicy: this.crossOriginPolicyn });n }nn // Sequence moden if (this.sequenceMode) {n this.bindSequenceControls();n }nn // Open initial tilesourcesn if (this.tileSources) {n this.open( this.tileSources );n }nn // Add custom controlsn for ( i = 0; i < this.customControls.length; i++ ) {n this.addControl(n this.customControls[ i ].id,n {anchor: this.customControls[ i ].anchor}n );n }nn // Initial fade outn $.requestAnimationFrame( function(){n beginControlsAutoHide( _this );n } );n};nn$.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, /** @lends OpenSeadragon.Viewer.prototype */{nnn /**n * @functionn * @return {Boolean}n */n isOpen: function () {n return !!this.world.getItemCount();n },nn // deprecatedn openDzi: function ( dzi ) {n $.console.error( "[Viewer.openDzi] this function is deprecated; use Viewer.open() instead." );n return this.open( dzi );n },nn // deprecatedn openTileSource: function ( tileSource ) {n $.console.error( "[Viewer.openTileSource] this function is deprecated; use Viewer.open() instead." );n return this.open( tileSource );n },nn /**n * Open tiled images into the viewer, closing any others.n * To get the TiledImage instance created by open, add an event listener forn * {@link OpenSeadragon.Viewer.html#.event:open}, which when fired can be used to get accessn * to the instance, i.e., viewer.world.getItemAt(0).n * @functionn * @param {Array|String|Object|Function} tileSources - This can be a TiledImagen * specifier, a TileSource specifier, or an array of either. A TiledImage specifiern * is the same as the options parameter for {@link OpenSeadragon.Viewer#addTiledImage},n * except for the index property; images are added in sequence.n * A TileSource specifier is anything you could pass as the tileSource propertyn * of the options parameter for {@link OpenSeadragon.Viewer#addTiledImage}.n * @param {Number} initialPage - If sequenceMode is true, display this page initiallyn * for the given tileSources. If specified, will overwrite the Viewer's existing initialPage property.n * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:openn * @fires OpenSeadragon.Viewer.event:open-failedn */n open: function (tileSources, initialPage) {n var _this = this;nn this.close();nn if (!tileSources) {n return;n }nn if (this.sequenceMode && $.isArray(tileSources)) {n if (this.referenceStrip) {n this.referenceStrip.destroy();n this.referenceStrip = null;n }nn if (typeof initialPage != 'undefined' && !isNaN(initialPage)) {n this.initialPage = initialPage;n }nn this.tileSources = tileSources;n this._sequenceIndex = Math.max(0, Math.min(this.tileSources.length - 1, this.initialPage));n if (this.tileSources.length) {n this.open(this.tileSources);nn if ( this.showReferenceStrip ){n this.addReferenceStrip();n }n }nn this._updateSequenceButtons( this._sequenceIndex );n return;n }nn if (!$.isArray(tileSources)) {n tileSources = [tileSources];n }nn if (!tileSources.length) {n return;n }nn this._opening = true;nn var expected = tileSources.length;n var successes = 0;n var failures = 0;n var failEvent;nn var checkCompletion = function() {n if (successes + failures === expected) {n if (successes) {n if (_this._firstOpen || !_this.preserveViewport) {n _this.viewport.goHome( true );n _this.viewport.update();n }nn _this._firstOpen = false;nn var source = tileSources;n if (source.tileSource) {n source = source.tileSource;n }nn // Global overlaysn if( _this.overlays && !_this.preserveOverlays ){n for ( var i = 0; i < _this.overlays.length; i++ ) {n _this.currentOverlays[ i ] = getOverlayObject( _this, _this.overlays[ i ] );n }n }nn _this._drawOverlays();n _this._opening = false;nn /**n * Raised when the viewer has opened and loaded one or more TileSources.n *n * @event openn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {OpenSeadragon.TileSource} source - The tile source that was opened.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n // TODO: what if there are multiple sources?n _this.raiseEvent( 'open', { source: source } );n } else {n _this._opening = false;nn /**n * Raised when an error occurs loading a TileSource.n *n * @event open-failedn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {String} message - Information about what failed.n * @property {String} source - The tile source that failed.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( 'open-failed', failEvent );n }n }n };nn var doOne = function(options) {n if (!$.isPlainObject(options) || !options.tileSource) {n options = {n tileSource: optionsn };n }nn if (options.index !== undefined) {n $.console.error(‘ setting indexes here is not supported; use addTiledImage instead');n delete options.index;n }nn if (options.collectionImmediately === undefined) {n options.collectionImmediately = true;n }nn var originalSuccess = options.success;n options.success = function(event) {n successes++;nn // TODO: now that options has other things besides tileSource, the overlaysn // should probably be at the options level, not the tileSource level.n if (options.tileSource.overlays) {n for (var i = 0; i < options.tileSource.overlays.length; i++) {n _this.addOverlay(options.tileSource.overlays);n }n }nn if (originalSuccess) {n originalSuccess(event);n }nn checkCompletion();n };nn var originalError = options.error;n options.error = function(event) {n failures++;nn if (!failEvent) {n failEvent = event;n }nn if (originalError) {n originalError(event);n }nn checkCompletion();n };nn _this.addTiledImage(options);n };nn // TileSourcesn for (var i = 0; i < tileSources.length; i++) {n doOne(tileSources);n }nn return this;n },nnn /**n * @functionn * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:closen */n close: function ( ) {n if ( !THIS[ this.hash ] ) {n //this viewer has already been destroyed: returning immediatelyn return this;n }nn this._opening = false;nn if ( this.navigator ) {n this.navigator.close();n }nn if (!this.preserveOverlays) {n this.clearOverlays();n this.overlaysContainer.innerHTML = "";n }nn THIS[ this.hash ].animating = false;n this.world.removeAll();n this.imageLoader.clear();nn /**n * Raised when the viewer is closed (see {@link OpenSeadragon.Viewer#close}).n *n * @event closen * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'close' );nn return this;n },nnn /**n * Function to destroy the viewer and clean up everything created by OpenSeadragon.n *n * Example:n * var viewer = OpenSeadragon({n * […]n * });n *n * //when you are done with the viewer:n * viewer.destroy();n * viewer = null; //importantn *n * @functionn */n destroy: function( ) {n if ( !THIS[ this.hash ] ) {n //this viewer has already been destroyed: returning immediatelyn return;n }nn this.close();nn this.clearOverlays();n this.overlaysContainer.innerHTML = "";nn //TODO: implement this…n //this.unbindSequenceControls()n //this.unbindStandardControls()nn if (this.referenceStrip) {n this.referenceStrip.destroy();n this.referenceStrip = null;n }nn if ( this._updateRequestId !== null ) {n $.cancelAnimationFrame( this._updateRequestId );n this._updateRequestId = null;n }nn if ( this.drawer ) {n this.drawer.destroy();n }nn this.removeAllHandlers();nn // Go through top element (passed to us) and remove all childrenn // Use removeChild to make sure it handles SVG or any non-htmln // also it performs better - jsperf.com/innerhtml-vs-removechild/15n if (this.element){n while (this.element.firstChild) {n this.element.removeChild(this.element.firstChild);n }n }nn // destroy the mouse trackersn if (this.innerTracker){n this.innerTracker.destroy();n }n if (this.outerTracker){n this.outerTracker.destroy();n }nn THIS[ this.hash ] = null;n delete THIS[ this.hash ];nn // clear all our references to dom objectsn this.canvas = null;n this.container = null;nn // clear our reference to the main element - they will need to pass it in again, creating a new viewern this.element = null;n },nn /**n * @functionn * @return {Boolean}n */n isMouseNavEnabled: function () {n return this.innerTracker.isTracking();n },nn /**n * @functionn * @param {Boolean} enabled - true to enable, false to disablen * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:mouse-enabledn */n setMouseNavEnabled: function( enabled ){n this.innerTracker.setTracking( enabled );n this.outerTracker.setTracking( enabled );n /**n * Raised when mouse/touch navigation is enabled or disabled (see {@link OpenSeadragon.Viewer#setMouseNavEnabled}).n *n * @event mouse-enabledn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {Boolean} enabledn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'mouse-enabled', { enabled: enabled } );n return this;n },nnn /**n * @functionn * @return {Boolean}n */n areControlsEnabled: function () {n var enabled = this.controls.length,n i;n for( i = 0; i < this.controls.length; i++ ){n enabled = enabled && this.controls[ i ].isVisibile();n }n return enabled;n },nnn /**n * Shows or hides the controls (e.g. the default navigation buttons).n *n * @functionn * @param {Boolean} true to show, false to hide.n * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:controls-enabledn */n setControlsEnabled: function( enabled ) {n if( enabled ){n abortControlsAutoHide( this );n } else {n beginControlsAutoHide( this );n }n /**n * Raised when the navigation controls are shown or hidden (see {@link OpenSeadragon.Viewer#setControlsEnabled}).n *n * @event controls-enabledn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {Boolean} enabledn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'controls-enabled', { enabled: enabled } );n return this;n },nn /**n * Turns debugging mode on or off for this viewer.n *n * @functionn * @param {Boolean} true to turn debug on, false to turn debug off.n */n setDebugMode: function(debugMode){nn for (var i = 0; i < this.world.getItemCount(); i++) {n this.world.getItemAt(i).debugMode = debugMode;n }nn this.debugMode = debugMode;n this.forceRedraw();n },nn /**n * @functionn * @return {Boolean}n */n isFullPage: function () {n return THIS[ this.hash ].fullPage;n },nnn /**n * Toggle full page mode.n * @functionn * @param {Boolean} fullPagen * If true, enter full page mode. If false, exit full page mode.n * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:pre-full-pagen * @fires OpenSeadragon.Viewer.event:full-pagen */n setFullPage: function( fullPage ) {nn var body = document.body,n bodyStyle = body.style,n docStyle = document.documentElement.style,n _this = this,n nodes,n i;nn //dont bother modifying the DOM if we are already in full page mode.n if ( fullPage == this.isFullPage() ) {n return this;n }nn var fullPageEventArgs = {n fullPage: fullPage,n preventDefaultAction: falsen };n /**n * Raised when the viewer is about to change to/from full-page mode (see {@link OpenSeadragon.Viewer#setFullPage}).n *n * @event pre-full-pagen * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {Boolean} fullPage - True if entering full-page mode, false if exiting full-page mode.n * @property {Boolean} preventDefaultAction - Set to true to prevent full-page mode change. Default: false.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'pre-full-page', fullPageEventArgs );n if ( fullPageEventArgs.preventDefaultAction ) {n return this;n }nn if ( fullPage ) {nn this.elementSize = $.getElementSize( this.element );n this.pageScroll = $.getPageScroll();nn this.elementMargin = this.element.style.margin;n this.element.style.margin = "0";n this.elementPadding = this.element.style.padding;n this.element.style.padding = "0";nn this.bodyMargin = bodyStyle.margin;n this.docMargin = docStyle.margin;n bodyStyle.margin = "0";n docStyle.margin = "0";nn this.bodyPadding = bodyStyle.padding;n this.docPadding = docStyle.padding;n bodyStyle.padding = "0";n docStyle.padding = "0";nn this.bodyWidth = bodyStyle.width;n this.docWidth = docStyle.width;n bodyStyle.width = "100%";n docStyle.width = "100%";nn this.bodyHeight = bodyStyle.height;n this.docHeight = docStyle.height;n bodyStyle.height = "100%";n docStyle.height = "100%";nn //when entering full screen on the ipad it wasnt sufficient to leaven //the body intact as only only the top half of the screen wouldn //respond to touch events on the canvas, while the bottom half treatedn //them as touch events on the document body. Thus we remove and storen //the bodies elements and replace them when we leave full screen.n this.previousBody = [];n THIS[ this.hash ].prevElementParent = this.element.parentNode;n THIS[ this.hash ].prevNextSibling = this.element.nextSibling;n THIS[ this.hash ].prevElementWidth = this.element.style.width;n THIS[ this.hash ].prevElementHeight = this.element.style.height;n nodes = body.childNodes.length;n for ( i = 0; i < nodes; i++ ) {n this.previousBody.push( body.childNodes[ 0 ] );n body.removeChild( body.childNodes[ 0 ] );n }nn //If we've got a toolbar, we need to enable the user to use css ton //preserve it in fullpage moden if ( this.toolbar && this.toolbar.element ) {n //save a reference to the parent so we can put it backn //in the long run we need a better strategyn this.toolbar.parentNode = this.toolbar.element.parentNode;n this.toolbar.nextSibling = this.toolbar.element.nextSibling;n body.appendChild( this.toolbar.element );nn //Make sure the user has some ability to style the toolbar basedn //on the moden $.addClass( this.toolbar.element, 'fullpage' );n }nn $.addClass( this.element, 'fullpage' );n body.appendChild( this.element );nn this.element.style.height = $.getWindowSize().y + 'px';n this.element.style.width = $.getWindowSize().x + 'px';nn if ( this.toolbar && this.toolbar.element ) {n this.element.style.height = (n $.getElementSize( this.element ).y - $.getElementSize( this.toolbar.element ).yn ) + 'px';n }nn THIS[ this.hash ].fullPage = true;nn // mouse will be inside container nown $.delegate( this, onContainerEnter )( {} );nn } else {nn this.element.style.margin = this.elementMargin;n this.element.style.padding = this.elementPadding;nn bodyStyle.margin = this.bodyMargin;n docStyle.margin = this.docMargin;nn bodyStyle.padding = this.bodyPadding;n docStyle.padding = this.docPadding;nn bodyStyle.width = this.bodyWidth;n docStyle.width = this.docWidth;nn bodyStyle.height = this.bodyHeight;n docStyle.height = this.docHeight;nn body.removeChild( this.element );n nodes = this.previousBody.length;n for ( i = 0; i < nodes; i++ ) {n body.appendChild( this.previousBody.shift() );n }nn $.removeClass( this.element, 'fullpage' );n THIS[ this.hash ].prevElementParent.insertBefore(n this.element,n THIS[ this.hash ].prevNextSiblingn );nn //If we've got a toolbar, we need to enable the user to use css ton //reset it to its original staten if ( this.toolbar && this.toolbar.element ) {n body.removeChild( this.toolbar.element );nn //Make sure the user has some ability to style the toolbar basedn //on the moden $.removeClass( this.toolbar.element, 'fullpage' );nn this.toolbar.parentNode.insertBefore(n this.toolbar.element,n this.toolbar.nextSiblingn );n delete this.toolbar.parentNode;n delete this.toolbar.nextSibling;n }nn this.element.style.width = THIS[ this.hash ].prevElementWidth;n this.element.style.height = THIS[ this.hash ].prevElementHeight;nn // After exiting fullPage or fullScreen, it can take some timen // before the browser can actually set the scroll.n var restoreScrollCounter = 0;n var restoreScroll = function() {n $.setPageScroll( _this.pageScroll );n var pageScroll = $.getPageScroll();n restoreScrollCounter++;n if (restoreScrollCounter < 10 &&n (pageScroll.x !== _this.pageScroll.x ||n pageScroll.y !== _this.pageScroll.y)) {n $.requestAnimationFrame( restoreScroll );n }n };n $.requestAnimationFrame( restoreScroll );nn THIS[ this.hash ].fullPage = false;nn // mouse will likely be outside nown $.delegate( this, onContainerExit )( { } );nn }nn if ( this.navigator && this.viewport ) {n this.navigator.update( this.viewport );n }nn /**n * Raised when the viewer has changed to/from full-page mode (see {@link OpenSeadragon.Viewer#setFullPage}).n *n * @event full-pagen * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {Boolean} fullPage - True if changed to full-page mode, false if exited full-page mode.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'full-page', { fullPage: fullPage } );nn return this;n },nn /**n * Toggle full screen mode if supported. Toggle full page mode otherwise.n * @functionn * @param {Boolean} fullScreenn * If true, enter full screen mode. If false, exit full screen mode.n * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:pre-full-screenn * @fires OpenSeadragon.Viewer.event:full-screenn */n setFullScreen: function( fullScreen ) {n var _this = this;nn if ( !$.supportsFullScreen ) {n return this.setFullPage( fullScreen );n }nn if ( $.isFullScreen() === fullScreen ) {n return this;n }nn var fullScreeEventArgs = {n fullScreen: fullScreen,n preventDefaultAction: falsen };n /**n * Raised when the viewer is about to change to/from full-screen mode (see {@link OpenSeadragon.Viewer#setFullScreen}).n * Note: the pre-full-screen event is not raised when the user is exitingn * full-screen mode by pressing the Esc key. In that case, consider usingn * the full-screen, pre-full-page or full-page events.n *n * @event pre-full-screenn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {Boolean} fullScreen - True if entering full-screen mode, false if exiting full-screen mode.n * @property {Boolean} preventDefaultAction - Set to true to prevent full-screen mode change. Default: false.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'pre-full-screen', fullScreeEventArgs );n if ( fullScreeEventArgs.preventDefaultAction ) {n return this;n }nn if ( fullScreen ) {nn this.setFullPage( true );n // If the full page mode is not actually entered, we need to preventn // the full screen mode.n if ( !this.isFullPage() ) {n return this;n }nn this.fullPageStyleWidth = this.element.style.width;n this.fullPageStyleHeight = this.element.style.height;n this.element.style.width = '100%';n this.element.style.height = '100%';nn var onFullScreenChange = function() {n var isFullScreen = $.isFullScreen();n if ( !isFullScreen ) {n $.removeEvent( document, $.fullScreenEventName, onFullScreenChange );n $.removeEvent( document, $.fullScreenErrorEventName, onFullScreenChange );nn _this.setFullPage( false );n if ( _this.isFullPage() ) {n _this.element.style.width = _this.fullPageStyleWidth;n _this.element.style.height = _this.fullPageStyleHeight;n }n }n if ( _this.navigator && _this.viewport ) {n _this.navigator.update( _this.viewport );n }n /**n * Raised when the viewer has changed to/from full-screen mode (see {@link OpenSeadragon.Viewer#setFullScreen}).n *n * @event full-screenn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {Boolean} fullScreen - True if changed to full-screen mode, false if exited full-screen mode.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( 'full-screen', { fullScreen: isFullScreen } );n };n $.addEvent( document, $.fullScreenEventName, onFullScreenChange );n $.addEvent( document, $.fullScreenErrorEventName, onFullScreenChange );nn $.requestFullScreen( document.body );nn } else {n $.exitFullScreen();n }n return this;n },nn /**n * @functionn * @return {Boolean}n */n isVisible: function () {n return this.container.style.visibility != "hidden";n },nnn /**n * @functionn * @param {Boolean} visiblen * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:visiblen */n setVisible: function( visible ){n this.container.style.visibility = visible ? "" : "hidden";n /**n * Raised when the viewer is shown or hidden (see {@link OpenSeadragon.Viewer#setVisible}).n *n * @event visiblen * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {Boolean} visiblen * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'visible', { visible: visible } );n return this;n },nn /**n * Add a tiled image to the viewer.n * options.tileSource can be anything that {@link OpenSeadragon.Viewer#open}n * supports except arrays of images.n * Note that you can specify options.width or options.height, but not both.n * The other dimension will be calculated according to the item's aspect ratio.n * If collectionMode is on (see {@link OpenSeadragon.Options}), the new image isn * automatically arranged with the others.n * @functionn * @param {Object} optionsn * @param {String|Object|Function} options.tileSource - The TileSource specifier.n * A String implies a url used to determine the tileSource implementationn * based on the file extension of url. JSONP is implied by *.js,n * otherwise the url is retrieved as text and the resulting text isn * introspected to determine if its json, xml, or text and parsed.n * An Object implies an inline configuration which has a singlen * property sufficient for being able to determine tileSourcen * implementation. If the object has a property which is a functionn * named 'getTileUrl', it is treated as a custom TileSource.n * @param {Number} [options.index] The index of the item. Added on top ofn * all other items if not specified.n * @param {Boolean} [options.replace=false] If true, the item at options.index will ben * removed and the new item is added in its place. options.tileSource will ben * interpreted and fetched if necessary before the old item is removed to avoid leavingn * a gap in the world.n * @param {Number} [options.x=0] The X position for the image in viewport coordinates.n * @param {Number} [options.y=0] The Y position for the image in viewport coordinates.n * @param {Number} [options.width=1] The width for the image in viewport coordinates.n * @param {Number} [options.height] The height for the image in viewport coordinates.n * @param {OpenSeadragon.Rect} [options.fitBounds] The bounds in viewport coordinatesn * to fit the image into. If specified, x, y, width and height get ignored.n * @param {OpenSeadragon.Placement} [options.fitBoundsPlacement=OpenSeadragon.Placement.CENTER]n * How to anchor the image in the bounds if options.fitBounds is set.n * @param {OpenSeadragon.Rect} [options.clip] - An area, in image pixels, to clip ton * (portions of the image outside of this area will not be visible). Only works onn * browsers that support the HTML5 canvas.n * @param {Number} [options.opacity=1] Proportional opacity of the tiled images (1=opaque, 0=hidden)n * @param {Boolean} [options.preload=false] Default switch for loading hidden images (true loads, false blocks)n * @param {Number} [options.degrees=0] Initial rotation of the tiled image aroundn * its top left corner in degrees.n * @param {String} [options.compositeOperation] How the image is composited onto other images.n * @param {String} [options.crossOriginPolicy] The crossOriginPolicy for this specific image,n * overriding viewer.crossOriginPolicy.n * @param {Boolean} [options.ajaxWithCredentials] Whether to set withCredentials on tile AJAXn * @param {Boolean} [options.loadTilesWithAjax]n * Whether to load tile data using AJAX requests.n * Defaults to the setting in {@link OpenSeadragon.Options}.n * @param {Object} [options.ajaxHeaders]n * A set of headers to include when making tile AJAX requests.n * Note that these headers will be merged over any headers specified in {@link OpenSeadragon.Options}.n * Specifying a falsy value for a header will clear its existing value set at the Viewer level (if any).n * requests.n * @param {Function} [options.success] A function that gets called when the image isn * successfully added. It's passed the event object which contains a single property:n * "item", which is the resulting instance of TiledImage.n * @param {Function} [options.error] A function that gets called if the image isn * unable to be added. It's passed the error event object, which contains "message"n * and "source" properties.n * @param {Boolean} [options.collectionImmediately=false] If collectionMode is on,n * specifies whether to snap to the new arrangement immediately or to animate to it.n * @param {String|CanvasGradient|CanvasPattern|Function} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}.n * @fires OpenSeadragon.World.event:add-itemn * @fires OpenSeadragon.Viewer.event:add-item-failedn */n addTiledImage: function( options ) {n $.console.assert(options, "[Viewer.addTiledImage] options is required");n $.console.assert(options.tileSource, "[Viewer.addTiledImage] options.tileSource is required");n $.console.assert(!options.replace || (options.index > -1 && options.index < this.world.getItemCount()),n "[Viewer.addTiledImage] if options.replace is used, options.index must be a valid index in Viewer.world");nn var _this = this;nn if (options.replace) {n options.replaceItem = _this.world.getItemAt(options.index);n }nn this._hideMessage();nn if (options.placeholderFillStyle === undefined) {n options.placeholderFillStyle = this.placeholderFillStyle;n }n if (options.opacity === undefined) {n options.opacity = this.opacity;n }n if (options.preload === undefined) {n options.preload = this.preload;n }n if (options.compositeOperation === undefined) {n options.compositeOperation = this.compositeOperation;n }n if (options.crossOriginPolicy === undefined) {n options.crossOriginPolicy = options.tileSource.crossOriginPolicy !== undefined ? options.tileSource.crossOriginPolicy : this.crossOriginPolicy;n }n if (options.ajaxWithCredentials === undefined) {n options.ajaxWithCredentials = this.ajaxWithCredentials;n }n if (options.loadTilesWithAjax === undefined) {n options.loadTilesWithAjax = this.loadTilesWithAjax;n }n if (options.ajaxHeaders === undefined || options.ajaxHeaders === null) {n options.ajaxHeaders = this.ajaxHeaders;n } else if ($.isPlainObject(options.ajaxHeaders) && $.isPlainObject(this.ajaxHeaders)) {n options.ajaxHeaders = $.extend({}, this.ajaxHeaders, options.ajaxHeaders);n }nn var myQueueItem = {n options: optionsn };nn function raiseAddItemFailed( event ) {n for (var i = 0; i < _this._loadQueue.length; i++) {n if (_this._loadQueue === myQueueItem) {n _this._loadQueue.splice(i, 1);n break;n }n }nn if (_this._loadQueue.length === 0) {n refreshWorld(myQueueItem);n }nn /**n * Raised when an error occurs while adding a item.n * @event add-item-failedn * @memberOf OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {String} messagen * @property {String} sourcen * @property {Object} options The options passed to the addTiledImage method.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( 'add-item-failed', event );nn if (options.error) {n options.error(event);n }n }nn function refreshWorld(theItem) {n if (_this.collectionMode) {n _this.world.arrange({n immediately: theItem.options.collectionImmediately,n rows: _this.collectionRows,n columns: _this.collectionColumns,n layout: _this.collectionLayout,n tileSize: _this.collectionTileSize,n tileMargin: _this.collectionTileMarginn });n _this.world.setAutoRefigureSizes(true);n }n }nn if ($.isArray(options.tileSource)) {n setTimeout(function() {n raiseAddItemFailed({n message: "[Viewer.addTiledImage] Sequences can not be added; add them one at a time instead.",n source: options.tileSource,n options: optionsn });n });n return;n }nn this._loadQueue.push(myQueueItem);nn function processReadyItems() {n var queueItem, tiledImage, optionsClone;n while (_this._loadQueue.length) {n queueItem = _this._loadQueue;n if (!queueItem.tileSource) {n break;n }nn _this._loadQueue.splice(0, 1);nn if (queueItem.options.replace) {n var newIndex = _this.world.getIndexOfItem(queueItem.options.replaceItem);n if (newIndex != -1) {n queueItem.options.index = newIndex;n }n _this.world.removeItem(queueItem.options.replaceItem);n }nn tiledImage = new $.TiledImage({n viewer: _this,n source: queueItem.tileSource,n viewport: _this.viewport,n drawer: _this.drawer,n tileCache: _this.tileCache,n imageLoader: _this.imageLoader,n x: queueItem.options.x,n y: queueItem.options.y,n width: queueItem.options.width,n height: queueItem.options.height,n fitBounds: queueItem.options.fitBounds,n fitBoundsPlacement: queueItem.options.fitBoundsPlacement,n clip: queueItem.options.clip,n placeholderFillStyle: queueItem.options.placeholderFillStyle,n opacity: queueItem.options.opacity,n preload: queueItem.options.preload,n degrees: queueItem.options.degrees,n compositeOperation: queueItem.options.compositeOperation,n springStiffness: _this.springStiffness,n animationTime: _this.animationTime,n minZoomImageRatio: _this.minZoomImageRatio,n wrapHorizontal: _this.wrapHorizontal,n wrapVertical: _this.wrapVertical,n immediateRender: _this.immediateRender,n blendTime: _this.blendTime,n alwaysBlend: _this.alwaysBlend,n minPixelRatio: _this.minPixelRatio,n smoothTileEdgesMinZoom: _this.smoothTileEdgesMinZoom,n iOSDevice: _this.iOSDevice,n crossOriginPolicy: queueItem.options.crossOriginPolicy,n ajaxWithCredentials: queueItem.options.ajaxWithCredentials,n loadTilesWithAjax: queueItem.options.loadTilesWithAjax,n ajaxHeaders: queueItem.options.ajaxHeaders,n debugMode: _this.debugModen });nn if (_this.collectionMode) {n _this.world.setAutoRefigureSizes(false);n }n _this.world.addItem( tiledImage, {n index: queueItem.options.indexn });nn if (_this._loadQueue.length === 0) {n //this restores the autoRefigureSizes flag to true.n refreshWorld(queueItem);n }nn if (_this.world.getItemCount() === 1 && !_this.preserveViewport) {n _this.viewport.goHome(true);n }nn if (_this.navigator) {n optionsClone = $.extend({}, queueItem.options, {n replace: false, // navigator already removed the layer, nothing to replacen originalTiledImage: tiledImage,n tileSource: queueItem.tileSourcen });nn _this.navigator.addTiledImage(optionsClone);n }nn if (queueItem.options.success) {n queueItem.options.success({n item: tiledImagen });n }n }n }nn getTileSourceImplementation( this, options.tileSource, options, function( tileSource ) {nn myQueueItem.tileSource = tileSource;nn // add everybody at the front of the queue that's ready to gon processReadyItems();n }, function( event ) {n event.options = options;n raiseAddItemFailed(event);nn // add everybody at the front of the queue that's ready to gon processReadyItems();n } );n },nn /**n * Add a simple image to the viewer.n * The options are the same as the ones in {@link OpenSeadragon.Viewer#addTiledImage}n * except for options.tileSource which is replaced by options.url.n * @functionn * @param {Object} options - See {@link OpenSeadragon.Viewer#addTiledImage}n * for all the optionsn * @param {String} options.url - The URL of the image to add.n * @fires OpenSeadragon.World.event:add-itemn * @fires OpenSeadragon.Viewer.event:add-item-failedn */n addSimpleImage: function(options) {n $.console.assert(options, "[Viewer.addSimpleImage] options is required");n $.console.assert(options.url, "[Viewer.addSimpleImage] options.url is required");nn var opts = $.extend({}, options, {n tileSource: {n type: 'image',n url: options.urln }n });n delete opts.url;n this.addTiledImage(opts);n },nn // deprecatedn addLayer: function( options ) {n var _this = this;nn $.console.error( "[Viewer.addLayer] this function is deprecated; use Viewer.addTiledImage() instead." );nn var optionsClone = $.extend({}, options, {n success: function(event) {n _this.raiseEvent("add-layer", {n options: options,n drawer: event.itemn });n },n error: function(event) {n _this.raiseEvent("add-layer-failed", event);n }n });nn this.addTiledImage(optionsClone);n return this;n },nn // deprecatedn getLayerAtLevel: function( level ) {n $.console.error( "[Viewer.getLayerAtLevel] this function is deprecated; use World.getItemAt() instead." );n return this.world.getItemAt(level);n },nn // deprecatedn getLevelOfLayer: function( drawer ) {n $.console.error( "[Viewer.getLevelOfLayer] this function is deprecated; use World.getIndexOfItem() instead." );n return this.world.getIndexOfItem(drawer);n },nn // deprecatedn getLayersCount: function() {n $.console.error( "[Viewer.getLayersCount] this function is deprecated; use World.getItemCount() instead." );n return this.world.getItemCount();n },nn // deprecatedn setLayerLevel: function( drawer, level ) {n $.console.error( "[Viewer.setLayerLevel] this function is deprecated; use World.setItemIndex() instead." );n return this.world.setItemIndex(drawer, level);n },nn // deprecatedn removeLayer: function( drawer ) {n $.console.error( "[Viewer.removeLayer] this function is deprecated; use World.removeItem() instead." );n return this.world.removeItem(drawer);n },nn /**n * Force the viewer to redraw its contents.n * @returns {OpenSeadragon.Viewer} Chainable.n */n forceRedraw: function() {n THIS[ this.hash ].forceRedraw = true;n return this;n },nn /**n * @functionn * @return {OpenSeadragon.Viewer} Chainable.n */n bindSequenceControls: function(){nn //////////////////////////////////////////////////////////////////////////n // Image Sequence Controlsn //////////////////////////////////////////////////////////////////////////n var onFocusHandler = $.delegate( this, onFocus ),n onBlurHandler = $.delegate( this, onBlur ),n onNextHandler = $.delegate( this, onNext ),n onPreviousHandler = $.delegate( this, onPrevious ),n navImages = this.navImages,n useGroup = true;nn if( this.showSequenceControl ){nn if( this.previousButton || this.nextButton ){n //if we are binding to custom buttons then layout andn //grouping is the responsibility of the page authorn useGroup = false;n }nn this.previousButton = new $.Button({n element: this.previousButton ? $.getElement( this.previousButton ) : null,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n tooltip: $.getString( "Tooltips.PreviousPage" ),n srcRest: resolveUrl( this.prefixUrl, navImages.previous.REST ),n srcGroup: resolveUrl( this.prefixUrl, navImages.previous.GROUP ),n srcHover: resolveUrl( this.prefixUrl, navImages.previous.HOVER ),n srcDown: resolveUrl( this.prefixUrl, navImages.previous.DOWN ),n onRelease: onPreviousHandler,n onFocus: onFocusHandler,n onBlur: onBlurHandlern });nn this.nextButton = new $.Button({n element: this.nextButton ? $.getElement( this.nextButton ) : null,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n tooltip: $.getString( "Tooltips.NextPage" ),n srcRest: resolveUrl( this.prefixUrl, navImages.next.REST ),n srcGroup: resolveUrl( this.prefixUrl, navImages.next.GROUP ),n srcHover: resolveUrl( this.prefixUrl, navImages.next.HOVER ),n srcDown: resolveUrl( this.prefixUrl, navImages.next.DOWN ),n onRelease: onNextHandler,n onFocus: onFocusHandler,n onBlur: onBlurHandlern });nn if( !this.navPrevNextWrap ){n this.previousButton.disable();n }nn if (!this.tileSources || !this.tileSources.length) {n this.nextButton.disable();n }nn if( useGroup ){n this.paging = new $.ButtonGroup({n buttons: [n this.previousButton,n this.nextButtonn ],n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThresholdn });nn this.pagingControl = this.paging.element;nn if( this.toolbar ){n this.toolbar.addControl(n this.pagingControl,n {anchor: $.ControlAnchor.BOTTOM_RIGHT}n );n }else{n this.addControl(n this.pagingControl,n {anchor: this.sequenceControlAnchor || $.ControlAnchor.TOP_LEFT}n );n }n }n }n return this;n },nnn /**n * @functionn * @return {OpenSeadragon.Viewer} Chainable.n */n bindStandardControls: function(){n //////////////////////////////////////////////////////////////////////////n // Navigation Controlsn //////////////////////////////////////////////////////////////////////////n var beginZoomingInHandler = $.delegate( this, beginZoomingIn ),n endZoomingHandler = $.delegate( this, endZooming ),n doSingleZoomInHandler = $.delegate( this, doSingleZoomIn ),n beginZoomingOutHandler = $.delegate( this, beginZoomingOut ),n doSingleZoomOutHandler = $.delegate( this, doSingleZoomOut ),n onHomeHandler = $.delegate( this, onHome ),n onFullScreenHandler = $.delegate( this, onFullScreen ),n onRotateLeftHandler = $.delegate( this, onRotateLeft ),n onRotateRightHandler = $.delegate( this, onRotateRight ),n onFlipHandler = $.delegate( this, onFlip),n onFocusHandler = $.delegate( this, onFocus ),n onBlurHandler = $.delegate( this, onBlur ),n navImages = this.navImages,n buttons = [],n useGroup = true;nnn if ( this.showNavigationControl ) {nn if( this.zoomInButton || this.zoomOutButton ||n this.homeButton || this.fullPageButton ||n this.rotateLeftButton || this.rotateRightButton ||n this.flipButton ) {n //if we are binding to custom buttons then layout andn //grouping is the responsibility of the page authorn useGroup = false;n }nn if ( this.showZoomControl ) {n buttons.push( this.zoomInButton = new $.Button({n element: this.zoomInButton ? $.getElement( this.zoomInButton ) : null,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n tooltip: $.getString( "Tooltips.ZoomIn" ),n srcRest: resolveUrl( this.prefixUrl, navImages.zoomIn.REST ),n srcGroup: resolveUrl( this.prefixUrl, navImages.zoomIn.GROUP ),n srcHover: resolveUrl( this.prefixUrl, navImages.zoomIn.HOVER ),n srcDown: resolveUrl( this.prefixUrl, navImages.zoomIn.DOWN ),n onPress: beginZoomingInHandler,n onRelease: endZoomingHandler,n onClick: doSingleZoomInHandler,n onEnter: beginZoomingInHandler,n onExit: endZoomingHandler,n onFocus: onFocusHandler,n onBlur: onBlurHandlern }));nn buttons.push( this.zoomOutButton = new $.Button({n element: this.zoomOutButton ? $.getElement( this.zoomOutButton ) : null,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n tooltip: $.getString( "Tooltips.ZoomOut" ),n srcRest: resolveUrl( this.prefixUrl, navImages.zoomOut.REST ),n srcGroup: resolveUrl( this.prefixUrl, navImages.zoomOut.GROUP ),n srcHover: resolveUrl( this.prefixUrl, navImages.zoomOut.HOVER ),n srcDown: resolveUrl( this.prefixUrl, navImages.zoomOut.DOWN ),n onPress: beginZoomingOutHandler,n onRelease: endZoomingHandler,n onClick: doSingleZoomOutHandler,n onEnter: beginZoomingOutHandler,n onExit: endZoomingHandler,n onFocus: onFocusHandler,n onBlur: onBlurHandlern }));n }nn if ( this.showHomeControl ) {n buttons.push( this.homeButton = new $.Button({n element: this.homeButton ? $.getElement( this.homeButton ) : null,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n tooltip: $.getString( "Tooltips.Home" ),n srcRest: resolveUrl( this.prefixUrl, navImages.home.REST ),n srcGroup: resolveUrl( this.prefixUrl, navImages.home.GROUP ),n srcHover: resolveUrl( this.prefixUrl, navImages.home.HOVER ),n srcDown: resolveUrl( this.prefixUrl, navImages.home.DOWN ),n onRelease: onHomeHandler,n onFocus: onFocusHandler,n onBlur: onBlurHandlern }));n }nn if ( this.showFullPageControl ) {n buttons.push( this.fullPageButton = new $.Button({n element: this.fullPageButton ? $.getElement( this.fullPageButton ) : null,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n tooltip: $.getString( "Tooltips.FullPage" ),n srcRest: resolveUrl( this.prefixUrl, navImages.fullpage.REST ),n srcGroup: resolveUrl( this.prefixUrl, navImages.fullpage.GROUP ),n srcHover: resolveUrl( this.prefixUrl, navImages.fullpage.HOVER ),n srcDown: resolveUrl( this.prefixUrl, navImages.fullpage.DOWN ),n onRelease: onFullScreenHandler,n onFocus: onFocusHandler,n onBlur: onBlurHandlern }));n }nn if ( this.showRotationControl ) {n buttons.push( this.rotateLeftButton = new $.Button({n element: this.rotateLeftButton ? $.getElement( this.rotateLeftButton ) : null,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n tooltip: $.getString( "Tooltips.RotateLeft" ),n srcRest: resolveUrl( this.prefixUrl, navImages.rotateleft.REST ),n srcGroup: resolveUrl( this.prefixUrl, navImages.rotateleft.GROUP ),n srcHover: resolveUrl( this.prefixUrl, navImages.rotateleft.HOVER ),n srcDown: resolveUrl( this.prefixUrl, navImages.rotateleft.DOWN ),n onRelease: onRotateLeftHandler,n onFocus: onFocusHandler,n onBlur: onBlurHandlern }));nn buttons.push( this.rotateRightButton = new $.Button({n element: this.rotateRightButton ? $.getElement( this.rotateRightButton ) : null,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n tooltip: $.getString( "Tooltips.RotateRight" ),n srcRest: resolveUrl( this.prefixUrl, navImages.rotateright.REST ),n srcGroup: resolveUrl( this.prefixUrl, navImages.rotateright.GROUP ),n srcHover: resolveUrl( this.prefixUrl, navImages.rotateright.HOVER ),n srcDown: resolveUrl( this.prefixUrl, navImages.rotateright.DOWN ),n onRelease: onRotateRightHandler,n onFocus: onFocusHandler,n onBlur: onBlurHandlern }));n }nn if ( this.showFlipControl ) {n buttons.push( this.flipButton = new $.Button({n element: this.flipButton ? $.getElement( this.flipButton ) : null,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n tooltip: $.getString( "Tooltips.Flip" ),n srcRest: resolveUrl( this.prefixUrl, navImages.flip.REST ),n srcGroup: resolveUrl( this.prefixUrl, navImages.flip.GROUP ),n srcHover: resolveUrl( this.prefixUrl, navImages.flip.HOVER ),n srcDown: resolveUrl( this.prefixUrl, navImages.flip.DOWN ),n onRelease: onFlipHandler,n onFocus: onFocusHandler,n onBlur: onBlurHandlern }));n }nn if ( useGroup ) {n this.buttons = new $.ButtonGroup({n buttons: buttons,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThresholdn });nn this.navControl = this.buttons.element;n this.addHandler( 'open', $.delegate( this, lightUp ) );nn if( this.toolbar ){n this.toolbar.addControl(n this.navControl,n {anchor: this.navigationControlAnchor || $.ControlAnchor.TOP_LEFT}n );n } else {n this.addControl(n this.navControl,n {anchor: this.navigationControlAnchor || $.ControlAnchor.TOP_LEFT}n );n }n }nn }n return this;n },nn /**n * Gets the active page of a sequencen * @functionn * @return {Number}n */n currentPage: function() {n return this._sequenceIndex;n },nn /**n * @functionn * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:pagen */n goToPage: function( page ){n if( this.tileSources && page >= 0 && page < this.tileSources.length ){n this._sequenceIndex = page;nn this._updateSequenceButtons( page );nn this.open( this.tileSources[ page ] );nn if( this.referenceStrip ){n this.referenceStrip.setFocus( page );n }nn /**n * Raised when the page is changed on a viewer configured with multiple image sources (see {@link OpenSeadragon.Viewer#goToPage}).n *n * @event pagen * @memberof OpenSeadragon.Viewern * @type {Object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {Number} page - The page index.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'page', { page: page } );n }nn return this;n },nn /**n * Adds an html element as an overlay to the current viewport. Useful forn * highlighting words or areas of interest on an image or other zoomablen * interface. The overlays added via this method are removed when the viewportn * is closed which include when changing page.n * @methodn * @param {Element|String|Object} element - A reference to an element or an id forn * the element which will be overlayed. Or an Object specifying the configuration for the overlay.n * If using an object, see {@link OpenSeadragon.Overlay} for a list ofn * all available options.n * @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point orn * rectangle which will be overlayed. This is a viewport relative location.n * @param {OpenSeadragon.Placement} placement - The position of then * viewport which the location coordinates will be treated as relativen * to.n * @param {function} onDraw - If supplied the callback is called when the overlayn * needs to be drawn. It it the responsibility of the callback to do any drawing/positioning.n * It is passed position, size and element.n * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:add-overlayn */n addOverlay: function( element, location, placement, onDraw ) {n var options;n if( $.isPlainObject( element ) ){n options = element;n } else {n options = {n element: element,n location: location,n placement: placement,n onDraw: onDrawn };n }nn element = $.getElement( options.element );nn if ( getOverlayIndex( this.currentOverlays, element ) >= 0 ) {n // they're trying to add a duplicate overlayn return this;n }nn var overlay = getOverlayObject( this, options);n this.currentOverlays.push(overlay);n overlay.drawHTML( this.overlaysContainer, this.viewport );nn /**n * Raised when an overlay is added to the viewer (see {@link OpenSeadragon.Viewer#addOverlay}).n *n * @event add-overlayn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {Element} element - The overlay element.n * @property {OpenSeadragon.Point|OpenSeadragon.Rect} locationn * @property {OpenSeadragon.Placement} placementn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'add-overlay', {n element: element,n location: options.location,n placement: options.placementn });n return this;n },nn /**n * Updates the overlay represented by the reference to the element orn * element id moving it to the new location, relative to the new placement.n * @methodn * @param {Element|String} element - A reference to an element or an id forn * the element which is overlayed.n * @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point orn * rectangle which will be overlayed. This is a viewport relative location.n * @param {OpenSeadragon.Placement} placement - The position of then * viewport which the location coordinates will be treated as relativen * to.n * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:update-overlayn */n updateOverlay: function( element, location, placement ) {n var i;nn element = $.getElement( element );n i = getOverlayIndex( this.currentOverlays, element );nn if ( i >= 0 ) {n this.currentOverlays[ i ].update( location, placement );n THIS[ this.hash ].forceRedraw = true;n /**n * Raised when an overlay's location or placement changesn * (see {@link OpenSeadragon.Viewer#updateOverlay}).n *n * @event update-overlayn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to then * Viewer which raised the event.n * @property {Element} elementn * @property {OpenSeadragon.Point|OpenSeadragon.Rect} locationn * @property {OpenSeadragon.Placement} placementn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'update-overlay', {n element: element,n location: location,n placement: placementn });n }n return this;n },nn /**n * Removes an overlay identified by the reference element or element idn * and schedules an update.n * @methodn * @param {Element|String} element - A reference to the element or ann * element id which represent the ovelay content to be removed.n * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:remove-overlayn */n removeOverlay: function( element ) {n var i;nn element = $.getElement( element );n i = getOverlayIndex( this.currentOverlays, element );nn if ( i >= 0 ) {n this.currentOverlays[ i ].destroy();n this.currentOverlays.splice( i, 1 );n THIS[ this.hash ].forceRedraw = true;n /**n * Raised when an overlay is removed from the viewern * (see {@link OpenSeadragon.Viewer#removeOverlay}).n *n * @event remove-overlayn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to then * Viewer which raised the event.n * @property {Element} element - The overlay element.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'remove-overlay', {n element: elementn });n }n return this;n },nn /**n * Removes all currently configured Overlays from this Viewer and schedulesn * an update.n * @methodn * @return {OpenSeadragon.Viewer} Chainable.n * @fires OpenSeadragon.Viewer.event:clear-overlayn */n clearOverlays: function() {n while ( this.currentOverlays.length > 0 ) {n this.currentOverlays.pop().destroy();n }n THIS[ this.hash ].forceRedraw = true;n /**n * Raised when all overlays are removed from the viewer (see {@link OpenSeadragon.Drawer#clearOverlays}).n *n * @event clear-overlayn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'clear-overlay', {} );n return this;n },nn /**n * Finds an overlay identified by the reference element or element idn * and returns it as an object, return null if not found.n * @methodn * @param {Element|String} element - A reference to the element or ann * element id which represents the overlay content.n * @return {OpenSeadragon.Overlay} the matching overlay or null if none found.n */n getOverlayById: function( element ) {n var i;nn element = $.getElement( element );n i = getOverlayIndex( this.currentOverlays, element );nn if (i >= 0) {n return this.currentOverlays;n } else {n return null;n }n },nn /**n * Updates the sequence buttons.n * @function OpenSeadragon.Viewer.prototype._updateSequenceButtonsn * @privaten * @param {Number} Sequence Valuen */n _updateSequenceButtons: function( page ) {nn if ( this.nextButton ) {n if(!this.tileSources || this.tileSources.length - 1 === page) {n //Disable next buttonn if ( !this.navPrevNextWrap ) {n this.nextButton.disable();n }n } else {n this.nextButton.enable();n }n }n if ( this.previousButton ) {n if ( page > 0 ) {n //Enable previous buttonn this.previousButton.enable();n } else {n if ( !this.navPrevNextWrap ) {n this.previousButton.disable();n }n }n }n },nn /**n * Display a message in the viewportn * @function OpenSeadragon.Viewer.prototype._showMessagen * @privaten * @param {String} text messagen */n _showMessage: function ( message ) {n this._hideMessage();nn var div = $.makeNeutralElement( "div" );n div.appendChild( document.createTextNode( message ) );nn this.messageDiv = $.makeCenteredNode( div );nn $.addClass(this.messageDiv, "openseadragon-message");nn this.container.appendChild( this.messageDiv );n },nn /**n * Hide any currently displayed viewport messagen * @function OpenSeadragon.Viewer.prototype._hideMessagen * @privaten */n _hideMessage: function () {n var div = this.messageDiv;n if (div) {n div.parentNode.removeChild(div);n delete this.messageDiv;n }n },nn /**n * Gets this viewer's gesture settings for the given pointer device type.n * @methodn * @param {String} type - The pointer device type to get the gesture settings for ("mouse", "touch", "pen", etc.).n * @return {OpenSeadragon.GestureSettings}n */n gestureSettingsByDeviceType: function ( type ) {n switch ( type ) {n case 'mouse':n return this.gestureSettingsMouse;n case 'touch':n return this.gestureSettingsTouch;n case 'pen':n return this.gestureSettingsPen;n default:n return this.gestureSettingsUnknown;n }n },nn // privaten _drawOverlays: function() {n var i,n length = this.currentOverlays.length;n for ( i = 0; i < length; i++ ) {n this.currentOverlays[ i ].drawHTML( this.overlaysContainer, this.viewport );n }n },nn /**n * Cancel the "in flight" images.n */n _cancelPendingImages: function() {n this._loadQueue = [];n },nn /**n * Removes the reference strip and disables displaying it.n * @functionn */n removeReferenceStrip: function() {n this.showReferenceStrip = false;nn if (this.referenceStrip) {n this.referenceStrip.destroy();n this.referenceStrip = null;n }n },nn /**n * Enables and displays the reference strip based on the currently set tileSources.n * Works only when the Viewer has sequenceMode set to true.n * @functionn */n addReferenceStrip: function() {n this.showReferenceStrip = true;nn if (this.sequenceMode) {n if (this.referenceStrip) {n return;n }nn if (this.tileSources.length && this.tileSources.length > 1) {n this.referenceStrip = new $.ReferenceStrip({n id: this.referenceStripElement,n position: this.referenceStripPosition,n sizeRatio: this.referenceStripSizeRatio,n scroll: this.referenceStripScroll,n height: this.referenceStripHeight,n width: this.referenceStripWidth,n tileSources: this.tileSources,n prefixUrl: this.prefixUrl,n viewer: thisn });nn this.referenceStrip.setFocus( this._sequenceIndex );n }n } else {n $.console.warn('Attempting to display a reference strip while "sequenceMode" is off.');n }n }n});nnn/**n * _getSafeElemSize is like getElementSize(), but refuses to return 0 for x or y,n * which was causing some calling operations to return NaN.n * @returns {Point}n * @privaten */nfunction _getSafeElemSize (oElement) {n oElement = $.getElement( oElement );nn return new $.Point(n (oElement.clientWidth === 0 ? 1 : oElement.clientWidth),n (oElement.clientHeight === 0 ? 1 : oElement.clientHeight)n );n}nnn/**n * @functionn * @privaten */nfunction getTileSourceImplementation( viewer, tileSource, imgOptions, successCallback,n failCallback ) {n var _this = viewer;nn //allow plain xml strings or json strings to be parsed heren if ( $.type( tileSource ) == 'string' ) {n //xml should start with "<" and end with ">"n if ( tileSource.match( /^\s*<.*>\s*$/ ) ) {n tileSource = $.parseXml( tileSource );n //json should start with "{" or "[" and end with "}" or "]"n } else if ( tileSource.match(/^\s*[\{\.*[\}\]]\s*$/ ) ) {n try {n var tileSourceJ = $.parseJSON(tileSource);n tileSource = tileSourceJ;n } catch (e) {n //tileSource = tileSource;n }n }n }nn function waitUntilReady(tileSource, originalTileSource) {n if (tileSource.ready) {n successCallback(tileSource);n } else {n tileSource.addHandler('ready', function () {n successCallback(tileSource);n });n tileSource.addHandler('open-failed', function (event) {n failCallback({n message: event.message,n source: originalTileSourcen });n });n }n }nn setTimeout( function() {n if ( $.type( tileSource ) == 'string' ) {n //If its still a string it means it must be a url at this pointn tileSource = new $.TileSource({n url: tileSource,n crossOriginPolicy: imgOptions.crossOriginPolicy !== undefined ?n imgOptions.crossOriginPolicy : viewer.crossOriginPolicy,n ajaxWithCredentials: viewer.ajaxWithCredentials,n ajaxHeaders: viewer.ajaxHeaders,n useCanvas: viewer.useCanvas,n success: function( event ) {n successCallback( event.tileSource );n }n });n tileSource.addHandler( 'open-failed', function( event ) {n failCallback( event );n } );nn } else if ($.isPlainObject(tileSource) || tileSource.nodeType) {n if (tileSource.crossOriginPolicy === undefined &&n (imgOptions.crossOriginPolicy !== undefined || viewer.crossOriginPolicy !== undefined)) {n tileSource.crossOriginPolicy = imgOptions.crossOriginPolicy !== undefined ?n imgOptions.crossOriginPolicy : viewer.crossOriginPolicy;n }n if (tileSource.ajaxWithCredentials === undefined) {n tileSource.ajaxWithCredentials = viewer.ajaxWithCredentials;n }n if (tileSource.useCanvas === undefined) {n tileSource.useCanvas = viewer.useCanvas;n }nn if ( $.isFunction( tileSource.getTileUrl ) ) {n //Custom tile sourcen var customTileSource = new $.TileSource( tileSource );n customTileSource.getTileUrl = tileSource.getTileUrl;n successCallback( customTileSource );n } else {n //inline configurationn var $TileSource = $.TileSource.determineType( _this, tileSource );n if ( !$TileSource ) {n failCallback( {n message: "Unable to load TileSource",n source: tileSourcen });n return;n }n var options = $TileSource.prototype.configure.apply( _this, [ tileSource ] );n waitUntilReady(new $TileSource(options), tileSource);n }n } else {n //can assume it's already a tile source implementationn waitUntilReady(tileSource, tileSource);n }n });n}nnfunction getOverlayObject( viewer, overlay ) {n if ( overlay instanceof $.Overlay ) {n return overlay;n }nn var element = null;n if ( overlay.element ) {n element = $.getElement( overlay.element );n } else {n var id = overlay.id ?n overlay.id :n "openseadragon-overlay-" + Math.floor( Math.random() * 10000000 );nn element = $.getElement( overlay.id );n if ( !element ) {n element = document.createElement( "a" );n element.href = "#/overlay/" + id;n }n element.id = id;n $.addClass( element, overlay.className ?n overlay.className :n "openseadragon-overlay"n );n }nn var location = overlay.location;n var width = overlay.width;n var height = overlay.height;n if (!location) {n var x = overlay.x;n var y = overlay.y;n if (overlay.px !== undefined) {n var rect = viewer.viewport.imageToViewportRectangle(new $.Rect(n overlay.px,n overlay.py,n width || 0,n height || 0));n x = rect.x;n y = rect.y;n width = width !== undefined ? rect.width : undefined;n height = height !== undefined ? rect.height : undefined;n }n location = new $.Point(x, y);n }nn var placement = overlay.placement;n if (placement && $.type(placement) === "string") {n placement = $.Placement;n }nn return new $.Overlay({n element: element,n location: location,n placement: placement,n onDraw: overlay.onDraw,n checkResize: overlay.checkResize,n width: width,n height: height,n rotationMode: overlay.rotationModen });n}nn/**n * @privaten * @innern * Determines the index of the given overlay in the given overlays array.n */nfunction getOverlayIndex( overlays, element ) {n var i;n for ( i = overlays.length - 1; i >= 0; i– ) {n if ( overlays[ i ].element === element ) {n return i;n }n }nn return -1;n}nn///////////////////////////////////////////////////////////////////////////////n// Schedulers provide the general engine for animationn///////////////////////////////////////////////////////////////////////////////nfunction scheduleUpdate( viewer, updateFunc ){n return $.requestAnimationFrame( function(){n updateFunc( viewer );n } );n}nnn//provides a sequence in the fade animationnfunction scheduleControlsFade( viewer ) {n $.requestAnimationFrame( function(){n updateControlsFade( viewer );n });n}nnn//initiates an animation to hide the controlsnfunction beginControlsAutoHide( viewer ) {n if ( !viewer.autoHideControls ) {n return;n }n viewer.controlsShouldFade = true;n viewer.controlsFadeBeginTime =n $.now() +n viewer.controlsFadeDelay;nn window.setTimeout( function(){n scheduleControlsFade( viewer );n }, viewer.controlsFadeDelay );n}nnn//determines if fade animation is done or continues the animationnfunction updateControlsFade( viewer ) {n var currentTime,n deltaTime,n opacity,n i;n if ( viewer.controlsShouldFade ) {n currentTime = $.now();n deltaTime = currentTime - viewer.controlsFadeBeginTime;n opacity = 1.0 - deltaTime / viewer.controlsFadeLength;nn opacity = Math.min( 1.0, opacity );n opacity = Math.max( 0.0, opacity );nn for ( i = viewer.controls.length - 1; i >= 0; i–) {n if (viewer.controls[ i ].autoFade) {n viewer.controls[ i ].setOpacity( opacity );n }n }nn if ( opacity > 0 ) {n // fade againn scheduleControlsFade( viewer );n }n }n}nnn//stop the fade animation on the controls and show themnfunction abortControlsAutoHide( viewer ) {n var i;n viewer.controlsShouldFade = false;n for ( i = viewer.controls.length - 1; i >= 0; i– ) {n viewer.controls[ i ].setOpacity( 1.0 );n }n}nnnn///////////////////////////////////////////////////////////////////////////////n// Default view event handlers.n///////////////////////////////////////////////////////////////////////////////nfunction onFocus(){n abortControlsAutoHide( this );n}nnfunction onBlur(){n beginControlsAutoHide( this );nn}nnfunction onCanvasKeyDown( event ) {n var canvasKeyDownEventArgs = {n originalEvent: event.originalEvent,n preventDefaultAction: event.preventDefaultAction,n preventVerticalPan: event.preventVerticalPan,n preventHorizontalPan: event.preventHorizontalPann };nn /**n * Raised when a keyboard key is pressed and the focus is on the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-keyn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {Object} originalEvent - The original DOM event.n * @property {Boolean} preventDefaultAction - Set to true to prevent default keyboard behaviour. Default: false.n * @property {Boolean} preventVerticalPan - Set to true to prevent keyboard vertical panning. Default: false.n * @property {Boolean} preventHorizontalPan - Set to true to prevent keyboard horizontal panning. Default: false.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */nn this.raiseEvent('canvas-key', canvasKeyDownEventArgs);nn if ( !canvasKeyDownEventArgs.preventDefaultAction && !event.ctrl && !event.alt && !event.meta ) {n switch( event.keyCode ){n case 38://up arrown if (!canvasKeyDownEventArgs.preventVerticalPan) {n if ( event.shift ) {n this.viewport.zoomBy(1.1);n } else {n this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(0, -this.pixelsPerArrowPress)));n }n this.viewport.applyConstraints();n }n return false;n case 40://down arrown if (!canvasKeyDownEventArgs.preventVerticalPan) {n if ( event.shift ) {n this.viewport.zoomBy(0.9);n } else {n this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(0, this.pixelsPerArrowPress)));n }n this.viewport.applyConstraints();n }n return false;n case 37://left arrown if (!canvasKeyDownEventArgs.preventHorizontalPan) {n this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(-this.pixelsPerArrowPress, 0)));n this.viewport.applyConstraints();n }n return false;n case 39://right arrown if (!canvasKeyDownEventArgs.preventHorizontalPan) {n this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(this.pixelsPerArrowPress, 0)));n this.viewport.applyConstraints();n }n return false;n default:n //console.log( 'navigator keycode %s', event.keyCode );n return true;n }n } else {n return true;n }n}nfunction onCanvasKeyPress( event ) {n var canvasKeyPressEventArgs = {n originalEvent: event.originalEvent,n preventDefaultAction: event.preventDefaultAction,n preventVerticalPan: event.preventVerticalPan,n preventHorizontalPan: event.preventHorizontalPann };nn // This event is documented in onCanvasKeyDownn this.raiseEvent('canvas-key', canvasKeyPressEventArgs);nn if ( !canvasKeyPressEventArgs.preventDefaultAction && !event.ctrl && !event.alt && !event.meta ) {n switch( event.keyCode ){n case 43://=|+n case 61://=|+n this.viewport.zoomBy(1.1);n this.viewport.applyConstraints();n return false;n case 45://-|_n this.viewport.zoomBy(0.9);n this.viewport.applyConstraints();n return false;n case 48://0|)n this.viewport.goHome();n this.viewport.applyConstraints();n return false;n case 119://wn case 87://Wn if (!canvasKeyPressEventArgs.preventVerticalPan) {n if ( event.shift ) {n this.viewport.zoomBy(1.1);n } else {n this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(0, -40)));n }n this.viewport.applyConstraints();n }n return false;n case 115://sn case 83://Sn if (!canvasKeyPressEventArgs.preventVerticalPan) {n if ( event.shift ) {n this.viewport.zoomBy(0.9);n } else {n this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(0, 40)));n }n this.viewport.applyConstraints();n }n return false;n case 97://an if (!canvasKeyPressEventArgs.preventHorizontalPan) {n this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(-40, 0)));n this.viewport.applyConstraints();n }n return false;n case 100://dn if (!canvasKeyPressEventArgs.preventHorizontalPan) {n this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(40, 0)));n this.viewport.applyConstraints();n }n return false;n case 114: //r - 90 degrees clockwise rotationn if(this.viewport.flipped){n this.viewport.setRotation(this.viewport.degrees - 90);n } else{n this.viewport.setRotation(this.viewport.degrees + 90);n }n this.viewport.applyConstraints();n return false;n case 82: //R - 90 degrees counterclockwise rotationn if(this.viewport.flipped){n this.viewport.setRotation(this.viewport.degrees + 90);n } else{n this.viewport.setRotation(this.viewport.degrees - 90);n }n this.viewport.applyConstraints();n return false;n case 102: //fn this.viewport.toggleFlip();n return false;n default:n // console.log( 'navigator keycode %s', event.keyCode );n return true;n }n } else {n return true;n }n}nnfunction onCanvasClick( event ) {n var gestureSettings;nn var haveKeyboardFocus = document.activeElement == this.canvas;nn // If we don't have keyboard focus, request it.n if ( !haveKeyboardFocus ) {n this.canvas.focus();n }n if(this.viewport.flipped){n event.position.x = this.viewport.getContainerSize().x - event.position.x;n }nn var canvasClickEventArgs = {n tracker: event.eventSource,n position: event.position,n quick: event.quick,n shift: event.shift,n originalEvent: event.originalEvent,n preventDefaultAction: event.preventDefaultActionn };nn /**n * Raised when a mouse press/release or touch/remove occurs on the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-clickn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Boolean} quick - True only if the clickDistThreshold and clickTimeThreshold are both passed. Useful for differentiating between clicks and drags.n * @property {Boolean} shift - True if the shift key was pressed during this event.n * @property {Object} originalEvent - The original DOM event.n * @property {Boolean} preventDefaultAction - Set to true to prevent default click to zoom behaviour. Default: false.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'canvas-click', canvasClickEventArgs);nn if ( !canvasClickEventArgs.preventDefaultAction && this.viewport && event.quick ) {n gestureSettings = this.gestureSettingsByDeviceType( event.pointerType );n if ( gestureSettings.clickToZoom ) {n this.viewport.zoomBy(n event.shift ? 1.0 / this.zoomPerClick : this.zoomPerClick,n gestureSettings.zoomToRefPoint ? this.viewport.pointFromPixel( event.position, true ) : nulln );n this.viewport.applyConstraints();n }n }n}nnfunction onCanvasDblClick( event ) {n var gestureSettings;nn var canvasDblClickEventArgs = {n tracker: event.eventSource,n position: event.position,n shift: event.shift,n originalEvent: event.originalEvent,n preventDefaultAction: event.preventDefaultActionn };nn /**n * Raised when a double mouse press/release or touch/remove occurs on the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-double-clickn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Boolean} shift - True if the shift key was pressed during this event.n * @property {Object} originalEvent - The original DOM event.n * @property {Boolean} preventDefaultAction - Set to true to prevent default double tap to zoom behaviour. Default: false.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'canvas-double-click', canvasDblClickEventArgs);nn if ( !canvasDblClickEventArgs.preventDefaultAction && this.viewport ) {n gestureSettings = this.gestureSettingsByDeviceType( event.pointerType );n if ( gestureSettings.dblClickToZoom ) {n this.viewport.zoomBy(n event.shift ? 1.0 / this.zoomPerClick : this.zoomPerClick,n gestureSettings.zoomToRefPoint ? this.viewport.pointFromPixel( event.position, true ) : nulln );n this.viewport.applyConstraints();n }n }n}nnfunction onCanvasDrag( event ) {n var gestureSettings;nn var canvasDragEventArgs = {n tracker: event.eventSource,n position: event.position,n delta: event.delta,n speed: event.speed,n direction: event.direction,n shift: event.shift,n originalEvent: event.originalEvent,n preventDefaultAction: event.preventDefaultActionn };nn /**n * Raised when a mouse or touch drag operation occurs on the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-dragn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {OpenSeadragon.Point} delta - The x,y components of the difference between start drag and end drag.n * @property {Number} speed - Current computed speed, in pixels per second.n * @property {Number} direction - Current computed direction, expressed as an angle counterclockwise relative to the positive X axis (-pi to pi, in radians). Only valid if speed > 0.n * @property {Boolean} shift - True if the shift key was pressed during this event.n * @property {Object} originalEvent - The original DOM event.n * @property {Boolean} preventDefaultAction - Set to true to prevent default drag behaviour. Default: false.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'canvas-drag', canvasDragEventArgs);nn if ( !canvasDragEventArgs.preventDefaultAction && this.viewport ) {n gestureSettings = this.gestureSettingsByDeviceType( event.pointerType );n if( !this.panHorizontal ){n event.delta.x = 0;n }n if( !this.panVertical ){n event.delta.y = 0;n }n if(this.viewport.flipped){n event.delta.x = -event.delta.x;n }nn if( this.constrainDuringPan ){n var delta = this.viewport.deltaPointsFromPixels( event.delta.negate() );nn this.viewport.centerSpringX.target.value += delta.x;n this.viewport.centerSpringY.target.value += delta.y;nn var bounds = this.viewport.getBounds();n var constrainedBounds = this.viewport.getConstrainedBounds();nn this.viewport.centerSpringX.target.value -= delta.x;n this.viewport.centerSpringY.target.value -= delta.y;nn if (bounds.x != constrainedBounds.x) {n event.delta.x = 0;n }nn if (bounds.y != constrainedBounds.y) {n event.delta.y = 0;n }n }nn this.viewport.panBy( this.viewport.deltaPointsFromPixels( event.delta.negate() ), gestureSettings.flickEnabled && !this.constrainDuringPan);n }n}nnfunction onCanvasDragEnd( event ) {n if (!event.preventDefaultAction && this.viewport) {n var gestureSettings = this.gestureSettingsByDeviceType(event.pointerType);n if (gestureSettings.flickEnabled &&n event.speed >= gestureSettings.flickMinSpeed) {n var amplitudeX = 0;n if (this.panHorizontal) {n amplitudeX = gestureSettings.flickMomentum * event.speed *n Math.cos(event.direction);n }n var amplitudeY = 0;n if (this.panVertical) {n amplitudeY = gestureSettings.flickMomentum * event.speed *n Math.sin(event.direction);n }n var center = this.viewport.pixelFromPoint(n this.viewport.getCenter(true));n var target = this.viewport.pointFromPixel(n new $.Point(center.x - amplitudeX, center.y - amplitudeY));n this.viewport.panTo(target, false);n }n this.viewport.applyConstraints();n }n /**n * Raised when a mouse or touch drag operation ends on the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-drag-endn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Number} speed - Speed at the end of a drag gesture, in pixels per second.n * @property {Number} direction - Direction at the end of a drag gesture, expressed as an angle counterclockwise relative to the positive X axis (-pi to pi, in radians). Only valid if speed > 0.n * @property {Boolean} shift - True if the shift key was pressed during this event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent('canvas-drag-end', {n tracker: event.eventSource,n position: event.position,n speed: event.speed,n direction: event.direction,n shift: event.shift,n originalEvent: event.originalEventn });n}nnfunction onCanvasEnter( event ) {n /**n * Raised when a pointer enters the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-entern * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {String} pointerType - "mouse", "touch", "pen", etc.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Number} buttons - Current buttons pressed. A combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @property {Number} pointers - Number of pointers (all types) active in the tracked element.n * @property {Boolean} insideElementPressed - True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false.n * @property {Boolean} buttonDownAny - Was the button down anywhere in the screen during the event. <span style="color:red;">Deprecated. Use buttons instead.</span>n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'canvas-enter', {n tracker: event.eventSource,n pointerType: event.pointerType,n position: event.position,n buttons: event.buttons,n pointers: event.pointers,n insideElementPressed: event.insideElementPressed,n buttonDownAny: event.buttonDownAny,n originalEvent: event.originalEventn });n}nnfunction onCanvasExit( event ) {nn if (window.location != window.parent.location){n $.MouseTracker.resetAllMouseTrackers();n }nn /**n * Raised when a pointer leaves the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-exitn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {String} pointerType - "mouse", "touch", "pen", etc.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Number} buttons - Current buttons pressed. A combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @property {Number} pointers - Number of pointers (all types) active in the tracked element.n * @property {Boolean} insideElementPressed - True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false.n * @property {Boolean} buttonDownAny - Was the button down anywhere in the screen during the event. <span style="color:red;">Deprecated. Use buttons instead.</span>n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'canvas-exit', {n tracker: event.eventSource,n pointerType: event.pointerType,n position: event.position,n buttons: event.buttons,n pointers: event.pointers,n insideElementPressed: event.insideElementPressed,n buttonDownAny: event.buttonDownAny,n originalEvent: event.originalEventn });n}nnfunction onCanvasPress( event ) {n /**n * Raised when the primary mouse button is pressed or touch starts on the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-pressn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {String} pointerType - "mouse", "touch", "pen", etc.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Boolean} insideElementPressed - True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false.n * @property {Boolean} insideElementReleased - True if the cursor still inside the tracked element when the button was released.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'canvas-press', {n tracker: event.eventSource,n pointerType: event.pointerType,n position: event.position,n insideElementPressed: event.insideElementPressed,n insideElementReleased: event.insideElementReleased,n originalEvent: event.originalEventn });n}nnfunction onCanvasRelease( event ) {n /**n * Raised when the primary mouse button is released or touch ends on the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-releasen * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {String} pointerType - "mouse", "touch", "pen", etc.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Boolean} insideElementPressed - True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false.n * @property {Boolean} insideElementReleased - True if the cursor still inside the tracked element when the button was released.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'canvas-release', {n tracker: event.eventSource,n pointerType: event.pointerType,n position: event.position,n insideElementPressed: event.insideElementPressed,n insideElementReleased: event.insideElementReleased,n originalEvent: event.originalEventn });n}nnfunction onCanvasNonPrimaryPress( event ) {n /**n * Raised when any non-primary pointer button is pressed on the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-nonprimary-pressn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {String} pointerType - "mouse", "touch", "pen", etc.n * @property {Number} button - Button which caused the event.n * -1: none, 0: primary/left, 1: aux/middle, 2: secondary/right, 3: X1/back, 4: X2/forward, 5: pen eraser.n * @property {Number} buttons - Current buttons pressed.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'canvas-nonprimary-press', {n tracker: event.eventSource,n position: event.position,n pointerType: event.pointerType,n button: event.button,n buttons: event.buttons,n originalEvent: event.originalEventn });n}nnfunction onCanvasNonPrimaryRelease( event ) {n /**n * Raised when any non-primary pointer button is released on the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-nonprimary-releasen * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {String} pointerType - "mouse", "touch", "pen", etc.n * @property {Number} button - Button which caused the event.n * -1: none, 0: primary/left, 1: aux/middle, 2: secondary/right, 3: X1/back, 4: X2/forward, 5: pen eraser.n * @property {Number} buttons - Current buttons pressed.n * Combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'canvas-nonprimary-release', {n tracker: event.eventSource,n position: event.position,n pointerType: event.pointerType,n button: event.button,n buttons: event.buttons,n originalEvent: event.originalEventn });n}nnfunction onCanvasPinch( event ) {n var gestureSettings,n centerPt,n lastCenterPt,n panByPt;nn if ( !event.preventDefaultAction && this.viewport ) {n gestureSettings = this.gestureSettingsByDeviceType( event.pointerType );n if ( gestureSettings.pinchToZoom ) {n centerPt = this.viewport.pointFromPixel( event.center, true );n lastCenterPt = this.viewport.pointFromPixel( event.lastCenter, true );n panByPt = lastCenterPt.minus( centerPt );n if( !this.panHorizontal ) {n panByPt.x = 0;n }n if( !this.panVertical ) {n panByPt.y = 0;n }n this.viewport.zoomBy( event.distance / event.lastDistance, centerPt, true );n if ( gestureSettings.zoomToRefPoint ) {n this.viewport.panBy(panByPt, true);n }n this.viewport.applyConstraints();n }n if ( gestureSettings.pinchRotate ) {n // Pinch rotaten var angle1 = Math.atan2(event.gesturePoints.currentPos.y - event.gesturePoints.currentPos.y,n event.gesturePoints.currentPos.x - event.gesturePoints.currentPos.x);n var angle2 = Math.atan2(event.gesturePoints.lastPos.y - event.gesturePoints.lastPos.y,n event.gesturePoints.lastPos.x - event.gesturePoints.lastPos.x);n this.viewport.setRotation(this.viewport.getRotation() + ((angle1 - angle2) * (180 / Math.PI)));n }n }n /**n * Raised when a pinch event occurs on the {@link OpenSeadragon.Viewer#canvas} element.n *n * @event canvas-pinchn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {Array.<OpenSeadragon.MouseTracker.GesturePoint>} gesturePoints - Gesture points associated with the gesture. Velocity data can be found here.n * @property {OpenSeadragon.Point} lastCenter - The previous center point of the two pinch contact points relative to the tracked element.n * @property {OpenSeadragon.Point} center - The center point of the two pinch contact points relative to the tracked element.n * @property {Number} lastDistance - The previous distance between the two pinch contact points in CSS pixels.n * @property {Number} distance - The distance between the two pinch contact points in CSS pixels.n * @property {Boolean} shift - True if the shift key was pressed during this event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent('canvas-pinch', {n tracker: event.eventSource,n gesturePoints: event.gesturePoints,n lastCenter: event.lastCenter,n center: event.center,n lastDistance: event.lastDistance,n distance: event.distance,n shift: event.shift,n originalEvent: event.originalEventn });n //cancels eventn return false;n}nnfunction onCanvasScroll( event ) {n var gestureSettings,n factor,n thisScrollTime,n deltaScrollTime;nn /* Certain scroll devices fire the scroll event way too fast so we are injecting a simple adjustment to keep thingsn * partially normalized. If we have already fired an event within the last 'minScrollDelta' milliseconds we skipn * this one and wait for the next event. */n thisScrollTime = $.now();n deltaScrollTime = thisScrollTime - this._lastScrollTime;n if (deltaScrollTime > this.minScrollDeltaTime) {n this._lastScrollTime = thisScrollTime;nn if(this.viewport.flipped){n event.position.x = this.viewport.getContainerSize().x - event.position.x;n }nn if ( !event.preventDefaultAction && this.viewport ) {n gestureSettings = this.gestureSettingsByDeviceType( event.pointerType );n if ( gestureSettings.scrollToZoom ) {n factor = Math.pow( this.zoomPerScroll, event.scroll );n this.viewport.zoomBy(n factor,n gestureSettings.zoomToRefPoint ? this.viewport.pointFromPixel( event.position, true ) : nulln );n this.viewport.applyConstraints();n }n }n /**n * Raised when a scroll event occurs on the {@link OpenSeadragon.Viewer#canvas} element (mouse wheel).n *n * @event canvas-scrolln * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Number} scroll - The scroll delta for the event.n * @property {Boolean} shift - True if the shift key was pressed during this event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'canvas-scroll', {n tracker: event.eventSource,n position: event.position,n scroll: event.scroll,n shift: event.shift,n originalEvent: event.originalEventn });n if (gestureSettings && gestureSettings.scrollToZoom) {n //cancels eventn return false;n }n }n else {n gestureSettings = this.gestureSettingsByDeviceType( event.pointerType );n if (gestureSettings && gestureSettings.scrollToZoom) {n return false; // We are swallowing this eventn }n }n}nnfunction onContainerEnter( event ) {n THIS[ this.hash ].mouseInside = true;n abortControlsAutoHide( this );n /**n * Raised when the cursor enters the {@link OpenSeadragon.Viewer#container} element.n *n * @event container-entern * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Number} buttons - Current buttons pressed. A combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @property {Number} pointers - Number of pointers (all types) active in the tracked element.n * @property {Boolean} insideElementPressed - True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false.n * @property {Boolean} buttonDownAny - Was the button down anywhere in the screen during the event. <span style="color:red;">Deprecated. Use buttons instead.</span>n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'container-enter', {n tracker: event.eventSource,n position: event.position,n buttons: event.buttons,n pointers: event.pointers,n insideElementPressed: event.insideElementPressed,n buttonDownAny: event.buttonDownAny,n originalEvent: event.originalEventn });n}nnfunction onContainerExit( event ) {n if ( event.pointers < 1 ) {n THIS[ this.hash ].mouseInside = false;n if ( !THIS[ this.hash ].animating ) {n beginControlsAutoHide( this );n }n }n /**n * Raised when the cursor leaves the {@link OpenSeadragon.Viewer#container} element.n *n * @event container-exitn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Number} buttons - Current buttons pressed. A combination of bit flags 0: none, 1: primary (or touch contact), 2: secondary, 4: aux (often middle), 8: X1 (often back), 16: X2 (often forward), 32: pen eraser.n * @property {Number} pointers - Number of pointers (all types) active in the tracked element.n * @property {Boolean} insideElementPressed - True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false.n * @property {Boolean} buttonDownAny - Was the button down anywhere in the screen during the event. <span style="color:red;">Deprecated. Use buttons instead.</span>n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'container-exit', {n tracker: event.eventSource,n position: event.position,n buttons: event.buttons,n pointers: event.pointers,n insideElementPressed: event.insideElementPressed,n buttonDownAny: event.buttonDownAny,n originalEvent: event.originalEventn });n}nnn///////////////////////////////////////////////////////////////////////////////n// Page update routines ( aka Views - for future reference )n///////////////////////////////////////////////////////////////////////////////nnfunction updateMulti( viewer ) {n updateOnce( viewer );nn // Request the next frame, unless we've been closedn if ( viewer.isOpen() ) {n viewer._updateRequestId = scheduleUpdate( viewer, updateMulti );n } else {n viewer._updateRequestId = false;n }n}nnfunction updateOnce( viewer ) {nn //viewer.profiler.beginUpdate();nn if (viewer._opening) {n return;n }nn if (viewer.autoResize) {n var containerSize = _getSafeElemSize(viewer.container);n var prevContainerSize = THIS.prevContainerSize;n if (!containerSize.equals(prevContainerSize)) {n var viewport = viewer.viewport;n if (viewer.preserveImageSizeOnResize) {n var resizeRatio = prevContainerSize.x / containerSize.x;n var zoom = viewport.getZoom() * resizeRatio;n var center = viewport.getCenter();n viewport.resize(containerSize, false);n viewport.zoomTo(zoom, null, true);n viewport.panTo(center, true);n } else {n // maintain image positionn var oldBounds = viewport.getBounds();n viewport.resize(containerSize, true);n viewport.fitBoundsWithConstraints(oldBounds, true);n }n THIS.prevContainerSize = containerSize;n THIS.forceRedraw = true;n }n }nn var viewportChange = viewer.viewport.update();n var animated = viewer.world.update() || viewportChange;nn if (viewportChange) {n /**n * Raised when any spring animation update occurs (zoom, pan, etc.),n * before the viewer has drawn the new location.n *n * @event viewport-changen * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n viewer.raiseEvent('viewport-change');n }nn if( viewer.referenceStrip ){n animated = viewer.referenceStrip.update( viewer.viewport ) || animated;n }nn if ( !THIS[ viewer.hash ].animating && animated ) {n /**n * Raised when any spring animation starts (zoom, pan, etc.).n *n * @event animation-startn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n viewer.raiseEvent( "animation-start" );n abortControlsAutoHide( viewer );n }nn if ( animated || THIS[ viewer.hash ].forceRedraw || viewer.world.needsDraw() ) {n drawWorld( viewer );n viewer._drawOverlays();n if( viewer.navigator ){n viewer.navigator.update( viewer.viewport );n }nn THIS[ viewer.hash ].forceRedraw = false;nn if (animated) {n /**n * Raised when any spring animation update occurs (zoom, pan, etc.),n * after the viewer has drawn the new location.n *n * @event animationn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n viewer.raiseEvent( "animation" );n }n }nn if ( THIS[ viewer.hash ].animating && !animated ) {n /**n * Raised when any spring animation ends (zoom, pan, etc.).n *n * @event animation-finishn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n viewer.raiseEvent( "animation-finish" );nn if ( !THIS[ viewer.hash ].mouseInside ) {n beginControlsAutoHide( viewer );n }n }nn THIS[ viewer.hash ].animating = animated;nn //viewer.profiler.endUpdate();n}nnfunction drawWorld( viewer ) {n viewer.imageLoader.clear();n viewer.drawer.clear();n viewer.world.draw();nn /**n * - Needs documentation -n *n * @event update-viewportn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n viewer.raiseEvent( 'update-viewport', {} );n}nn///////////////////////////////////////////////////////////////////////////////n// Navigation Controlsn///////////////////////////////////////////////////////////////////////////////nfunction resolveUrl( prefix, url ) {n return prefix ? prefix + url : url;n}nnnnfunction beginZoomingIn() {n THIS[ this.hash ].lastZoomTime = $.now();n THIS[ this.hash ].zoomFactor = this.zoomPerSecond;n THIS[ this.hash ].zooming = true;n scheduleZoom( this );n}nnnfunction beginZoomingOut() {n THIS[ this.hash ].lastZoomTime = $.now();n THIS[ this.hash ].zoomFactor = 1.0 / this.zoomPerSecond;n THIS[ this.hash ].zooming = true;n scheduleZoom( this );n}nnnfunction endZooming() {n THIS[ this.hash ].zooming = false;n}nnnfunction scheduleZoom( viewer ) {n $.requestAnimationFrame( $.delegate( viewer, doZoom ) );n}nnnfunction doZoom() {n var currentTime,n deltaTime,n adjustedFactor;nn if ( THIS[ this.hash ].zooming && this.viewport) {n currentTime = $.now();n deltaTime = currentTime - THIS[ this.hash ].lastZoomTime;n adjustedFactor = Math.pow( THIS[ this.hash ].zoomFactor, deltaTime / 1000 );nn this.viewport.zoomBy( adjustedFactor );n this.viewport.applyConstraints();n THIS[ this.hash ].lastZoomTime = currentTime;n scheduleZoom( this );n }n}nnnfunction doSingleZoomIn() {n if ( this.viewport ) {n THIS[ this.hash ].zooming = false;n this.viewport.zoomBy(n this.zoomPerClick / 1.0n );n this.viewport.applyConstraints();n }n}nnnfunction doSingleZoomOut() {n if ( this.viewport ) {n THIS[ this.hash ].zooming = false;n this.viewport.zoomBy(n 1.0 / this.zoomPerClickn );n this.viewport.applyConstraints();n }n}nnnfunction lightUp() {n this.buttons.emulateEnter();n this.buttons.emulateExit();n}nnnfunction onHome() {n if ( this.viewport ) {n this.viewport.goHome();n }n}nnnfunction onFullScreen() {n if ( this.isFullPage() && !$.isFullScreen() ) {n // Is fullPage but not fullScreenn this.setFullPage( false );n } else {n this.setFullScreen( !this.isFullPage() );n }n // correct for no mouseout event on changen if ( this.buttons ) {n this.buttons.emulateExit();n }n this.fullPageButton.element.focus();n if ( this.viewport ) {n this.viewport.applyConstraints();n }n}nn/**n * Note: The current rotation feature is limited to 90 degree turns.n */nfunction onRotateLeft() {n if ( this.viewport ) {n var currRotation = this.viewport.getRotation();nn if ( this.viewport.flipped ){n currRotation = $.positiveModulo(currRotation + 90, 360);n } else {n currRotation = $.positiveModulo(currRotation - 90, 360);n }n this.viewport.setRotation(currRotation);n }n}nn/**n * Note: The current rotation feature is limited to 90 degree turns.n */nfunction onRotateRight() {n if ( this.viewport ) {n var currRotation = this.viewport.getRotation();nn if ( this.viewport.flipped ){n currRotation = $.positiveModulo(currRotation - 90, 360);n } else {n currRotation = $.positiveModulo(currRotation + 90, 360);n }n this.viewport.setRotation(currRotation);n }n}nn/**n * Note: When pressed flip control buttonn */nfunction onFlip() {n this.viewport.toggleFlip();n}nnfunction onPrevious(){n var previous = this._sequenceIndex - 1;n if(this.navPrevNextWrap && previous < 0){n previous += this.tileSources.length;n }n this.goToPage( previous );n}nnnfunction onNext(){n var next = this._sequenceIndex + 1;n if(this.navPrevNextWrap && next >= this.tileSources.length){n next = 0;n }n this.goToPage( next );n}nnn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - Navigatorn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * @class Navigatorn * @classdesc The Navigator provides a small view of the current image as fixedn * while representing the viewport as a moving box serving as a framen * of reference in the larger viewport as to which portion of the imagen * is currently being examined. The navigator's viewport can be interactedn * with using the keyboard or the mouse.n *n * @memberof OpenSeadragonn * @extends OpenSeadragon.Viewern * @extends OpenSeadragon.EventSourcen * @param {Object} optionsn */n$.Navigator = function( options ){nn var viewer = options.viewer,n _this = this,n viewerSize,n navigatorSize;nn //We may need to create a new element and id if they did notn //provide the id for the existing elementn if( !options.id ){n options.id = 'navigator-' + $.now();n this.element = $.makeNeutralElement( "div" );n options.controlOptions = {n anchor: $.ControlAnchor.TOP_RIGHT,n attachToViewer: true,n autoFade: options.autoFaden };nn if( options.position ){n if( 'BOTTOM_RIGHT' == options.position ){n options.controlOptions.anchor = $.ControlAnchor.BOTTOM_RIGHT;n } else if( 'BOTTOM_LEFT' == options.position ){n options.controlOptions.anchor = $.ControlAnchor.BOTTOM_LEFT;n } else if( 'TOP_RIGHT' == options.position ){n options.controlOptions.anchor = $.ControlAnchor.TOP_RIGHT;n } else if( 'TOP_LEFT' == options.position ){n options.controlOptions.anchor = $.ControlAnchor.TOP_LEFT;n } else if( 'ABSOLUTE' == options.position ){n options.controlOptions.anchor = $.ControlAnchor.ABSOLUTE;n options.controlOptions.top = options.top;n options.controlOptions.left = options.left;n options.controlOptions.height = options.height;n options.controlOptions.width = options.width;n }n }nn } else {n this.element = document.getElementById( options.id );n options.controlOptions = {n anchor: $.ControlAnchor.NONE,n attachToViewer: false,n autoFade: falsen };n }n this.element.id = options.id;n this.element.className += ' navigator';nn options = $.extend( true, {n sizeRatio: $.DEFAULT_SETTINGS.navigatorSizeRation }, options, {n element: this.element,n tabIndex: -1, // No keyboard navigation, omit from tab ordern //These need to be overridden to prevent recursion sincen //the navigator is a viewer and a viewer has a navigatorn showNavigator: false,n mouseNavEnabled: false,n showNavigationControl: false,n showSequenceControl: false,n immediateRender: true,n blendTime: 0,n animationTime: 0,n autoResize: options.autoResize,n // prevent resizing the navigator from adding unwanted space around the imagen minZoomImageRatio: 1.0,n background: options.background,n opacity: options.opacity,n borderColor: options.borderColor,n displayRegionColor: options.displayRegionColorn });nn options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio;nn $.setElementTouchActionNone( this.element );nn this.borderWidth = 2;n //At some browser magnification levels the display regions lines up correctly, but at some there appears ton //be a one pixel gap.n this.fudge = new $.Point(1, 1);n this.totalBorderWidths = new $.Point(this.borderWidth * 2, this.borderWidth * 2).minus(this.fudge);nnn if ( options.controlOptions.anchor != $.ControlAnchor.NONE ) {n (function( style, borderWidth ){n style.margin = '0px';n style.border = borderWidth + 'px solid ' + options.borderColor;n style.padding = '0px';n style.background = options.background;n style.opacity = options.opacity;n style.overflow = 'hidden';n }( this.element.style, this.borderWidth));n }nn this.displayRegion = $.makeNeutralElement( "div" );n this.displayRegion.id = this.element.id + '-displayregion';n this.displayRegion.className = 'displayregion';nn (function( style, borderWidth ){n style.position = 'relative';n style.top = '0px';n style.left = '0px';n style.fontSize = '0px';n style.overflow = 'hidden';n style.border = borderWidth + 'px solid ' + options.displayRegionColor;n style.margin = '0px';n style.padding = '0px';n //TODO: IE doesnt like this property being setn //try{ style.outline = '2px auto #909'; }catch(e){/ignore/}nn style.background = 'transparent';nn // We use square bracket notation on the statement below, because float is a keyword.n // This is important for the Google Closure compiler, if nothing else.n /*jshint sub:true */n style = 'left'; //Webkitnn style.cssFloat = 'left'; //Firefoxn style.styleFloat = 'left'; //IEn style.zIndex = 999999999;n style.cursor = 'default';n }( this.displayRegion.style, this.borderWidth ));nn this.displayRegionContainer = $.makeNeutralElement("div");n this.displayRegionContainer.id = this.element.id + '-displayregioncontainer';n this.displayRegionContainer.className = "displayregioncontainer";n this.displayRegionContainer.style.width = "100%";n this.displayRegionContainer.style.height = "100%";nn viewer.addControl(n this.element,n options.controlOptionsn );nn this._resizeWithViewer = options.controlOptions.anchor != $.ControlAnchor.ABSOLUTE &&n options.controlOptions.anchor != $.ControlAnchor.NONE;nn if ( this._resizeWithViewer ) {n if ( options.width && options.height ) {n this.element.style.height = typeof (options.height) == "number" ? (options.height + 'px') : options.height;n this.element.style.width = typeof (options.width) == "number" ? (options.width + 'px') : options.width;n } else {n viewerSize = $.getElementSize( viewer.element );n this.element.style.height = Math.round( viewerSize.y * options.sizeRatio ) + 'px';n this.element.style.width = Math.round( viewerSize.x * options.sizeRatio ) + 'px';n this.oldViewerSize = viewerSize;n }n navigatorSize = $.getElementSize( this.element );n this.elementArea = navigatorSize.x * navigatorSize.y;n }nn this.oldContainerSize = new $.Point( 0, 0 );nn $.Viewer.apply( this, [ options ] );nn this.displayRegionContainer.appendChild(this.displayRegion);n this.element.getElementsByTagName(’div’).appendChild(this.displayRegionContainer);nn function rotate(degrees) {n _setTransformRotate(_this.displayRegionContainer, degrees);n _setTransformRotate(_this.displayRegion, -degrees);n _this.viewport.setRotation(degrees);n }n if (options.navigatorRotate) {n var degrees = options.viewer.viewport ?n options.viewer.viewport.getRotation() :n options.viewer.degrees || 0;nn rotate(degrees);n options.viewer.addHandler("rotate", function (args) {n rotate(args.degrees);n });n }nnn // Remove the base class' (Viewer's) innerTracker and replace it with our ownn this.innerTracker.destroy();n this.innerTracker = new $.MouseTracker({n element: this.element,n dragHandler: $.delegate( this, onCanvasDrag ),n clickHandler: $.delegate( this, onCanvasClick ),n releaseHandler: $.delegate( this, onCanvasRelease ),n scrollHandler: $.delegate( this, onCanvasScroll )n });nn this.addHandler("reset-size", function() {n if (_this.viewport) {n _this.viewport.goHome(true);n }n });nn viewer.world.addHandler("item-index-change", function(event) {n window.setTimeout(function(){n var item = _this.world.getItemAt(event.previousIndex);n _this.world.setItemIndex(item, event.newIndex);n }, 1);n });nn viewer.world.addHandler("remove-item", function(event) {n var theirItem = event.item;n var myItem = _this._getMatchingItem(theirItem);n if (myItem) {n _this.world.removeItem(myItem);n }n });nn this.update(viewer.viewport);n};nn$.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /** @lends OpenSeadragon.Navigator.prototype */{nn /**n * Used to notify the navigator when its size has changed.n * Especially useful when {@link OpenSeadragon.Options}.navigatorAutoResize is set to false and the navigator is resizable.n * @functionn */n updateSize: function () {n if ( this.viewport ) {n var containerSize = new $.Point(n (this.container.clientWidth === 0 ? 1 : this.container.clientWidth),n (this.container.clientHeight === 0 ? 1 : this.container.clientHeight)n );nn if ( !containerSize.equals( this.oldContainerSize ) ) {n this.viewport.resize( containerSize, true );n this.viewport.goHome(true);n this.oldContainerSize = containerSize;n this.drawer.clear();n this.world.draw();n }n }n },n /**n /* Flip navigator elementn * @param {Boolean} state - Flip state to set.n */n setFlip: function(state) {n this.viewport.setFlip(state);nn this.setDisplayTransform(this.viewer.viewport.getFlip() ? "scale(-1,1)" : "scale(1,1)");n return this;n },nn setDisplayTransform: function(rule) {n setElementTransform(this.displayRegion, rule);n setElementTransform(this.canvas, rule);n setElementTransform(this.element, rule);n },nn /**n * Used to update the navigator minimap's viewport rectangle when a change in the viewer's viewport occurs.n * @functionn * @param {OpenSeadragon.Viewport} The viewport this navigator is tracking.n */n update: function( viewport ) {nn var viewerSize,n newWidth,n newHeight,n bounds,n topleft,n bottomright;nn viewerSize = $.getElementSize( this.viewer.element );n if ( this._resizeWithViewer && viewerSize.x && viewerSize.y && !viewerSize.equals( this.oldViewerSize ) ) {n this.oldViewerSize = viewerSize;nn if ( this.maintainSizeRatio || !this.elementArea) {n newWidth = viewerSize.x * this.sizeRatio;n newHeight = viewerSize.y * this.sizeRatio;n } else {n newWidth = Math.sqrt(this.elementArea * (viewerSize.x / viewerSize.y));n newHeight = this.elementArea / newWidth;n }nn this.element.style.width = Math.round( newWidth ) + 'px';n this.element.style.height = Math.round( newHeight ) + 'px';nn if (!this.elementArea) {n this.elementArea = newWidth * newHeight;n }nn this.updateSize();n }nn if (viewport && this.viewport) {n bounds = viewport.getBoundsNoRotate(true);n topleft = this.viewport.pixelFromPointNoRotate(bounds.getTopLeft(), false);n bottomright = this.viewport.pixelFromPointNoRotate(bounds.getBottomRight(), false)n .minus( this.totalBorderWidths );nn //update style for navigator-boxn var style = this.displayRegion.style;n style.display = this.world.getItemCount() ? 'block' : 'none';nn style.top = Math.round( topleft.y ) + 'px';n style.left = Math.round( topleft.x ) + 'px';nn var width = Math.abs( topleft.x - bottomright.x );n var height = Math.abs( topleft.y - bottomright.y );n // make sure width and height are non-negative so IE doesn't thrown style.width = Math.round( Math.max( width, 0 ) ) + 'px';n style.height = Math.round( Math.max( height, 0 ) ) + 'px';n }nn },nn // overrides Viewer.addTiledImagen addTiledImage: function(options) {n var _this = this;nn var original = options.originalTiledImage;n delete options.original;nn var optionsClone = $.extend({}, options, {n success: function(event) {n var myItem = event.item;n myItem._originalForNavigator = original;n _this._matchBounds(myItem, original, true);nn function matchBounds() {n _this._matchBounds(myItem, original);n }nn function matchOpacity() {n _this._matchOpacity(myItem, original);n }nn function matchCompositeOperation() {n _this._matchCompositeOperation(myItem, original);n }nn original.addHandler('bounds-change', matchBounds);n original.addHandler('clip-change', matchBounds);n original.addHandler('opacity-change', matchOpacity);n original.addHandler('composite-operation-change', matchCompositeOperation);n }n });nn return $.Viewer.prototype.addTiledImage.apply(this, [optionsClone]);n },nn // privaten _getMatchingItem: function(theirItem) {n var count = this.world.getItemCount();n var item;n for (var i = 0; i < count; i++) {n item = this.world.getItemAt(i);n if (item._originalForNavigator === theirItem) {n return item;n }n }nn return null;n },nn // privaten _matchBounds: function(myItem, theirItem, immediately) {n var bounds = theirItem.getBoundsNoRotate();n myItem.setPosition(bounds.getTopLeft(), immediately);n myItem.setWidth(bounds.width, immediately);n myItem.setRotation(theirItem.getRotation(), immediately);n myItem.setClip(theirItem.getClip());n },nn // privaten _matchOpacity: function(myItem, theirItem) {n myItem.setOpacity(theirItem.opacity);n },nn // privaten _matchCompositeOperation: function(myItem, theirItem) {n myItem.setCompositeOperation(theirItem.compositeOperation);n }n});nnn/**n * @privaten * @innern * @functionn */nfunction onCanvasClick( event ) {n var canvasClickEventArgs = {n tracker: event.eventSource,n position: event.position,n quick: event.quick,n shift: event.shift,n originalEvent: event.originalEvent,n preventDefaultAction: event.preventDefaultActionn };n /**n * Raised when a click event occurs on the {@link OpenSeadragon.Viewer#navigator} element.n *n * @event navigator-clickn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Boolean} quick - True only if the clickDistThreshold and clickTimeThreshold are both passed. Useful for differentiating between clicks and drags.n * @property {Boolean} shift - True if the shift key was pressed during this event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n * @property {Boolean} preventDefaultAction - Set to true to prevent default click to zoom behaviour. Default: false.n */nn this.viewer.raiseEvent('navigator-click', canvasClickEventArgs);nn if ( !canvasClickEventArgs.preventDefaultAction && event.quick && this.viewer.viewport && (this.panVertical || this.panHorizontal)) {n if(this.viewer.viewport.flipped) {n event.position.x = this.viewport.getContainerSize().x - event.position.x;n }n var target = this.viewport.pointFromPixel(event.position);n if (!this.panVertical) {n // perform only horizonal pann target.y = this.viewer.viewport.getCenter(true).y;n } else if (!this.panHorizontal) {n // perform only vertical pann target.x = this.viewer.viewport.getCenter(true).x;n }n this.viewer.viewport.panTo(target);n this.viewer.viewport.applyConstraints();n }nn}nn/**n * @privaten * @innern * @functionn */nfunction onCanvasDrag( event ) {n var canvasDragEventArgs = {n tracker: event.eventSource,n position: event.position,n delta: event.delta,n speed: event.speed,n direction: event.direction,n shift: event.shift,n originalEvent: event.originalEvent,n preventDefaultAction: event.preventDefaultActionn };n /**n * Raised when a drag event occurs on the {@link OpenSeadragon.Viewer#navigator} element.n *n * @event navigator-dragn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {OpenSeadragon.Point} delta - The x,y components of the difference between start drag and end drag.n * @property {Number} speed - Current computed speed, in pixels per second.n * @property {Number} direction - Current computed direction, expressed as an angle counterclockwise relative to the positive X axis (-pi to pi, in radians). Only valid if speed > 0.n * @property {Boolean} shift - True if the shift key was pressed during this event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n * @property {Boolean} preventDefaultAction - Set to true to prevent default click to zoom behaviour. Default: false.n */n this.viewer.raiseEvent('navigator-drag', canvasDragEventArgs);nn if ( !canvasDragEventArgs.preventDefaultAction && this.viewer.viewport ) {n if( !this.panHorizontal ){n event.delta.x = 0;n }n if( !this.panVertical ){n event.delta.y = 0;n }nn if(this.viewer.viewport.flipped){n event.delta.x = -event.delta.x;n }nn this.viewer.viewport.panBy(n this.viewport.deltaPointsFromPixels(n event.deltan )n );n if( this.viewer.constrainDuringPan ){n this.viewer.viewport.applyConstraints();n }n }n}nnn/**n * @privaten * @innern * @functionn */nfunction onCanvasRelease( event ) {n if ( event.insideElementPressed && this.viewer.viewport ) {n this.viewer.viewport.applyConstraints();n }n}nnn/**n * @privaten * @innern * @functionn */nfunction onCanvasScroll( event ) {n /**n * Raised when a scroll event occurs on the {@link OpenSeadragon.Viewer#navigator} element (mouse wheel, touch pinch, etc.).n *n * @event navigator-scrolln * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.n * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.n * @property {Number} scroll - The scroll delta for the event.n * @property {Boolean} shift - True if the shift key was pressed during this event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.viewer.raiseEvent( 'navigator-scroll', {n tracker: event.eventSource,n position: event.position,n scroll: event.scroll,n shift: event.shift,n originalEvent: event.originalEventn });nn //dont scroll the page up and down if the user is scrollingn //in the navigatorn return false;n}nn/**n * @functionn * @privaten * @param {Object} elementn * @param {Number} degreesn */nfunction _setTransformRotate( element, degrees ) {n setElementTransform(element, "rotate(" + degrees + "deg)");n}nnfunction setElementTransform( element, rule ) {n element.style.webkitTransform = rule;n element.style.mozTransform = rule;n element.style.msTransform = rule;n element.style.oTransform = rule;n element.style.transform = rule;n}nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - getString/setStringn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn//TODO: I guess this is where the i18n needs to be reimplemented. I'll lookn// into existing patterns for i18n in javascript but i think that mimickingn// pythons gettext might be a reasonable approach.nvar I18N = {n Errors: {n Dzc: "Sorry, we don't support Deep Zoom Collections!",n Dzi: "Hmm, this doesn't appear to be a valid Deep Zoom Image.",n Xml: "Hmm, this doesn't appear to be a valid Deep Zoom Image.",n ImageFormat: "Sorry, we don't support {0}-based Deep Zoom Images.",n Security: "It looks like a security restriction stopped us from " +n "loading this Deep Zoom Image.",n Status: "This space unintentionally left blank ({0} {1}).",n OpenFailed: "Unable to open {0}: {1}"n },nn Tooltips: {n FullPage: "Toggle full page",n Home: "Go home",n ZoomIn: "Zoom in",n ZoomOut: "Zoom out",n NextPage: "Next page",n PreviousPage: "Previous page",n RotateLeft: "Rotate left",n RotateRight: "Rotate right",n Flip: "Flip Horizontally"n }n};nn$.extend( $, /** @lends OpenSeadragon */{nn /**n * @functionn * @param {String} propertyn */n getString: function( prop ) {nn var props = prop.split('.'),n string = null,n args = arguments,n container = I18N,n i;nn for (i = 0; i < props.length - 1; i++) {n // in case not a subpropertyn container = container[ props[ i ] ] || {};n }n string = container[ props[ i ] ];nn if ( typeof ( string ) != "string" ) {n $.console.log( "Untranslated source string:", prop );n string = ""; // FIXME: this breaks gettext()-style convention, which would return sourcen }nn return string.replace(/\{\d+\}/g, function(capture) {n var i = parseInt( capture.match( /\d+/ ), 10 ) + 1;n return i < args.length ?n args[ i ] :n "";n });n },nn /**n * @functionn * @param {String} propertyn * @param {*} valuen */n setString: function( prop, value ) {nn var props = prop.split('.'),n container = I18N,n i;nn for ( i = 0; i < props.length - 1; i++ ) {n if ( !container[ props[ i ] ] ) {n container[ props[ i ] ] = {};n }n container = container[ props[ i ] ];n }nn container[ props[ i ] ] = value;n }nn});nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - Pointn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * @class Pointn * @classdesc A Point is really used as a 2-dimensional vector, equally useful forn * representing a point on a plane, or the height and width of a planen * not requiring any other frame of reference.n *n * @memberof OpenSeadragonn * @param {Number} [x] The vector component 'x'. Defaults to the origin at 0.n * @param {Number} [y] The vector component 'y'. Defaults to the origin at 0.n */n$.Point = function( x, y ) {n /**n * The vector component 'x'.n * @member {Number} xn * @memberof OpenSeadragon.Point#n */n this.x = typeof ( x ) == "number" ? x : 0;n /**n * The vector component 'y'.n * @member {Number} yn * @memberof OpenSeadragon.Point#n */n this.y = typeof ( y ) == "number" ? y : 0;n};nn/** @lends OpenSeadragon.Point.prototype */n$.Point.prototype = {n /**n * @functionn * @returns {OpenSeadragon.Point} a duplicate of this Pointn */n clone: function() {n return new $.Point(this.x, this.y);n },nn /**n * Add another Point to this point and return a new Point.n * @functionn * @param {OpenSeadragon.Point} point The point to add vector components.n * @returns {OpenSeadragon.Point} A new point representing the sum of then * vector componentsn */n plus: function( point ) {n return new $.Point(n this.x + point.x,n this.y + point.yn );n },nn /**n * Substract another Point to this point and return a new Point.n * @functionn * @param {OpenSeadragon.Point} point The point to substract vector components.n * @returns {OpenSeadragon.Point} A new point representing the substraction of then * vector componentsn */n minus: function( point ) {n return new $.Point(n this.x - point.x,n this.y - point.yn );n },nn /**n * Multiply this point by a factor and return a new Point.n * @functionn * @param {Number} factor The factor to multiply vector components.n * @returns {OpenSeadragon.Point} A new point representing the multiplicationn * of the vector components by the factorn */n times: function( factor ) {n return new $.Point(n this.x * factor,n this.y * factorn );n },nn /**n * Divide this point by a factor and return a new Point.n * @functionn * @param {Number} factor The factor to divide vector components.n * @returns {OpenSeadragon.Point} A new point representing the division of then * vector components by the factorn */n divide: function( factor ) {n return new $.Point(n this.x / factor,n this.y / factorn );n },nn /**n * Compute the opposite of this point and return a new Point.n * @functionn * @returns {OpenSeadragon.Point} A new point representing the opposite of then * vector componentsn */n negate: function() {n return new $.Point( -this.x, -this.y );n },nn /**n * Compute the distance between this point and another point.n * @functionn * @param {OpenSeadragon.Point} point The point to compute the distance with.n * @returns {Number} The distance between the 2 pointsn */n distanceTo: function( point ) {n return Math.sqrt(n Math.pow( this.x - point.x, 2 ) +n Math.pow( this.y - point.y, 2 )n );n },nn /**n * Compute the squared distance between this point and another point.n * Useful for optimizing things like comparing distances.n * @functionn * @param {OpenSeadragon.Point} point The point to compute the squared distance with.n * @returns {Number} The squared distance between the 2 pointsn */n squaredDistanceTo: function( point ) {n return Math.pow( this.x - point.x, 2 ) +n Math.pow( this.y - point.y, 2 );n },nn /**n * Apply a function to each coordinate of this point and return a new point.n * @functionn * @param {function} func The function to apply to each coordinate.n * @returns {OpenSeadragon.Point} A new point with the coordinates computedn * by the specified functionn */n apply: function( func ) {n return new $.Point( func( this.x ), func( this.y ) );n },nn /**n * Check if this point is equal to another one.n * @functionn * @param {OpenSeadragon.Point} point The point to compare this point with.n * @returns {Boolean} true if they are equal, false otherwise.n */n equals: function( point ) {n return (n point instanceof $.Pointn ) && (n this.x === point.xn ) && (n this.y === point.yn );n },nn /**n * Rotates the point around the specified pivotn * From stackoverflow.com/questions/4465931/rotate-rectangle-around-a-pointn * @functionn * @param {Number} degress to rotate around the pivot.n * @param {OpenSeadragon.Point} [pivot=(0,0)] Point around which to rotate.n * Defaults to the origin.n * @returns {OpenSeadragon.Point}. A new point representing the point rotated around the specified pivotn */n rotate: function (degrees, pivot) {n pivot = pivot || new $.Point(0, 0);n var cos;n var sin;n // Avoid float computations when possiblen if (degrees % 90 === 0) {n var d = $.positiveModulo(degrees, 360);n switch (d) {n case 0:n cos = 1;n sin = 0;n break;n case 90:n cos = 0;n sin = 1;n break;n case 180:n cos = -1;n sin = 0;n break;n case 270:n cos = 0;n sin = -1;n break;n }n } else {n var angle = degrees * Math.PI / 180.0;n cos = Math.cos(angle);n sin = Math.sin(angle);n }n var x = cos * (this.x - pivot.x) - sin * (this.y - pivot.y) + pivot.x;n var y = sin * (this.x - pivot.x) + cos * (this.y - pivot.y) + pivot.y;n return new $.Point(x, y);n },nn /**n * Convert this point to a string in the format (x,y) where x and y aren * rounded to the nearest integer.n * @functionn * @returns {String} A string representation of this point.n */n toString: function() {n return "(" + (Math.round(this.x * 100) / 100) + "," + (Math.round(this.y * 100) / 100) + ")";n }n};nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - TileSourcen *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nnn/**n * @class TileSourcen * @classdesc The TileSource contains the most basic implementation required to create an * smooth transition between layers in an image pyramid. It has only a single keyn * interface that must be implemented to complete its key functionality:n * 'getTileUrl'. It also has several optional interfaces that can ben * implemented if a new TileSource wishes to support configuration via a simplen * object or array ('configure') and if the tile source supports or requiresn * configuration via retrieval of a document on the network ala AJAX or JSONP,n * ('getImageInfo').n * <br/>n * By default the image pyramid is split into N layers where the image's longestn * side in M (in pixels), where N is the smallest integer which satisfiesn * <strong>2^(N+1) >= M</strong>.n *n * @memberof OpenSeadragonn * @extends OpenSeadragon.EventSourcen * @param {Object} optionsn * You can either specify a URL, or literally define the TileSource (by specifyingn * width, height, tileSize, tileOverlap, minLevel, and maxLevel). For the former,n * the extending class is expected to implement 'getImageInfo' and 'configure'.n * For the latter, the construction is assumed to occur throughn * the extending classes implementation of 'configure'.n * @param {String} [options.url]n * The URL for the data necessary for this TileSource.n * @param {String} [options.referenceStripThumbnailUrl]n * The URL for a thumbnail image to be used by the reference stripn * @param {Function} [options.success]n * A function to be called upon successful creation.n * @param {Boolean} [options.ajaxWithCredentials]n * If this TileSource needs to make an AJAX call, this specifies whether to setn * the XHR's withCredentials (for accessing secure data).n * @param {Object} [options.ajaxHeaders]n * A set of headers to include in AJAX requests.n * @param {Number} [options.width]n * Width of the source image at max resolution in pixels.n * @param {Number} [options.height]n * Height of the source image at max resolution in pixels.n * @param {Number} [options.tileSize]n * The size of the tiles to assumed to make up each pyramid layer in pixels.n * Tile size determines the point at which the image pyramid must ben * divided into a matrix of smaller images.n * Use options.tileWidth and options.tileHeight to support non-square tiles.n * @param {Number} [options.tileWidth]n * The width of the tiles to assumed to make up each pyramid layer in pixels.n * @param {Number} [options.tileHeight]n * The height of the tiles to assumed to make up each pyramid layer in pixels.n * @param {Number} [options.tileOverlap]n * The number of pixels each tile is expected to overlap touching tiles.n * @param {Number} [options.minLevel]n * The minimum level to attempt to load.n * @param {Number} [options.maxLevel]n * The maximum level to attempt to load.n */n$.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLevel ) {n var _this = this;nn var args = arguments,n options,n i;nn if( $.isPlainObject( width ) ){n options = width;n }else{n options = {n width: args,n height: args,n tileSize: args,n tileOverlap: args,n minLevel: args,n maxLevel: argsn };n }nn //Tile sources supply some events, namely 'ready' when they must be configuredn //by asynchronously fetching their configuration data.n $.EventSource.call( this );nn //we allow options to override anything we dont treat asn //required via idiomatic options or which is functionallyn //set depending on the state of the readiness of this tilen //sourcen $.extend( true, this, options );nn if (!this.success) {n //Any functions that are passed as arguments are bound to the ready callbackn for ( i = 0; i < arguments.length; i++ ) {n if ( $.isFunction( arguments[ i ] ) ) {n this.success = arguments[ i ];n //only one callback per constructorn break;n }n }n }nn if (this.success) {n this.addHandler( 'ready', function ( event ) {n _this.success( event );n } );n }nn /**n * Ratio of width to heightn * @member {Number} aspectRation * @memberof OpenSeadragon.TileSource#n */n /**n * Vector storing x and y dimensions ( width and height respectively ).n * @member {OpenSeadragon.Point} dimensionsn * @memberof OpenSeadragon.TileSource#n */n /**n * The overlap in pixels each tile shares with its adjacent neighbors.n * @member {Number} tileOverlapn * @memberof OpenSeadragon.TileSource#n */n /**n * The minimum pyramid level this tile source supports or should attempt to load.n * @member {Number} minLeveln * @memberof OpenSeadragon.TileSource#n */n /**n * The maximum pyramid level this tile source supports or should attempt to load.n * @member {Number} maxLeveln * @memberof OpenSeadragon.TileSource#n */n /**n *n * @member {Boolean} readyn * @memberof OpenSeadragon.TileSource#n */nn if( 'string' == $.type( arguments[ 0 ] ) ){n this.url = arguments;n }nn if (this.url) {n //in case the getImageInfo method is overriden and/or implies ann //async mechanism set some safe defaults firstn this.aspectRatio = 1;n this.dimensions = new $.Point( 10, 10 );n this._tileWidth = 0;n this._tileHeight = 0;n this.tileOverlap = 0;n this.minLevel = 0;n this.maxLevel = 0;n this.ready = false;n //configuration via url implies the extending classn //implements and 'configure'n this.getImageInfo( this.url );nn } else {nn //explicit configuration via positional args in constructorn //or the more idiomatic 'options' objectn this.ready = true;n this.aspectRatio = (options.width && options.height) ?n (options.width / options.height) : 1;n this.dimensions = new $.Point( options.width, options.height );nn if ( this.tileSize ){n this._tileWidth = this._tileHeight = this.tileSize;n delete this.tileSize;n } else {n if( this.tileWidth ){n // We were passed tileWidth in options, but we want to rename itn // with a leading underscore to make clear that it is not safe to directly modify itn this._tileWidth = this.tileWidth;n delete this.tileWidth;n } else {n this._tileWidth = 0;n }nn if( this.tileHeight ){n // See note above about renaming this.tileWidthn this._tileHeight = this.tileHeight;n delete this.tileHeight;n } else {n this._tileHeight = 0;n }n }nn this.tileOverlap = options.tileOverlap ? options.tileOverlap : 0;n this.minLevel = options.minLevel ? options.minLevel : 0;n this.maxLevel = ( undefined !== options.maxLevel && null !== options.maxLevel ) ?n options.maxLevel : (n ( options.width && options.height ) ? Math.ceil(n Math.log( Math.max( options.width, options.height ) ) /n Math.log( 2 )n ) : 0n );n if( this.success && $.isFunction( this.success ) ){n this.success( this );n }n }nnn};nn/** @lends OpenSeadragon.TileSource.prototype */n$.TileSource.prototype = {nn getTileSize: function( level ) {n $.console.error(n "[TileSource.getTileSize] is deprecated." +n "Use TileSource.getTileWidth() and TileSource.getTileHeight() instead"n );n return this._tileWidth;n },nn /**n * Return the tileWidth for a given level.n * Subclasses should override this if tileWidth can be different at different levelsn * such as in IIIFTileSource. Code should use this function rather than readingn * from ._tileWidth directly.n * @functionn * @param {Number} leveln */n getTileWidth: function( level ) {n if (!this._tileWidth) {n return this.getTileSize(level);n }n return this._tileWidth;n },nn /**n * Return the tileHeight for a given level.n * Subclasses should override this if tileHeight can be different at different levelsn * such as in IIIFTileSource. Code should use this function rather than readingn * from ._tileHeight directly.n * @functionn * @param {Number} leveln */n getTileHeight: function( level ) {n if (!this._tileHeight) {n return this.getTileSize(level);n }n return this._tileHeight;n },nn /**n * @functionn * @param {Number} leveln */n getLevelScale: function( level ) {nn // see github.com/openseadragon/openseadragon/issues/22n // we use the tilesources implementation of getLevelScale to generaten // a memoized re-implementationn var levelScaleCache = {},n i;n for( i = 0; i <= this.maxLevel; i++ ){n levelScaleCache[ i ] = 1 / Math.pow(2, this.maxLevel - i);n }n this.getLevelScale = function( _level ){n return levelScaleCache[ _level ];n };n return this.getLevelScale( level );n },nn /**n * @functionn * @param {Number} leveln */n getNumTiles: function( level ) {n var scale = this.getLevelScale( level ),n x = Math.ceil( scale * this.dimensions.x / this.getTileWidth(level) ),n y = Math.ceil( scale * this.dimensions.y / this.getTileHeight(level) );nn return new $.Point( x, y );n },nn /**n * @functionn * @param {Number} leveln */n getPixelRatio: function( level ) {n var imageSizeScaled = this.dimensions.times( this.getLevelScale( level ) ),n rx = 1.0 / imageSizeScaled.x,n ry = 1.0 / imageSizeScaled.y;nn return new $.Point(rx, ry);n },nnn /**n * @functionn * @returns {Number} The highest level in this tile source that can be contained in a single tile.n */n getClosestLevel: function() {n var i,n tiles;nn for (i = this.minLevel + 1; i <= this.maxLevel; i++){n tiles = this.getNumTiles(i);n if (tiles.x > 1 || tiles.y > 1) {n break;n }n }nn return i - 1;n },nn /**n * @functionn * @param {Number} leveln * @param {OpenSeadragon.Point} pointn */n getTileAtPoint: function(level, point) {n var validPoint = point.x >= 0 && point.x <= 1 &&n point.y >= 0 && point.y <= 1 / this.aspectRatio;n $.console.assert(validPoint, "[TileSource.getTileAtPoint] must be called with a valid point.");nn var widthScaled = this.dimensions.x * this.getLevelScale(level);n var pixelX = point.x * widthScaled;n var pixelY = point.y * widthScaled;nn var x = Math.floor(pixelX / this.getTileWidth(level));n var y = Math.floor(pixelY / this.getTileHeight(level));nn // When point.x == 1 or point.y == 1 / this.aspectRatio we want ton // return the last tile of the row/columnn if (point.x >= 1) {n x = this.getNumTiles(level).x - 1;n }n var EPSILON = 1e-15;n if (point.y >= 1 / this.aspectRatio - EPSILON) {n y = this.getNumTiles(level).y - 1;n }nn return new $.Point(x, y);n },nn /**n * @functionn * @param {Number} leveln * @param {Number} xn * @param {Number} yn * @param {Boolean} [isSource=false] Whether to return the source bounds of the tile.n * @returns {OpenSeadragon.Rect} Either where this tile fits (in normalized coordinates) or then * portion of the tile to use as the source of the drawing operation (in pixels), depending onn * the isSource parameter.n */n getTileBounds: function( level, x, y, isSource ) {n var dimensionsScaled = this.dimensions.times( this.getLevelScale( level ) ),n tileWidth = this.getTileWidth(level),n tileHeight = this.getTileHeight(level),n px = ( x === 0 ) ? 0 : tileWidth * x - this.tileOverlap,n py = ( y === 0 ) ? 0 : tileHeight * y - this.tileOverlap,n sx = tileWidth + ( x === 0 ? 1 : 2 ) * this.tileOverlap,n sy = tileHeight + ( y === 0 ? 1 : 2 ) * this.tileOverlap,n scale = 1.0 / dimensionsScaled.x;nn sx = Math.min( sx, dimensionsScaled.x - px );n sy = Math.min( sy, dimensionsScaled.y - py );nn if (isSource) {n return new $.Rect(0, 0, sx, sy);n }nn return new $.Rect( px * scale, py * scale, sx * scale, sy * scale );n },nnn /**n * Responsible for retrieving, and caching then * image metadata pertinent to this TileSources implementation.n * @functionn * @param {String} urln * @throws {Error}n */n getImageInfo: function( url ) {n var _this = this,n callbackName,n callback,n readySource,n options,n urlParts,n filename,n lastDot;nnn if( url ) {n urlParts = url.split( '/' );n filename = urlParts[ urlParts.length - 1 ];n lastDot = filename.lastIndexOf( '.' );n if ( lastDot > -1 ) {n urlParts[ urlParts.length - 1 ] = filename.slice( 0, lastDot );n }n }nn callback = function( data ){n if( typeof (data) === "string" ) {n data = $.parseXml( data );n }n var $TileSource = $.TileSource.determineType( _this, data, url );n if ( !$TileSource ) {n /**n * Raised when an error occurs loading a TileSource.n *n * @event open-failedn * @memberof OpenSeadragon.TileSourcen * @type {object}n * @property {OpenSeadragon.TileSource} eventSource - A reference to the TileSource which raised the event.n * @property {String} messagen * @property {String} sourcen * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( 'open-failed', { message: "Unable to load TileSource", source: url } );n return;n }nn options = $TileSource.prototype.configure.apply( _this, [ data, url ]);n if (options.ajaxWithCredentials === undefined) {n options.ajaxWithCredentials = _this.ajaxWithCredentials;n }nn readySource = new $TileSource( options );n _this.ready = true;n /**n * Raised when a TileSource is opened and initialized.n *n * @event readyn * @memberof OpenSeadragon.TileSourcen * @type {object}n * @property {OpenSeadragon.TileSource} eventSource - A reference to the TileSource which raised the event.n * @property {Object} tileSourcen * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( 'ready', { tileSource: readySource } );n };nn if( url.match(/\.js$/) ){n //TODO: Its not very flexible to require tile sources to end jsonpn // request for info with a url that ends with '.js' but forn // now it's the only way I see to distinguish uniformly.n callbackName = url.split('/').pop().replace('.js', '');n $.jsonp({n url: url,n async: false,n callbackName: callbackName,n callback: callbackn });n } else {n // request info via xhr asynchronously.n $.makeAjaxRequest( {n url: url,n withCredentials: this.ajaxWithCredentials,n headers: this.ajaxHeaders,n success: function( xhr ) {n var data = processResponse( xhr );n callback( data );n },n error: function ( xhr, exc ) {n var msg;nn /*n IE < 10 will block XHR requests to different origins. Any property access on the requestn object will raise an exception which we'll attempt to handle by formatting the originaln exception rather than the second one raised when we try to access xhr.statusn */n try {n msg = "HTTP " + xhr.status + " attempting to load TileSource";n } catch ( e ) {n var formattedExc;n if ( typeof ( exc ) == "undefined" || !exc.toString ) {n formattedExc = "Unknown error";n } else {n formattedExc = exc.toString();n }nn msg = formattedExc + " attempting to load TileSource";n }nn /***n * Raised when an error occurs loading a TileSource.n *n * @event open-failedn * @memberof OpenSeadragon.TileSourcen * @type {object}n * @property {OpenSeadragon.TileSource} eventSource - A reference to the TileSource which raised the event.n * @property {String} messagen * @property {String} sourcen * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( 'open-failed', {n message: msg,n source: urln });n }n });n }nn },nn /**n * Responsible determining if a the particular TileSource supports then * data format ( and allowed to apply logic against the url the data wasn * loaded from, if any ). Overriding implementations are expected to don * something smart with data and / or url to determine support. Alson * understand that iteration order of TileSources is not guarunteed son * please make sure your data or url is expressive enough to ensure a simplen * and sufficient mechanisim for clear determination.n * @functionn * @param {String|Object|Array|Document} datan * @param {String} url - the url the data was loadedn * from if any.n * @return {Boolean}n */n supports: function( data, url ) {n return false;n },nn /**n * Responsible for parsing and configuring then * image metadata pertinent to this TileSources implementation.n * This method is not implemented by this class other than to throw an Errorn * announcing you have to implement it. Because of the variety of tilen * server technologies, and various specifications for building imagen * pyramids, this method is here to allow easy integration.n * @functionn * @param {String|Object|Array|Document} datan * @param {String} url - the url the data was loadedn * from if any.n * @return {Object} options - A dictionary of keyword arguments sufficientn * to configure this tile sources constructor.n * @throws {Error}n */n configure: function( data, url ) {n throw new Error( "Method not implemented." );n },nn /**n * Responsible for retrieving the url which will return an image for then * region specified by the given x, y, and level components.n * This method is not implemented by this class other than to throw an Errorn * announcing you have to implement it. Because of the variety of tilen * server technologies, and various specifications for building imagen * pyramids, this method is here to allow easy integration.n * @functionn * @param {Number} leveln * @param {Number} xn * @param {Number} yn * @throws {Error}n */n getTileUrl: function( level, x, y ) {n throw new Error( "Method not implemented." );n },nn /**n * Responsible for retrieving the headers which will be attached to the image request for then * region specified by the given x, y, and level components.n * This option is only relevant if {@link OpenSeadragon.Options}.loadTilesWithAjax is set to true.n * The headers returned here will override headers specified at the Viewer or TiledImage level.n * Specifying a falsy value for a header will clear its existing value set at the Viewer orn * TiledImage level (if any).n * @functionn * @param {Number} leveln * @param {Number} xn * @param {Number} yn * @returns {Object}n */n getTileAjaxHeaders: function( level, x, y ) {n return {};n },nn /**n * @functionn * @param {Number} leveln * @param {Number} xn * @param {Number} yn */n tileExists: function( level, x, y ) {n var numTiles = this.getNumTiles( level );n return level >= this.minLevel &&n level <= this.maxLevel &&n x >= 0 &&n y >= 0 &&n x < numTiles.x &&n y < numTiles.y;n }n};nnn$.extend( true, $.TileSource.prototype, $.EventSource.prototype );nnn/**n * Decides whether to try to process the response as xml, json, or hand backn * the textn * @privaten * @innern * @functionn * @param {XMLHttpRequest} xhr - the completed network requestn */nfunction processResponse( xhr ){n var responseText = xhr.responseText,n status = xhr.status,n statusText,n data;nn if ( !xhr ) {n throw new Error( $.getString( "Errors.Security" ) );n } else if ( xhr.status !== 200 && xhr.status !== 0 ) {n status = xhr.status;n statusText = ( status == 404 ) ?n "Not Found" :n xhr.statusText;n throw new Error( $.getString( "Errors.Status", status, statusText ) );n }nn if( responseText.match(/\s*<.*/) ){n try{n data = ( xhr.responseXML && xhr.responseXML.documentElement ) ?n xhr.responseXML :n $.parseXml( responseText );n } catch (e){n data = xhr.responseText;n }n }else if( responseText.match(/\s*[\{\.*/) ){n try{n data = $.parseJSON(responseText);n } catch(e){n data = responseText;n }n }else{n data = responseText;n }n return data;n}nnn/**n * Determines the TileSource Implementation by introspection of OpenSeadragonn * namespace, calling each TileSource implementation of 'isType'n * @privaten * @innern * @functionn * @param {Object|Array|Document} data - the tile source configuration objectn * @param {String} url - the url where the tile source configuration object wasn * loaded from, if any.n */n$.TileSource.determineType = function( tileSource, data, url ){n var property;n for( property in OpenSeadragon ){n if( property.match(/.+TileSource$/) &&n $.isFunction( OpenSeadragon[ property ] ) &&n $.isFunction( OpenSeadragon[ property ].prototype.supports ) &&n OpenSeadragon[ property ].prototype.supports.call( tileSource, data, url )n ){n return OpenSeadragon[ property ];n }n }nn $.console.error( "No TileSource was able to open %s %s", url, data );n};nnn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - DziTileSourcen *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * @class DziTileSourcen * @memberof OpenSeadragonn * @extends OpenSeadragon.TileSourcen * @param {Number|Object} width - the pixel width of the image or the idiomaticn * options object which is used instead of positional arguments.n * @param {Number} heightn * @param {Number} tileSizen * @param {Number} tileOverlapn * @param {String} tilesUrln * @param {String} fileFormatn * @param {OpenSeadragon.DisplayRect[]} displayRectsn * @property {String} tilesUrln * @property {String} fileFormatn * @property {OpenSeadragon.DisplayRect[]} displayRectsn */n$.DziTileSource = function( width, height, tileSize, tileOverlap, tilesUrl, fileFormat, displayRects, minLevel, maxLevel ) {n var i,n rect,n level,n options;nn if( $.isPlainObject( width ) ){n options = width;n }else{n options = {n width: arguments[ 0 ],n height: arguments[ 1 ],n tileSize: arguments[ 2 ],n tileOverlap: arguments[ 3 ],n tilesUrl: arguments[ 4 ],n fileFormat: arguments[ 5 ],n displayRects: arguments[ 6 ],n minLevel: arguments[ 7 ],n maxLevel: arguments[ 8 ]n };n }nn this._levelRects = {};n this.tilesUrl = options.tilesUrl;n this.fileFormat = options.fileFormat;n this.displayRects = options.displayRects;nn if ( this.displayRects ) {n for ( i = this.displayRects.length - 1; i >= 0; i– ) {n rect = this.displayRects[ i ];n for ( level = rect.minLevel; level <= rect.maxLevel; level++ ) {n if ( !this._levelRects[ level ] ) {n this._levelRects[ level ] = [];n }n this._levelRects[ level ].push( rect );n }n }n }nn $.TileSource.apply( this, [ options ] );nn};nn$.extend( $.DziTileSource.prototype, $.TileSource.prototype, /** @lends OpenSeadragon.DziTileSource.prototype */{nnn /**n * Determine if the data and/or url imply the image service is supported byn * this tile source.n * @functionn * @param {Object|Array} datan * @param {String} optional - urln */n supports: function( data, url ){n var ns;n if ( data.Image ) {n ns = data.Image.xmlns;n } else if ( data.documentElement) {n if ("Image" == data.documentElement.localName || "Image" == data.documentElement.tagName) {n ns = data.documentElement.namespaceURI;n }n }nn ns = (ns || '').toLowerCase();nn return (ns.indexOf('schemas.microsoft.com/deepzoom/2008') !== -1 ||n ns.indexOf('schemas.microsoft.com/deepzoom/2009') !== -1);n },nn /**n *n * @functionn * @param {Object|XMLDocument} data - the raw configurationn * @param {String} url - the url the data was retreived from if any.n * @return {Object} options - A dictionary of keyword arguments sufficientn * to configure this tile sources constructor.n */n configure: function( data, url ){nn var options;nn if( !$.isPlainObject(data) ){nn options = configureFromXML( this, data );nn }else{nn options = configureFromObject( this, data );n }nn if (url && !options.tilesUrl) {n options.tilesUrl = url.replace(n /([^\/]+?)(\.(dzi|xml|js)?(\?*)?)?\/?$/, '$1_files/');nn if (url.search(/\.(dzi|xml|js)\?/) != -1) {n options.queryParams = url.match(/\?.*/);n }else{n options.queryParams = '';n }n }nn return options;n },nnn /**n * @functionn * @param {Number} leveln * @param {Number} xn * @param {Number} yn */n getTileUrl: function( level, x, y ) {n return [ this.tilesUrl, level, '/', x, '_', y, '.', this.fileFormat, this.queryParams ].join( '' );n },nnn /**n * @functionn * @param {Number} leveln * @param {Number} xn * @param {Number} yn */n tileExists: function( level, x, y ) {n var rects = this._levelRects[ level ],n rect,n scale,n xMin,n yMin,n xMax,n yMax,n i;nn if ((this.minLevel && level < this.minLevel) || (this.maxLevel && level > this.maxLevel)) {n return false;n }nn if ( !rects || !rects.length ) {n return true;n }nn for ( i = rects.length - 1; i >= 0; i– ) {n rect = rects[ i ];nn if ( level < rect.minLevel || level > rect.maxLevel ) {n continue;n }nn scale = this.getLevelScale( level );n xMin = rect.x * scale;n yMin = rect.y * scale;n xMax = xMin + rect.width * scale;n yMax = yMin + rect.height * scale;nn xMin = Math.floor( xMin / this._tileWidth );n yMin = Math.floor( yMin / this._tileWidth ); // DZI tiles are square, so we just use _tileWidthn xMax = Math.ceil( xMax / this._tileWidth );n yMax = Math.ceil( yMax / this._tileWidth );nn if ( xMin <= x && x < xMax && yMin <= y && y < yMax ) {n return true;n }n }nn return false;n }n});nnn/**n * @privaten * @innern * @functionn */nfunction configureFromXML( tileSource, xmlDoc ){nn if ( !xmlDoc || !xmlDoc.documentElement ) {n throw new Error( $.getString( "Errors.Xml" ) );n }nn var root = xmlDoc.documentElement,n rootName = root.localName || root.tagName,n ns = xmlDoc.documentElement.namespaceURI,n configuration = null,n displayRects = [],n dispRectNodes,n dispRectNode,n rectNode,n sizeNode,n i;nn if ( rootName == "Image" ) {nn try {n sizeNode = root.getElementsByTagName("Size" )[ 0 ];n if (sizeNode === undefined) {n sizeNode = root.getElementsByTagNameNS(ns, "Size" )[ 0 ];n }nn configuration = {n Image: {n xmlns: "http://schemas.microsoft.com/deepzoom/2008",n Url: root.getAttribute( "Url" ),n Format: root.getAttribute( "Format" ),n DisplayRect: null,n Overlap: parseInt( root.getAttribute( "Overlap" ), 10 ),n TileSize: parseInt( root.getAttribute( "TileSize" ), 10 ),n Size: {n Height: parseInt( sizeNode.getAttribute( "Height" ), 10 ),n Width: parseInt( sizeNode.getAttribute( "Width" ), 10 )n }n }n };nn if ( !$.imageFormatSupported( configuration.Image.Format ) ) {n throw new Error(n $.getString( "Errors.ImageFormat", configuration.Image.Format.toUpperCase() )n );n }nn dispRectNodes = root.getElementsByTagName("DisplayRect" );n if (dispRectNodes === undefined) {n dispRectNodes = root.getElementsByTagNameNS(ns, "DisplayRect" )[ 0 ];n }nn for ( i = 0; i < dispRectNodes.length; i++ ) {n dispRectNode = dispRectNodes[ i ];n rectNode = dispRectNode.getElementsByTagName("Rect" )[ 0 ];n if (rectNode === undefined) {n rectNode = dispRectNode.getElementsByTagNameNS(ns, "Rect" )[ 0 ];n }nn displayRects.push({n Rect: {n X: parseInt( rectNode.getAttribute( "X" ), 10 ),n Y: parseInt( rectNode.getAttribute( "Y" ), 10 ),n Width: parseInt( rectNode.getAttribute( "Width" ), 10 ),n Height: parseInt( rectNode.getAttribute( "Height" ), 10 ),n MinLevel: parseInt( dispRectNode.getAttribute( "MinLevel" ), 10 ),n MaxLevel: parseInt( dispRectNode.getAttribute( "MaxLevel" ), 10 )n }n });n }nn if( displayRects.length ){n configuration.Image.DisplayRect = displayRects;n }nn return configureFromObject( tileSource, configuration );nn } catch ( e ) {n throw (e instanceof Error) ?n e :n new Error( $.getString("Errors.Dzi") );n }n } else if ( rootName == "Collection" ) {n throw new Error( $.getString( "Errors.Dzc" ) );n } else if ( rootName == "Error" ) {n var messageNode = root.getElementsByTagName("Message");n var message = messageNode.firstChild.nodeValue;n throw new Error(message);n }nn throw new Error( $.getString( "Errors.Dzi" ) );n}nn/**n * @privaten * @innern * @functionn */nfunction configureFromObject( tileSource, configuration ){n var imageData = configuration.Image,n tilesUrl = imageData.Url,n fileFormat = imageData.Format,n sizeData = imageData.Size,n dispRectData = imageData.DisplayRect || [],n width = parseInt( sizeData.Width, 10 ),n height = parseInt( sizeData.Height, 10 ),n tileSize = parseInt( imageData.TileSize, 10 ),n tileOverlap = parseInt( imageData.Overlap, 10 ),n displayRects = [],n rectData,n i;nn //TODO: need to figure out out to better handle image format compatibilityn // which actually includes additional file formats like xml and pdfn // and plain text for various tilesource implementations to avoid lown // level errors.n //n // For now, just don't perform the check.n //n /*if ( !imageFormatSupported( fileFormat ) ) {n throw new Error(n $.getString( "Errors.ImageFormat", fileFormat.toUpperCase() )n );n }*/nn for ( i = 0; i < dispRectData.length; i++ ) {n rectData = dispRectData[ i ].Rect;nn displayRects.push( new $.DisplayRect(n parseInt( rectData.X, 10 ),n parseInt( rectData.Y, 10 ),n parseInt( rectData.Width, 10 ),n parseInt( rectData.Height, 10 ),n parseInt( rectData.MinLevel, 10 ),n parseInt( rectData.MaxLevel, 10 )n ));n }nn return $.extend(true, {n width: width, /* width *required */n height: height, /* height *required */n tileSize: tileSize, /* tileSize *required */n tileOverlap: tileOverlap, /* tileOverlap *required */n minLevel: null, /* minLevel */n maxLevel: null, /* maxLevel */n tilesUrl: tilesUrl, /* tilesUrl */n fileFormat: fileFormat, /* fileFormat */n displayRects: displayRects /* displayRects */n }, configuration );nn}nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - IIIFTileSourcen *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * @class IIIFTileSourcen * @classdesc A client implementation of the International Image Interoperability Frameworkn * Format: Image API 1.0 - 2.1n *n * @memberof OpenSeadragonn * @extends OpenSeadragon.TileSourcen * @see iiif.io/api/image/n */n$.IIIFTileSource = function( options ){nn /* eslint-disable camelcase */nn $.extend( true, this, options );nn if ( !( this.height && this.width && this ) ) {n throw new Error( 'IIIF required parameters not provided.' );n }nn options.tileSizePerScaleFactor = {};nn // N.B. 2.0 renamed scale_factors to scaleFactorsn if ( this.tile_width && this.tile_height ) {n options.tileWidth = this.tile_width;n options.tileHeight = this.tile_height;n } else if ( this.tile_width ) {n options.tileSize = this.tile_width;n } else if ( this.tile_height ) {n options.tileSize = this.tile_height;n } else if ( this.tiles ) {n // Version 2.0 forwardsn if ( this.tiles.length == 1 ) {n options.tileWidth = this.tiles.width;n // Use height if provided, otherwise assume square tiles and use width.n options.tileHeight = this.tiles.height || this.tiles.width;n this.scale_factors = this.tiles.scaleFactors;n } else {n // Multiple tile sizes at different levelsn this.scale_factors = [];n for (var t = 0; t < this.tiles.length; t++ ) {n for (var sf = 0; sf < this.tiles.scaleFactors.length; sf++) {n var scaleFactor = this.tiles.scaleFactors;n this.scale_factors.push(scaleFactor);n options.tileSizePerScaleFactor = {n width: this.tiles.width,n height: this.tiles.height || this.tiles.widthn };n }n }n }n } else if ( canBeTiled(options.profile) ) {n // use the largest of tileOptions that is smaller than the short dimensionn var shortDim = Math.min( this.height, this.width ),n tileOptions = [256, 512, 1024],n smallerTiles = [];nn for ( var c = 0; c < tileOptions.length; c++ ) {n if ( tileOptions <= shortDim ) {n smallerTiles.push( tileOptions );n }n }nn if ( smallerTiles.length > 0 ) {n options.tileSize = Math.max.apply( null, smallerTiles );n } else {n // If we're smaller than 256, just use the short side.n options.tileSize = shortDim;n }n } else if (this.sizes && this.sizes.length > 0) {n // This info.json can't be tiled, but we can still construct a legacy pyramid from the sizes array.n // In this mode, IIIFTileSource will call functions from the abstract baseTileSource or then // LegacyTileSource instead of performing IIIF tiling.n this.emulateLegacyImagePyramid = true;nn options.levels = constructLevels( this );n // use the largest available size to define tilesn $.extend( true, options, {n width: options.levels[ options.levels.length - 1 ].width,n height: options.levels[ options.levels.length - 1 ].height,n tileSize: Math.max( options.height, options.width ),n tileOverlap: 0,n minLevel: 0,n maxLevel: options.levels.length - 1n });n this.levels = options.levels;n } else {n $.console.error("Nothing in the info.json to construct image pyramids from");n }nn if (!options.maxLevel && !this.emulateLegacyImagePyramid) {n if (!this.scale_factors) {n options.maxLevel = Number(Math.ceil(Math.log(Math.max(this.width, this.height), 2)));n } else {n var maxScaleFactor = Math.max.apply(null, this.scale_factors);n options.maxLevel = Math.round(Math.log(maxScaleFactor) * Math.LOG2E);n }n }nn $.TileSource.apply( this, [ options ] );n};nn$.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSeadragon.IIIFTileSource.prototype */{n /**n * Determine if the data and/or url imply the image service is supported byn * this tile source.n * @functionn * @param {Object|Array} datan * @param {String} optional - urln */nn supports: function( data, url ) {n // Version 2.0 and forwardsn if (data.protocol && data.protocol == 'iiif.io/api/image') {n return true;n // Version 1.1n } else if ( data && (n data == "http://library.stanford.edu/iiif/image-api/1.1/context.json" ||n data == "http://iiif.io/api/image/1/context.json") ) {n // N.B. the iiif.io context is wrong, but where the representation lives so likely to be usedn return true;nn // Version 1.0n } else if ( data.profile &&n data.profile.indexOf("http://library.stanford.edu/iiif/image-api/compliance.html") === 0) {n return true;n } else if ( data.identifier && data.width && data.height ) {n return true;n } else if ( data.documentElement &&n "info" == data.documentElement.tagName &&n "http://library.stanford.edu/iiif/image-api/ns/" ==n data.documentElement.namespaceURI) {n return true;nn // Not IIIFn } else {n return false;n }n },nn /**n *n * @functionn * @param {Object} data - the raw configurationn * @example <caption>IIIF 1.1 Info Looks like this</caption>n * {n * "" : "http://library.stanford.edu/iiif/image-api/1.1/context.json",n * "" : "http://iiif.example.com/prefix/1E34750D-38DB-4825-A38A-B60A345E591C",n * "width" : 6000,n * "height" : 4000,n * "scale_factors" : [ 1, 2, 4 ],n * "tile_width" : 1024,n * "tile_height" : 1024,n * "formats" : [ "jpg", "png" ],n * "qualities" : [ "native", "grey" ],n * "profile" : "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0"n * }n */n configure: function( data, url ){n // Try to deduce our version and fake it upwards if neededn if ( !$.isPlainObject(data) ) {n var options = configureFromXml10( data );n options = "http://iiif.io/api/image/1.0/context.json";n options = url.replace('/info.xml', '');n return options;n } else if ( !data ) {n data = 'iiif.io/api/image/1.0/context.json’;n data = url.replace('/info.json', '');n return data;n } else {n return data;n }n },nn /**n * Return the tileWidth for the given level.n * @functionn * @param {Number} leveln */n getTileWidth: function( level ) {nn if(this.emulateLegacyImagePyramid) {n return $.TileSource.prototype.getTileWidth.call(this, level);n }nn var scaleFactor = Math.pow(2, this.maxLevel - level);nn if (this.tileSizePerScaleFactor && this.tileSizePerScaleFactor) {n return this.tileSizePerScaleFactor.width;n }n return this._tileWidth;n },nn /**n * Return the tileHeight for the given level.n * @functionn * @param {Number} leveln */n getTileHeight: function( level ) {nn if(this.emulateLegacyImagePyramid) {n return $.TileSource.prototype.getTileHeight.call(this, level);n }nn var scaleFactor = Math.pow(2, this.maxLevel - level);nn if (this.tileSizePerScaleFactor && this.tileSizePerScaleFactor) {n return this.tileSizePerScaleFactor.height;n }n return this._tileHeight;n },nn /**n * @functionn * @param {Number} leveln */n getLevelScale: function ( level ) {nn if(this.emulateLegacyImagePyramid) {n var levelScale = NaN;n if (this.levels.length > 0 && level >= this.minLevel && level <= this.maxLevel) {n levelScale =n this.levels.width /n this.levels.width;n }n return levelScale;n }nn return $.TileSource.prototype.getLevelScale.call(this, level);n },nn /**n * @functionn * @param {Number} leveln */n getNumTiles: function( level ) {nn if(this.emulateLegacyImagePyramid) {n var scale = this.getLevelScale(level);n if (scale) {n return new $.Point(1, 1);n } else {n return new $.Point(0, 0);n }n }nn return $.TileSource.prototype.getNumTiles.call(this, level);n },nnn /**n * @functionn * @param {Number} leveln * @param {OpenSeadragon.Point} pointn */n getTileAtPoint: function( level, point ) {nn if(this.emulateLegacyImagePyramid) {n return new $.Point(0, 0);n }nn return $.TileSource.prototype.getTileAtPoint.call(this, level, point);n },nnn /**n * Responsible for retrieving the url which will return an image for then * region specified by the given x, y, and level components.n * @functionn * @param {Number} level - z indexn * @param {Number} xn * @param {Number} yn * @throws {Error}n */n getTileUrl: function( level, x, y ){nn if(this.emulateLegacyImagePyramid) {n var url = null;n if ( this.levels.length > 0 && level >= this.minLevel && level <= this.maxLevel ) {n url = this.levels[ level ].url;n }n return url;n }nn //# constantsn var IIIF_ROTATION = '0',n //## get the scale (level as a decimal)n scale = Math.pow( 0.5, this.maxLevel - level ),nn //# image dimensions at this leveln levelWidth = Math.ceil( this.width * scale ),n levelHeight = Math.ceil( this.height * scale ),nn //## iiif regionn tileWidth,n tileHeight,n iiifTileSizeWidth,n iiifTileSizeHeight,n iiifRegion,n iiifTileX,n iiifTileY,n iiifTileW,n iiifTileH,n iiifSize,n iiifQuality,n uri;nn tileWidth = this.getTileWidth(level);n tileHeight = this.getTileHeight(level);n iiifTileSizeWidth = Math.ceil( tileWidth / scale );n iiifTileSizeHeight = Math.ceil( tileHeight / scale );nn if ( this.indexOf('/1.0/context.json') > -1 ||n this.indexOf('/1.1/context.json') > -1 ||n this.indexOf('/1/context.json') > -1 ) {n iiifQuality = "native.jpg";n } else {n iiifQuality = "default.jpg";n }nn if ( levelWidth < tileWidth && levelHeight < tileHeight ){n iiifSize = levelWidth + ",";n iiifRegion = 'full';n } else {n iiifTileX = x * iiifTileSizeWidth;n iiifTileY = y * iiifTileSizeHeight;n iiifTileW = Math.min( iiifTileSizeWidth, this.width - iiifTileX );n iiifTileH = Math.min( iiifTileSizeHeight, this.height - iiifTileY );n iiifSize = Math.ceil( iiifTileW * scale ) + ",";n iiifRegion = [ iiifTileX, iiifTileY, iiifTileW, iiifTileH ].join( ',' );n }n uri = [ this, iiifRegion, iiifSize, IIIF_ROTATION, iiifQuality ].join( '/' );nn return uri;n }nn });nn /**n * Determine whether arbitrary tile requests can be made against a service with the given profilen * @functionn * @param {object} profile - IIIF profile objectn * @throws {Error}n */n function canBeTiled (profile ) {n var level0Profiles = [n "http://library.stanford.edu/iiif/image-api/compliance.html#level0",n "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0",n "http://iiif.io/api/image/2/level0.json"n ];n var isLevel0 = (level0Profiles.indexOf(profile) != -1);n return !isLevel0 || (profile.indexOf("sizeByW") != -1);n }nn /**n * Build the legacy pyramid URLs (one tile per level)n * @functionn * @param {object} options - infoJsonn * @throws {Error}n */n function constructLevels(options) {n var levels = [];n for(var i = 0; i < options.sizes.length; i++) {n levels.push({n url: options + '/full/' + options.sizes.width + ',/0/default.jpg',n width: options.sizes.width,n height: options.sizes.heightn });n }n return levels.sort(function(a, b) {n return a.width - b.width;n });n }nnn function configureFromXml10(xmlDoc) {n //parse the xmln if ( !xmlDoc || !xmlDoc.documentElement ) {n throw new Error( $.getString( "Errors.Xml" ) );n }nn var root = xmlDoc.documentElement,n rootName = root.tagName,n configuration = null;nn if ( rootName == "info" ) {n try {n configuration = {};n parseXML10( root, configuration );n return configuration;nn } catch ( e ) {n throw (e instanceof Error) ?n e :n new Error( $.getString("Errors.IIIF") );n }n }n throw new Error( $.getString( "Errors.IIIF" ) );n }nn function parseXML10( node, configuration, property ) {n var i,n value;n if ( node.nodeType == 3 && property ) {//text noden value = node.nodeValue.trim();n if( value.match(/^\d*$/)){n value = Number( value );n }n if( !configuration[ property ] ){n configuration[ property ] = value;n }else{n if( !$.isArray( configuration[ property ] ) ){n configuration[ property ] = [ configuration[ property ] ];n }n configuration[ property ].push( value );n }n } else if( node.nodeType == 1 ){n for( i = 0; i < node.childNodes.length; i++ ){n parseXML10( node.childNodes[ i ], configuration, node.nodeName );n }n }n }nnnn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - OsmTileSourcen *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn/*n * Derived from the OSM tile source in Rainer Simon's seajax-utils projectn * <github.com/rsimon/seajax-utils>. Rainer Simon has contributedn * the included code to the OpenSeadragon project under the New BSD license;n * see <gasi.ch/blog/inside-deep-zoom-2). I.e. there is an * difference of log2(256)=8 levels.
n *n * Note 2. Image dimension. According to the OSM Wikin * (wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Zoom_levels)n * the highest Mapnik zoom level has 256.144x256.144 tiles, with a 256x256n * pixel size. I.e. the Deep Zoom image dimension is 65.572.864x65.572.864n * pixels.n *n * @memberof OpenSeadragonn * @extends OpenSeadragon.TileSourcen * @param {Number|Object} width - the pixel width of the image or the idiomaticn * options object which is used instead of positional arguments.n * @param {Number} heightn * @param {Number} tileSizen * @param {Number} tileOverlapn * @param {String} tilesUrln */n$.OsmTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) {n var options;nn if( $.isPlainObject( width ) ){n options = width;n }else{n options = {n width: arguments,n height: arguments,n tileSize: arguments,n tileOverlap: arguments,n tilesUrl: argumentsn };n }n //apply default setting for standard public OpenStreatMaps servicen //but allow them to be specified so fliks can host there own instancen //or apply against other services supportting the same standardn if( !options.width || !options.height ){n options.width = 65572864;n options.height = 65572864;n }n if( !options.tileSize ){n options.tileSize = 256;n options.tileOverlap = 0;n }n if( !options.tilesUrl ){n options.tilesUrl = "http://tile.openstreetmap.org/";n }n options.minLevel = 8;nn $.TileSource.apply( this, [ options ] );nn};nn$.extend( $.OsmTileSource.prototype, $.TileSource.prototype, /** @lends OpenSeadragon.OsmTileSource.prototype */{nnn /**n * Determine if the data and/or url imply the image service is supported byn * this tile source.n * @functionn * @param {Object|Array} datan * @param {String} optional - urln */n supports: function( data, url ){n return (n data.type &&n "openstreetmaps" == data.typen );n },nn /**n *n * @functionn * @param {Object} data - the raw configurationn * @param {String} url - the url the data was retreived from if any.n * @return {Object} options - A dictionary of keyword arguments sufficientn * to configure this tile sources constructor.n */n configure: function( data, url ){n return data;n },nnn /**n * @functionn * @param {Number} leveln * @param {Number} xn * @param {Number} yn */n getTileUrl: function( level, x, y ) {n return this.tilesUrl + (level - 8) + "/" + x + "/" + y + ".png";n }n});nnn}( OpenSeadragon ));n“,”/*n * OpenSeadragon - TmsTileSourcen *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn/*n * Derived from the TMS tile source in Rainer Simon's seajax-utils projectn * <github.com/rsimon/seajax-utils>. Rainer Simon has contributedn * the included code to the OpenSeadragon project under the New BSD license;n * see <openlayers.org/dev/examples/tms.html ).n *n * @memberof OpenSeadragonn * @extends OpenSeadragon.TileSourcen * @param {Number|Object} width - the pixel width of the image or the idiomaticn * options object which is used instead of positional arguments.n * @param {Number} heightn * @param {Number} tileSizen * @param {Number} tileOverlapn * @param {String} tilesUrln */n$.TmsTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) {n var options;nn if( $.isPlainObject( width ) ){n options = width;n }else{n options = {n width: arguments,n height: arguments,n tileSize: arguments,n tileOverlap: arguments,n tilesUrl: argumentsn };n }n // TMS has integer multiples of 256 for width/height and adds buffern // if necessary -> account for this!n var bufferedWidth = Math.ceil(options.width / 256) * 256,n bufferedHeight = Math.ceil(options.height / 256) * 256,n max;nn // Compute number of zoomlevels in this tilesetn if (bufferedWidth > bufferedHeight) {n max = bufferedWidth / 256;n } else {n max = bufferedHeight / 256;n }n options.maxLevel = Math.ceil(Math.log(max) / Math.log(2)) - 1;n options.tileSize = 256;n options.width = bufferedWidth;n options.height = bufferedHeight;nn $.TileSource.apply( this, [ options ] );nn};nn$.extend( $.TmsTileSource.prototype, $.TileSource.prototype, /** @lends OpenSeadragon.TmsTileSource.prototype */{nnn /**n * Determine if the data and/or url imply the image service is supported byn * this tile source.n * @functionn * @param {Object|Array} datan * @param {String} optional - urln */n supports: function( data, url ){n return ( data.type && "tiledmapservice" == data.type );n },nn /**n *n * @functionn * @param {Object} data - the raw configurationn * @param {String} url - the url the data was retreived from if any.n * @return {Object} options - A dictionary of keyword arguments sufficientn * to configure this tile sources constructor.n */n configure: function( data, url ){n return data;n },nnn /**n * @functionn * @param {Number} leveln * @param {Number} xn * @param {Number} yn */n getTileUrl: function( level, x, y ) {n // Convert from Deep Zoom definition to TMS zoom definitionn var yTiles = this.getNumTiles( level ).y - 1;nn return this.tilesUrl + level + "/" + x + "/" + (yTiles - y) + ".png";n }n});nnn}( OpenSeadragon ));n”,“(function($) {nn /**n * @class ZoomifyTileSourcen * @classdesc A tilesource implementation for the zoomify format.n *n * A description of the format can be found here:n * ecommons.cornell.edu/bitstream/handle/1813/5410/Introducing_Zoomify_Image.pdfn *n * There are two ways of creating a zoomify tilesource for openseadragonn *n * 1) Supplying all necessary information in the tilesource object. A minimal example object for this method looks like this:n *n * {n * type: "zoomifytileservice",n * width: 1000,n * height: 1000,n * tilesUrl: "/test/data/zoomify/"n * }n *n * The tileSize is currently hardcoded to 256 (the usual Zoomify default). The tileUrl must the path to the image directory.n *n * 2) Loading image metadata from xml file: (CURRENTLY NOT SUPPORTED)n *n * When creating zoomify formatted images one "xml" like file with name ImageProperties.xmln * will be created as well. Here is an example of such a file:n *n * <IMAGE_PROPERTIES WIDTH="1000" HEIGHT="1000" NUMTILES="21" NUMIMAGES="1" VERSION="1.8" TILESIZE="256" />n *n * To use this xml file as metadata source you must supply the path to the ImageProperties.xml file and leave out all other parameters:n * As stated above, this method of loading a zoomify tilesource is currently not supportedn *n * {n * type: "zoomifytileservice",n * tilesUrl: "/test/data/zoomify/ImageProperties.xml"n * }nn *n * @memberof OpenSeadragonn * @extends OpenSeadragon.TileSourcen * @param {Number} width - the pixel width of the image.n * @param {Number} heightn * @param {Number} tileSizen * @param {String} tilesUrln */n $.ZoomifyTileSource = function(options) {n options.tileSize = 256;nn var currentImageSize = {n x: options.width,n y: options.heightn };n options.imageSizes = [{n x: options.width,n y: options.heightn }];n options.gridSize = [this._getGridSize(options.width, options.height, options.tileSize)];nn while (parseInt(currentImageSize.x, 10) > options.tileSize || parseInt(currentImageSize.y, 10) > options.tileSize) {n currentImageSize.x = Math.floor(currentImageSize.x / 2);n currentImageSize.y = Math.floor(currentImageSize.y / 2);n options.imageSizes.push({n x: currentImageSize.x,n y: currentImageSize.yn });n options.gridSize.push(this._getGridSize(currentImageSize.x, currentImageSize.y, options.tileSize));n }n options.imageSizes.reverse();n options.gridSize.reverse();n options.minLevel = 0;n options.maxLevel = options.gridSize.length - 1;nn OpenSeadragon.TileSource.apply(this, [options]);n };nn $.extend($.ZoomifyTileSource.prototype, $.TileSource.prototype, /** @lends OpenSeadragon.ZoomifyTileSource.prototype */ {nn //privaten _getGridSize: function(width, height, tileSize) {n return {n x: Math.ceil(width / tileSize),n y: Math.ceil(height / tileSize)n };n },nn //privaten _calculateAbsoluteTileNumber: function(level, x, y) {n var num = 0;n var size = {};nn //Sum up all tiles below the level we want the number of tilesn for (var z = 0; z < level; z++) {n size = this.gridSize;n num += size.x * size.y;n }n //Add the tiles of the leveln size = this.gridSize;n num += size.x * y + x;n return num;n },nn /**n * Determine if the data and/or url imply the image service is supported byn * this tile source.n * @functionn * @param {Object|Array} datan * @param {String} optional - urln */n supports: function(data, url) {n return (data.type && "zoomifytileservice" == data.type);n },nn /**n *n * @functionn * @param {Object} data - the raw configurationn * @param {String} url - the url the data was retreived from if any.n * @return {Object} options - A dictionary of keyword arguments sufficientn * to configure this tile sources constructor.n */n configure: function(data, url) {n return data;n },nn /**n * @functionn * @param {Number} leveln * @param {Number} xn * @param {Number} yn */n getTileUrl: function(level, x, y) {n //console.log(level);n var result = 0;n var num = this._calculateAbsoluteTileNumber(level, x, y);n result = Math.floor(num / 256);n return this.tilesUrl + 'TileGroup' + result + '/' + level + '-' + x + '-' + y + '.jpg';nn }n });nn}(OpenSeadragon));nn”,“/*n * OpenSeadragon - LegacyTileSourcen *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * @class LegacyTileSourcen * @classdesc The LegacyTileSource allows simple, traditional image pyramids to be loadedn * into an OpenSeadragon Viewer. Basically, this translates to the historicallyn * common practice of starting with a 'master' image, maybe a tiff for example,n * and generating a set of 'service' images like one or more thumbnails, a mediumn * resolution image and a high resolution image in standard web formats liken * png or jpg.n *n * @memberof OpenSeadragonn * @extends OpenSeadragon.TileSourcen * @param {Array} levels An array of file descriptions, each is an object withn * a 'url', a 'width', and a 'height'. Overriding classes can expect moren * properties but these properties are sufficient for this implementation.n * Additionally, the levels are required to be listed in order fromn * smallest to largest.n * @property {Number} aspectRation * @property {Number} dimensionsn * @property {Number} tileSizen * @property {Number} tileOverlapn * @property {Number} minLeveln * @property {Number} maxLeveln * @property {Array} levelsn */n$.LegacyTileSource = function( levels ) {nn var options,n width,n height;nn if( $.isArray( levels ) ){n options = {n type: 'legacy-image-pyramid',n levels: levelsn };n }nn //clean up the levels to make sure we support all formatsn options.levels = filterFiles( options.levels );nn if ( options.levels.length > 0 ) {n width = options.levels[ options.levels.length - 1 ].width;n height = options.levels[ options.levels.length - 1 ].height;n }n else {n width = 0;n height = 0;n $.console.error( "No supported image formats found" );n }nn $.extend( true, options, {n width: width,n height: height,n tileSize: Math.max( height, width ),n tileOverlap: 0,n minLevel: 0,n maxLevel: options.levels.length > 0 ? options.levels.length - 1 : 0n } );nn $.TileSource.apply( this, [ options ] );nn this.levels = options.levels;n};nn$.extend( $.LegacyTileSource.prototype, $.TileSource.prototype, /** @lends OpenSeadragon.LegacyTileSource.prototype */{n /**n * Determine if the data and/or url imply the image service is supported byn * this tile source.n * @functionn * @param {Object|Array} datan * @param {String} optional - urln */n supports: function( data, url ){n return (n data.type &&n "legacy-image-pyramid" == data.typen ) || (n data.documentElement &&n "legacy-image-pyramid" == data.documentElement.getAttribute('type')n );n },nnn /**n *n * @functionn * @param {Object|XMLDocument} configuration - the raw configurationn * @param {String} dataUrl - the url the data was retreived from if any.n * @return {Object} options - A dictionary of keyword arguments sufficientn * to configure this tile sources constructor.n */n configure: function( configuration, dataUrl ){nn var options;nn if( !$.isPlainObject(configuration) ){nn options = configureFromXML( this, configuration );nn }else{nn options = configureFromObject( this, configuration );n }nn return options;nn },nn /**n * @functionn * @param {Number} leveln */n getLevelScale: function ( level ) {n var levelScale = NaN;n if ( this.levels.length > 0 && level >= this.minLevel && level <= this.maxLevel ) {n levelScale =n this.levels[ level ].width /n this.levels[ this.maxLevel ].width;n }n return levelScale;n },nn /**n * @functionn * @param {Number} leveln */n getNumTiles: function( level ) {n var scale = this.getLevelScale( level );n if ( scale ){n return new $.Point( 1, 1 );n } else {n return new $.Point( 0, 0 );n }n },nn /**n * This method is not implemented by this class other than to throw an Errorn * announcing you have to implement it. Because of the variety of tilen * server technologies, and various specifications for building imagen * pyramids, this method is here to allow easy integration.n * @functionn * @param {Number} leveln * @param {Number} xn * @param {Number} yn * @throws {Error}n */n getTileUrl: function ( level, x, y ) {n var url = null;n if ( this.levels.length > 0 && level >= this.minLevel && level <= this.maxLevel ) {n url = this.levels[ level ].url;n }n return url;n }n} );nn/**n * This method removes any files from the Array which dont conform to ourn * basic requirements for a 'level' in the LegacyTileSource.n * @privaten * @innern * @functionn */nfunction filterFiles( files ){n var filtered = [],n file,n i;n for( i = 0; i < files.length; i++ ){n file = files[ i ];n if( file.height &&n file.width &&n file.url ){n //This is sufficient to serve as a leveln filtered.push({n url: file.url,n width: Number( file.width ),n height: Number( file.height )n });n }n else {n $.console.error( 'Unsupported image format: %s', file.url ? file.url : '<no URL>' );n }n }nn return filtered.sort(function(a, b) {n return a.height - b.height;n });nn}nn/**n * @privaten * @innern * @functionn */nfunction configureFromXML( tileSource, xmlDoc ){nn if ( !xmlDoc || !xmlDoc.documentElement ) {n throw new Error( $.getString( "Errors.Xml" ) );n }nn var root = xmlDoc.documentElement,n rootName = root.tagName,n conf = null,n levels = [],n level,n i;nn if ( rootName == "image" ) {nn try {n conf = {n type: root.getAttribute( "type" ),n levels: []n };nn levels = root.getElementsByTagName( "level" );n for ( i = 0; i < levels.length; i++ ) {n level = levels[ i ];nn conf.levels.push({n url: level.getAttribute( "url" ),n width: parseInt( level.getAttribute( "width" ), 10 ),n height: parseInt( level.getAttribute( "height" ), 10 )n });n }nn return configureFromObject( tileSource, conf );nn } catch ( e ) {n throw (e instanceof Error) ?n e :n new Error( 'Unknown error parsing Legacy Image Pyramid XML.' );n }n } else if ( rootName == "collection" ) {n throw new Error( 'Legacy Image Pyramid Collections not yet supported.' );n } else if ( rootName == "error" ) {n throw new Error( 'Error: ' + xmlDoc );n }nn throw new Error( 'Unknown element ' + rootName );n}nn/**n * @privaten * @innern * @functionn */nfunction configureFromObject( tileSource, configuration ){nn return configuration.levels;nn}nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - ImageTileSourcen *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function ($) {nn /**n * @class ImageTileSourcen * @classdesc The ImageTileSource allows a simple image to be loadedn * into an OpenSeadragon Viewer.n * There are 2 ways to open an ImageTileSource:n * 1. viewer.open({type: 'image', url: fooUrl});n * 2. viewer.open(new OpenSeadragon.ImageTileSource({url: fooUrl}));n *n * With the first syntax, the crossOriginPolicy, ajaxWithCredentials andn * useCanvas options are inherited from the viewer if they are notn * specified directly in the options object.n *n * @memberof OpenSeadragonn * @extends OpenSeadragon.TileSourcen * @param {Object} options Options object.n * @param {String} options.url URL of the imagen * @param {Boolean} [options.buildPyramid=true] If set to true (default), an * pyramid will be built internally to provide a better downsampling.n * @param {String|Boolean} [options.crossOriginPolicy=false] Valid values aren * 'Anonymous', 'use-credentials', and false. If false, image requests willn * not use CORS preventing internal pyramid building for images from othern * domains.n * @param {String|Boolean} [options.ajaxWithCredentials=false] Whether to setn * the withCredentials XHR flag for AJAX requests (when loading tile sources).n * @param {Boolean} [options.useCanvas=true] Set to false to prevent any usen * of the canvas API.n */n $.ImageTileSource = function (options) {nn options = $.extend({n buildPyramid: true,n crossOriginPolicy: false,n ajaxWithCredentials: false,n useCanvas: truen }, options);n $.TileSource.apply(this, [options]);nn };nn $.extend($.ImageTileSource.prototype, $.TileSource.prototype, /** @lends OpenSeadragon.ImageTileSource.prototype */{n /**n * Determine if the data and/or url imply the image service is supported byn * this tile source.n * @functionn * @param {Object|Array} datan * @param {String} optional - urln */n supports: function (data, url) {n return data.type && data.type === "image";n },n /**n *n * @functionn * @param {Object} options - the optionsn * @param {String} dataUrl - the url the image was retreived from, if any.n * @return {Object} options - A dictionary of keyword arguments sufficientn * to configure this tile sources constructor.n */n configure: function (options, dataUrl) {n return options;n },n /**n * Responsible for retrieving, and caching then * image metadata pertinent to this TileSources implementation.n * @functionn * @param {String} urln * @throws {Error}n */n getImageInfo: function (url) {n var image = this._image = new Image();n var _this = this;nn if (this.crossOriginPolicy) {n image.crossOrigin = this.crossOriginPolicy;n }n if (this.ajaxWithCredentials) {n image.useCredentials = this.ajaxWithCredentials;n }nn $.addEvent(image, 'load', function () {n /* IE8 fix since it has no naturalWidth and naturalHeight */n _this.width = Object.prototype.hasOwnProperty.call(image, 'naturalWidth') ? image.naturalWidth : image.width;n _this.height = Object.prototype.hasOwnProperty.call(image, 'naturalHeight') ? image.naturalHeight : image.height;n _this.aspectRatio = _this.width / _this.height;n _this.dimensions = new $.Point(_this.width, _this.height);n _this._tileWidth = _this.width;n _this._tileHeight = _this.height;n _this.tileOverlap = 0;n _this.minLevel = 0;n _this.levels = _this._buildLevels();n _this.maxLevel = _this.levels.length - 1;nn _this.ready = true;nn // Note: this event is documented elsewhere, in TileSourcen _this.raiseEvent('ready', {tileSource: _this});n });nn $.addEvent(image, 'error', function () {n // Note: this event is documented elsewhere, in TileSourcen _this.raiseEvent('open-failed', {n message: "Error loading image at " + url,n source: urln });n });nn image.src = url;n },n /**n * @functionn * @param {Number} leveln */n getLevelScale: function (level) {n var levelScale = NaN;n if (level >= this.minLevel && level <= this.maxLevel) {n levelScale =n this.levels.width /n this.levels.width;n }n return levelScale;n },n /**n * @functionn * @param {Number} leveln */n getNumTiles: function (level) {n var scale = this.getLevelScale(level);n if (scale) {n return new $.Point(1, 1);n } else {n return new $.Point(0, 0);n }n },n /**n * Retrieves a tile urln * @functionn * @param {Number} level Level of the tilen * @param {Number} x x coordinate of the tilen * @param {Number} y y coordinate of the tilen */n getTileUrl: function (level, x, y) {n var url = null;n if (level >= this.minLevel && level <= this.maxLevel) {n url = this.levels.url;n }n return url;n },n /**n * Retrieves a tile context 2Dn * @functionn * @param {Number} level Level of the tilen * @param {Number} x x coordinate of the tilen * @param {Number} y y coordinate of the tilen */n getContext2D: function (level, x, y) {n var context = null;n if (level >= this.minLevel && level <= this.maxLevel) {n context = this.levels.context2D;n }n return context;n },nn // privaten //n // Builds the differents levels of the pyramid if possiblen // (i.e. if canvas API enabled and no canvas tainting issue).n _buildLevels: function () {n var levels = [{n url: this._image.src,n /* IE8 fix since it has no naturalWidth and naturalHeight */n width: Object.prototype.hasOwnProperty.call(this._image, 'naturalWidth') ? this._image.naturalWidth : this._image.width,n height: Object.prototype.hasOwnProperty.call(this._image, 'naturalHeight') ? this._image.naturalHeight : this._image.heightn }];nn if (!this.buildPyramid || !$.supportsCanvas || !this.useCanvas) {n // We don't need the image anymore. Allows it to be GC.n delete this._image;n return levels;n }nn /* IE8 fix since it has no naturalWidth and naturalHeight */n var currentWidth = Object.prototype.hasOwnProperty.call(this._image, 'naturalWidth') ? this._image.naturalWidth : this._image.width;n var currentHeight = Object.prototype.hasOwnProperty.call(this._image, 'naturalHeight') ? this._image.naturalHeight : this._image.height;nnn var bigCanvas = document.createElement("canvas");n var bigContext = bigCanvas.getContext("2d");nn bigCanvas.width = currentWidth;n bigCanvas.height = currentHeight;n bigContext.drawImage(this._image, 0, 0, currentWidth, currentHeight);n // We cache the context of the highest level because the browsern // is a lot faster at downsampling something it already hasn // downsampled before.n levels.context2D = bigContext;n // We don't need the image anymore. Allows it to be GC.n delete this._image;nn if ($.isCanvasTainted(bigCanvas)) {n // If the canvas is tainted, we can't compute the pyramid.n return levels;n }nn // We build smaller levels until either width or height becomesn // 1 pixel wide.n while (currentWidth >= 2 && currentHeight >= 2) {n currentWidth = Math.floor(currentWidth / 2);n currentHeight = Math.floor(currentHeight / 2);n var smallCanvas = document.createElement("canvas");n var smallContext = smallCanvas.getContext("2d");n smallCanvas.width = currentWidth;n smallCanvas.height = currentHeight;n smallContext.drawImage(bigCanvas, 0, 0, currentWidth, currentHeight);nn levels.splice(0, 0, {n context2D: smallContext,n width: currentWidth,n height: currentHeightn });nn bigCanvas = smallCanvas;n bigContext = smallContext;n }n return levels;n }n });nn}(OpenSeadragon));n”,“/*n * OpenSeadragon - TileSourceCollectionn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function($) {nn// deprecatedn$.TileSourceCollection = function(tileSize, tileSources, rows, layout) {n $.console.error('TileSourceCollection is deprecated; use World instead');n};nn}(OpenSeadragon));n”,“/*n * OpenSeadragon - Buttonn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * An enumeration of button statesn * @member ButtonStaten * @memberof OpenSeadragonn * @staticn * @type {Object}n * @property {Number} RESTn * @property {Number} GROUPn * @property {Number} HOVERn * @property {Number} DOWNn */n$.ButtonState = {n REST: 0,n GROUP: 1,n HOVER: 2,n DOWN: 3n};nn/**n * @class Buttonn * @classdesc Manages events, hover states for individual buttons, tool-tips, as welln * as fading the buttons out when the user has not interacted with themn * for a specified period.n *n * @memberof OpenSeadragonn * @extends OpenSeadragon.EventSourcen * @param {Object} optionsn * @param {Element} [options.element=null] Element to use as the button. If not specified, an HTML &lt;div&gt; element is created.n * @param {String} [options.tooltip=null] Provides context help for the button when then * user hovers over it.n * @param {String} [options.srcRest=null] URL of image to use in 'rest' state.n * @param {String} [options.srcGroup=null] URL of image to use in 'up' state.n * @param {String} [options.srcHover=null] URL of image to use in 'hover' state.n * @param {String} [options.srcDown=null] URL of image to use in 'down' state.n * @param {Number} [options.fadeDelay=0] How long to wait before fading.n * @param {Number} [options.fadeLength=2000] How long should it take to fade the button.n * @param {OpenSeadragon.EventHandler} [options.onPress=null] Event handler callback for {@link OpenSeadragon.Button.event:press}.n * @param {OpenSeadragon.EventHandler} [options.onRelease=null] Event handler callback for {@link OpenSeadragon.Button.event:release}.n * @param {OpenSeadragon.EventHandler} [options.onClick=null] Event handler callback for {@link OpenSeadragon.Button.event:click}.n * @param {OpenSeadragon.EventHandler} [options.onEnter=null] Event handler callback for {@link OpenSeadragon.Button.event:enter}.n * @param {OpenSeadragon.EventHandler} [options.onExit=null] Event handler callback for {@link OpenSeadragon.Button.event:exit}.n * @param {OpenSeadragon.EventHandler} [options.onFocus=null] Event handler callback for {@link OpenSeadragon.Button.event:focus}.n * @param {OpenSeadragon.EventHandler} [options.onBlur=null] Event handler callback for {@link OpenSeadragon.Button.event:blur}.n */n$.Button = function( options ) {nn var _this = this;nn $.EventSource.call( this );nn $.extend( true, this, {nn tooltip: null,n srcRest: null,n srcGroup: null,n srcHover: null,n srcDown: null,n clickTimeThreshold: $.DEFAULT_SETTINGS.clickTimeThreshold,n clickDistThreshold: $.DEFAULT_SETTINGS.clickDistThreshold,n /**n * How long to wait before fading.n * @member {Number} fadeDelayn * @memberof OpenSeadragon.Button#n */n fadeDelay: 0,n /**n * How long should it take to fade the button.n * @member {Number} fadeLengthn * @memberof OpenSeadragon.Button#n */n fadeLength: 2000,n onPress: null,n onRelease: null,n onClick: null,n onEnter: null,n onExit: null,n onFocus: null,n onBlur: nullnn }, options );nn /**n * The button element.n * @member {Element} elementn * @memberof OpenSeadragon.Button#n */n this.element = options.element || $.makeNeutralElement("div");nn //if the user has specified the element to bind the control to explicitlyn //then do not add the default control imagesn if ( !options.element ) {n this.imgRest = $.makeTransparentImage( this.srcRest );n this.imgGroup = $.makeTransparentImage( this.srcGroup );n this.imgHover = $.makeTransparentImage( this.srcHover );n this.imgDown = $.makeTransparentImage( this.srcDown );nn this.imgRest.alt =n this.imgGroup.alt =n this.imgHover.alt =n this.imgDown.alt =n this.tooltip;nn this.element.style.position = "relative";n $.setElementTouchActionNone( this.element );nn this.imgGroup.style.position =n this.imgHover.style.position =n this.imgDown.style.position =n "absolute";nn this.imgGroup.style.top =n this.imgHover.style.top =n this.imgDown.style.top =n "0px";nn this.imgGroup.style.left =n this.imgHover.style.left =n this.imgDown.style.left =n "0px";nn this.imgHover.style.visibility =n this.imgDown.style.visibility =n "hidden";nn if ($.Browser.vendor == $.BROWSERS.FIREFOX && $.Browser.version < 3) {n this.imgGroup.style.top =n this.imgHover.style.top =n this.imgDown.style.top =n "";n }nn this.element.appendChild( this.imgRest );n this.element.appendChild( this.imgGroup );n this.element.appendChild( this.imgHover );n this.element.appendChild( this.imgDown );n }nnn this.addHandler("press", this.onPress);n this.addHandler("release", this.onRelease);n this.addHandler("click", this.onClick);n this.addHandler("enter", this.onEnter);n this.addHandler("exit", this.onExit);n this.addHandler("focus", this.onFocus);n this.addHandler("blur", this.onBlur);nn /**n * The button's current state.n * @member {OpenSeadragon.ButtonState} currentStaten * @memberof OpenSeadragon.Button#n */n this.currentState = $.ButtonState.GROUP;nn // When the button last began to fade.n this.fadeBeginTime = null;n // Whether this button should fade after user stops interacting with the viewport.n this.shouldFade = false;nn this.element.style.display = "inline-block";n this.element.style.position = "relative";n this.element.title = this.tooltip;nn /**n * Tracks mouse/touch/key events on the button.n * @member {OpenSeadragon.MouseTracker} trackern * @memberof OpenSeadragon.Button#n */n this.tracker = new $.MouseTracker({nn element: this.element,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,nn enterHandler: function( event ) {n if ( event.insideElementPressed ) {n inTo( _this, $.ButtonState.DOWN );n /**n * Raised when the cursor enters the Button element.n *n * @event entern * @memberof OpenSeadragon.Buttonn * @type {object}n * @property {OpenSeadragon.Button} eventSource - A reference to the Button which raised the event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( "enter", { originalEvent: event.originalEvent } );n } else if ( !event.buttonDownAny ) {n inTo( _this, $.ButtonState.HOVER );n }n },nn focusHandler: function ( event ) {n this.enterHandler( event );n /**n * Raised when the Button element receives focus.n *n * @event focusn * @memberof OpenSeadragon.Buttonn * @type {object}n * @property {OpenSeadragon.Button} eventSource - A reference to the Button which raised the event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( "focus", { originalEvent: event.originalEvent } );n },nn exitHandler: function( event ) {n outTo( _this, $.ButtonState.GROUP );n if ( event.insideElementPressed ) {n /**n * Raised when the cursor leaves the Button element.n *n * @event exitn * @memberof OpenSeadragon.Buttonn * @type {object}n * @property {OpenSeadragon.Button} eventSource - A reference to the Button which raised the event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( "exit", { originalEvent: event.originalEvent } );n }n },nn blurHandler: function ( event ) {n this.exitHandler( event );n /**n * Raised when the Button element loses focus.n *n * @event blurn * @memberof OpenSeadragon.Buttonn * @type {object}n * @property {OpenSeadragon.Button} eventSource - A reference to the Button which raised the event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( "blur", { originalEvent: event.originalEvent } );n },nn pressHandler: function ( event ) {n inTo( _this, $.ButtonState.DOWN );n /**n * Raised when a mouse button is pressed or touch occurs in the Button element.n *n * @event pressn * @memberof OpenSeadragon.Buttonn * @type {object}n * @property {OpenSeadragon.Button} eventSource - A reference to the Button which raised the event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( "press", { originalEvent: event.originalEvent } );n },nn releaseHandler: function( event ) {n if ( event.insideElementPressed && event.insideElementReleased ) {n outTo( _this, $.ButtonState.HOVER );n /**n * Raised when the mouse button is released or touch ends in the Button element.n *n * @event releasen * @memberof OpenSeadragon.Buttonn * @type {object}n * @property {OpenSeadragon.Button} eventSource - A reference to the Button which raised the event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( "release", { originalEvent: event.originalEvent } );n } else if ( event.insideElementPressed ) {n outTo( _this, $.ButtonState.GROUP );n } else {n inTo( _this, $.ButtonState.HOVER );n }n },nn clickHandler: function( event ) {n if ( event.quick ) {n /**n * Raised when a mouse button is pressed and released or touch is initiated and ended in the Button element within the time and distance threshold.n *n * @event clickn * @memberof OpenSeadragon.Buttonn * @type {object}n * @property {OpenSeadragon.Button} eventSource - A reference to the Button which raised the event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent("click", { originalEvent: event.originalEvent });n }n },nn keyHandler: function( event ){n //console.log( "%s : handling key %s!", _this.tooltip, event.keyCode);n if( 13 === event.keyCode ){n /***n * Raised when a mouse button is pressed and released or touch is initiated and ended in the Button element within the time and distance threshold.n *n * @event clickn * @memberof OpenSeadragon.Buttonn * @type {object}n * @property {OpenSeadragon.Button} eventSource - A reference to the Button which raised the event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( "click", { originalEvent: event.originalEvent } );n /***n * Raised when the mouse button is released or touch ends in the Button element.n *n * @event releasen * @memberof OpenSeadragon.Buttonn * @type {object}n * @property {OpenSeadragon.Button} eventSource - A reference to the Button which raised the event.n * @property {Object} originalEvent - The original DOM event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.raiseEvent( "release", { originalEvent: event.originalEvent } );n return false;n }n return true;n }nn });nn outTo( this, $.ButtonState.REST );n};nn$.extend( $.Button.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.Button.prototype */{nn /**n * TODO: Determine what this function is intended to do and if it's actuallyn * useful as an API point.n * @functionn */n notifyGroupEnter: function() {n inTo( this, $.ButtonState.GROUP );n },nn /**n * TODO: Determine what this function is intended to do and if it's actuallyn * useful as an API point.n * @functionn */n notifyGroupExit: function() {n outTo( this, $.ButtonState.REST );n },nn /**n * @functionn */n disable: function(){n this.notifyGroupExit();n this.element.disabled = true;n $.setElementOpacity( this.element, 0.2, true );n },nn /**n * @functionn */n enable: function(){n this.element.disabled = false;n $.setElementOpacity( this.element, 1.0, true );n this.notifyGroupEnter();n }nn});nnnfunction scheduleFade( button ) {n $.requestAnimationFrame(function(){n updateFade( button );n });n}nnfunction updateFade( button ) {n var currentTime,n deltaTime,n opacity;nn if ( button.shouldFade ) {n currentTime = $.now();n deltaTime = currentTime - button.fadeBeginTime;n opacity = 1.0 - deltaTime / button.fadeLength;n opacity = Math.min( 1.0, opacity );n opacity = Math.max( 0.0, opacity );nn if( button.imgGroup ){n $.setElementOpacity( button.imgGroup, opacity, true );n }n if ( opacity > 0 ) {n // fade againn scheduleFade( button );n }n }n}nnfunction beginFading( button ) {n button.shouldFade = true;n button.fadeBeginTime = $.now() + button.fadeDelay;n window.setTimeout( function(){n scheduleFade( button );n }, button.fadeDelay );n}nnfunction stopFading( button ) {n button.shouldFade = false;n if( button.imgGroup ){n $.setElementOpacity( button.imgGroup, 1.0, true );n }n}nnfunction inTo( button, newState ) {nn if( button.element.disabled ){n return;n }nn if ( newState >= $.ButtonState.GROUP &&n button.currentState == $.ButtonState.REST ) {n stopFading( button );n button.currentState = $.ButtonState.GROUP;n }nn if ( newState >= $.ButtonState.HOVER &&n button.currentState == $.ButtonState.GROUP ) {n if( button.imgHover ){n button.imgHover.style.visibility = "";n }n button.currentState = $.ButtonState.HOVER;n }nn if ( newState >= $.ButtonState.DOWN &&n button.currentState == $.ButtonState.HOVER ) {n if( button.imgDown ){n button.imgDown.style.visibility = "";n }n button.currentState = $.ButtonState.DOWN;n }n}nnnfunction outTo( button, newState ) {nn if( button.element.disabled ){n return;n }nn if ( newState <= $.ButtonState.HOVER &&n button.currentState == $.ButtonState.DOWN ) {n if( button.imgDown ){n button.imgDown.style.visibility = "hidden";n }n button.currentState = $.ButtonState.HOVER;n }nn if ( newState <= $.ButtonState.GROUP &&n button.currentState == $.ButtonState.HOVER ) {n if( button.imgHover ){n button.imgHover.style.visibility = "hidden";n }n button.currentState = $.ButtonState.GROUP;n }nn if ( newState <= $.ButtonState.REST &&n button.currentState == $.ButtonState.GROUP ) {n beginFading( button );n button.currentState = $.ButtonState.REST;n }n}nnnn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - ButtonGroupn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){n/**n * @class ButtonGroupn * @classdesc Manages events on groups of buttons.n *n * @memberof OpenSeadragonn * @param {Object} options - A dictionary of settings applied against the entire group of buttons.n * @param {Array} options.buttons Array of buttonsn * @param {Element} [options.element] Element to use as the containern **/n$.ButtonGroup = function( options ) {nn $.extend( true, this, {n /**n * An array containing the buttons themselves.n * @member {Array} buttonsn * @memberof OpenSeadragon.ButtonGroup#n */n buttons: [],n clickTimeThreshold: $.DEFAULT_SETTINGS.clickTimeThreshold,n clickDistThreshold: $.DEFAULT_SETTINGS.clickDistThreshold,n labelText: ""n }, options );nn // copy the button elements TODO: Why?n var buttons = this.buttons.concat([]),n _this = this,n i;nn /**n * The shared container for the buttons.n * @member {Element} elementn * @memberof OpenSeadragon.ButtonGroup#n */n this.element = options.element || $.makeNeutralElement( "div" );nn // TODO What if there IS an options.group specified?n if( !options.group ){n this.label = $.makeNeutralElement( "label" );n //TODO: support labels for ButtonGroupsn //this.label.innerHTML = this.labelText;n this.element.style.display = "inline-block";n this.element.appendChild( this.label );n for ( i = 0; i < buttons.length; i++ ) {n this.element.appendChild( buttons[ i ].element );n }n }nn $.setElementTouchActionNone( this.element );nn /**n * Tracks mouse/touch/key events accross the group of buttons.n * @member {OpenSeadragon.MouseTracker} trackern * @memberof OpenSeadragon.ButtonGroup#n */n this.tracker = new $.MouseTracker({n element: this.element,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n enterHandler: function ( event ) {n var i;n for ( i = 0; i < _this.buttons.length; i++ ) {n _this.buttons[ i ].notifyGroupEnter();n }n },n exitHandler: function ( event ) {n var i;n if ( !event.insideElementPressed ) {n for ( i = 0; i < _this.buttons.length; i++ ) {n _this.buttons[ i ].notifyGroupExit();n }n }n },n });n};nn/** @lends OpenSeadragon.ButtonGroup.prototype */n$.ButtonGroup.prototype = {nn /**n * TODO: Figure out why this is used on the public API and if a more usefuln * api can be created.n * @functionn * @privaten */n emulateEnter: function() {n this.tracker.enterHandler( { eventSource: this.tracker } );n },nn /**n * TODO: Figure out why this is used on the public API and if a more usefuln * api can be created.n * @functionn * @privaten */n emulateExit: function() {n this.tracker.exitHandler( { eventSource: this.tracker } );n }n};nnn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - Rectn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function($) {nn/**n * @class Rectn * @classdesc A Rectangle is described by it top left coordinates (x, y), width,n * height and degrees of rotation around (x, y).n * Note that the coordinate system used is the one commonly used with images:n * x increases when going to the rightn * y increases when going to the bottomn * degrees increases clockwise with 0 being the horizontaln *n * The constructor normalizes the rectangle to always have 0 <= degrees < 90n *n * @memberof OpenSeadragonn * @param {Number} [x=0] The vector component 'x'.n * @param {Number} [y=0] The vector component 'y'.n * @param {Number} [width=0] The vector component 'width'.n * @param {Number} [height=0] The vector component 'height'.n * @param {Number} [degrees=0] Rotation of the rectangle around (x,y) in degrees.n */n$.Rect = function(x, y, width, height, degrees) {n /**n * The vector component 'x'.n * @member {Number} xn * @memberof OpenSeadragon.Rect#n */n this.x = typeof (x) === "number" ? x : 0;n /**n * The vector component 'y'.n * @member {Number} yn * @memberof OpenSeadragon.Rect#n */n this.y = typeof (y) === "number" ? y : 0;n /**n * The vector component 'width'.n * @member {Number} widthn * @memberof OpenSeadragon.Rect#n */n this.width = typeof (width) === "number" ? width : 0;n /**n * The vector component 'height'.n * @member {Number} heightn * @memberof OpenSeadragon.Rect#n */n this.height = typeof (height) === "number" ? height : 0;nn this.degrees = typeof (degrees) === "number" ? degrees : 0;nn // Normalizes the rectangle.n this.degrees = $.positiveModulo(this.degrees, 360);n var newTopLeft, newWidth;n if (this.degrees >= 270) {n newTopLeft = this.getTopRight();n this.x = newTopLeft.x;n this.y = newTopLeft.y;n newWidth = this.height;n this.height = this.width;n this.width = newWidth;n this.degrees -= 270;n } else if (this.degrees >= 180) {n newTopLeft = this.getBottomRight();n this.x = newTopLeft.x;n this.y = newTopLeft.y;n this.degrees -= 180;n } else if (this.degrees >= 90) {n newTopLeft = this.getBottomLeft();n this.x = newTopLeft.x;n this.y = newTopLeft.y;n newWidth = this.height;n this.height = this.width;n this.width = newWidth;n this.degrees -= 90;n }n};nn/**n * Builds a rectangle having the 3 specified points as summits.n * @staticn * @memberof OpenSeadragon.Rectn * @param {OpenSeadragon.Point} topLeftn * @param {OpenSeadragon.Point} topRightn * @param {OpenSeadragon.Point} bottomLeftn * @returns {OpenSeadragon.Rect}n */n$.Rect.fromSummits = function(topLeft, topRight, bottomLeft) {n var width = topLeft.distanceTo(topRight);n var height = topLeft.distanceTo(bottomLeft);n var diff = topRight.minus(topLeft);n var radians = Math.atan(diff.y / diff.x);n if (diff.x < 0) {n radians += Math.PI;n } else if (diff.y < 0) {n radians += 2 * Math.PI;n }n return new $.Rect(n topLeft.x,n topLeft.y,n width,n height,n radians / Math.PI * 180);n};nn/** @lends OpenSeadragon.Rect.prototype */n$.Rect.prototype = {n /**n * @functionn * @returns {OpenSeadragon.Rect} a duplicate of this Rectn */n clone: function() {n return new $.Rect(n this.x,n this.y,n this.width,n this.height,n this.degrees);n },nn /**n * The aspect ratio is simply the ratio of width to height.n * @functionn * @returns {Number} The ratio of width to height.n */n getAspectRatio: function() {n return this.width / this.height;n },nn /**n * Provides the coordinates of the upper-left corner of the rectangle as an * point.n * @functionn * @returns {OpenSeadragon.Point} The coordinate of the upper-left corner ofn * the rectangle.n */n getTopLeft: function() {n return new $.Point(n this.x,n this.yn );n },nn /**n * Provides the coordinates of the bottom-right corner of the rectangle as an * point.n * @functionn * @returns {OpenSeadragon.Point} The coordinate of the bottom-right corner ofn * the rectangle.n */n getBottomRight: function() {n return new $.Point(this.x + this.width, this.y + this.height)n .rotate(this.degrees, this.getTopLeft());n },nn /**n * Provides the coordinates of the top-right corner of the rectangle as an * point.n * @functionn * @returns {OpenSeadragon.Point} The coordinate of the top-right corner ofn * the rectangle.n */n getTopRight: function() {n return new $.Point(this.x + this.width, this.y)n .rotate(this.degrees, this.getTopLeft());n },nn /**n * Provides the coordinates of the bottom-left corner of the rectangle as an * point.n * @functionn * @returns {OpenSeadragon.Point} The coordinate of the bottom-left corner ofn * the rectangle.n */n getBottomLeft: function() {n return new $.Point(this.x, this.y + this.height)n .rotate(this.degrees, this.getTopLeft());n },nn /**n * Computes the center of the rectangle.n * @functionn * @returns {OpenSeadragon.Point} The center of the rectangle as representedn * as represented by a 2-dimensional vector (x,y)n */n getCenter: function() {n return new $.Point(n this.x + this.width / 2.0,n this.y + this.height / 2.0n ).rotate(this.degrees, this.getTopLeft());n },nn /**n * Returns the width and height component as a vector OpenSeadragon.Pointn * @functionn * @returns {OpenSeadragon.Point} The 2 dimensional vector representing then * the width and height of the rectangle.n */n getSize: function() {n return new $.Point(this.width, this.height);n },nn /**n * Determines if two Rectangles have equivalent components.n * @functionn * @param {OpenSeadragon.Rect} rectangle The Rectangle to compare to.n * @return {Boolean} 'true' if all components are equal, otherwise 'false'.n */n equals: function(other) {n return (other instanceof $.Rect) &&n this.x === other.x &&n this.y === other.y &&n this.width === other.width &&n this.height === other.height &&n this.degrees === other.degrees;n },nn /**n * Multiply all dimensions (except degrees) in this Rect by a factor andn * return a new Rect.n * @functionn * @param {Number} factor The factor to multiply vector components.n * @returns {OpenSeadragon.Rect} A new rect representing the multiplicationn * of the vector components by the factorn */n times: function(factor) {n return new $.Rect(n this.x * factor,n this.y * factor,n this.width * factor,n this.height * factor,n this.degrees);n },nn /**n * Translate/move this Rect by a vector and return new Rect.n * @functionn * @param {OpenSeadragon.Point} delta The translation vector.n * @returns {OpenSeadragon.Rect} A new rect with altered positionn */n translate: function(delta) {n return new $.Rect(n this.x + delta.x,n this.y + delta.y,n this.width,n this.height,n this.degrees);n },nn /**n * Returns the smallest rectangle that will contain this and the givenn * rectangle bounding boxes.n * @param {OpenSeadragon.Rect} rectn * @return {OpenSeadragon.Rect} The new rectangle.n */n union: function(rect) {n var thisBoundingBox = this.getBoundingBox();n var otherBoundingBox = rect.getBoundingBox();nn var left = Math.min(thisBoundingBox.x, otherBoundingBox.x);n var top = Math.min(thisBoundingBox.y, otherBoundingBox.y);n var right = Math.max(n thisBoundingBox.x + thisBoundingBox.width,n otherBoundingBox.x + otherBoundingBox.width);n var bottom = Math.max(n thisBoundingBox.y + thisBoundingBox.height,n otherBoundingBox.y + otherBoundingBox.height);nn return new $.Rect(n left,n top,n right - left,n bottom - top);n },nn /**n * Returns the bounding box of the intersection of this rectangle with then * given rectangle.n * @param {OpenSeadragon.Rect} rectn * @return {OpenSeadragon.Rect} the bounding box of the intersectionn * or null if the rectangles don't intersect.n */n intersection: function(rect) {n // Simplified version of Weiler Atherton clipping algorithmn // en.wikipedia.org/wiki/Weiler%E2%80%93Atherton_clipping_algorithmn // Because we just want the bounding box of the intersection,n // we can just compute the bounding box of:n // 1. all the summits of this which are inside rectn // 2. all the summits of rect which are inside thisn // 3. all the intersections of rect and thisn var EPSILON = 0.0000000001;nn var intersectionPoints = [];nn var thisTopLeft = this.getTopLeft();n if (rect.containsPoint(thisTopLeft, EPSILON)) {n intersectionPoints.push(thisTopLeft);n }n var thisTopRight = this.getTopRight();n if (rect.containsPoint(thisTopRight, EPSILON)) {n intersectionPoints.push(thisTopRight);n }n var thisBottomLeft = this.getBottomLeft();n if (rect.containsPoint(thisBottomLeft, EPSILON)) {n intersectionPoints.push(thisBottomLeft);n }n var thisBottomRight = this.getBottomRight();n if (rect.containsPoint(thisBottomRight, EPSILON)) {n intersectionPoints.push(thisBottomRight);n }nn var rectTopLeft = rect.getTopLeft();n if (this.containsPoint(rectTopLeft, EPSILON)) {n intersectionPoints.push(rectTopLeft);n }n var rectTopRight = rect.getTopRight();n if (this.containsPoint(rectTopRight, EPSILON)) {n intersectionPoints.push(rectTopRight);n }n var rectBottomLeft = rect.getBottomLeft();n if (this.containsPoint(rectBottomLeft, EPSILON)) {n intersectionPoints.push(rectBottomLeft);n }n var rectBottomRight = rect.getBottomRight();n if (this.containsPoint(rectBottomRight, EPSILON)) {n intersectionPoints.push(rectBottomRight);n }nn var thisSegments = this._getSegments();n var rectSegments = rect._getSegments();n for (var i = 0; i < thisSegments.length; i++) {n var thisSegment = thisSegments;n for (var j = 0; j < rectSegments.length; j++) {n var rectSegment = rectSegments;n var intersect = getIntersection(thisSegment, thisSegment,n rectSegment, rectSegment);n if (intersect) {n intersectionPoints.push(intersect);n }n }n }nn // Get intersection point of segments [a,b] and [c,d]n function getIntersection(a, b, c, d) {n // stackoverflow.com/a/1968345/1440403n var abVector = b.minus(a);n var cdVector = d.minus©;nn var denom = -cdVector.x * abVector.y + abVector.x * cdVector.y;n if (denom === 0) {n return null;n }nn var s = (abVector.x * (a.y - c.y) - abVector.y * (a.x - c.x)) / denom;n var t = (cdVector.x * (a.y - c.y) - cdVector.y * (a.x - c.x)) / denom;nn if (-EPSILON <= s && s <= 1 - EPSILON &&n -EPSILON <= t && t <= 1 - EPSILON) {n return new $.Point(a.x + t * abVector.x, a.y + t * abVector.y);n }n return null;n }nn if (intersectionPoints.length === 0) {n return null;n }nn var minX = intersectionPoints.x;n var maxX = intersectionPoints.x;n var minY = intersectionPoints.y;n var maxY = intersectionPoints.y;n for (var k = 1; k < intersectionPoints.length; k++) {n var point = intersectionPoints;n if (point.x < minX) {n minX = point.x;n }n if (point.x > maxX) {n maxX = point.x;n }n if (point.y < minY) {n minY = point.y;n }n if (point.y > maxY) {n maxY = point.y;n }n }n return new $.Rect(minX, minY, maxX - minX, maxY - minY);n },nn // privaten _getSegments: function() {n var topLeft = this.getTopLeft();n var topRight = this.getTopRight();n var bottomLeft = this.getBottomLeft();n var bottomRight = this.getBottomRight();n return [[topLeft, topRight],n [topRight, bottomRight],n [bottomRight, bottomLeft],n [bottomLeft, topLeft]];n },nn /**n * Rotates a rectangle around a point.n * @functionn * @param {Number} degrees The angle in degrees to rotate.n * @param {OpenSeadragon.Point} [pivot] The point about which to rotate.n * Defaults to the center of the rectangle.n * @return {OpenSeadragon.Rect}n */n rotate: function(degrees, pivot) {n degrees = $.positiveModulo(degrees, 360);n if (degrees === 0) {n return this.clone();n }nn pivot = pivot || this.getCenter();n var newTopLeft = this.getTopLeft().rotate(degrees, pivot);n var newTopRight = this.getTopRight().rotate(degrees, pivot);nn var diff = newTopRight.minus(newTopLeft);n // Handle floating point errorn diff = diff.apply(function(x) {n var EPSILON = 1e-15;n return Math.abs(x) < EPSILON ? 0 : x;n });n var radians = Math.atan(diff.y / diff.x);n if (diff.x < 0) {n radians += Math.PI;n } else if (diff.y < 0) {n radians += 2 * Math.PI;n }n return new $.Rect(n newTopLeft.x,n newTopLeft.y,n this.width,n this.height,n radians / Math.PI * 180);n },nn /**n * Retrieves the smallest horizontal (degrees=0) rectangle which containsn * this rectangle.n * @returns {OpenSeadragon.Rect}n */n getBoundingBox: function() {n if (this.degrees === 0) {n return this.clone();n }n var topLeft = this.getTopLeft();n var topRight = this.getTopRight();n var bottomLeft = this.getBottomLeft();n var bottomRight = this.getBottomRight();n var minX = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);n var maxX = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);n var minY = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);n var maxY = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);n return new $.Rect(n minX,n minY,n maxX - minX,n maxY - minY);n },nn /**n * Retrieves the smallest horizontal (degrees=0) rectangle which containsn * this rectangle and has integers x, y, width and heightn * @returns {OpenSeadragon.Rect}n */n getIntegerBoundingBox: function() {n var boundingBox = this.getBoundingBox();n var x = Math.floor(boundingBox.x);n var y = Math.floor(boundingBox.y);n var width = Math.ceil(boundingBox.width + boundingBox.x - x);n var height = Math.ceil(boundingBox.height + boundingBox.y - y);n return new $.Rect(x, y, width, height);n },nn /**n * Determines whether a point is inside this rectangle (edge included).n * @functionn * @param {OpenSeadragon.Point} pointn * @param {Number} [epsilon=0] the margin of error allowedn * @returns {Boolean} true if the point is inside this rectangle, falsen * otherwise.n */n containsPoint: function(point, epsilon) {n epsilon = epsilon || 0;nn // See stackoverflow.com/a/2752754/1440403 for explanationn var topLeft = this.getTopLeft();n var topRight = this.getTopRight();n var bottomLeft = this.getBottomLeft();n var topDiff = topRight.minus(topLeft);n var leftDiff = bottomLeft.minus(topLeft);nn return ((point.x - topLeft.x) * topDiff.x +n (point.y - topLeft.y) * topDiff.y >= -epsilon) &&nn ((point.x - topRight.x) * topDiff.x +n (point.y - topRight.y) * topDiff.y <= epsilon) &&nn ((point.x - topLeft.x) * leftDiff.x +n (point.y - topLeft.y) * leftDiff.y >= -epsilon) &&nn ((point.x - bottomLeft.x) * leftDiff.x +n (point.y - bottomLeft.y) * leftDiff.y <= epsilon);n },nn /**n * Provides a string representation of the rectangle which is useful forn * debugging.n * @functionn * @returns {String} A string representation of the rectangle.n */n toString: function() {n return "[" +n (Math.round(this.x * 100) / 100) + ", " +n (Math.round(this.y * 100) / 100) + ", " +n (Math.round(this.width * 100) / 100) + "x" +n (Math.round(this.height * 100) / 100) + ", " +n (Math.round(this.degrees * 100) / 100) + "deg" +n "]";n }n};nnn}(OpenSeadragon));n”,“/*n * OpenSeadragon - ReferenceStripn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function ( $ ) {nn// dictionary from id to private propertiesnvar THIS = {};nn/**n * The CollectionDrawer is a reimplementation if the Drawer API thatn * focuses on allowing a viewport to be redefined as a collectionn * of smaller viewports, defined by a clear number of rows and / orn * columns of which each item in the matrix of viewports has its ownn * source.n *n * This idea is a reexpression of the idea of dzi collectionsn * which allows a clearer algorithm to reuse the tile sources alreadyn * supported by OpenSeadragon, in heterogenious or homogeniousn * sequences just like mixed groups already supported by the viewern * for the purpose of image sequnces.n *n * TODO: The difficult part of this feature is figuring out how to expressn * this functionality as a combination of the functionality alreadyn * provided by Drawer, Viewport, TileSource, and Navigator. It mayn * require better abstraction at those points in order to effecientlyn * reuse those paradigms.n */n/**n * @class ReferenceStripn * @memberof OpenSeadragonn * @param {Object} optionsn */n$.ReferenceStrip = function ( options ) {nn var _this = this,n viewer = options.viewer,n viewerSize = $.getElementSize( viewer.element ),n element,n style,n i;nn //We may need to create a new element and id if they did notn //provide the id for the existing elementn if ( !options.id ) {n options.id = 'referencestrip-' + $.now();n this.element = $.makeNeutralElement( "div" );n this.element.id = options.id;n this.element.className = 'referencestrip';n }nn options = $.extend( true, {n sizeRatio: $.DEFAULT_SETTINGS.referenceStripSizeRatio,n position: $.DEFAULT_SETTINGS.referenceStripPosition,n scroll: $.DEFAULT_SETTINGS.referenceStripScroll,n clickTimeThreshold: $.DEFAULT_SETTINGS.clickTimeThresholdn }, options, {n //required overridesn element: this.element,n //These need to be overridden to prevent recursion sincen //the navigator is a viewer and a viewer has a navigatorn showNavigator: false,n mouseNavEnabled: false,n showNavigationControl: false,n showSequenceControl: falsen } );nn $.extend( this, options );n //Private state propertiesn THIS = {n "animating": falsen };nn this.minPixelRatio = this.viewer.minPixelRatio;nn style = this.element.style;n style.marginTop = '0px';n style.marginRight = '0px';n style.marginBottom = '0px';n style.marginLeft = '0px';n style.left = '0px';n style.bottom = '0px';n style.border = '0px';n style.background = '#000';n style.position = 'relative';nn $.setElementTouchActionNone( this.element );nn $.setElementOpacity( this.element, 0.8 );nn this.viewer = viewer;n this.innerTracker = new $.MouseTracker( {n element: this.element,n dragHandler: $.delegate( this, onStripDrag ),n scrollHandler: $.delegate( this, onStripScroll ),n enterHandler: $.delegate( this, onStripEnter ),n exitHandler: $.delegate( this, onStripExit ),n keyDownHandler: $.delegate( this, onKeyDown ),n keyHandler: $.delegate( this, onKeyPress )n } );nn //Controls the position and orientation of the reference strip and sets then //appropriate width and heightn if ( options.width && options.height ) {n this.element.style.width = options.width + 'px';n this.element.style.height = options.height + 'px';n viewer.addControl(n this.element,n { anchor: $.ControlAnchor.BOTTOM_LEFT }n );n } else {n if ( "horizontal" == options.scroll ) {n this.element.style.width = (n viewerSize.x *n options.sizeRatio *n viewer.tileSources.lengthn ) + ( 12 * viewer.tileSources.length ) + 'px';nn this.element.style.height = (n viewerSize.y *n options.sizeRation ) + 'px';nn viewer.addControl(n this.element,n { anchor: $.ControlAnchor.BOTTOM_LEFT }n );n } else {n this.element.style.height = (n viewerSize.y *n options.sizeRatio *n viewer.tileSources.lengthn ) + ( 12 * viewer.tileSources.length ) + 'px';nn this.element.style.width = (n viewerSize.x *n options.sizeRation ) + 'px';nn viewer.addControl(n this.element,n { anchor: $.ControlAnchor.TOP_LEFT }n );nn }n }nn this.panelWidth = ( viewerSize.x * this.sizeRatio ) + 8;n this.panelHeight = ( viewerSize.y * this.sizeRatio ) + 8;n this.panels = [];n this.miniViewers = {};nn /*jshint loopfunc:true*/n for ( i = 0; i < viewer.tileSources.length; i++ ) {nn element = $.makeNeutralElement( 'div' );n element.id = this.element.id + "-" + i;nn element.style.width = _this.panelWidth + 'px';n element.style.height = _this.panelHeight + 'px';n element.style.display = 'inline';n element.style.float = 'left'; //Webkitn element.style.cssFloat = 'left'; //Firefoxn element.style.styleFloat = 'left'; //IEn element.style.padding = '2px';n $.setElementTouchActionNone( element );nn element.innerTracker = new $.MouseTracker( {n element: element,n clickTimeThreshold: this.clickTimeThreshold,n clickDistThreshold: this.clickDistThreshold,n pressHandler: function ( event ) {n event.eventSource.dragging = $.now();n },n releaseHandler: function ( event ) {n var tracker = event.eventSource,n id = tracker.element.id,n page = Number( id.split( '-' )[2] ),n now = $.now();nn if ( event.insideElementPressed &&n event.insideElementReleased &&n tracker.dragging &&n ( now - tracker.dragging ) < tracker.clickTimeThreshold ) {n tracker.dragging = null;n viewer.goToPage( page );n }n }n } );nn this.element.appendChild( element );nn element.activePanel = false;nn this.panels.push( element );nn }n loadPanels( this, this.scroll == 'vertical' ? viewerSize.y : viewerSize.x, 0 );n this.setFocus( 0 );nn};nn$.extend( $.ReferenceStrip.prototype, $.EventSource.prototype, $.Viewer.prototype, /** @lends OpenSeadragon.ReferenceStrip.prototype */{nn /**n * @functionn */n setFocus: function ( page ) {n var element = $.getElement( this.element.id + '-' + page ),n viewerSize = $.getElementSize( this.viewer.canvas ),n scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ),n scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ),n offsetLeft = -Number( this.element.style.marginLeft.replace( 'px', '' ) ),n offsetTop = -Number( this.element.style.marginTop.replace( 'px', '' ) ),n offset;nn if ( this.currentSelected !== element ) {n if ( this.currentSelected ) {n this.currentSelected.style.background = '#000';n }n this.currentSelected = element;n this.currentSelected.style.background = '#999';nn if ( 'horizontal' == this.scroll ) {n //right leftn offset = ( Number( page ) ) * ( this.panelWidth + 3 );n if ( offset > offsetLeft + viewerSize.x - this.panelWidth ) {n offset = Math.min( offset, ( scrollWidth - viewerSize.x ) );n this.element.style.marginLeft = -offset + 'px';n loadPanels( this, viewerSize.x, -offset );n } else if ( offset < offsetLeft ) {n offset = Math.max( 0, offset - viewerSize.x / 2 );n this.element.style.marginLeft = -offset + 'px';n loadPanels( this, viewerSize.x, -offset );n }n } else {n offset = ( Number( page ) ) * ( this.panelHeight + 3 );n if ( offset > offsetTop + viewerSize.y - this.panelHeight ) {n offset = Math.min( offset, ( scrollHeight - viewerSize.y ) );n this.element.style.marginTop = -offset + 'px';n loadPanels( this, viewerSize.y, -offset );n } else if ( offset < offsetTop ) {n offset = Math.max( 0, offset - viewerSize.y / 2 );n this.element.style.marginTop = -offset + 'px';n loadPanels( this, viewerSize.y, -offset );n }n }nn this.currentPage = page;n onStripEnter.call( this, { eventSource: this.innerTracker } );n }n },nn /**n * @functionn */n update: function () {n if ( THIS.animating ) {n $.console.log( 'image reference strip update' );n return true;n }n return false;n },nn // Overrides Viewer.destroyn destroy: function() {n if (this.miniViewers) {n for (var key in this.miniViewers) {n this.miniViewers.destroy();n }n }nn if (this.element) {n this.element.parentNode.removeChild(this.element);n }n }nn} );nnnnn/**n * @privaten * @innern * @functionn */nfunction onStripDrag( event ) {nn var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ),n offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ),n scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ),n scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ),n viewerSize = $.getElementSize( this.viewer.canvas );n this.dragging = true;n if ( this.element ) {n if ( 'horizontal' == this.scroll ) {n if ( -event.delta.x > 0 ) {n //forwardn if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) {n this.element.style.marginLeft = ( offsetLeft + ( event.delta.x * 2 ) ) + 'px';n loadPanels( this, viewerSize.x, offsetLeft + ( event.delta.x * 2 ) );n }n } else if ( -event.delta.x < 0 ) {n //reversen if ( offsetLeft < 0 ) {n this.element.style.marginLeft = ( offsetLeft + ( event.delta.x * 2 ) ) + 'px';n loadPanels( this, viewerSize.x, offsetLeft + ( event.delta.x * 2 ) );n }n }n } else {n if ( -event.delta.y > 0 ) {n //forwardn if ( offsetTop > -( scrollHeight - viewerSize.y ) ) {n this.element.style.marginTop = ( offsetTop + ( event.delta.y * 2 ) ) + 'px';n loadPanels( this, viewerSize.y, offsetTop + ( event.delta.y * 2 ) );n }n } else if ( -event.delta.y < 0 ) {n //reversen if ( offsetTop < 0 ) {n this.element.style.marginTop = ( offsetTop + ( event.delta.y * 2 ) ) + 'px';n loadPanels( this, viewerSize.y, offsetTop + ( event.delta.y * 2 ) );n }n }n }n }n return false;nn}nnnn/**n * @privaten * @innern * @functionn */nfunction onStripScroll( event ) {n var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ),n offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ),n scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ),n scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ),n viewerSize = $.getElementSize( this.viewer.canvas );n if ( this.element ) {n if ( 'horizontal' == this.scroll ) {n if ( event.scroll > 0 ) {n //forwardn if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) {n this.element.style.marginLeft = ( offsetLeft - ( event.scroll * 60 ) ) + 'px';n loadPanels( this, viewerSize.x, offsetLeft - ( event.scroll * 60 ) );n }n } else if ( event.scroll < 0 ) {n //reversen if ( offsetLeft < 0 ) {n this.element.style.marginLeft = ( offsetLeft - ( event.scroll * 60 ) ) + 'px';n loadPanels( this, viewerSize.x, offsetLeft - ( event.scroll * 60 ) );n }n }n } else {n if ( event.scroll < 0 ) {n //scroll upn if ( offsetTop > viewerSize.y - scrollHeight ) {n this.element.style.marginTop = ( offsetTop + ( event.scroll * 60 ) ) + 'px';n loadPanels( this, viewerSize.y, offsetTop + ( event.scroll * 60 ) );n }n } else if ( event.scroll > 0 ) {n //scroll dowmn if ( offsetTop < 0 ) {n this.element.style.marginTop = ( offsetTop + ( event.scroll * 60 ) ) + 'px';n loadPanels( this, viewerSize.y, offsetTop + ( event.scroll * 60 ) );n }n }n }n }n //cancels eventn return false;n}nnnfunction loadPanels( strip, viewerSize, scroll ) {n var panelSize,n activePanelsStart,n activePanelsEnd,n miniViewer,n style,n i,n element;n if ( 'horizontal' == strip.scroll ) {n panelSize = strip.panelWidth;n } else {n panelSize = strip.panelHeight;n }n activePanelsStart = Math.ceil( viewerSize / panelSize ) + 5;n activePanelsEnd = Math.ceil( ( Math.abs( scroll ) + viewerSize ) / panelSize ) + 1;n activePanelsStart = activePanelsEnd - activePanelsStart;n activePanelsStart = activePanelsStart < 0 ? 0 : activePanelsStart;nn for ( i = activePanelsStart; i < activePanelsEnd && i < strip.panels.length; i++ ) {n element = strip.panels;n if ( !element.activePanel ) {n var miniTileSource;n var originalTileSource = strip.viewer.tileSources;n if (originalTileSource.referenceStripThumbnailUrl) {n miniTileSource = {n type: 'image',n url: originalTileSource.referenceStripThumbnailUrln };n } else {n miniTileSource = originalTileSource;n }n miniViewer = new $.Viewer( {n id: element.id,n tileSources: [miniTileSource],n element: element,n navigatorSizeRatio: strip.sizeRatio,n showNavigator: false,n mouseNavEnabled: false,n showNavigationControl: false,n showSequenceControl: false,n immediateRender: true,n blendTime: 0,n animationTime: 0n } );nn miniViewer.displayRegion = $.makeNeutralElement( "div" );n miniViewer.displayRegion.id = element.id + '-displayregion';n miniViewer.displayRegion.className = 'displayregion';nn style = miniViewer.displayRegion.style;n style.position = 'relative';n style.top = '0px';n style.left = '0px';n style.fontSize = '0px';n style.overflow = 'hidden';n style.float = 'left'; //Webkitn style.cssFloat = 'left'; //Firefoxn style.styleFloat = 'left'; //IEn style.zIndex = 999999999;n style.cursor = 'default';n style.width = ( strip.panelWidth - 4 ) + 'px';n style.height = ( strip.panelHeight - 4 ) + 'px';nn // TODO: What is this for? Future keyboard navigation support?n miniViewer.displayRegion.innerTracker = new $.MouseTracker( {n element: miniViewer.displayRegion,n startDisabled: truen } );nn element.getElementsByTagName( 'div' )[0].appendChild(n miniViewer.displayRegionn );nn strip.miniViewers = miniViewer;nn element.activePanel = true;n }n }n}nnn/**n * @privaten * @innern * @functionn */nfunction onStripEnter( event ) {n var element = event.eventSource.element;nn //$.setElementOpacity(element, 0.8);nn //element.style.border = '1px solid #555';n //element.style.background = '#000';nn if ( 'horizontal' == this.scroll ) {nn //element.style.paddingTop = "0px";n element.style.marginBottom = "0px";nn } else {nn //element.style.paddingRight = "0px";n element.style.marginLeft = "0px";nn }n return false;n}nnn/**n * @privaten * @innern * @functionn */nfunction onStripExit( event ) {n var element = event.eventSource.element;nn if ( 'horizontal' == this.scroll ) {nn //element.style.paddingTop = "10px";n element.style.marginBottom = "-" + ( $.getElementSize( element ).y / 2 ) + "px";nn } else {nn //element.style.paddingRight = "10px";n element.style.marginLeft = "-" + ( $.getElementSize( element ).x / 2 ) + "px";nn }n return false;n}nnn/**n * @privaten * @innern * @functionn */nfunction onKeyDown( event ) {n //console.log( event.keyCode );nn if ( !event.preventDefaultAction && !event.ctrl && !event.alt && !event.meta ) {n switch ( event.keyCode ) {n case 38: //up arrown onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );n return false;n case 40: //down arrown onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );n return false;n case 37: //left arrown onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );n return false;n case 39: //right arrown onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );n return false;n default:n //console.log( 'navigator keycode %s', event.keyCode );n return true;n }n } else {n return true;n }n}nnn/**n * @privaten * @innern * @functionn */nfunction onKeyPress( event ) {n //console.log( event.keyCode );nn if ( !event.preventDefaultAction && !event.ctrl && !event.alt && !event.meta ) {n switch ( event.keyCode ) {n case 61: //=|+n onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );n return false;n case 45: //-|_n onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );n return false;n case 48: //0|)n case 119: //wn case 87: //Wn onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );n return false;n case 115: //sn case 83: //Sn onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );n return false;n case 97: //an onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );n return false;n case 100: //dn onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );n return false;n default:n //console.log( 'navigator keycode %s', event.keyCode );n return true;n }n } else {n return true;n }n}nn}(OpenSeadragon));n”,“/*n * OpenSeadragon - DisplayRectn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * @class DisplayRectn * @classdesc A display rectangle is very similar to {@link OpenSeadragon.Rect} but adds twon * fields, 'minLevel' and 'maxLevel' which denote the supported zoom levelsn * for this rectangle.n *n * @memberof OpenSeadragonn * @extends OpenSeadragon.Rectn * @param {Number} x The vector component 'x'.n * @param {Number} y The vector component 'y'.n * @param {Number} width The vector component 'height'.n * @param {Number} height The vector component 'width'.n * @param {Number} minLevel The lowest zoom level supported.n * @param {Number} maxLevel The highest zoom level supported.n */n$.DisplayRect = function( x, y, width, height, minLevel, maxLevel ) {n $.Rect.apply( this, [ x, y, width, height ] );nn /**n * The lowest zoom level supported.n * @member {Number} minLeveln * @memberof OpenSeadragon.DisplayRect#n */n this.minLevel = minLevel;n /**n * The highest zoom level supported.n * @member {Number} maxLeveln * @memberof OpenSeadragon.DisplayRect#n */n this.maxLevel = maxLevel;n};nn$.extend( $.DisplayRect.prototype, $.Rect.prototype );nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - Springn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * @class Springn * @memberof OpenSeadragonn * @param {Object} options - Spring configuration settings.n * @param {Number} options.springStiffness - Spring stiffness. Must be greater than zero.n * The closer to zero, the closer to linear animation.n * @param {Number} options.animationTime - Animation duration per spring, in seconds.n * Must be zero or greater.n * @param {Number} [options.initial=0] - Initial value of spring.n * @param {Boolean} [options.exponential=false] - Whether this spring representsn * an exponential scale (such as zoom) and should be animated accordingly. Note thatn * exponential springs must have non-zero values.n */n$.Spring = function( options ) {n var args = arguments;nn if( typeof ( options ) != 'object' ){n //allows backward compatible use of ( initialValue, config ) asn //constructor parametersn options = {n initial: args.length && typeof ( args[ 0 ] ) == "number" ?n args[ 0 ] :n undefined,n /**n * Spring stiffness.n * @member {Number} springStiffnessn * @memberof OpenSeadragon.Spring#n */n springStiffness: args.length > 1 ?n args[ 1 ].springStiffness :n 5.0,n /**n * Animation duration per spring.n * @member {Number} animationTimen * @memberof OpenSeadragon.Spring#n */n animationTime: args.length > 1 ?n args[ 1 ].animationTime :n 1.5n };n }nn $.console.assert(typeof options.springStiffness === "number" && options.springStiffness !== 0,n "[OpenSeadragon.Spring] options.springStiffness must be a non-zero number");nn $.console.assert(typeof options.animationTime === "number" && options.animationTime >= 0,n "[OpenSeadragon.Spring] options.animationTime must be a number greater than or equal to 0");nn if (options.exponential) {n this._exponential = true;n delete options.exponential;n }nn $.extend( true, this, options);nn /**n * @member {Object} currentn * @memberof OpenSeadragon.Spring#n * @property {Number} valuen * @property {Number} timen */n this.current = {n value: typeof ( this.initial ) == "number" ?n this.initial :n (this._exponential ? 0 : 1),n time: $.now() // always work in millisecondsn };nn $.console.assert(!this._exponential || this.current.value !== 0,n "[OpenSeadragon.Spring] value must be non-zero for exponential springs");nn /**n * @member {Object} startn * @memberof OpenSeadragon.Spring#n * @property {Number} valuen * @property {Number} timen */n this.start = {n value: this.current.value,n time: this.current.timen };nn /**n * @member {Object} targetn * @memberof OpenSeadragon.Spring#n * @property {Number} valuen * @property {Number} timen */n this.target = {n value: this.current.value,n time: this.current.timen };nn if (this._exponential) {n this.start._logValue = Math.log(this.start.value);n this.target._logValue = Math.log(this.target.value);n this.current._logValue = Math.log(this.current.value);n }n};nn/** @lends OpenSeadragon.Spring.prototype */n$.Spring.prototype = {nn /**n * @functionn * @param {Number} targetn */n resetTo: function( target ) {n $.console.assert(!this._exponential || target !== 0,n "[OpenSeadragon.Spring.resetTo] target must be non-zero for exponential springs");nn this.start.value = this.target.value = this.current.value = target;n this.start.time = this.target.time = this.current.time = $.now();nn if (this._exponential) {n this.start._logValue = Math.log(this.start.value);n this.target._logValue = Math.log(this.target.value);n this.current._logValue = Math.log(this.current.value);n }n },nn /**n * @functionn * @param {Number} targetn */n springTo: function( target ) {n $.console.assert(!this._exponential || target !== 0,n "[OpenSeadragon.Spring.springTo] target must be non-zero for exponential springs");nn this.start.value = this.current.value;n this.start.time = this.current.time;n this.target.value = target;n this.target.time = this.start.time + 1000 * this.animationTime;nn if (this._exponential) {n this.start._logValue = Math.log(this.start.value);n this.target._logValue = Math.log(this.target.value);n }n },nn /**n * @functionn * @param {Number} deltan */n shiftBy: function( delta ) {n this.start.value += delta;n this.target.value += delta;nn if (this._exponential) {n $.console.assert(this.target.value !== 0 && this.start.value !== 0,n "[OpenSeadragon.Spring.shiftBy] spring value must be non-zero for exponential springs");nn this.start._logValue = Math.log(this.start.value);n this.target._logValue = Math.log(this.target.value);n }n },nn setExponential: function(value) {n this._exponential = value;nn if (this._exponential) {n $.console.assert(this.current.value !== 0 && this.target.value !== 0 && this.start.value !== 0,n "[OpenSeadragon.Spring.setExponential] spring value must be non-zero for exponential springs");nn this.start._logValue = Math.log(this.start.value);n this.target._logValue = Math.log(this.target.value);n this.current._logValue = Math.log(this.current.value);n }n },nn /**n * @functionn * @returns true if the value got updated, false otherwisen */n update: function() {n this.current.time = $.now();nn var startValue, targetValue;n if (this._exponential) {n startValue = this.start._logValue;n targetValue = this.target._logValue;n } else {n startValue = this.start.value;n targetValue = this.target.value;n }nn var currentValue = (this.current.time >= this.target.time) ?n targetValue :n startValue +n ( targetValue - startValue ) *n transform(n this.springStiffness,n ( this.current.time - this.start.time ) /n ( this.target.time - this.start.time )n );nn var oldValue = this.current.value;n if (this._exponential) {n this.current.value = Math.exp(currentValue);n } else {n this.current.value = currentValue;n }nn return oldValue != this.current.value;n },nn /**n * Returns whether the spring is at the target valuen * @functionn * @returns {Boolean} True if at target value, false otherwisen */n isAtTargetValue: function() {n return this.current.value === this.target.value;n }n};nn/**n * @privaten */nfunction transform( stiffness, x ) {n return ( 1.0 - Math.exp( stiffness * -x ) ) /n ( 1.0 - Math.exp( -stiffness ) );n}nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - ImageLoadern *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsnn * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function($){nn/**n * @privaten * @class ImageJobn * @classdesc Handles downloading of a single image.n * @param {Object} options - Options for this ImageJob.n * @param {String} [options.src] - URL of image to download.n * @param {String} [options.loadWithAjax] - Whether to load this image with AJAX.n * @param {String} [options.ajaxHeaders] - Headers to add to the image request if using AJAX.n * @param {String} [options.crossOriginPolicy] - CORS policy to use for downloadsn * @param {Function} [options.callback] - Called once image has been downloaded.n * @param {Function} [options.abort] - Called when this image job is aborted.n * @param {Number} [options.timeout] - The max number of milliseconds that this image job may take to complete.n */nfunction ImageJob (options) {nn $.extend(true, this, {n timeout: $.DEFAULT_SETTINGS.timeout,n jobId: nulln }, options);nn /**n * Image object which will contain downloaded image.n * @member {Image} imagen * @memberof OpenSeadragon.ImageJob#n */n this.image = null;n}nnImageJob.prototype = {n errorMsg: null,nn /**n * Starts the image job.n * @methodn */n start: function(){n var self = this;n var selfAbort = this.abort;nn this.image = new Image();nn this.image.onload = function(){n self.finish(true);n };n this.image.onabort = this.image.onerror = function() {n self.errorMsg = "Image load aborted";n self.finish(false);n };nn this.jobId = window.setTimeout(function(){n self.errorMsg = "Image load exceeded timeout";n self.finish(false);n }, this.timeout);nn // Load the tile with an AJAX request if the loadWithAjax option isn // set. Otherwise load the image by setting the source proprety of the image object.n if (this.loadWithAjax) {n this.request = $.makeAjaxRequest({n url: this.src,n withCredentials: this.ajaxWithCredentials,n headers: this.ajaxHeaders,n responseType: "arraybuffer",n success: function(request) {n var blb;n // Make the raw data into a blob.n // BlobBuilder fallback adapted fromn // stackoverflow.com/questions/15293694/blob-constructor-browser-compatibilityn try {n blb = new window.Blob();n } catch (e) {n var BlobBuilder = (n window.BlobBuilder ||n window.WebKitBlobBuilder ||n window.MozBlobBuilder ||n window.MSBlobBuildern );n if (e.name === 'TypeError' && BlobBuilder) {n var bb = new BlobBuilder();n bb.append(request.response);n blb = bb.getBlob();n }n }n // If the blob is empty for some reason consider the image load a failure.n if (blb.size === 0) {n self.errorMsg = "Empty image response.";n self.finish(false);n }n // Create a URL for the blob data and make it the source of the image object.n // This will still trigger Image.onload to indicate a successful tile load.n var url = (window.URL || window.webkitURL).createObjectURL(blb);n self.image.src = url;n },n error: function(request) {n self.errorMsg = "Image load aborted - XHR error";n self.finish(false);n }n });nn // Provide a function to properly abort the request.n this.abort = function() {n self.request.abort();nn // Call the existing abort function if availablen if (typeof selfAbort === "function") {n selfAbort();n }n };n } else {n if (this.crossOriginPolicy !== false) {n this.image.crossOrigin = this.crossOriginPolicy;n }nn this.image.src = this.src;n }n },nn finish: function(successful) {n this.image.onload = this.image.onerror = this.image.onabort = null;n if (!successful) {n this.image = null;n }nn if (this.jobId) {n window.clearTimeout(this.jobId);n }nn this.callback(this);n }nn};nn/**n * @class ImageLoadern * @memberof OpenSeadragonn * @classdesc Handles downloading of a set of images using asynchronous queue pattern.n * You generally won't have to interact with the ImageLoader directly.n * @param {Object} options - Options for this ImageLoader.n * @param {Number} [options.jobLimit] - The number of concurrent image requests. See imageLoaderLimit in {@link OpenSeadragon.Options} for details.n * @param {Number} [options.timeout] - The max number of milliseconds that an image job may take to complete.n */n$.ImageLoader = function(options) {nn $.extend(true, this, {n jobLimit: $.DEFAULT_SETTINGS.imageLoaderLimit,n timeout: $.DEFAULT_SETTINGS.timeout,n jobQueue: [],n jobsInProgress: 0n }, options);nn};nn/** @lends OpenSeadragon.ImageLoader.prototype */n$.ImageLoader.prototype = {nn /**n * Add an unloaded image to the loader queue.n * @methodn * @param {Object} options - Options for this job.n * @param {String} [options.src] - URL of image to download.n * @param {String} [options.loadWithAjax] - Whether to load this image with AJAX.n * @param {String} [options.ajaxHeaders] - Headers to add to the image request if using AJAX.n * @param {String|Boolean} [options.crossOriginPolicy] - CORS policy to use for downloadsn * @param {Boolean} [options.ajaxWithCredentials] - Whether to set withCredentials on AJAXn * requests.n * @param {Function} [options.callback] - Called once image has been downloaded.n * @param {Function} [options.abort] - Called when this image job is aborted.n */n addJob: function(options) {n var _this = this,n complete = function(job) {n completeJob(_this, job, options.callback);n },n jobOptions = {n src: options.src,n loadWithAjax: options.loadWithAjax,n ajaxHeaders: options.loadWithAjax ? options.ajaxHeaders : null,n crossOriginPolicy: options.crossOriginPolicy,n ajaxWithCredentials: options.ajaxWithCredentials,n callback: complete,n abort: options.abort,n timeout: this.timeoutn },n newJob = new ImageJob(jobOptions);nn if ( !this.jobLimit || this.jobsInProgress < this.jobLimit ) {n newJob.start();n this.jobsInProgress++;n }n else {n this.jobQueue.push( newJob );n }n },nn /**n * Clear any unstarted image loading jobs from the queue.n * @methodn */n clear: function() {n for( var i = 0; i < this.jobQueue.length; i++ ) {n var job = this.jobQueue;n if ( typeof job.abort === "function" ) {n job.abort();n }n }nn this.jobQueue = [];n }n};nn/**n * Cleans up ImageJob once completed.n * @methodn * @privaten * @param loader - ImageLoader used to start job.n * @param job - The ImageJob that has completed.n * @param callback - Called once cleanup is finished.n */nfunction completeJob(loader, job, callback) {n var nextJob;nn loader.jobsInProgress–;nn if ((!loader.jobLimit || loader.jobsInProgress < loader.jobLimit) && loader.jobQueue.length > 0) {n nextJob = loader.jobQueue.shift();n nextJob.start();n loader.jobsInProgress++;n }nn callback(job.image, job.errorMsg, job.request);n}nn}(OpenSeadragon));n”,“/*n * OpenSeadragon - Tilen *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * @class Tilen * @memberof OpenSeadragonn * @param {Number} level The zoom level this tile belongs to.n * @param {Number} x The vector component 'x'.n * @param {Number} y The vector component 'y'.n * @param {OpenSeadragon.Rect} bounds Where this tile fits, in normalizedn * coordinates.n * @param {Boolean} exists Is this tile a part of a sparse image? ( Also hasn * this tile failed to load? )n * @param {String} url The URL of this tile's image.n * @param {CanvasRenderingContext2D} context2D The context2D of this tile if itn * is provided directly by the tile source.n * @param {Boolean} loadWithAjax Whether this tile image should be loaded with an AJAX request .n * @param {Object} ajaxHeaders The headers to send with this tile's AJAX request (if applicable).n * @param {OpenSeadragon.Rect} sourceBounds The portion of the tile to use as the source of then * drawing operation, in pixels. Note that this only works when drawing with canvas; when drawingn * with HTML the entire tile is always used.n */n$.Tile = function(level, x, y, bounds, exists, url, context2D, loadWithAjax, ajaxHeaders, sourceBounds) {n /**n * The zoom level this tile belongs to.n * @member {Number} leveln * @memberof OpenSeadragon.Tile#n */n this.level = level;n /**n * The vector component 'x'.n * @member {Number} xn * @memberof OpenSeadragon.Tile#n */n this.x = x;n /**n * The vector component 'y'.n * @member {Number} yn * @memberof OpenSeadragon.Tile#n */n this.y = y;n /**n * Where this tile fits, in normalized coordinatesn * @member {OpenSeadragon.Rect} boundsn * @memberof OpenSeadragon.Tile#n */n this.bounds = bounds;n /**n * The portion of the tile to use as the source of the drawing operation, in pixels. Note thatn * this only works when drawing with canvas; when drawing with HTML the entire tile is always used.n * @member {OpenSeadragon.Rect} sourceBoundsn * @memberof OpenSeadragon.Tile#n */n this.sourceBounds = sourceBounds;n /**n * Is this tile a part of a sparse image? Also has this tile failed to load?n * @member {Boolean} existsn * @memberof OpenSeadragon.Tile#n */n this.exists = exists;n /**n * The URL of this tile's image.n * @member {String} urln * @memberof OpenSeadragon.Tile#n */n this.url = url;n /**n * The context2D of this tile if it is provided directly by the tile source.n * @member {CanvasRenderingContext2D} context2Dn * @memberOf OpenSeadragon.Tile#n */n this.context2D = context2D;n /**n * Whether to load this tile's image with an AJAX request.n * @member {Boolean} loadWithAjaxn * @memberof OpenSeadragon.Tile#n */n this.loadWithAjax = loadWithAjax;n /**n * The headers to be used in requesting this tile's image.n * Only used if loadWithAjax is set to true.n * @member {Object} ajaxHeadersn * @memberof OpenSeadragon.Tile#n */n this.ajaxHeaders = ajaxHeaders;n /**n * The unique cache key for this tile.n * @member {String} cacheKeyn * @memberof OpenSeadragon.Tile#n */n if (this.ajaxHeaders) {n this.cacheKey = this.url + "+" + JSON.stringify(this.ajaxHeaders);n } else {n this.cacheKey = this.url;n }n /**n * Is this tile loaded?n * @member {Boolean} loadedn * @memberof OpenSeadragon.Tile#n */n this.loaded = false;n /**n * Is this tile loading?n * @member {Boolean} loadingn * @memberof OpenSeadragon.Tile#n */n this.loading = false;nn /**n * The HTML div element for this tilen * @member {Element} elementn * @memberof OpenSeadragon.Tile#n */n this.element = null;n /**n * The HTML img element for this tile.n * @member {Element} imgElementn * @memberof OpenSeadragon.Tile#n */n this.imgElement = null;n /**n * The Image object for this tile.n * @member {Object} imagen * @memberof OpenSeadragon.Tile#n */n this.image = null;nn /**n * The alias of this.element.style.n * @member {String} stylen * @memberof OpenSeadragon.Tile#n */n this.style = null;n /**n * This tile's position on screen, in pixels.n * @member {OpenSeadragon.Point} positionn * @memberof OpenSeadragon.Tile#n */n this.position = null;n /**n * This tile's size on screen, in pixels.n * @member {OpenSeadragon.Point} sizen * @memberof OpenSeadragon.Tile#n */n this.size = null;n /**n * The start time of this tile's blending.n * @member {Number} blendStartn * @memberof OpenSeadragon.Tile#n */n this.blendStart = null;n /**n * The current opacity this tile should be.n * @member {Number} opacityn * @memberof OpenSeadragon.Tile#n */n this.opacity = null;n /**n * The squared distance of this tile to the viewport center.n * Use for comparing tiles.n * @privaten * @member {Number} squaredDistancen * @memberof OpenSeadragon.Tile#n */n this.squaredDistance = null;n /**n * The visibility score of this tile.n * @member {Number} visibilityn * @memberof OpenSeadragon.Tile#n */n this.visibility = null;nn /**n * Whether this tile is currently being drawn.n * @member {Boolean} beingDrawnn * @memberof OpenSeadragon.Tile#n */n this.beingDrawn = false;nn /**n * Timestamp the tile was last touched.n * @member {Number} lastTouchTimen * @memberof OpenSeadragon.Tile#n */n this.lastTouchTime = 0;nn /**n * Whether this tile is in the right-most column for its level.n * @member {Boolean} isRightMostn * @memberof OpenSeadragon.Tile#n */n this.isRightMost = false;nn /**n * Whether this tile is in the bottom-most row for its level.n * @member {Boolean} isBottomMostn * @memberof OpenSeadragon.Tile#n */n this.isBottomMost = false;n};nn/** @lends OpenSeadragon.Tile.prototype */n$.Tile.prototype = {nn /**n * Provides a string representation of this tiles level and (x,y)n * components.n * @functionn * @returns {String}n */n toString: function() {n return this.level + "/" + this.x + "_" + this.y;n },nn // privaten _hasTransparencyChannel: function() {n return !!this.context2D || this.url.match('.png');n },nn /**n * Renders the tile in an html container.n * @functionn * @param {Element} containern */n drawHTML: function( container ) {n if (!this.cacheImageRecord) {n $.console.warn(n '[Tile.drawHTML] attempting to draw tile %s when it\'s not cached',n this.toString());n return;n }nn if ( !this.loaded ) {n $.console.warn(n "Attempting to draw tile %s when it's not yet loaded.",n this.toString()n );n return;n }nn //EXPERIMENTAL - trying to figure out how to scale the containern // content during animation of the container size.nn if ( !this.element ) {n this.element = $.makeNeutralElement( "div" );n this.imgElement = this.cacheImageRecord.getImage().cloneNode();n this.imgElement.style.msInterpolationMode = "nearest-neighbor";n this.imgElement.style.width = "100%";n this.imgElement.style.height = "100%";nn this.style = this.element.style;n this.style.position = "absolute";n }n if ( this.element.parentNode != container ) {n container.appendChild( this.element );n }n if ( this.imgElement.parentNode != this.element ) {n this.element.appendChild( this.imgElement );n }nn this.style.top = this.position.y + "px";n this.style.left = this.position.x + "px";n this.style.height = this.size.y + "px";n this.style.width = this.size.x + "px";nn $.setElementOpacity( this.element, this.opacity );n },nn /**n * Renders the tile in a canvas-based context.n * @functionn * @param {Canvas} contextn * @param {Function} drawingHandler - Method for firing the drawing event.n * drawingHandler({context, tile, rendered})n * where rendered is the context with the pre-drawn image.n * @param {Number} [scale=1] - Apply a scale to position and sizen * @param {OpenSeadragon.Point} [translate] - A translation vectorn */n drawCanvas: function( context, drawingHandler, scale, translate ) {nn var position = this.position.times($.pixelDensityRatio),n size = this.size.times($.pixelDensityRatio),n rendered;nn if (!this.context2D && !this.cacheImageRecord) {n $.console.warn(n '[Tile.drawCanvas] attempting to draw tile %s when it\'s not cached',n this.toString());n return;n }nn rendered = this.context2D || this.cacheImageRecord.getRenderedContext();nn if ( !this.loaded || !rendered ){n $.console.warn(n "Attempting to draw tile %s when it's not yet loaded.",n this.toString()n );nn return;n }nn context.save();nn context.globalAlpha = this.opacity;nn if (typeof scale === 'number' && scale !== 1) {n // draw tile at a different scalen position = position.times(scale);n size = size.times(scale);n }nn if (translate instanceof $.Point) {n // shift tile position slightlyn position = position.plus(translate);n }nn //if we are supposed to be rendering fully opaque rectangle,n //ie its done fading or fading is turned off, and if we are drawingn //an image with an alpha channel, then the only wayn //to avoid seeing the tile underneath is to clear the rectanglen if (context.globalAlpha === 1 && this._hasTransparencyChannel()) {n //clearing only the inside of the rectangle occupiedn //by the png prevents edge flikeringn context.clearRect(n position.x,n position.y,n size.x,n size.yn );n }nn // This gives the application a chance to make image manipulationn // changes as we are rendering the imagen drawingHandler({context: context, tile: this, rendered: rendered});nn var sourceWidth, sourceHeight;n if (this.sourceBounds) {n sourceWidth = Math.min(this.sourceBounds.width, rendered.canvas.width);n sourceHeight = Math.min(this.sourceBounds.height, rendered.canvas.height);n } else {n sourceWidth = rendered.canvas.width;n sourceHeight = rendered.canvas.height;n }nn context.drawImage(n rendered.canvas,n 0,n 0,n sourceWidth,n sourceHeight,n position.x,n position.y,n size.x,n size.yn );nn context.restore();n },nn /**n * Get the ratio between current and original size.n * @functionn * @return {Float}n */n getScaleForEdgeSmoothing: function() {n var context;n if (this.cacheImageRecord) {n context = this.cacheImageRecord.getRenderedContext();n } else if (this.context2D) {n context = this.context2D;n } else {n $.console.warn(n '[Tile.drawCanvas] attempting to get tile scale %s when tile\'s not cached',n this.toString());n return 1;n }n return context.canvas.width / (this.size.x * $.pixelDensityRatio);n },nn /**n * Get a translation vector that when applied to the tile position produces integer coordinates.n * Needed to avoid swimming and twitching.n * @functionn * @param {Number} [scale=1] - Scale to be applied to position.n * @return {OpenSeadragon.Point}n */n getTranslationForEdgeSmoothing: function(scale, canvasSize, sketchCanvasSize) {n // The translation vector must have positive values, otherwise the image goes a bit offn // the sketch canvas to the top and left and we must use negative coordinates to repaint itn // to the main canvas. In that case, some browsers throw:n // INDEX_SIZE_ERR: DOM Exception 1: Index or size was negative, or greater than the allowed value.n var x = Math.max(1, Math.ceil((sketchCanvasSize.x - canvasSize.x) / 2));n var y = Math.max(1, Math.ceil((sketchCanvasSize.y - canvasSize.y) / 2));n return new $.Point(x, y).minus(n this.positionn .times($.pixelDensityRatio)n .times(scale || 1)n .apply(function(x) {n return x % 1;n })n );n },nn /**n * Removes tile from its container.n * @functionn */n unload: function() {n if ( this.imgElement && this.imgElement.parentNode ) {n this.imgElement.parentNode.removeChild( this.imgElement );n }n if ( this.element && this.element.parentNode ) {n this.element.parentNode.removeChild( this.element );n }nn this.element = null;n this.imgElement = null;n this.loaded = false;n this.loading = false;n }n};nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - Overlayn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function($) {nn /**n * An enumeration of positions that an overlay may be assigned relative ton * the viewport.n * It is identical to OpenSeadragon.Placement but is kept for backwardn * compatibility.n * @member OverlayPlacementn * @memberof OpenSeadragonn * @see OpenSeadragon.Placementn * @staticn * @readonlyn * @type {Object}n * @property {Number} CENTERn * @property {Number} TOP_LEFTn * @property {Number} TOPn * @property {Number} TOP_RIGHTn * @property {Number} RIGHTn * @property {Number} BOTTOM_RIGHTn * @property {Number} BOTTOMn * @property {Number} BOTTOM_LEFTn * @property {Number} LEFTn */n $.OverlayPlacement = $.Placement;nn /**n * An enumeration of possible ways to handle overlays rotationn * @member OverlayRotationModen * @memberOf OpenSeadragonn * @staticn * @readonlyn * @property {Number} NO_ROTATION The overlay ignore the viewport rotation.n * @property {Number} EXACT The overlay use CSS 3 transforms to rotate withn * the viewport. If the overlay contains text, it will get rotated as well.n * @property {Number} BOUNDING_BOX The overlay adjusts for rotation byn * taking the size of the bounding box of the rotated bounds.n * Only valid for overlays with Rect location and scalable in both directions.n */n $.OverlayRotationMode = $.freezeObject({n NO_ROTATION: 1,n EXACT: 2,n BOUNDING_BOX: 3n });nn /**n * @class Overlayn * @classdesc Provides a way to float an HTML element on top of the viewer element.n *n * @memberof OpenSeadragonn * @param {Object} optionsn * @param {Element} options.elementn * @param {OpenSeadragon.Point|OpenSeadragon.Rect} options.location - Then * location of the overlay on the image. If a {@link OpenSeadragon.Point}n * is specified, the overlay will be located at this location with respectn * to the placement option. If a {@link OpenSeadragon.Rect} is specified,n * the overlay will be placed at this location with the corresponding widthn * and height and placement TOP_LEFT.n * @param {OpenSeadragon.Placement} [options.placement=OpenSeadragon.Placement.TOP_LEFT]n * Defines what part of the overlay should be at the specified options.locationn * @param {OpenSeadragon.Overlay.OnDrawCallback} [options.onDraw]n * @param {Boolean} [options.checkResize=true] Set to false to avoid ton * check the size of the overlay everytime it is drawn in the directionsn * which are not scaled. It will improve performances but will cause an * misalignment if the overlay size changes.n * @param {Number} [options.width] The width of the overlay in viewportn * coordinates. If specified, the width of the overlay will be adjusted whenn * the zoom changes.n * @param {Number} [options.height] The height of the overlay in viewportn * coordinates. If specified, the height of the overlay will be adjusted whenn * the zoom changes.n * @param {Boolean} [options.rotationMode=OpenSeadragon.OverlayRotationMode.EXACT]n * How to handle the rotation of the viewport.n */n $.Overlay = function(element, location, placement) {nn /**n * onDraw callback signature used by {@link OpenSeadragon.Overlay}.n *n * @callback OnDrawCallbackn * @memberof OpenSeadragon.Overlayn * @param {OpenSeadragon.Point} positionn * @param {OpenSeadragon.Point} sizen * @param {Element} elementn */nn var options;n if ($.isPlainObject(element)) {n options = element;n } else {n options = {n element: element,n location: location,n placement: placementn };n }nn this.element = options.element;n this.style = options.element.style;n this._init(options);n };nn /** @lends OpenSeadragon.Overlay.prototype */n $.Overlay.prototype = {nn // privaten _init: function(options) {n this.location = options.location;n this.placement = options.placement === undefined ?n $.Placement.TOP_LEFT : options.placement;n this.onDraw = options.onDraw;n this.checkResize = options.checkResize === undefined ?n true : options.checkResize;nn // When this.width is not null, the overlay get scaled horizontallyn this.width = options.width === undefined ? null : options.width;nn // When this.height is not null, the overlay get scaled verticallyn this.height = options.height === undefined ? null : options.height;nn this.rotationMode = options.rotationMode || $.OverlayRotationMode.EXACT;nn // Having a rect as location is a syntactic sugarn if (this.location instanceof $.Rect) {n this.width = this.location.width;n this.height = this.location.height;n this.location = this.location.getTopLeft();n this.placement = $.Placement.TOP_LEFT;n }nn // Deprecated properties kept for backward compatibility.n this.scales = this.width !== null && this.height !== null;n this.bounds = new $.Rect(n this.location.x, this.location.y, this.width, this.height);n this.position = this.location;n },nn /**n * Internal function to adjust the position of an overlayn * depending on it size and placement.n * @functionn * @param {OpenSeadragon.Point} positionn * @param {OpenSeadragon.Point} sizen */n adjust: function(position, size) {n var properties = $.Placement.properties;n if (!properties) {n return;n }n if (properties.isHorizontallyCentered) {n position.x -= size.x / 2;n } else if (properties.isRight) {n position.x -= size.x;n }n if (properties.isVerticallyCentered) {n position.y -= size.y / 2;n } else if (properties.isBottom) {n position.y -= size.y;n }n },nn /**n * @functionn */n destroy: function() {n var element = this.element;n var style = this.style;nn if (element.parentNode) {n element.parentNode.removeChild(element);n //this should allow us to preserve overlays when required betweenn //pagesn if (element.prevElementParent) {n style.display = 'none';n //element.prevElementParent.insertBefore(n // element,n // element.prevNextSiblingn //);n document.body.appendChild(element);n }n }nn // clear the onDraw callbackn this.onDraw = null;nn style.top = "";n style.left = "";n style.position = "";nn if (this.width !== null) {n style.width = "";n }n if (this.height !== null) {n style.height = "";n }n var transformOriginProp = $.getCssPropertyWithVendorPrefix(n 'transformOrigin');n var transformProp = $.getCssPropertyWithVendorPrefix(n 'transform');n if (transformOriginProp && transformProp) {n style = "";n style = "";n }n },nn /**n * @functionn * @param {Element} containern */n drawHTML: function(container, viewport) {n var element = this.element;n if (element.parentNode !== container) {n //save the source parent for later if we need itn element.prevElementParent = element.parentNode;n element.prevNextSibling = element.nextSibling;n container.appendChild(element);nn // have to set position before calculating size, fix #1116n this.style.position = "absolute";n // this.size is used by overlays which don't get scaled in atn // least one direction when this.checkResize is set to false.n this.size = $.getElementSize(element);n }nn var positionAndSize = this._getOverlayPositionAndSize(viewport);nn var position = positionAndSize.position;n var size = this.size = positionAndSize.size;n var rotate = positionAndSize.rotate;nn // call the onDraw callback if it exists to allow one to overwriten // the drawing/positioning/sizing of the overlayn if (this.onDraw) {n this.onDraw(position, size, this.element);n } else {n var style = this.style;n style.left = position.x + "px";n style.top = position.y + "px";n if (this.width !== null) {n style.width = size.x + "px";n }n if (this.height !== null) {n style.height = size.y + "px";n }n var transformOriginProp = $.getCssPropertyWithVendorPrefix(n 'transformOrigin');n var transformProp = $.getCssPropertyWithVendorPrefix(n 'transform');n if (transformOriginProp && transformProp) {n if (rotate) {n style = this._getTransformOrigin();n style = "rotate(" + rotate + "deg)";n } else {n style = "";n style = "";n }n }nn if (style.display !== 'none') {n style.display = 'block';n }n }n },nn // privaten _getOverlayPositionAndSize: function(viewport) {n var position = viewport.pixelFromPoint(this.location, true);n var size = this._getSizeInPixels(viewport);n this.adjust(position, size);nn var rotate = 0;n if (viewport.degrees &&n this.rotationMode !== $.OverlayRotationMode.NO_ROTATION) {n // BOUNDING_BOX is only valid if both directions get scaled.n // Get replaced by EXACT otherwise.n if (this.rotationMode === $.OverlayRotationMode.BOUNDING_BOX &&n this.width !== null && this.height !== null) {n var rect = new $.Rect(position.x, position.y, size.x, size.y);n var boundingBox = this._getBoundingBox(rect, viewport.degrees);n position = boundingBox.getTopLeft();n size = boundingBox.getSize();n } else {n rotate = viewport.degrees;n }n }nn return {n position: position,n size: size,n rotate: rotaten };n },nn // privaten _getSizeInPixels: function(viewport) {n var width = this.size.x;n var height = this.size.y;n if (this.width !== null || this.height !== null) {n var scaledSize = viewport.deltaPixelsFromPointsNoRotate(n new $.Point(this.width || 0, this.height || 0), true);n if (this.width !== null) {n width = scaledSize.x;n }n if (this.height !== null) {n height = scaledSize.y;n }n }n if (this.checkResize &&n (this.width === null || this.height === null)) {n var eltSize = this.size = $.getElementSize(this.element);n if (this.width === null) {n width = eltSize.x;n }n if (this.height === null) {n height = eltSize.y;n }n }n return new $.Point(width, height);n },nn // privaten _getBoundingBox: function(rect, degrees) {n var refPoint = this._getPlacementPoint(rect);n return rect.rotate(degrees, refPoint).getBoundingBox();n },nn // privaten _getPlacementPoint: function(rect) {n var result = new $.Point(rect.x, rect.y);n var properties = $.Placement.properties;n if (properties) {n if (properties.isHorizontallyCentered) {n result.x += rect.width / 2;n } else if (properties.isRight) {n result.x += rect.width;n }n if (properties.isVerticallyCentered) {n result.y += rect.height / 2;n } else if (properties.isBottom) {n result.y += rect.height;n }n }n return result;n },nn // privaten _getTransformOrigin: function() {n var result = "";n var properties = $.Placement.properties;n if (!properties) {n return result;n }n if (properties.isLeft) {n result = "left";n } else if (properties.isRight) {n result = "right";n }n if (properties.isTop) {n result += " top";n } else if (properties.isBottom) {n result += " bottom";n }n return result;n },nn /**n * Changes the overlay settings.n * @functionn * @param {OpenSeadragon.Point|OpenSeadragon.Rect|Object} locationn * If an object is specified, the options are the same than the constructorn * except for the element which can not be changed.n * @param {OpenSeadragon.Placement} placementn */n update: function(location, placement) {n var options = $.isPlainObject(location) ? location : {n location: location,n placement: placementn };n this._init({n location: options.location || this.location,n placement: options.placement !== undefined ?n options.placement : this.placement,n onDraw: options.onDraw || this.onDraw,n checkResize: options.checkResize || this.checkResize,n width: options.width !== undefined ? options.width : this.width,n height: options.height !== undefined ? options.height : this.height,n rotationMode: options.rotationMode || this.rotationModen });n },nn /**n * Returns the current bounds of the overlay in viewport coordinatesn * @functionn * @param {OpenSeadragon.Viewport} viewport the viewportn * @returns {OpenSeadragon.Rect} overlay boundsn */n getBounds: function(viewport) {n $.console.assert(viewport,n 'A viewport must now be passed to Overlay.getBounds.');n var width = this.width;n var height = this.height;n if (width === null || height === null) {n var size = viewport.deltaPointsFromPixelsNoRotate(this.size, true);n if (width === null) {n width = size.x;n }n if (height === null) {n height = size.y;n }n }n var location = this.location.clone();n this.adjust(location, new $.Point(width, height));n return this._adjustBoundsForRotation(n viewport, new $.Rect(location.x, location.y, width, height));n },nn // privaten _adjustBoundsForRotation: function(viewport, bounds) {n if (!viewport ||n viewport.degrees === 0 ||n this.rotationMode === $.OverlayRotationMode.EXACT) {n return bounds;n }n if (this.rotationMode === $.OverlayRotationMode.BOUNDING_BOX) {n // If overlay not fully scalable, BOUNDING_BOX falls back to EXACTn if (this.width === null || this.height === null) {n return bounds;n }n // It is easier to just compute the position and size andn // convert to viewport coordinates.n var positionAndSize = this._getOverlayPositionAndSize(viewport);n return viewport.viewerElementToViewportRectangle(new $.Rect(n positionAndSize.position.x,n positionAndSize.position.y,n positionAndSize.size.x,n positionAndSize.size.y));n }nn // NO_ROTATION casen return bounds.rotate(-viewport.degrees,n this._getPlacementPoint(bounds));n }n };nn}(OpenSeadragon));n”,“/*n * OpenSeadragon - Drawern *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * @class Drawern * @memberof OpenSeadragonn * @classdesc Handles rendering of tiles for an {@link OpenSeadragon.Viewer}.n * @param {Object} options - Options for this Drawer.n * @param {OpenSeadragon.Viewer} options.viewer - The Viewer that owns this Drawer.n * @param {OpenSeadragon.Viewport} options.viewport - Reference to Viewer viewport.n * @param {Element} options.element - Parent element.n * @param {Number} [options.debugGridColor] - See debugGridColor in {@link OpenSeadragon.Options} for details.n */n$.Drawer = function( options ) {nn $.console.assert( options.viewer, "[Drawer] options.viewer is required" );nn //backward compatibility for positional args while prefering moren //idiomatic javascript options object as the only argumentn var args = arguments;nn if( !$.isPlainObject( options ) ){n options = {n source: args[ 0 ], // Reference to Viewer tile source.n viewport: args[ 1 ], // Reference to Viewer viewport.n element: args[ 2 ] // Parent element.n };n }nn $.console.assert( options.viewport, "[Drawer] options.viewport is required" );n $.console.assert( options.element, "[Drawer] options.element is required" );nn if ( options.source ) {n $.console.error( "[Drawer] options.source is no longer accepted; use TiledImage instead" );n }nn this.viewer = options.viewer;n this.viewport = options.viewport;n this.debugGridColor = typeof options.debugGridColor === 'string' ? [options.debugGridColor] : options.debugGridColor || $.DEFAULT_SETTINGS.debugGridColor;n if (options.opacity) {n $.console.error( "[Drawer] options.opacity is no longer accepted; set the opacity on the TiledImage instead" );n }nn this.useCanvas = $.supportsCanvas && ( this.viewer ? this.viewer.useCanvas : true );n /**n * The parent element of this Drawer instance, passed in when the Drawer was created.n * The parent of {@link OpenSeadragon.Drawer#canvas}.n * @member {Element} containern * @memberof OpenSeadragon.Drawer#n */n this.container = $.getElement( options.element );n /**n * A &lt;canvas&gt; element if the browser supports them, otherwise a &lt;div&gt; element.n * Child element of {@link OpenSeadragon.Drawer#container}.n * @member {Element} canvasn * @memberof OpenSeadragon.Drawer#n */n this.canvas = $.makeNeutralElement( this.useCanvas ? "canvas" : "div" );n /**n * 2d drawing context for {@link OpenSeadragon.Drawer#canvas} if it's a &lt;canvas&gt; element, otherwise null.n * @member {Object} contextn * @memberof OpenSeadragon.Drawer#n */n this.context = this.useCanvas ? this.canvas.getContext( "2d" ) : null;nn /**n * Sketch canvas used to temporarily draw tiles which cannot be drawn directlyn * to the main canvas due to opacity. Lazily initialized.n */n this.sketchCanvas = null;n this.sketchContext = null;nn /**n * @member {Element} elementn * @memberof OpenSeadragon.Drawer#n * @deprecated Alias for {@link OpenSeadragon.Drawer#container}.n */n this.element = this.container;nn // We force our container to ltr because our drawing math doesn't work in rtl.n // This issue only affects our canvas renderer, but we do it always for consistency.n // Note that this means overlays you want to be rtl need to be explicitly set to rtl.n this.container.dir = 'ltr';nn // check canvas available width and height, set canvas width and height such that the canvas backing store is set to the proper pixel densityn if (this.useCanvas) {n var viewportSize = this._calculateCanvasSize();n this.canvas.width = viewportSize.x;n this.canvas.height = viewportSize.y;n }nn this.canvas.style.width = "100%";n this.canvas.style.height = "100%";n this.canvas.style.position = "absolute";n $.setElementOpacity( this.canvas, this.opacity, true );nn // explicit left-alignn this.container.style.textAlign = "left";n this.container.appendChild( this.canvas );n};nn/** @lends OpenSeadragon.Drawer.prototype */n$.Drawer.prototype = {n // deprecatedn addOverlay: function( element, location, placement, onDraw ) {n $.console.error("drawer.addOverlay is deprecated. Use viewer.addOverlay instead.");n this.viewer.addOverlay( element, location, placement, onDraw );n return this;n },nn // deprecatedn updateOverlay: function( element, location, placement ) {n $.console.error("drawer.updateOverlay is deprecated. Use viewer.updateOverlay instead.");n this.viewer.updateOverlay( element, location, placement );n return this;n },nn // deprecatedn removeOverlay: function( element ) {n $.console.error("drawer.removeOverlay is deprecated. Use viewer.removeOverlay instead.");n this.viewer.removeOverlay( element );n return this;n },nn // deprecatedn clearOverlays: function() {n $.console.error("drawer.clearOverlays is deprecated. Use viewer.clearOverlays instead.");n this.viewer.clearOverlays();n return this;n },nn /**n * Set the opacity of the drawer.n * @param {Number} opacityn * @return {OpenSeadragon.Drawer} Chainable.n */n setOpacity: function( opacity ) {n $.console.error("drawer.setOpacity is deprecated. Use tiledImage.setOpacity instead.");n var world = this.viewer.world;n for (var i = 0; i < world.getItemCount(); i++) {n world.getItemAt( i ).setOpacity( opacity );n }n return this;n },nn /**n * Get the opacity of the drawer.n * @returns {Number}n */n getOpacity: function() {n $.console.error("drawer.getOpacity is deprecated. Use tiledImage.getOpacity instead.");n var world = this.viewer.world;n var maxOpacity = 0;n for (var i = 0; i < world.getItemCount(); i++) {n var opacity = world.getItemAt( i ).getOpacity();n if ( opacity > maxOpacity ) {n maxOpacity = opacity;n }n }n return maxOpacity;n },nn // deprecatedn needsUpdate: function() {n $.console.error( "[Drawer.needsUpdate] this function is deprecated. Use World.needsDraw instead." );n return this.viewer.world.needsDraw();n },nn // deprecatedn numTilesLoaded: function() {n $.console.error( "[Drawer.numTilesLoaded] this function is deprecated. Use TileCache.numTilesLoaded instead." );n return this.viewer.tileCache.numTilesLoaded();n },nn // deprecatedn reset: function() {n $.console.error( "[Drawer.reset] this function is deprecated. Use World.resetItems instead." );n this.viewer.world.resetItems();n return this;n },nn // deprecatedn update: function() {n $.console.error( "[Drawer.update] this function is deprecated. Use Drawer.clear and World.draw instead." );n this.clear();n this.viewer.world.draw();n return this;n },nn /**n * @return {Boolean} True if rotation is supported.n */n canRotate: function() {n return this.useCanvas;n },nn /**n * Destroy the drawer (unload current loaded tiles)n */n destroy: function() {n //force unloading of current canvas (1x1 will be gc later, trick not necessarily needed)n this.canvas.width = 1;n this.canvas.height = 1;n this.sketchCanvas = null;n this.sketchContext = null;n },nn /**n * Clears the Drawer so it's ready to draw another frame.n */n clear: function() {n this.canvas.innerHTML = "";n if ( this.useCanvas ) {n var viewportSize = this._calculateCanvasSize();n if( this.canvas.width != viewportSize.x ||n this.canvas.height != viewportSize.y ) {n this.canvas.width = viewportSize.x;n this.canvas.height = viewportSize.y;n if ( this.sketchCanvas !== null ) {n var sketchCanvasSize = this._calculateSketchCanvasSize();n this.sketchCanvas.width = sketchCanvasSize.x;n this.sketchCanvas.height = sketchCanvasSize.y;n }n }n this._clear();n }n },nn _clear: function (useSketch, bounds) {n if (!this.useCanvas) {n return;n }n var context = this._getContext(useSketch);n if (bounds) {n context.clearRect(bounds.x, bounds.y, bounds.width, bounds.height);n } else {n var canvas = context.canvas;n context.clearRect(0, 0, canvas.width, canvas.height);n }n },nn /**n * Scale from OpenSeadragon viewer rectangle to drawer rectanglen * (ignoring rotation)n * @param {OpenSeadragon.Rect} rectangle - The rectangle in viewport coordinate system.n * @return {OpenSeadragon.Rect} Rectangle in drawer coordinate system.n */n viewportToDrawerRectangle: function(rectangle) {n var topLeft = this.viewport.pixelFromPointNoRotate(rectangle.getTopLeft(), true);n var size = this.viewport.deltaPixelsFromPointsNoRotate(rectangle.getSize(), true);nn return new $.Rect(n topLeft.x * $.pixelDensityRatio,n topLeft.y * $.pixelDensityRatio,n size.x * $.pixelDensityRatio,n size.y * $.pixelDensityRation );n },nn /**n * Draws the given tile.n * @param {OpenSeadragon.Tile} tile - The tile to draw.n * @param {Function} drawingHandler - Method for firing the drawing event if using canvas.n * drawingHandler({context, tile, rendered})n * @param {Boolean} useSketch - Whether to use the sketch canvas or not.n * where rendered is the context with the pre-drawn image.n * @param {Float} [scale=1] - Apply a scale to tile position and size. Defaults to 1.n * @param {OpenSeadragon.Point} [translate] A translation vector to offset tile positionn */n drawTile: function(tile, drawingHandler, useSketch, scale, translate) {n $.console.assert(tile, '[Drawer.drawTile] tile is required');n $.console.assert(drawingHandler, '[Drawer.drawTile] drawingHandler is required');nn if (this.useCanvas) {n var context = this._getContext(useSketch);n scale = scale || 1;n tile.drawCanvas(context, drawingHandler, scale, translate);n } else {n tile.drawHTML( this.canvas );n }n },nn _getContext: function( useSketch ) {n var context = this.context;n if ( useSketch ) {n if (this.sketchCanvas === null) {n this.sketchCanvas = document.createElement( "canvas" );n var sketchCanvasSize = this._calculateSketchCanvasSize();n this.sketchCanvas.width = sketchCanvasSize.x;n this.sketchCanvas.height = sketchCanvasSize.y;n this.sketchContext = this.sketchCanvas.getContext( "2d" );nn // If the viewport is not currently rotated, the sketchCanvasn // will have the same size as the main canvas. However, ifn // the viewport get rotated later on, we will need to resize it.n if (this.viewport.getRotation() === 0) {n var self = this;n this.viewer.addHandler('rotate', function resizeSketchCanvas() {n if (self.viewport.getRotation() === 0) {n return;n }n self.viewer.removeHandler('rotate', resizeSketchCanvas);n var sketchCanvasSize = self._calculateSketchCanvasSize();n self.sketchCanvas.width = sketchCanvasSize.x;n self.sketchCanvas.height = sketchCanvasSize.y;n });n }n }n context = this.sketchContext;n }n return context;n },nn // privaten saveContext: function( useSketch ) {n if (!this.useCanvas) {n return;n }nn this._getContext( useSketch ).save();n },nn // privaten restoreContext: function( useSketch ) {n if (!this.useCanvas) {n return;n }nn this._getContext( useSketch ).restore();n },nn // privaten setClip: function(rect, useSketch) {n if (!this.useCanvas) {n return;n }nn var context = this._getContext( useSketch );n context.beginPath();n context.rect(rect.x, rect.y, rect.width, rect.height);n context.clip();n },nn // privaten drawRectangle: function(rect, fillStyle, useSketch) {n if (!this.useCanvas) {n return;n }nn var context = this._getContext( useSketch );n context.save();n context.fillStyle = fillStyle;n context.fillRect(rect.x, rect.y, rect.width, rect.height);n context.restore();n },nn /**n * Blends the sketch canvas in the main canvas.n * @param {Object} options The optionsn * @param {Float} options.opacity The opacity of the blending.n * @param {Float} [options.scale=1] The scale at which tiles were drawn onn * the sketch. Default is 1.n * Use scale to draw at a lower scale and then enlarge onto the main canvas.n * @param {OpenSeadragon.Point} [options.translate] A translation vectorn * that was used to draw the tilesn * @param {String} [options.compositeOperation] - How the image isn * composited onto other images; see compositeOperation inn * {@link OpenSeadragon.Options} for possible values.n * @param {OpenSeadragon.Rect} [options.bounds] The part of the sketchn * canvas to blend in the main canvas. If specified, options.scale andn * options.translate get ignored.n */n blendSketch: function(opacity, scale, translate, compositeOperation) {n var options = opacity;n if (!$.isPlainObject(options)) {n options = {n opacity: opacity,n scale: scale,n translate: translate,n compositeOperation: compositeOperationn };n }n if (!this.useCanvas || !this.sketchCanvas) {n return;n }n opacity = options.opacity;n compositeOperation = options.compositeOperation;n var bounds = options.bounds;nn this.context.save();n this.context.globalAlpha = opacity;n if (compositeOperation) {n this.context.globalCompositeOperation = compositeOperation;n }n if (bounds) {n // Internet Explorer, Microsoft Edge, and Safari have problemsn // when you call context.drawImage with negative x or yn // or x + width or y + height greater than the canvas width or height respectively.n if (bounds.x < 0) {n bounds.width += bounds.x;n bounds.x = 0;n }n if (bounds.x + bounds.width > this.canvas.width) {n bounds.width = this.canvas.width - bounds.x;n }n if (bounds.y < 0) {n bounds.height += bounds.y;n bounds.y = 0;n }n if (bounds.y + bounds.height > this.canvas.height) {n bounds.height = this.canvas.height - bounds.y;n }nn this.context.drawImage(n this.sketchCanvas,n bounds.x,n bounds.y,n bounds.width,n bounds.height,n bounds.x,n bounds.y,n bounds.width,n bounds.heightn );n } else {n scale = options.scale || 1;n translate = options.translate;n var position = translate instanceof $.Point ?n translate : new $.Point(0, 0);nn var widthExt = 0;n var heightExt = 0;n if (translate) {n var widthDiff = this.sketchCanvas.width - this.canvas.width;n var heightDiff = this.sketchCanvas.height - this.canvas.height;n widthExt = Math.round(widthDiff / 2);n heightExt = Math.round(heightDiff / 2);n }n this.context.drawImage(n this.sketchCanvas,n position.x - widthExt * scale,n position.y - heightExt * scale,n (this.canvas.width + 2 * widthExt) * scale,n (this.canvas.height + 2 * heightExt) * scale,n -widthExt,n -heightExt,n this.canvas.width + 2 * widthExt,n this.canvas.height + 2 * heightExtn );n }n this.context.restore();n },nn // privaten drawDebugInfo: function(tile, count, i, tiledImage) {n if ( !this.useCanvas ) {n return;n }nn var colorIndex = this.viewer.world.getIndexOfItem(tiledImage) % this.debugGridColor.length;n var context = this.context;n context.save();n context.lineWidth = 2 * $.pixelDensityRatio;n context.font = 'small-caps bold ' + (13 * $.pixelDensityRatio) + 'px arial';n context.strokeStyle = this.debugGridColor;n context.fillStyle = this.debugGridColor;nn if ( this.viewport.degrees !== 0 ) {n this._offsetForRotation({degrees: this.viewport.degrees});n } else{n if(this.viewer.viewport.flipped) {n this._flip();n }n }n if (tiledImage.getRotation(true) % 360 !== 0) {n this._offsetForRotation({n degrees: tiledImage.getRotation(true),n point: tiledImage.viewport.pixelFromPointNoRotate(n tiledImage._getRotationPoint(true), true)n });n }nn context.strokeRect(n tile.position.x * $.pixelDensityRatio,n tile.position.y * $.pixelDensityRatio,n tile.size.x * $.pixelDensityRatio,n tile.size.y * $.pixelDensityRation );nn var tileCenterX = (tile.position.x + (tile.size.x / 2)) * $.pixelDensityRatio;n var tileCenterY = (tile.position.y + (tile.size.y / 2)) * $.pixelDensityRatio;nn // Rotate the text the right way around.n context.translate( tileCenterX, tileCenterY );n context.rotate( Math.PI / 180 * -this.viewport.degrees );n context.translate( -tileCenterX, -tileCenterY );nn if( tile.x === 0 && tile.y === 0 ){n context.fillText(n "Zoom: " + this.viewport.getZoom(),n tile.position.x * $.pixelDensityRatio,n (tile.position.y - 30) * $.pixelDensityRation );n context.fillText(n "Pan: " + this.viewport.getBounds().toString(),n tile.position.x * $.pixelDensityRatio,n (tile.position.y - 20) * $.pixelDensityRation );n }n context.fillText(n "Level: " + tile.level,n (tile.position.x + 10) * $.pixelDensityRatio,n (tile.position.y + 20) * $.pixelDensityRation );n context.fillText(n "Column: " + tile.x,n (tile.position.x + 10) * $.pixelDensityRatio,n (tile.position.y + 30) * $.pixelDensityRation );n context.fillText(n "Row: " + tile.y,n (tile.position.x + 10) * $.pixelDensityRatio,n (tile.position.y + 40) * $.pixelDensityRation );n context.fillText(n "Order: " + i + " of " + count,n (tile.position.x + 10) * $.pixelDensityRatio,n (tile.position.y + 50) * $.pixelDensityRation );n context.fillText(n "Size: " + tile.size.toString(),n (tile.position.x + 10) * $.pixelDensityRatio,n (tile.position.y + 60) * $.pixelDensityRation );n context.fillText(n "Position: " + tile.position.toString(),n (tile.position.x + 10) * $.pixelDensityRatio,n (tile.position.y + 70) * $.pixelDensityRation );nn if ( this.viewport.degrees !== 0 ) {n this._restoreRotationChanges();n }n if (tiledImage.getRotation(true) % 360 !== 0) {n this._restoreRotationChanges();n }n context.restore();n },nn // privaten debugRect: function(rect) {n if ( this.useCanvas ) {n var context = this.context;n context.save();n context.lineWidth = 2 * $.pixelDensityRatio;n context.strokeStyle = this.debugGridColor;n context.fillStyle = this.debugGridColor;nn context.strokeRect(n rect.x * $.pixelDensityRatio,n rect.y * $.pixelDensityRatio,n rect.width * $.pixelDensityRatio,n rect.height * $.pixelDensityRation );nn context.restore();n }n },nn /**n * Get the canvas sizen * @param {Boolean} sketch If set to true return the size of the sketch canvasn * @returns {OpenSeadragon.Point} The size of the canvasn */n getCanvasSize: function(sketch) {n var canvas = this._getContext(sketch).canvas;n return new $.Point(canvas.width, canvas.height);n },nn getCanvasCenter: function() {n return new $.Point(this.canvas.width / 2, this.canvas.height / 2);n },nn // privaten _offsetForRotation: function(options) {n var point = options.point ?n options.point.times($.pixelDensityRatio) :n this.getCanvasCenter();nn var context = this._getContext(options.useSketch);n context.save();nn context.translate(point.x, point.y);n if(this.viewer.viewport.flipped){n context.rotate(Math.PI / 180 * -options.degrees);n context.scale(-1, 1);n } else{n context.rotate(Math.PI / 180 * options.degrees);n }n context.translate(-point.x, -point.y);n },nn // privaten _flip: function(options) {n options = options || {};n var point = options.point ?n options.point.times($.pixelDensityRatio) :n this.getCanvasCenter();n var context = this._getContext(options.useSketch);nn context.translate(point.x, 0);n context.scale(-1, 1);n context.translate(-point.x, 0);n },nn // privaten _restoreRotationChanges: function(useSketch) {n var context = this._getContext(useSketch);n context.restore();n },nn // privaten _calculateCanvasSize: function() {n var pixelDensityRatio = $.pixelDensityRatio;n var viewportSize = this.viewport.getContainerSize();n return {n x: viewportSize.x * pixelDensityRatio,n y: viewportSize.y * pixelDensityRation };n },nn // privaten _calculateSketchCanvasSize: function() {n var canvasSize = this._calculateCanvasSize();n if (this.viewport.getRotation() === 0) {n return canvasSize;n }n // If the viewport is rotated, we need a larger sketch canvas in ordern // to support edge smoothing.n var sketchCanvasSize = Math.ceil(Math.sqrt(n canvasSize.x * canvasSize.x +n canvasSize.y * canvasSize.y));n return {n x: sketchCanvasSize,n y: sketchCanvasSizen };n }n};nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - Viewportn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nnn/**n * @class Viewportn * @memberof OpenSeadragonn * @classdesc Handles coordinate-related functionality (zoom, pan, rotation, etc.)n * for an {@link OpenSeadragon.Viewer}.n * @param {Object} options - Options for this Viewport.n * @param {Object} [options.margins] - See viewportMargins in {@link OpenSeadragon.Options}.n * @param {Number} [options.springStiffness] - See springStiffness in {@link OpenSeadragon.Options}.n * @param {Number} [options.animationTime] - See animationTime in {@link OpenSeadragon.Options}.n * @param {Number} [options.minZoomImageRatio] - See minZoomImageRatio in {@link OpenSeadragon.Options}.n * @param {Number} [options.maxZoomPixelRatio] - See maxZoomPixelRatio in {@link OpenSeadragon.Options}.n * @param {Number} [options.visibilityRatio] - See visibilityRatio in {@link OpenSeadragon.Options}.n * @param {Boolean} [options.wrapHorizontal] - See wrapHorizontal in {@link OpenSeadragon.Options}.n * @param {Boolean} [options.wrapVertical] - See wrapVertical in {@link OpenSeadragon.Options}.n * @param {Number} [options.defaultZoomLevel] - See defaultZoomLevel in {@link OpenSeadragon.Options}.n * @param {Number} [options.minZoomLevel] - See minZoomLevel in {@link OpenSeadragon.Options}.n * @param {Number} [options.maxZoomLevel] - See maxZoomLevel in {@link OpenSeadragon.Options}.n * @param {Number} [options.degrees] - See degrees in {@link OpenSeadragon.Options}.n * @param {Boolean} [options.homeFillsViewer] - See homeFillsViewer in {@link OpenSeadragon.Options}.n */n$.Viewport = function( options ) {nn //backward compatibility for positional args while prefering moren //idiomatic javascript options object as the only argumentn var args = arguments;n if (args.length && args instanceof $.Point) {n options = {n containerSize: args,n contentSize: args,n config: argsn };n }nn //options.config and the general config argument are deprecatedn //in favor of the more direct specification of optional settingsn //being passed directly on the options objectn if ( options.config ){n $.extend( true, options, options.config );n delete options.config;n }nn this._margins = $.extend({n left: 0,n top: 0,n right: 0,n bottom: 0n }, options.margins || {});nn delete options.margins;nn $.extend( true, this, {nn //required settingsn containerSize: null,n contentSize: null,nn //internal state propertiesn zoomPoint: null,n viewer: null,nn //configurable optionsn springStiffness: $.DEFAULT_SETTINGS.springStiffness,n animationTime: $.DEFAULT_SETTINGS.animationTime,n minZoomImageRatio: $.DEFAULT_SETTINGS.minZoomImageRatio,n maxZoomPixelRatio: $.DEFAULT_SETTINGS.maxZoomPixelRatio,n visibilityRatio: $.DEFAULT_SETTINGS.visibilityRatio,n wrapHorizontal: $.DEFAULT_SETTINGS.wrapHorizontal,n wrapVertical: $.DEFAULT_SETTINGS.wrapVertical,n defaultZoomLevel: $.DEFAULT_SETTINGS.defaultZoomLevel,n minZoomLevel: $.DEFAULT_SETTINGS.minZoomLevel,n maxZoomLevel: $.DEFAULT_SETTINGS.maxZoomLevel,n degrees: $.DEFAULT_SETTINGS.degrees,n flipped: $.DEFAULT_SETTINGS.flipped,n homeFillsViewer: $.DEFAULT_SETTINGS.homeFillsViewernn }, options );nn this._updateContainerInnerSize();nn this.centerSpringX = new $.Spring({n initial: 0,n springStiffness: this.springStiffness,n animationTime: this.animationTimen });n this.centerSpringY = new $.Spring({n initial: 0,n springStiffness: this.springStiffness,n animationTime: this.animationTimen });n this.zoomSpring = new $.Spring({n exponential: true,n initial: 1,n springStiffness: this.springStiffness,n animationTime: this.animationTimen });nn this._oldCenterX = this.centerSpringX.current.value;n this._oldCenterY = this.centerSpringY.current.value;n this._oldZoom = this.zoomSpring.current.value;nn this._setContentBounds(new $.Rect(0, 0, 1, 1), 1);nn this.goHome(true);n this.update();n};nn/** @lends OpenSeadragon.Viewport.prototype */n$.Viewport.prototype = {n /**n * Updates the viewport's home bounds and constraints for the given content size.n * @functionn * @param {OpenSeadragon.Point} contentSize - size of the content in content unitsn * @return {OpenSeadragon.Viewport} Chainable.n * @fires OpenSeadragon.Viewer.event:reset-sizen */n resetContentSize: function(contentSize) {n $.console.assert(contentSize, "[Viewport.resetContentSize] contentSize is required");n $.console.assert(contentSize instanceof $.Point, "[Viewport.resetContentSize] contentSize must be an OpenSeadragon.Point");n $.console.assert(contentSize.x > 0, "[Viewport.resetContentSize] contentSize.x must be greater than 0");n $.console.assert(contentSize.y > 0, "[Viewport.resetContentSize] contentSize.y must be greater than 0");nn this._setContentBounds(new $.Rect(0, 0, 1, contentSize.y / contentSize.x), contentSize.x);n return this;n },nn // deprecatedn setHomeBounds: function(bounds, contentFactor) {n $.console.error(" this function is deprecated; The content bounds should not be set manually.");n this._setContentBounds(bounds, contentFactor);n },nn // Set the viewport's content boundsn // @param {OpenSeadragon.Rect} bounds - the new bounds in viewport coordinatesn // without rotationn // @param {Number} contentFactor - how many content units per viewport unitn // @fires OpenSeadragon.Viewer.event:reset-sizen // @privaten _setContentBounds: function(bounds, contentFactor) {n $.console.assert(bounds, "[Viewport._setContentBounds] bounds is required");n $.console.assert(bounds instanceof $.Rect, "[Viewport._setContentBounds] bounds must be an OpenSeadragon.Rect");n $.console.assert(bounds.width > 0, "[Viewport._setContentBounds] bounds.width must be greater than 0");n $.console.assert(bounds.height > 0, "[Viewport._setContentBounds] bounds.height must be greater than 0");nn this._contentBoundsNoRotate = bounds.clone();n this._contentSizeNoRotate = this._contentBoundsNoRotate.getSize().times(n contentFactor);nn this._contentBounds = bounds.rotate(this.degrees).getBoundingBox();n this._contentSize = this._contentBounds.getSize().times(contentFactor);n this._contentAspectRatio = this._contentSize.x / this._contentSize.y;nn if (this.viewer) {n /**n * Raised when the viewer's content size or home bounds are resetn * (see {@link OpenSeadragon.Viewport#resetContentSize}).n *n * @event reset-sizen * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.Point} contentSizen * @property {OpenSeadragon.Rect} contentBounds - Content bounds.n * @property {OpenSeadragon.Rect} homeBounds - Content bounds.n * Deprecated use contentBounds instead.n * @property {Number} contentFactorn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.viewer.raiseEvent('reset-size', {n contentSize: this._contentSizeNoRotate.clone(),n contentFactor: contentFactor,n homeBounds: this._contentBoundsNoRotate.clone(),n contentBounds: this._contentBounds.clone()n });n }n },nn /**n * Returns the home zoom in "viewport zoom" value.n * @functionn * @returns {Number} The home zoom in "viewport zoom".n */n getHomeZoom: function() {n if (this.defaultZoomLevel) {n return this.defaultZoomLevel;n }nn var aspectFactor = this._contentAspectRatio / this.getAspectRatio();n var output;n if (this.homeFillsViewer) { // fill the viewer and clip the imagen output = aspectFactor >= 1 ? aspectFactor : 1;n } else {n output = aspectFactor >= 1 ? 1 : aspectFactor;n }nn return output / this._contentBounds.width;n },nn /**n * Returns the home bounds in viewport coordinates.n * @functionn * @returns {OpenSeadragon.Rect} The home bounds in vewport coordinates.n */n getHomeBounds: function() {n return this.getHomeBoundsNoRotate().rotate(-this.getRotation());n },nn /**n * Returns the home bounds in viewport coordinates.n * This method ignores the viewport rotation. Usen * {@link OpenSeadragon.Viewport#getHomeBounds} to take it into account.n * @functionn * @returns {OpenSeadragon.Rect} The home bounds in vewport coordinates.n */n getHomeBoundsNoRotate: function() {n var center = this._contentBounds.getCenter();n var width = 1.0 / this.getHomeZoom();n var height = width / this.getAspectRatio();nn return new $.Rect(n center.x - (width / 2.0),n center.y - (height / 2.0),n width,n heightn );n },nn /**n * @functionn * @param {Boolean} immediatelyn * @fires OpenSeadragon.Viewer.event:homen */n goHome: function(immediately) {n if (this.viewer) {n /**n * Raised when the "home" operation occurs (see {@link OpenSeadragon.Viewport#goHome}).n *n * @event homen * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {Boolean} immediatelyn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.viewer.raiseEvent('home', {n immediately: immediatelyn });n }n return this.fitBounds(this.getHomeBounds(), immediately);n },nn /**n * @functionn */n getMinZoom: function() {n var homeZoom = this.getHomeZoom(),n zoom = this.minZoomLevel ?n this.minZoomLevel :n this.minZoomImageRatio * homeZoom;nn return zoom;n },nn /**n * @functionn */n getMaxZoom: function() {n var zoom = this.maxZoomLevel;n if (!zoom) {n zoom = this._contentSize.x * this.maxZoomPixelRatio / this._containerInnerSize.x;n zoom /= this._contentBounds.width;n }nn return Math.max( zoom, this.getHomeZoom() );n },nn /**n * @functionn */n getAspectRatio: function() {n return this._containerInnerSize.x / this._containerInnerSize.y;n },nn /**n * @functionn * @returns {OpenSeadragon.Point} The size of the container, in screen coordinates.n */n getContainerSize: function() {n return new $.Point(n this.containerSize.x,n this.containerSize.yn );n },nn /**n * The margins push the "home" region in from the sides by the specified amounts.n * @functionn * @returns {Object} Properties (Numbers, in screen coordinates): left, top, right, bottom.n */n getMargins: function() {n return $.extend({}, this._margins); // Make a copy so we are not returning our originaln },nn /**n * The margins push the "home" region in from the sides by the specified amounts.n * @functionn * @param {Object} margins - Properties (Numbers, in screen coordinates): left, top, right, bottom.n */n setMargins: function(margins) {n $.console.assert($.type(margins) === 'object', '[Viewport.setMargins] margins must be an object');nn this._margins = $.extend({n left: 0,n top: 0,n right: 0,n bottom: 0n }, margins);nn this._updateContainerInnerSize();n if (this.viewer) {n this.viewer.forceRedraw();n }n },nn /**n * Returns the bounds of the visible area in viewport coordinates.n * @functionn * @param {Boolean} current - Pass true for the current location; defaults to false (target location).n * @returns {OpenSeadragon.Rect} The location you are zoomed/panned to, in viewport coordinates.n */n getBounds: function(current) {n return this.getBoundsNoRotate(current).rotate(-this.getRotation());n },nn /**n * Returns the bounds of the visible area in viewport coordinates.n * This method ignores the viewport rotation. Usen * {@link OpenSeadragon.Viewport#getBounds} to take it into account.n * @functionn * @param {Boolean} current - Pass true for the current location; defaults to false (target location).n * @returns {OpenSeadragon.Rect} The location you are zoomed/panned to, in viewport coordinates.n */n getBoundsNoRotate: function(current) {n var center = this.getCenter(current);n var width = 1.0 / this.getZoom(current);n var height = width / this.getAspectRatio();nn return new $.Rect(n center.x - (width / 2.0),n center.y - (height / 2.0),n width,n heightn );n },nn /**n * @functionn * @param {Boolean} current - Pass true for the current location; defaults to false (target location).n * @returns {OpenSeadragon.Rect} The location you are zoomed/panned to,n * including the space taken by margins, in viewport coordinates.n */n getBoundsWithMargins: function(current) {n return this.getBoundsNoRotateWithMargins(current).rotate(n -this.getRotation(), this.getCenter(current));n },nn /**n * @functionn * @param {Boolean} current - Pass true for the current location; defaults to false (target location).n * @returns {OpenSeadragon.Rect} The location you are zoomed/panned to,n * including the space taken by margins, in viewport coordinates.n */n getBoundsNoRotateWithMargins: function(current) {n var bounds = this.getBoundsNoRotate(current);n var factor = this._containerInnerSize.x * this.getZoom(current);n bounds.x -= this._margins.left / factor;n bounds.y -= this._margins.top / factor;n bounds.width += (this._margins.left + this._margins.right) / factor;n bounds.height += (this._margins.top + this._margins.bottom) / factor;n return bounds;n },nn /**n * @functionn * @param {Boolean} current - Pass true for the current location; defaults to false (target location).n */n getCenter: function( current ) {n var centerCurrent = new $.Point(n this.centerSpringX.current.value,n this.centerSpringY.current.valuen ),n centerTarget = new $.Point(n this.centerSpringX.target.value,n this.centerSpringY.target.valuen ),n oldZoomPixel,n zoom,n width,n height,n bounds,n newZoomPixel,n deltaZoomPixels,n deltaZoomPoints;nn if ( current ) {n return centerCurrent;n } else if ( !this.zoomPoint ) {n return centerTarget;n }nn oldZoomPixel = this.pixelFromPoint(this.zoomPoint, true);nn zoom = this.getZoom();n width = 1.0 / zoom;n height = width / this.getAspectRatio();n bounds = new $.Rect(n centerCurrent.x - width / 2.0,n centerCurrent.y - height / 2.0,n width,n heightn );nn newZoomPixel = this._pixelFromPoint(this.zoomPoint, bounds);n deltaZoomPixels = newZoomPixel.minus( oldZoomPixel );n deltaZoomPoints = deltaZoomPixels.divide( this._containerInnerSize.x * zoom );nn return centerTarget.plus( deltaZoomPoints );n },nn /**n * @functionn * @param {Boolean} current - Pass true for the current location; defaults to false (target location).n */n getZoom: function( current ) {n if ( current ) {n return this.zoomSpring.current.value;n } else {n return this.zoomSpring.target.value;n }n },nn // privaten _applyZoomConstraints: function(zoom) {n return Math.max(n Math.min(zoom, this.getMaxZoom()),n this.getMinZoom());n },nn /**n * @functionn * @privaten * @param {OpenSeadragon.Rect} boundsn * @return {OpenSeadragon.Rect} constrained bounds.n */n _applyBoundaryConstraints: function(bounds) {n var newBounds = new $.Rect(n bounds.x,n bounds.y,n bounds.width,n bounds.height);nn if (this.wrapHorizontal) {n //do nothingn } else {n var horizontalThreshold = this.visibilityRatio * newBounds.width;n var boundsRight = newBounds.x + newBounds.width;n var contentRight = this._contentBoundsNoRotate.x + this._contentBoundsNoRotate.width;n var leftDx = this._contentBoundsNoRotate.x - boundsRight + horizontalThreshold;n var rightDx = contentRight - newBounds.x - horizontalThreshold;nn if (horizontalThreshold > this._contentBoundsNoRotate.width) {n newBounds.x += (leftDx + rightDx) / 2;n } else if (rightDx < 0) {n newBounds.x += rightDx;n } else if (leftDx > 0) {n newBounds.x += leftDx;n }n }nn if (this.wrapVertical) {n //do nothingn } else {n var verticalThreshold = this.visibilityRatio * newBounds.height;n var boundsBottom = newBounds.y + newBounds.height;n var contentBottom = this._contentBoundsNoRotate.y + this._contentBoundsNoRotate.height;n var topDy = this._contentBoundsNoRotate.y - boundsBottom + verticalThreshold;n var bottomDy = contentBottom - newBounds.y - verticalThreshold;nn if (verticalThreshold > this._contentBoundsNoRotate.height) {n newBounds.y += (topDy + bottomDy) / 2;n } else if (bottomDy < 0) {n newBounds.y += bottomDy;n } else if (topDy > 0) {n newBounds.y += topDy;n }n }nn return newBounds;n },nn /**n * @functionn * @privaten * @param {Boolean} [immediately=false] - whether the function that triggered this event wasn * called with the "immediately" flagn */n _raiseConstraintsEvent: function(immediately) {n if (this.viewer) {n /**n * Raised when the viewport constraints are applied (see {@link OpenSeadragon.Viewport#applyConstraints}).n *n * @event constrainn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {Boolean} immediately - whether the function that triggered this event wasn * called with the "immediately" flagn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.viewer.raiseEvent( 'constrain', {n immediately: immediatelyn });n }n },nn /**n * Enforces the minZoom, maxZoom and visibilityRatio constraints byn * zooming and panning to the closest acceptable zoom and location.n * @functionn * @param {Boolean} [immediately=false]n * @return {OpenSeadragon.Viewport} Chainable.n * @fires OpenSeadragon.Viewer.event:constrainn */n applyConstraints: function(immediately) {n var actualZoom = this.getZoom();n var constrainedZoom = this._applyZoomConstraints(actualZoom);nn if (actualZoom !== constrainedZoom) {n this.zoomTo(constrainedZoom, this.zoomPoint, immediately);n }nn var bounds = this.getBoundsNoRotate();n var constrainedBounds = this._applyBoundaryConstraints(bounds);n this._raiseConstraintsEvent(immediately);nn if (bounds.x !== constrainedBounds.x ||n bounds.y !== constrainedBounds.y ||n immediately) {n this.fitBounds(n constrainedBounds.rotate(-this.getRotation()),n immediately);n }n return this;n },nn /**n * Equivalent to {@link OpenSeadragon.Viewport#applyConstraints}n * @functionn * @param {Boolean} [immediately=false]n * @return {OpenSeadragon.Viewport} Chainable.n * @fires OpenSeadragon.Viewer.event:constrainn */n ensureVisible: function(immediately) {n return this.applyConstraints(immediately);n },nn /**n * @functionn * @privaten * @param {OpenSeadragon.Rect} boundsn * @param {Object} options (immediately=false, constraints=false)n * @return {OpenSeadragon.Viewport} Chainable.n */n _fitBounds: function(bounds, options) {n options = options || {};n var immediately = options.immediately || false;n var constraints = options.constraints || false;nn var aspect = this.getAspectRatio();n var center = bounds.getCenter();nn // Compute width and height of bounding box.n var newBounds = new $.Rect(n bounds.x,n bounds.y,n bounds.width,n bounds.height,n bounds.degrees + this.getRotation())n .getBoundingBox();nn if (newBounds.getAspectRatio() >= aspect) {n newBounds.height = newBounds.width / aspect;n } else {n newBounds.width = newBounds.height * aspect;n }nn // Compute x and y from width, height and center positionn newBounds.x = center.x - newBounds.width / 2;n newBounds.y = center.y - newBounds.height / 2;n var newZoom = 1.0 / newBounds.width;nn if (constraints) {n var newBoundsAspectRatio = newBounds.getAspectRatio();n var newConstrainedZoom = this._applyZoomConstraints(newZoom);nn if (newZoom !== newConstrainedZoom) {n newZoom = newConstrainedZoom;n newBounds.width = 1.0 / newZoom;n newBounds.x = center.x - newBounds.width / 2;n newBounds.height = newBounds.width / newBoundsAspectRatio;n newBounds.y = center.y - newBounds.height / 2;n }nn newBounds = this._applyBoundaryConstraints(newBounds);n center = newBounds.getCenter();n this._raiseConstraintsEvent(immediately);n }nn if (immediately) {n this.panTo(center, true);n return this.zoomTo(newZoom, null, true);n }nn this.panTo(this.getCenter(true), true);n this.zoomTo(this.getZoom(true), null, true);nn var oldBounds = this.getBounds();n var oldZoom = this.getZoom();nn if (oldZoom === 0 || Math.abs(newZoom / oldZoom - 1) < 0.00000001) {n this.zoomTo(newZoom, true);n return this.panTo(center, immediately);n }nn newBounds = newBounds.rotate(-this.getRotation());n var referencePoint = newBounds.getTopLeft().times(newZoom)n .minus(oldBounds.getTopLeft().times(oldZoom))n .divide(newZoom - oldZoom);nn return this.zoomTo(newZoom, referencePoint, immediately);n },nn /**n * Makes the viewport zoom and pan so that the specified bounds taken * as much space as possible in the viewport.n * Note: this method ignores the constraints (minZoom, maxZoom andn * visibilityRatio).n * Use {@link OpenSeadragon.Viewport#fitBoundsWithConstraints} to enforcen * them.n * @functionn * @param {OpenSeadragon.Rect} boundsn * @param {Boolean} [immediately=false]n * @return {OpenSeadragon.Viewport} Chainable.n */n fitBounds: function(bounds, immediately) {n return this._fitBounds(bounds, {n immediately: immediately,n constraints: falsen });n },nn /**n * Makes the viewport zoom and pan so that the specified bounds taken * as much space as possible in the viewport while enforcing the constraintsn * (minZoom, maxZoom and visibilityRatio).n * Note: because this method enforces the constraints, part of then * provided bounds may end up outside of the viewport.n * Use {@link OpenSeadragon.Viewport#fitBounds} to ignore them.n * @functionn * @param {OpenSeadragon.Rect} boundsn * @param {Boolean} [immediately=false]n * @return {OpenSeadragon.Viewport} Chainable.n */n fitBoundsWithConstraints: function(bounds, immediately) {n return this._fitBounds(bounds, {n immediately: immediately,n constraints: truen });n },nn /**n * Zooms so the image just fills the viewer vertically.n * @param {Boolean} immediatelyn * @return {OpenSeadragon.Viewport} Chainable.n */n fitVertically: function(immediately) {n var box = new $.Rect(n this._contentBounds.x + (this._contentBounds.width / 2),n this._contentBounds.y,n 0,n this._contentBounds.height);n return this.fitBounds(box, immediately);n },nn /**n * Zooms so the image just fills the viewer horizontally.n * @param {Boolean} immediatelyn * @return {OpenSeadragon.Viewport} Chainable.n */n fitHorizontally: function(immediately) {n var box = new $.Rect(n this._contentBounds.x,n this._contentBounds.y + (this._contentBounds.height / 2),n this._contentBounds.width,n 0);n return this.fitBounds(box, immediately);n },nnn /**n * Returns bounds taking constraints into accountn * Added to improve constrained panningn * @param {Boolean} current - Pass true for the current location; defaults to false (target location).n * @return {OpenSeadragon.Viewport} Chainable.n */n getConstrainedBounds: function(current) {n var bounds,n constrainedBounds;nn bounds = this.getBounds(current);nn constrainedBounds = this._applyBoundaryConstraints(bounds);nn return constrainedBounds;n },nn /**n * @functionn * @param {OpenSeadragon.Point} deltan * @param {Boolean} immediatelyn * @return {OpenSeadragon.Viewport} Chainable.n * @fires OpenSeadragon.Viewer.event:pann */n panBy: function( delta, immediately ) {n var center = new $.Point(n this.centerSpringX.target.value,n this.centerSpringY.target.valuen );n return this.panTo( center.plus( delta ), immediately );n },nn /**n * @functionn * @param {OpenSeadragon.Point} centern * @param {Boolean} immediatelyn * @return {OpenSeadragon.Viewport} Chainable.n * @fires OpenSeadragon.Viewer.event:pann */n panTo: function( center, immediately ) {n if ( immediately ) {n this.centerSpringX.resetTo( center.x );n this.centerSpringY.resetTo( center.y );n } else {n this.centerSpringX.springTo( center.x );n this.centerSpringY.springTo( center.y );n }nn if( this.viewer ){n /**n * Raised when the viewport is panned (see {@link OpenSeadragon.Viewport#panBy} and {@link OpenSeadragon.Viewport#panTo}).n *n * @event pann * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.Point} centern * @property {Boolean} immediatelyn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.viewer.raiseEvent( 'pan', {n center: center,n immediately: immediatelyn });n }nn return this;n },nn /**n * @functionn * @return {OpenSeadragon.Viewport} Chainable.n * @fires OpenSeadragon.Viewer.event:zoomn */n zoomBy: function(factor, refPoint, immediately) {n return this.zoomTo(n this.zoomSpring.target.value * factor, refPoint, immediately);n },nn /**n * Zooms to the specified zoom leveln * @functionn * @param {Number} zoom The zoom level to zoom to.n * @param {OpenSeadragon.Point} [refPoint] The point which will stay atn * the same screen location. Defaults to the viewport center.n * @param {Boolean} [immediately=false]n * @return {OpenSeadragon.Viewport} Chainable.n * @fires OpenSeadragon.Viewer.event:zoomn */n zoomTo: function(zoom, refPoint, immediately) {n var _this = this;nn this.zoomPoint = refPoint instanceof $.Point &&n !isNaN(refPoint.x) &&n !isNaN(refPoint.y) ?n refPoint :n null;nn if (immediately) {n this._adjustCenterSpringsForZoomPoint(function() {n _this.zoomSpring.resetTo(zoom);n });n } else {n this.zoomSpring.springTo(zoom);n }nn if (this.viewer) {n /**n * Raised when the viewport zoom level changes (see {@link OpenSeadragon.Viewport#zoomBy} and {@link OpenSeadragon.Viewport#zoomTo}).n *n * @event zoomn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {Number} zoomn * @property {OpenSeadragon.Point} refPointn * @property {Boolean} immediatelyn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.viewer.raiseEvent('zoom', {n zoom: zoom,n refPoint: refPoint,n immediately: immediatelyn });n }nn return this;n },nn /**n * Rotates this viewport to the angle specified.n * @functionn * @return {OpenSeadragon.Viewport} Chainable.n */n setRotation: function(degrees) {n if (!this.viewer || !this.viewer.drawer.canRotate()) {n return this;n }n this.degrees = $.positiveModulo(degrees, 360);n this._setContentBounds(n this.viewer.world.getHomeBounds(),n this.viewer.world.getContentFactor());n this.viewer.forceRedraw();nn /**n * Raised when rotation has been changed.n *n * @event rotaten * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {Number} degrees - The number of degrees the rotation was set to.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.viewer.raiseEvent('rotate', {"degrees": degrees});n return this;n },nn /**n * Gets the current rotation in degrees.n * @functionn * @return {Number} The current rotation in degrees.n */n getRotation: function() {n return this.degrees;n },nn /**n * @functionn * @return {OpenSeadragon.Viewport} Chainable.n * @fires OpenSeadragon.Viewer.event:resizen */n resize: function( newContainerSize, maintain ) {n var oldBounds = this.getBoundsNoRotate(),n newBounds = oldBounds,n widthDeltaFactor;nn this.containerSize.x = newContainerSize.x;n this.containerSize.y = newContainerSize.y;nn this._updateContainerInnerSize();nn if ( maintain ) {n // TODO: widthDeltaFactor will always be 1; probably not what's intendedn widthDeltaFactor = newContainerSize.x / this.containerSize.x;n newBounds.width = oldBounds.width * widthDeltaFactor;n newBounds.height = newBounds.width / this.getAspectRatio();n }nn if( this.viewer ){n /**n * Raised when the viewer is resized (see {@link OpenSeadragon.Viewport#resize}).n *n * @event resizen * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.n * @property {OpenSeadragon.Point} newContainerSizen * @property {Boolean} maintainn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.viewer.raiseEvent( 'resize', {n newContainerSize: newContainerSize,n maintain: maintainn });n }nn return this.fitBounds( newBounds, true );n },nn // privaten _updateContainerInnerSize: function() {n this._containerInnerSize = new $.Point(n Math.max(1, this.containerSize.x - (this._margins.left + this._margins.right)),n Math.max(1, this.containerSize.y - (this._margins.top + this._margins.bottom))n );n },nn /**n * Update the zoom and center (X and Y) springs.n * @functionn * @returns {Boolean} True if any change has been made, false otherwise.n */n update: function() {n var _this = this;n this._adjustCenterSpringsForZoomPoint(function() {n _this.zoomSpring.update();n });nn this.centerSpringX.update();n this.centerSpringY.update();nn var changed = this.centerSpringX.current.value !== this._oldCenterX ||n this.centerSpringY.current.value !== this._oldCenterY ||n this.zoomSpring.current.value !== this._oldZoom;nn this._oldCenterX = this.centerSpringX.current.value;n this._oldCenterY = this.centerSpringY.current.value;n this._oldZoom = this.zoomSpring.current.value;nn return changed;n },nn _adjustCenterSpringsForZoomPoint: function(zoomSpringHandler) {n if (this.zoomPoint) {n var oldZoomPixel = this.pixelFromPoint(this.zoomPoint, true);n zoomSpringHandler();n var newZoomPixel = this.pixelFromPoint(this.zoomPoint, true);nn var deltaZoomPixels = newZoomPixel.minus(oldZoomPixel);n var deltaZoomPoints = this.deltaPointsFromPixels(n deltaZoomPixels, true);nn this.centerSpringX.shiftBy(deltaZoomPoints.x);n this.centerSpringY.shiftBy(deltaZoomPoints.y);nn if (this.zoomSpring.isAtTargetValue()) {n this.zoomPoint = null;n }n } else {n zoomSpringHandler();n }n },nn /**n * Convert a delta (translation vector) from viewport coordinates to pixelsn * coordinates. This method does not take rotation into account.n * Consider using deltaPixelsFromPoints if you need to account for rotation.n * @param {OpenSeadragon.Point} deltaPoints - The translation vector to convert.n * @param {Boolean} [current=false] - Pass true for the current location;n * defaults to false (target location).n * @returns {OpenSeadragon.Point}n */n deltaPixelsFromPointsNoRotate: function(deltaPoints, current) {n return deltaPoints.times(n this._containerInnerSize.x * this.getZoom(current)n );n },nn /**n * Convert a delta (translation vector) from viewport coordinates to pixelsn * coordinates.n * @param {OpenSeadragon.Point} deltaPoints - The translation vector to convert.n * @param {Boolean} [current=false] - Pass true for the current location;n * defaults to false (target location).n * @returns {OpenSeadragon.Point}n */n deltaPixelsFromPoints: function(deltaPoints, current) {n return this.deltaPixelsFromPointsNoRotate(n deltaPoints.rotate(this.getRotation()),n current);n },nn /**n * Convert a delta (translation vector) from pixels coordinates to viewportn * coordinates. This method does not take rotation into account.n * Consider using deltaPointsFromPixels if you need to account for rotation.n * @param {OpenSeadragon.Point} deltaPixels - The translation vector to convert.n * @param {Boolean} [current=false] - Pass true for the current location;n * defaults to false (target location).n * @returns {OpenSeadragon.Point}n */n deltaPointsFromPixelsNoRotate: function(deltaPixels, current) {n return deltaPixels.divide(n this._containerInnerSize.x * this.getZoom(current)n );n },nn /**n * Convert a delta (translation vector) from pixels coordinates to viewportn * coordinates.n * @param {OpenSeadragon.Point} deltaPixels - The translation vector to convert.n * @param {Boolean} [current=false] - Pass true for the current location;n * defaults to false (target location).n * @returns {OpenSeadragon.Point}n */n deltaPointsFromPixels: function(deltaPixels, current) {n return this.deltaPointsFromPixelsNoRotate(deltaPixels, current)n .rotate(-this.getRotation());n },nn /**n * Convert viewport coordinates to pixels coordinates.n * This method does not take rotation into account.n * Consider using pixelFromPoint if you need to account for rotation.n * @param {OpenSeadragon.Point} point the viewport coordinatesn * @param {Boolean} [current=false] - Pass true for the current location;n * defaults to false (target location).n * @returns {OpenSeadragon.Point}n */n pixelFromPointNoRotate: function(point, current) {n return this._pixelFromPointNoRotate(n point, this.getBoundsNoRotate(current));n },nn /**n * Convert viewport coordinates to pixel coordinates.n * @param {OpenSeadragon.Point} point the viewport coordinatesn * @param {Boolean} [current=false] - Pass true for the current location;n * defaults to false (target location).n * @returns {OpenSeadragon.Point}n */n pixelFromPoint: function(point, current) {n return this._pixelFromPoint(point, this.getBoundsNoRotate(current));n },nn // privaten _pixelFromPointNoRotate: function(point, bounds) {n return point.minus(n bounds.getTopLeft()n ).times(n this._containerInnerSize.x / bounds.widthn ).plus(n new $.Point(this._margins.left, this._margins.top)n );n },nn // privaten _pixelFromPoint: function(point, bounds) {n return this._pixelFromPointNoRotate(n point.rotate(this.getRotation(), this.getCenter(true)),n bounds);n },nn /**n * Convert pixel coordinates to viewport coordinates.n * This method does not take rotation into account.n * Consider using pointFromPixel if you need to account for rotation.n * @param {OpenSeadragon.Point} pixel Pixel coordinatesn * @param {Boolean} [current=false] - Pass true for the current location;n * defaults to false (target location).n * @returns {OpenSeadragon.Point}n */n pointFromPixelNoRotate: function(pixel, current) {n var bounds = this.getBoundsNoRotate(current);n return pixel.minus(n new $.Point(this._margins.left, this._margins.top)n ).divide(n this._containerInnerSize.x / bounds.widthn ).plus(n bounds.getTopLeft()n );n },nn /**n * Convert pixel coordinates to viewport coordinates.n * @param {OpenSeadragon.Point} pixel Pixel coordinatesn * @param {Boolean} [current=false] - Pass true for the current location;n * defaults to false (target location).n * @returns {OpenSeadragon.Point}n */n pointFromPixel: function(pixel, current) {n return this.pointFromPixelNoRotate(pixel, current).rotate(n -this.getRotation(),n this.getCenter(true)n );n },nn // privaten _viewportToImageDelta: function( viewerX, viewerY ) {n var scale = this._contentBoundsNoRotate.width;n return new $.Point(n viewerX * this._contentSizeNoRotate.x / scale,n viewerY * this._contentSizeNoRotate.x / scale);n },nn /**n * Translates from OpenSeadragon viewer coordinate system to image coordinate system.n * This method can be called either by passing X,Y coordinates or ann * OpenSeadragon.Pointn * Note: not accurate with multi-image; use TiledImage.viewportToImageCoordinates instead.n * @functionn * @param {(OpenSeadragon.Point|Number)} viewerX either a point or the Xn * coordinate in viewport coordinate system.n * @param {Number} [viewerY] Y coordinate in viewport coordinate system.n * @return {OpenSeadragon.Point} a point representing the coordinates in the image.n */n viewportToImageCoordinates: function(viewerX, viewerY) {n if (viewerX instanceof $.Point) {n //they passed a point instead of individual componentsn return this.viewportToImageCoordinates(viewerX.x, viewerX.y);n }nn if (this.viewer) {n var count = this.viewer.world.getItemCount();n if (count > 1) {n $.console.error(‘ is not accurate ' +n 'with multi-image; use TiledImage.viewportToImageCoordinates instead.');n } else if (count === 1) {n // It is better to use TiledImage.viewportToImageCoordinatesn // because this._contentBoundsNoRotate can not be relied onn // with clipping.n var item = this.viewer.world.getItemAt(0);n return item.viewportToImageCoordinates(viewerX, viewerY, true);n }n }nn return this._viewportToImageDelta(n viewerX - this._contentBoundsNoRotate.x,n viewerY - this._contentBoundsNoRotate.y);n },nn // privaten _imageToViewportDelta: function( imageX, imageY ) {n var scale = this._contentBoundsNoRotate.width;n return new $.Point(n imageX / this._contentSizeNoRotate.x * scale,n imageY / this._contentSizeNoRotate.x * scale);n },nn /**n * Translates from image coordinate system to OpenSeadragon viewer coordinate systemn * This method can be called either by passing X,Y coordinates or ann * OpenSeadragon.Pointn * Note: not accurate with multi-image; use TiledImage.imageToViewportCoordinates instead.n * @functionn * @param {(OpenSeadragon.Point | Number)} imageX the point or then * X coordinate in image coordinate system.n * @param {Number} [imageY] Y coordinate in image coordinate system.n * @return {OpenSeadragon.Point} a point representing the coordinates in the viewport.n */n imageToViewportCoordinates: function(imageX, imageY) {n if (imageX instanceof $.Point) {n //they passed a point instead of individual componentsn return this.imageToViewportCoordinates(imageX.x, imageX.y);n }nn if (this.viewer) {n var count = this.viewer.world.getItemCount();n if (count > 1) {n $.console.error(’ is not accurate ' +n 'with multi-image; use TiledImage.imageToViewportCoordinates instead.');n } else if (count === 1) {n // It is better to use TiledImage.viewportToImageCoordinatesn // because this._contentBoundsNoRotate can not be relied onn // with clipping.n var item = this.viewer.world.getItemAt(0);n return item.imageToViewportCoordinates(imageX, imageY, true);n }n }nn var point = this._imageToViewportDelta(imageX, imageY);n point.x += this._contentBoundsNoRotate.x;n point.y += this._contentBoundsNoRotate.y;n return point;n },nn /**n * Translates from a rectangle which describes a portion of the image inn * pixel coordinates to OpenSeadragon viewport rectangle coordinates.n * This method can be called either by passing X,Y,width,height or ann * OpenSeadragon.Rectn * Note: not accurate with multi-image; use TiledImage.imageToViewportRectangle instead.n * @functionn * @param {(OpenSeadragon.Rect | Number)} imageX the rectangle or the Xn * coordinate of the top left corner of the rectangle in image coordinate system.n * @param {Number} [imageY] the Y coordinate of the top left corner of the rectanglen * in image coordinate system.n * @param {Number} [pixelWidth] the width in pixel of the rectangle.n * @param {Number} [pixelHeight] the height in pixel of the rectangle.n * @returns {OpenSeadragon.Rect} This image's bounds in viewport coordinatesn */n imageToViewportRectangle: function(imageX, imageY, pixelWidth, pixelHeight) {n var rect = imageX;n if (!(rect instanceof $.Rect)) {n //they passed individual components instead of a rectanglen rect = new $.Rect(imageX, imageY, pixelWidth, pixelHeight);n }nn if (this.viewer) {n var count = this.viewer.world.getItemCount();n if (count > 1) {n $.console.error(‘ is not accurate ' +n 'with multi-image; use TiledImage.imageToViewportRectangle instead.');n } else if (count === 1) {n // It is better to use TiledImage.imageToViewportRectanglen // because this._contentBoundsNoRotate can not be relied onn // with clipping.n var item = this.viewer.world.getItemAt(0);n return item.imageToViewportRectangle(n imageX, imageY, pixelWidth, pixelHeight, true);n }n }nn var coordA = this.imageToViewportCoordinates(rect.x, rect.y);n var coordB = this._imageToViewportDelta(rect.width, rect.height);n return new $.Rect(n coordA.x,n coordA.y,n coordB.x,n coordB.y,n rect.degreesn );n },nn /**n * Translates from a rectangle which describes a portion ofn * the viewport in point coordinates to image rectangle coordinates.n * This method can be called either by passing X,Y,width,height or ann * OpenSeadragon.Rectn * Note: not accurate with multi-image; use TiledImage.viewportToImageRectangle instead.n * @functionn * @param {(OpenSeadragon.Rect | Number)} viewerX either a rectangle orn * the X coordinate of the top left corner of the rectangle in viewportn * coordinate system.n * @param {Number} [viewerY] the Y coordinate of the top left corner of the rectanglen * in viewport coordinate system.n * @param {Number} [pointWidth] the width of the rectangle in viewport coordinate system.n * @param {Number} [pointHeight] the height of the rectangle in viewport coordinate system.n */n viewportToImageRectangle: function(viewerX, viewerY, pointWidth, pointHeight) {n var rect = viewerX;n if (!(rect instanceof $.Rect)) {n //they passed individual components instead of a rectanglen rect = new $.Rect(viewerX, viewerY, pointWidth, pointHeight);n }nn if (this.viewer) {n var count = this.viewer.world.getItemCount();n if (count > 1) {n $.console.error(’ is not accurate ' +n 'with multi-image; use TiledImage.viewportToImageRectangle instead.');n } else if (count === 1) {n // It is better to use TiledImage.viewportToImageCoordinatesn // because this._contentBoundsNoRotate can not be relied onn // with clipping.n var item = this.viewer.world.getItemAt(0);n return item.viewportToImageRectangle(n viewerX, viewerY, pointWidth, pointHeight, true);n }n }nn var coordA = this.viewportToImageCoordinates(rect.x, rect.y);n var coordB = this._viewportToImageDelta(rect.width, rect.height);n return new $.Rect(n coordA.x,n coordA.y,n coordB.x,n coordB.y,n rect.degreesn );n },nn /**n * Convert pixel coordinates relative to the viewer element to imagen * coordinates.n * Note: not accurate with multi-image.n * @param {OpenSeadragon.Point} pixeln * @returns {OpenSeadragon.Point}n */n viewerElementToImageCoordinates: function( pixel ) {n var point = this.pointFromPixel( pixel, true );n return this.viewportToImageCoordinates( point );n },nn /**n * Convert pixel coordinates relative to the image ton * viewer element coordinates.n * Note: not accurate with multi-image.n * @param {OpenSeadragon.Point} pixeln * @returns {OpenSeadragon.Point}n */n imageToViewerElementCoordinates: function( pixel ) {n var point = this.imageToViewportCoordinates( pixel );n return this.pixelFromPoint( point, true );n },nn /**n * Convert pixel coordinates relative to the window to image coordinates.n * Note: not accurate with multi-image.n * @param {OpenSeadragon.Point} pixeln * @returns {OpenSeadragon.Point}n */n windowToImageCoordinates: function(pixel) {n $.console.assert(this.viewer,n "[Viewport.windowToImageCoordinates] the viewport must have a viewer.");n var viewerCoordinates = pixel.minus(n $.getElementPosition(this.viewer.element));n return this.viewerElementToImageCoordinates(viewerCoordinates);n },nn /**n * Convert image coordinates to pixel coordinates relative to the window.n * Note: not accurate with multi-image.n * @param {OpenSeadragon.Point} pixeln * @returns {OpenSeadragon.Point}n */n imageToWindowCoordinates: function(pixel) {n $.console.assert(this.viewer,n "[Viewport.imageToWindowCoordinates] the viewport must have a viewer.");n var viewerCoordinates = this.imageToViewerElementCoordinates(pixel);n return viewerCoordinates.plus(n $.getElementPosition(this.viewer.element));n },nn /**n * Convert pixel coordinates relative to the viewer element to viewportn * coordinates.n * @param {OpenSeadragon.Point} pixeln * @returns {OpenSeadragon.Point}n */n viewerElementToViewportCoordinates: function( pixel ) {n return this.pointFromPixel( pixel, true );n },nn /**n * Convert viewport coordinates to pixel coordinates relative to then * viewer element.n * @param {OpenSeadragon.Point} pointn * @returns {OpenSeadragon.Point}n */n viewportToViewerElementCoordinates: function( point ) {n return this.pixelFromPoint( point, true );n },nn /**n * Convert a rectangle in pixel coordinates relative to the viewer elementn * to viewport coordinates.n * @param {OpenSeadragon.Rect} rectangle the rectangle to convertn * @returns {OpenSeadragon.Rect} the converted rectanglen */n viewerElementToViewportRectangle: function(rectangle) {n return $.Rect.fromSummits(n this.pointFromPixel(rectangle.getTopLeft(), true),n this.pointFromPixel(rectangle.getTopRight(), true),n this.pointFromPixel(rectangle.getBottomLeft(), true)n );n },nn /**n * Convert a rectangle in viewport coordinates to pixel coordinates relativen * to the viewer element.n * @param {OpenSeadragon.Rect} rectangle the rectangle to convertn * @returns {OpenSeadragon.Rect} the converted rectanglen */n viewportToViewerElementRectangle: function(rectangle) {n return $.Rect.fromSummits(n this.pixelFromPoint(rectangle.getTopLeft(), true),n this.pixelFromPoint(rectangle.getTopRight(), true),n this.pixelFromPoint(rectangle.getBottomLeft(), true)n );n },nn /**n * Convert pixel coordinates relative to the window to viewport coordinates.n * @param {OpenSeadragon.Point} pixeln * @returns {OpenSeadragon.Point}n */n windowToViewportCoordinates: function(pixel) {n $.console.assert(this.viewer,n "[Viewport.windowToViewportCoordinates] the viewport must have a viewer.");n var viewerCoordinates = pixel.minus(n $.getElementPosition(this.viewer.element));n return this.viewerElementToViewportCoordinates(viewerCoordinates);n },nn /**n * Convert viewport coordinates to pixel coordinates relative to the window.n * @param {OpenSeadragon.Point} pointn * @returns {OpenSeadragon.Point}n */n viewportToWindowCoordinates: function(point) {n $.console.assert(this.viewer,n "[Viewport.viewportToWindowCoordinates] the viewport must have a viewer.");n var viewerCoordinates = this.viewportToViewerElementCoordinates(point);n return viewerCoordinates.plus(n $.getElementPosition(this.viewer.element));n },nn /**n * Convert a viewport zoom to an image zoom.n * Image zoom: ratio of the original image size to displayed image size.n * 1 means original image size, 0.5 half size…n * Viewport zoom: ratio of the displayed image's width to viewport's width.n * 1 means identical width, 2 means image's width is twice the viewport's width…n * Note: not accurate with multi-image.n * @functionn * @param {Number} viewportZoom The viewport zoomn * target zoom.n * @returns {Number} imageZoom The image zoomn */n viewportToImageZoom: function(viewportZoom) {n if (this.viewer) {n var count = this.viewer.world.getItemCount();n if (count > 1) {n $.console.error(‘ is not ' +n 'accurate with multi-image.');n } else if (count === 1) {n // It is better to use TiledImage.viewportToImageZoomn // because this._contentBoundsNoRotate can not be relied onn // with clipping.n var item = this.viewer.world.getItemAt(0);n return item.viewportToImageZoom(viewportZoom);n }n }nn var imageWidth = this._contentSizeNoRotate.x;n var containerWidth = this._containerInnerSize.x;n var scale = this._contentBoundsNoRotate.width;n var viewportToImageZoomRatio = (containerWidth / imageWidth) * scale;n return viewportZoom * viewportToImageZoomRatio;n },nn /**n * Convert an image zoom to a viewport zoom.n * Image zoom: ratio of the original image size to displayed image size.n * 1 means original image size, 0.5 half size…n * Viewport zoom: ratio of the displayed image's width to viewport's width.n * 1 means identical width, 2 means image's width is twice the viewport's width…n * Note: not accurate with multi-image.n * @functionn * @param {Number} imageZoom The image zoomn * target zoom.n * @returns {Number} viewportZoom The viewport zoomn */n imageToViewportZoom: function(imageZoom) {n if (this.viewer) {n var count = this.viewer.world.getItemCount();n if (count > 1) {n $.console.error(’ is not accurate ' +n 'with multi-image.');n } else if (count === 1) {n // It is better to use TiledImage.imageToViewportZoomn // because this._contentBoundsNoRotate can not be relied onn // with clipping.n var item = this.viewer.world.getItemAt(0);n return item.imageToViewportZoom(imageZoom);n }n }nn var imageWidth = this._contentSizeNoRotate.x;n var containerWidth = this._containerInnerSize.x;n var scale = this._contentBoundsNoRotate.width;n var viewportToImageZoomRatio = (imageWidth / containerWidth) / scale;n return imageZoom * viewportToImageZoomRatio;n },nn /**n * Toggles flip state and demands a new drawing on navigator and viewer objects.n * @functionn * @return {OpenSeadragon.Viewport} Chainable.n */n toggleFlip: function() {n this.setFlip(!this.getFlip());n return this;n },nn /**n * Gets flip state stored on viewport.n * @functionn * @return {Boolean} Flip state.n */n getFlip: function() {n return this.flipped;n },nn /**n * Sets flip state according to the state input argument.n * @functionn * @param {Boolean} state - Flip state to set.n * @return {OpenSeadragon.Viewport} Chainable.n */n setFlip: function( state ) {n if ( this.flipped === state ) {n return this;n }nn this.flipped = state;n if(this.viewer.navigator){n this.viewer.navigator.setFlip(this.getFlip());n }n this.viewer.forceRedraw();nn /**n * Raised when flip state has been changed.n *n * @event flipn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {Number} flipped - The flip state after this change.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.viewer.raiseEvent('flip', {"flipped": state});n return this;n }nn};nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - TiledImagen *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * You shouldn't have to create a TiledImage instance directly; get it asynchronously byn * using {@link OpenSeadragon.Viewer#open} or {@link OpenSeadragon.Viewer#addTiledImage} instead.n * @class TiledImagen * @memberof OpenSeadragonn * @extends OpenSeadragon.EventSourcen * @classdesc Handles rendering of tiles for an {@link OpenSeadragon.Viewer}.n * A new instance is created for each TileSource opened.n * @param {Object} options - Configuration for this TiledImage.n * @param {OpenSeadragon.TileSource} options.source - The TileSource that defines this TiledImage.n * @param {OpenSeadragon.Viewer} options.viewer - The Viewer that owns this TiledImage.n * @param {OpenSeadragon.TileCache} options.tileCache - The TileCache for this TiledImage to use.n * @param {OpenSeadragon.Drawer} options.drawer - The Drawer for this TiledImage to draw onto.n * @param {OpenSeadragon.ImageLoader} options.imageLoader - The ImageLoader for this TiledImage to use.n * @param {Number} [options.x=0] - Left position, in viewport coordinates.n * @param {Number} [options.y=0] - Top position, in viewport coordinates.n * @param {Number} [options.width=1] - Width, in viewport coordinates.n * @param {Number} [options.height] - Height, in viewport coordinates.n * @param {OpenSeadragon.Rect} [options.fitBounds] The bounds in viewport coordinatesn * to fit the image into. If specified, x, y, width and height get ignored.n * @param {OpenSeadragon.Placement} [options.fitBoundsPlacement=OpenSeadragon.Placement.CENTER]n * How to anchor the image in the bounds if options.fitBounds is set.n * @param {OpenSeadragon.Rect} [options.clip] - An area, in image pixels, to clip ton * (portions of the image outside of this area will not be visible). Only works onn * browsers that support the HTML5 canvas.n * @param {Number} [options.springStiffness] - See {@link OpenSeadragon.Options}.n * @param {Boolean} [options.animationTime] - See {@link OpenSeadragon.Options}.n * @param {Number} [options.minZoomImageRatio] - See {@link OpenSeadragon.Options}.n * @param {Boolean} [options.wrapHorizontal] - See {@link OpenSeadragon.Options}.n * @param {Boolean} [options.wrapVertical] - See {@link OpenSeadragon.Options}.n * @param {Boolean} [options.immediateRender] - See {@link OpenSeadragon.Options}.n * @param {Number} [options.blendTime] - See {@link OpenSeadragon.Options}.n * @param {Boolean} [options.alwaysBlend] - See {@link OpenSeadragon.Options}.n * @param {Number} [options.minPixelRatio] - See {@link OpenSeadragon.Options}.n * @param {Number} [options.smoothTileEdgesMinZoom] - See {@link OpenSeadragon.Options}.n * @param {Boolean} [options.iOSDevice] - See {@link OpenSeadragon.Options}.n * @param {Number} [options.opacity=1] - Set to draw at proportional opacity. If zero, images will not draw.n * @param {Boolean} [options.preload=false] - Set true to load even when the image is hidden by zero opacity.n * @param {String} [options.compositeOperation] - How the image is composited onto other images; see compositeOperation in {@link OpenSeadragon.Options} for possible values.n * @param {Boolean} [options.debugMode] - See {@link OpenSeadragon.Options}.n * @param {String|CanvasGradient|CanvasPattern|Function} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}.n * @param {String|Boolean} [options.crossOriginPolicy] - See {@link OpenSeadragon.Options}.n * @param {Boolean} [options.ajaxWithCredentials] - See {@link OpenSeadragon.Options}.n * @param {Boolean} [options.loadTilesWithAjax]n * Whether to load tile data using AJAX requests.n * Defaults to the setting in {@link OpenSeadragon.Options}.n * @param {Object} [options.ajaxHeaders={}]n * A set of headers to include when making tile AJAX requests.n */n$.TiledImage = function( options ) {n var _this = this;n /**n * The {@link OpenSeadragon.TileSource} that defines this TiledImage.n * @member {OpenSeadragon.TileSource} sourcen * @memberof OpenSeadragon.TiledImage#n */n $.console.assert( options.tileCache, "[TiledImage] options.tileCache is required" );n $.console.assert( options.drawer, "[TiledImage] options.drawer is required" );n $.console.assert( options.viewer, "[TiledImage] options.viewer is required" );n $.console.assert( options.imageLoader, "[TiledImage] options.imageLoader is required" );n $.console.assert( options.source, "[TiledImage] options.source is required" );n $.console.assert(!options.clip || options.clip instanceof $.Rect,n "[TiledImage] options.clip must be an OpenSeadragon.Rect if present");nn $.EventSource.call( this );nn this._tileCache = options.tileCache;n delete options.tileCache;nn this._drawer = options.drawer;n delete options.drawer;nn this._imageLoader = options.imageLoader;n delete options.imageLoader;nn if (options.clip instanceof $.Rect) {n this._clip = options.clip.clone();n }nn delete options.clip;nn var x = options.x || 0;n delete options.x;n var y = options.y || 0;n delete options.y;nn // Ratio of zoomable image height to width.n this.normHeight = options.source.dimensions.y / options.source.dimensions.x;n this.contentAspectX = options.source.dimensions.x / options.source.dimensions.y;nn var scale = 1;n if ( options.width ) {n scale = options.width;n delete options.width;nn if ( options.height ) {n $.console.error( "specifying both width and height to a tiledImage is not supported" );n delete options.height;n }n } else if ( options.height ) {n scale = options.height / this.normHeight;n delete options.height;n }nn var fitBounds = options.fitBounds;n delete options.fitBounds;n var fitBoundsPlacement = options.fitBoundsPlacement || OpenSeadragon.Placement.CENTER;n delete options.fitBoundsPlacement;nn var degrees = options.degrees || 0;n delete options.degrees;nn $.extend( true, this, {nn //internal state propertiesn viewer: null,n tilesMatrix: {}, // A '3d' dictionary [level][y] –> Tile.n coverage: {}, // A '3d' dictionary [level][y] –> Boolean; shows what areas have been drawn.n loadingCoverage: {}, // A '3d' dictionary [level][y] –> Boolean; shows what areas are loaded or are being loaded/blended.n lastDrawn: [], // An unordered list of Tiles drawn last frame.n lastResetTime: 0, // Last time for which the tiledImage was reset.n _midDraw: false, // Is the tiledImage currently updating the viewport?n _needsDraw: true, // Does the tiledImage need to update the viewport again?n _hasOpaqueTile: false, // Do we have even one fully opaque tile?n _tilesLoading: 0, // The number of pending tile requests.n //configurable settingsn springStiffness: $.DEFAULT_SETTINGS.springStiffness,n animationTime: $.DEFAULT_SETTINGS.animationTime,n minZoomImageRatio: $.DEFAULT_SETTINGS.minZoomImageRatio,n wrapHorizontal: $.DEFAULT_SETTINGS.wrapHorizontal,n wrapVertical: $.DEFAULT_SETTINGS.wrapVertical,n immediateRender: $.DEFAULT_SETTINGS.immediateRender,n blendTime: $.DEFAULT_SETTINGS.blendTime,n alwaysBlend: $.DEFAULT_SETTINGS.alwaysBlend,n minPixelRatio: $.DEFAULT_SETTINGS.minPixelRatio,n smoothTileEdgesMinZoom: $.DEFAULT_SETTINGS.smoothTileEdgesMinZoom,n iOSDevice: $.DEFAULT_SETTINGS.iOSDevice,n debugMode: $.DEFAULT_SETTINGS.debugMode,n crossOriginPolicy: $.DEFAULT_SETTINGS.crossOriginPolicy,n ajaxWithCredentials: $.DEFAULT_SETTINGS.ajaxWithCredentials,n placeholderFillStyle: $.DEFAULT_SETTINGS.placeholderFillStyle,n opacity: $.DEFAULT_SETTINGS.opacity,n preload: $.DEFAULT_SETTINGS.preload,n compositeOperation: $.DEFAULT_SETTINGS.compositeOperationn }, options );nn this._preload = this.preload;n delete this.preload;nn this._fullyLoaded = false;nn this._xSpring = new $.Spring({n initial: x,n springStiffness: this.springStiffness,n animationTime: this.animationTimen });nn this._ySpring = new $.Spring({n initial: y,n springStiffness: this.springStiffness,n animationTime: this.animationTimen });nn this._scaleSpring = new $.Spring({n initial: scale,n springStiffness: this.springStiffness,n animationTime: this.animationTimen });nn this._degreesSpring = new $.Spring({n initial: degrees,n springStiffness: this.springStiffness,n animationTime: this.animationTimen });nn this._updateForScale();nn if (fitBounds) {n this.fitBounds(fitBounds, fitBoundsPlacement, true);n }nn // We need a callback to give image manipulation a chance to happenn this._drawingHandler = function(args) {n /**n * This event is fired just before the tile is drawn giving the application a chance to alter the image.n *n * NOTE: This event is only fired when the drawer is using a &lt;canvas&gt;.n *n * @event tile-drawingn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {OpenSeadragon.Tile} tile - The Tile being drawn.n * @property {OpenSeadragon.TiledImage} tiledImage - Which TiledImage is being drawn.n * @property {OpenSeadragon.Tile} context - The HTML canvas context being drawn into.n * @property {OpenSeadragon.Tile} rendered - The HTML canvas context containing the tile imagery.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n _this.viewer.raiseEvent('tile-drawing', $.extend({n tiledImage: _thisn }, args));n };n};nn$.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.TiledImage.prototype */{n /**n * @returns {Boolean} Whether the TiledImage needs to be drawn.n */n needsDraw: function() {n return this._needsDraw;n },nn /**n * @returns {Boolean} Whether all tiles necessary for this TiledImage to draw at the current view have been loaded.n */n getFullyLoaded: function() {n return this._fullyLoaded;n },nn // privaten _setFullyLoaded: function(flag) {n if (flag === this._fullyLoaded) {n return;n }nn this._fullyLoaded = flag;nn /**n * Fired when the TiledImage's "fully loaded" flag (whether all tiles necessary for this TiledImagen * to draw at the current view have been loaded) changes.n *n * @event fully-loaded-changen * @memberof OpenSeadragon.TiledImagen * @type {object}n * @property {Boolean} fullyLoaded - The new "fully loaded" value.n * @property {OpenSeadragon.TiledImage} eventSource - A reference to the TiledImage which raised the event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent('fully-loaded-change', {n fullyLoaded: this._fullyLoadedn });n },nn /**n * Clears all tiles and triggers an update on the next call ton * {@link OpenSeadragon.TiledImage#update}.n */n reset: function() {n this._tileCache.clearTilesFor(this);n this.lastResetTime = $.now();n this._needsDraw = true;n },nn /**n * Updates the TiledImage's bounds, animating if needed.n * @returns {Boolean} Whether the TiledImage animated.n */n update: function() {n var xUpdated = this._xSpring.update();n var yUpdated = this._ySpring.update();n var scaleUpdated = this._scaleSpring.update();n var degreesUpdated = this._degreesSpring.update();nn if (xUpdated || yUpdated || scaleUpdated || degreesUpdated) {n this._updateForScale();n this._needsDraw = true;n return true;n }nn return false;n },nn /**n * Draws the TiledImage to its Drawer.n */n draw: function() {n if (this.opacity !== 0 || this._preload) {n this._midDraw = true;n this._updateViewport();n this._midDraw = false;n }n // Images with opacity 0 should not need to be drawn in future. this._needsDraw = false is set in this._updateViewport() for other images.n else {n this._needsDraw = false;n }n },nn /**n * Destroy the TiledImage (unload current loaded tiles).n */n destroy: function() {n this.reset();n },nn /**n * Get this TiledImage's bounds in viewport coordinates.n * @param {Boolean} [current=false] - Pass true for the current location;n * false for target location.n * @returns {OpenSeadragon.Rect} This TiledImage's bounds in viewport coordinates.n */n getBounds: function(current) {n return this.getBoundsNoRotate(current)n .rotate(this.getRotation(current), this._getRotationPoint(current));n },nn /**n * Get this TiledImage's bounds in viewport coordinates without takingn * rotation into account.n * @param {Boolean} [current=false] - Pass true for the current location;n * false for target location.n * @returns {OpenSeadragon.Rect} This TiledImage's bounds in viewport coordinates.n */n getBoundsNoRotate: function(current) {n return current ?n new $.Rect(n this._xSpring.current.value,n this._ySpring.current.value,n this._worldWidthCurrent,n this._worldHeightCurrent) :n new $.Rect(n this._xSpring.target.value,n this._ySpring.target.value,n this._worldWidthTarget,n this._worldHeightTarget);n },nn // deprecatedn getWorldBounds: function() {n $.console.error(‘ is deprecated; use TiledImage.getBounds instead');n return this.getBounds();n },nn /**n * Get the bounds of the displayed part of the tiled image.n * @param {Boolean} [current=false] Pass true for the current location,n * false for the target location.n * @returns {$.Rect} The clipped bounds in viewport coordinates.n */n getClippedBounds: function(current) {n var bounds = this.getBoundsNoRotate(current);n if (this._clip) {n var worldWidth = current ?n this._worldWidthCurrent : this._worldWidthTarget;n var ratio = worldWidth / this.source.dimensions.x;n var clip = this._clip.times(ratio);n bounds = new $.Rect(n bounds.x + clip.x,n bounds.y + clip.y,n clip.width,n clip.height);n }n return bounds.rotate(this.getRotation(current), this._getRotationPoint(current));n },nn /**n * @returns {OpenSeadragon.Point} This TiledImage's content size, in original pixels.n */n getContentSize: function() {n return new $.Point(this.source.dimensions.x, this.source.dimensions.y);n },nn // privaten _viewportToImageDelta: function( viewerX, viewerY, current ) {n var scale = (current ? this._scaleSpring.current.value : this._scaleSpring.target.value);n return new $.Point(viewerX * (this.source.dimensions.x / scale),n viewerY * ((this.source.dimensions.y * this.contentAspectX) / scale));n },nn /**n * Translates from OpenSeadragon viewer coordinate system to image coordinate system.n * This method can be called either by passing X,Y coordinates or an {@link OpenSeadragon.Point}.n * @param {Number|OpenSeadragon.Point} viewerX - The X coordinate or point in viewport coordinate system.n * @param {Number} [viewerY] - The Y coordinate in viewport coordinate system.n * @param {Boolean} [current=false] - Pass true to use the current location; false for target location.n * @return {OpenSeadragon.Point} A point representing the coordinates in the image.n */n viewportToImageCoordinates: function(viewerX, viewerY, current) {n var point;n if (viewerX instanceof $.Point) {n //they passed a point instead of individual componentsn current = viewerY;n point = viewerX;n } else {n point = new $.Point(viewerX, viewerY);n }nn point = point.rotate(-this.getRotation(current), this._getRotationPoint(current));n return current ?n this._viewportToImageDelta(n point.x - this._xSpring.current.value,n point.y - this._ySpring.current.value) :n this._viewportToImageDelta(n point.x - this._xSpring.target.value,n point.y - this._ySpring.target.value);n },nn // privaten _imageToViewportDelta: function( imageX, imageY, current ) {n var scale = (current ? this._scaleSpring.current.value : this._scaleSpring.target.value);n return new $.Point((imageX / this.source.dimensions.x) * scale,n (imageY / this.source.dimensions.y / this.contentAspectX) * scale);n },nn /**n * Translates from image coordinate system to OpenSeadragon viewer coordinate systemn * This method can be called either by passing X,Y coordinates or an {@link OpenSeadragon.Point}.n * @param {Number|OpenSeadragon.Point} imageX - The X coordinate or point in image coordinate system.n * @param {Number} [imageY] - The Y coordinate in image coordinate system.n * @param {Boolean} [current=false] - Pass true to use the current location; false for target location.n * @return {OpenSeadragon.Point} A point representing the coordinates in the viewport.n */n imageToViewportCoordinates: function(imageX, imageY, current) {n if (imageX instanceof $.Point) {n //they passed a point instead of individual componentsn current = imageY;n imageY = imageX.y;n imageX = imageX.x;n }nn var point = this._imageToViewportDelta(imageX, imageY);n if (current) {n point.x += this._xSpring.current.value;n point.y += this._ySpring.current.value;n } else {n point.x += this._xSpring.target.value;n point.y += this._ySpring.target.value;n }nn return point.rotate(this.getRotation(current), this._getRotationPoint(current));n },nn /**n * Translates from a rectangle which describes a portion of the image inn * pixel coordinates to OpenSeadragon viewport rectangle coordinates.n * This method can be called either by passing X,Y,width,height or an {@link OpenSeadragon.Rect}.n * @param {Number|OpenSeadragon.Rect} imageX - The left coordinate or rectangle in image coordinate system.n * @param {Number} [imageY] - The top coordinate in image coordinate system.n * @param {Number} [pixelWidth] - The width in pixel of the rectangle.n * @param {Number} [pixelHeight] - The height in pixel of the rectangle.n * @param {Boolean} [current=false] - Pass true to use the current location; false for target location.n * @return {OpenSeadragon.Rect} A rect representing the coordinates in the viewport.n */n imageToViewportRectangle: function(imageX, imageY, pixelWidth, pixelHeight, current) {n var rect = imageX;n if (rect instanceof $.Rect) {n //they passed a rect instead of individual componentsn current = imageY;n } else {n rect = new $.Rect(imageX, imageY, pixelWidth, pixelHeight);n }nn var coordA = this.imageToViewportCoordinates(rect.getTopLeft(), current);n var coordB = this._imageToViewportDelta(rect.width, rect.height, current);nn return new $.Rect(n coordA.x,n coordA.y,n coordB.x,n coordB.y,n rect.degrees + this.getRotation(current)n );n },nn /**n * Translates from a rectangle which describes a portion ofn * the viewport in point coordinates to image rectangle coordinates.n * This method can be called either by passing X,Y,width,height or an {@link OpenSeadragon.Rect}.n * @param {Number|OpenSeadragon.Rect} viewerX - The left coordinate or rectangle in viewport coordinate system.n * @param {Number} [viewerY] - The top coordinate in viewport coordinate system.n * @param {Number} [pointWidth] - The width in viewport coordinate system.n * @param {Number} [pointHeight] - The height in viewport coordinate system.n * @param {Boolean} [current=false] - Pass true to use the current location; false for target location.n * @return {OpenSeadragon.Rect} A rect representing the coordinates in the image.n */n viewportToImageRectangle: function( viewerX, viewerY, pointWidth, pointHeight, current ) {n var rect = viewerX;n if (viewerX instanceof $.Rect) {n //they passed a rect instead of individual componentsn current = viewerY;n } else {n rect = new $.Rect(viewerX, viewerY, pointWidth, pointHeight);n }nn var coordA = this.viewportToImageCoordinates(rect.getTopLeft(), current);n var coordB = this._viewportToImageDelta(rect.width, rect.height, current);nn return new $.Rect(n coordA.x,n coordA.y,n coordB.x,n coordB.y,n rect.degrees - this.getRotation(current)n );n },nn /**n * Convert pixel coordinates relative to the viewer element to imagen * coordinates.n * @param {OpenSeadragon.Point} pixeln * @returns {OpenSeadragon.Point}n */n viewerElementToImageCoordinates: function( pixel ) {n var point = this.viewport.pointFromPixel( pixel, true );n return this.viewportToImageCoordinates( point );n },nn /**n * Convert pixel coordinates relative to the image ton * viewer element coordinates.n * @param {OpenSeadragon.Point} pixeln * @returns {OpenSeadragon.Point}n */n imageToViewerElementCoordinates: function( pixel ) {n var point = this.imageToViewportCoordinates( pixel );n return this.viewport.pixelFromPoint( point, true );n },nn /**n * Convert pixel coordinates relative to the window to image coordinates.n * @param {OpenSeadragon.Point} pixeln * @returns {OpenSeadragon.Point}n */n windowToImageCoordinates: function( pixel ) {n var viewerCoordinates = pixel.minus(n OpenSeadragon.getElementPosition( this.viewer.element ));n return this.viewerElementToImageCoordinates( viewerCoordinates );n },nn /**n * Convert image coordinates to pixel coordinates relative to the window.n * @param {OpenSeadragon.Point} pixeln * @returns {OpenSeadragon.Point}n */n imageToWindowCoordinates: function( pixel ) {n var viewerCoordinates = this.imageToViewerElementCoordinates( pixel );n return viewerCoordinates.plus(n OpenSeadragon.getElementPosition( this.viewer.element ));n },nn // privaten // Convert rectangle in viewport coordinates to this tiled image pointn // coordinates (x in [0, 1] and y in [0, aspectRatio])n _viewportToTiledImageRectangle: function(rect) {n var scale = this._scaleSpring.current.value;n rect = rect.rotate(-this.getRotation(true), this._getRotationPoint(true));n return new $.Rect(n (rect.x - this._xSpring.current.value) / scale,n (rect.y - this._ySpring.current.value) / scale,n rect.width / scale,n rect.height / scale,n rect.degrees);n },nn /**n * Convert a viewport zoom to an image zoom.n * Image zoom: ratio of the original image size to displayed image size.n * 1 means original image size, 0.5 half size…n * Viewport zoom: ratio of the displayed image's width to viewport's width.n * 1 means identical width, 2 means image's width is twice the viewport's width…n * @functionn * @param {Number} viewportZoom The viewport zoomn * @returns {Number} imageZoom The image zoomn */n viewportToImageZoom: function( viewportZoom ) {n var ratio = this._scaleSpring.current.value *n this.viewport._containerInnerSize.x / this.source.dimensions.x;n return ratio * viewportZoom;n },nn /**n * Convert an image zoom to a viewport zoom.n * Image zoom: ratio of the original image size to displayed image size.n * 1 means original image size, 0.5 half size…n * Viewport zoom: ratio of the displayed image's width to viewport's width.n * 1 means identical width, 2 means image's width is twice the viewport's width…n * Note: not accurate with multi-image.n * @functionn * @param {Number} imageZoom The image zoomn * @returns {Number} viewportZoom The viewport zoomn */n imageToViewportZoom: function( imageZoom ) {n var ratio = this._scaleSpring.current.value *n this.viewport._containerInnerSize.x / this.source.dimensions.x;n return imageZoom / ratio;n },nn /**n * Sets the TiledImage's position in the world.n * @param {OpenSeadragon.Point} position - The new position, in viewport coordinates.n * @param {Boolean} [immediately=false] - Whether to animate to the new position or snap immediately.n * @fires OpenSeadragon.TiledImage.event:bounds-changen */n setPosition: function(position, immediately) {n var sameTarget = (this._xSpring.target.value === position.x &&n this._ySpring.target.value === position.y);nn if (immediately) {n if (sameTarget && this._xSpring.current.value === position.x &&n this._ySpring.current.value === position.y) {n return;n }nn this._xSpring.resetTo(position.x);n this._ySpring.resetTo(position.y);n this._needsDraw = true;n } else {n if (sameTarget) {n return;n }nn this._xSpring.springTo(position.x);n this._ySpring.springTo(position.y);n this._needsDraw = true;n }nn if (!sameTarget) {n this._raiseBoundsChange();n }n },nn /**n * Sets the TiledImage's width in the world, adjusting the height to match based on aspect ratio.n * @param {Number} width - The new width, in viewport coordinates.n * @param {Boolean} [immediately=false] - Whether to animate to the new size or snap immediately.n * @fires OpenSeadragon.TiledImage.event:bounds-changen */n setWidth: function(width, immediately) {n this._setScale(width, immediately);n },nn /**n * Sets the TiledImage's height in the world, adjusting the width to match based on aspect ratio.n * @param {Number} height - The new height, in viewport coordinates.n * @param {Boolean} [immediately=false] - Whether to animate to the new size or snap immediately.n * @fires OpenSeadragon.TiledImage.event:bounds-changen */n setHeight: function(height, immediately) {n this._setScale(height / this.normHeight, immediately);n },nn /**n * Positions and scales the TiledImage to fit in the specified bounds.n * Note: this method fires OpenSeadragon.TiledImage.event:bounds-changen * twicen * @param {OpenSeadragon.Rect} bounds The bounds to fit the image into.n * @param {OpenSeadragon.Placement} [anchor=OpenSeadragon.Placement.CENTER]n * How to anchor the image in the bounds.n * @param {Boolean} [immediately=false] Whether to animate to the new sizen * or snap immediately.n * @fires OpenSeadragon.TiledImage.event:bounds-changen */n fitBounds: function(bounds, anchor, immediately) {n anchor = anchor || $.Placement.CENTER;n var anchorProperties = $.Placement.properties;n var aspectRatio = this.contentAspectX;n var xOffset = 0;n var yOffset = 0;n var displayedWidthRatio = 1;n var displayedHeightRatio = 1;n if (this._clip) {n aspectRatio = this._clip.getAspectRatio();n displayedWidthRatio = this._clip.width / this.source.dimensions.x;n displayedHeightRatio = this._clip.height / this.source.dimensions.y;n if (bounds.getAspectRatio() > aspectRatio) {n xOffset = this._clip.x / this._clip.height * bounds.height;n yOffset = this._clip.y / this._clip.height * bounds.height;n } else {n xOffset = this._clip.x / this._clip.width * bounds.width;n yOffset = this._clip.y / this._clip.width * bounds.width;n }n }nn if (bounds.getAspectRatio() > aspectRatio) {n // We will have margins on the X axisn var height = bounds.height / displayedHeightRatio;n var marginLeft = 0;n if (anchorProperties.isHorizontallyCentered) {n marginLeft = (bounds.width - bounds.height * aspectRatio) / 2;n } else if (anchorProperties.isRight) {n marginLeft = bounds.width - bounds.height * aspectRatio;n }n this.setPosition(n new $.Point(bounds.x - xOffset + marginLeft, bounds.y - yOffset),n immediately);n this.setHeight(height, immediately);n } else {n // We will have margins on the Y axisn var width = bounds.width / displayedWidthRatio;n var marginTop = 0;n if (anchorProperties.isVerticallyCentered) {n marginTop = (bounds.height - bounds.width / aspectRatio) / 2;n } else if (anchorProperties.isBottom) {n marginTop = bounds.height - bounds.width / aspectRatio;n }n this.setPosition(n new $.Point(bounds.x - xOffset, bounds.y - yOffset + marginTop),n immediately);n this.setWidth(width, immediately);n }n },nn /**n * @returns {OpenSeadragon.Rect|null} The TiledImage's current clip rectangle,n * in image pixels, or null if none.n */n getClip: function() {n if (this._clip) {n return this._clip.clone();n }nn return null;n },nn /**n * @param {OpenSeadragon.Rect|null} newClip - An area, in image pixels, to clip ton * (portions of the image outside of this area will not be visible). Only works onn * browsers that support the HTML5 canvas.n * @fires OpenSeadragon.TiledImage.event:clip-changen */n setClip: function(newClip) {n $.console.assert(!newClip || newClip instanceof $.Rect,n "[TiledImage.setClip] newClip must be an OpenSeadragon.Rect or null");nn if (newClip instanceof $.Rect) {n this._clip = newClip.clone();n } else {n this._clip = null;n }nn this._needsDraw = true;n /**n * Raised when the TiledImage's clip is changed.n * @event clip-changen * @memberOf OpenSeadragon.TiledImagen * @type {object}n * @property {OpenSeadragon.TiledImage} eventSource - A reference to then * TiledImage which raised the event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent('clip-change');n },nn /**n * @returns {Number} The TiledImage's current opacity.n */n getOpacity: function() {n return this.opacity;n },nn /**n * @param {Number} opacity Opacity the tiled image should be drawn at.n * @fires OpenSeadragon.TiledImage.event:opacity-changen */n setOpacity: function(opacity) {n if (opacity === this.opacity) {n return;n }nn this.opacity = opacity;n this._needsDraw = true;n /**n * Raised when the TiledImage's opacity is changed.n * @event opacity-changen * @memberOf OpenSeadragon.TiledImagen * @type {object}n * @property {Number} opacity - The new opacity value.n * @property {OpenSeadragon.TiledImage} eventSource - A reference to then * TiledImage which raised the event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent('opacity-change', {n opacity: this.opacityn });n },nn /**n * @returns {Boolean} whether the tiledImage can load its tiles even when it has zero opacity.n */n getPreload: function() {n return this._preload;n },nn /**n * Set true to load even when hidden. Set false to block loading when hidden.n */n setPreload: function(preload) {n this._preload = !!preload;n this._needsDraw = true;n },nn /**n * Get the rotation of this tiled image in degrees.n * @param {Boolean} [current=false] True for current rotation, false for target.n * @returns {Number} the rotation of this tiled image in degrees.n */n getRotation: function(current) {n return current ?n this._degreesSpring.current.value :n this._degreesSpring.target.value;n },nn /**n * Set the current rotation of this tiled image in degrees.n * @param {Number} degrees the rotation in degrees.n * @param {Boolean} [immediately=false] Whether to animate to the new anglen * or rotate immediately.n * @fires OpenSeadragon.TiledImage.event:bounds-changen */n setRotation: function(degrees, immediately) {n if (this._degreesSpring.target.value === degrees &&n this._degreesSpring.isAtTargetValue()) {n return;n }n if (immediately) {n this._degreesSpring.resetTo(degrees);n } else {n this._degreesSpring.springTo(degrees);n }n this._needsDraw = true;n this._raiseBoundsChange();n },nn /**n * Get the point around which this tiled image is rotatedn * @privaten * @param {Boolean} current True for current rotation point, false for target.n * @returns {OpenSeadragon.Point}n */n _getRotationPoint: function(current) {n return this.getBoundsNoRotate(current).getCenter();n },nn /**n * @returns {String} The TiledImage's current compositeOperation.n */n getCompositeOperation: function() {n return this.compositeOperation;n },nn /**n * @param {String} compositeOperation the tiled image should be drawn with this globalCompositeOperation.n * @fires OpenSeadragon.TiledImage.event:composite-operation-changen */n setCompositeOperation: function(compositeOperation) {n if (compositeOperation === this.compositeOperation) {n return;n }nn this.compositeOperation = compositeOperation;n this._needsDraw = true;n /**n * Raised when the TiledImage's opacity is changed.n * @event composite-operation-changen * @memberOf OpenSeadragon.TiledImagen * @type {object}n * @property {String} compositeOperation - The new compositeOperation value.n * @property {OpenSeadragon.TiledImage} eventSource - A reference to then * TiledImage which raised the event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent('composite-operation-change', {n compositeOperation: this.compositeOperationn });n },nn // privaten _setScale: function(scale, immediately) {n var sameTarget = (this._scaleSpring.target.value === scale);n if (immediately) {n if (sameTarget && this._scaleSpring.current.value === scale) {n return;n }nn this._scaleSpring.resetTo(scale);n this._updateForScale();n this._needsDraw = true;n } else {n if (sameTarget) {n return;n }nn this._scaleSpring.springTo(scale);n this._updateForScale();n this._needsDraw = true;n }nn if (!sameTarget) {n this._raiseBoundsChange();n }n },nn // privaten _updateForScale: function() {n this._worldWidthTarget = this._scaleSpring.target.value;n this._worldHeightTarget = this.normHeight * this._scaleSpring.target.value;n this._worldWidthCurrent = this._scaleSpring.current.value;n this._worldHeightCurrent = this.normHeight * this._scaleSpring.current.value;n },nn // privaten _raiseBoundsChange: function() {n /**n * Raised when the TiledImage's bounds are changed.n * Note that this event is triggered only when the animation target is changed;n * not for every frame of animation.n * @event bounds-changen * @memberOf OpenSeadragon.TiledImagen * @type {object}n * @property {OpenSeadragon.TiledImage} eventSource - A reference to then * TiledImage which raised the event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent('bounds-change');n },nn // privaten _isBottomItem: function() {n return this.viewer.world.getItemAt(0) === this;n },nn // privaten _getLevelsInterval: function() {n var lowestLevel = Math.max(n this.source.minLevel,n Math.floor(Math.log(this.minZoomImageRatio) / Math.log(2))n );n var currentZeroRatio = this.viewport.deltaPixelsFromPointsNoRotate(n this.source.getPixelRatio(0), true).x *n this._scaleSpring.current.value;n var highestLevel = Math.min(n Math.abs(this.source.maxLevel),n Math.abs(Math.floor(n Math.log(currentZeroRatio / this.minPixelRatio) / Math.log(2)n ))n );nn // Calculations for the interval of levels to drawn // can return invalid intervals; fix that here if necessaryn highestLevel = Math.max(highestLevel, this.source.minLevel || 0);n lowestLevel = Math.min(lowestLevel, highestLevel);n return {n lowestLevel: lowestLevel,n highestLevel: highestLeveln };n },nn /**n * @privaten * @innern * Pretty much every other line in this needs to be documented so it's clearn * how each piece of this routine contributes to the drawing process. That'sn * why there are so many TODO's inside this function.n */n _updateViewport: function() {n this._needsDraw = false;n this._tilesLoading = 0;n this.loadingCoverage = {};nn // Reset tile's internal drawn staten while (this.lastDrawn.length > 0) {n var tile = this.lastDrawn.pop();n tile.beingDrawn = false;n }nn var viewport = this.viewport;n var drawArea = this._viewportToTiledImageRectangle(n viewport.getBoundsWithMargins(true));nn if (!this.wrapHorizontal && !this.wrapVertical) {n var tiledImageBounds = this._viewportToTiledImageRectangle(n this.getClippedBounds(true));n drawArea = drawArea.intersection(tiledImageBounds);n if (drawArea === null) {n return;n }n }nn var levelsInterval = this._getLevelsInterval();n var lowestLevel = levelsInterval.lowestLevel;n var highestLevel = levelsInterval.highestLevel;n var bestTile = null;n var haveDrawn = false;n var currentTime = $.now();nn // Update any level that will be drawnn for (var level = highestLevel; level >= lowestLevel; level–) {n var drawLevel = false;nn //Avoid calculations for draw if we have already drawn thisn var currentRenderPixelRatio = viewport.deltaPixelsFromPointsNoRotate(n this.source.getPixelRatio(level),n truen ).x * this._scaleSpring.current.value;nn if (level === lowestLevel ||n (!haveDrawn && currentRenderPixelRatio >= this.minPixelRatio)) {n drawLevel = true;n haveDrawn = true;n } else if (!haveDrawn) {n continue;n }nn //Perform calculations for draw if we haven't drawn thisn var targetRenderPixelRatio = viewport.deltaPixelsFromPointsNoRotate(n this.source.getPixelRatio(level),n falsen ).x * this._scaleSpring.current.value;nn var targetZeroRatio = viewport.deltaPixelsFromPointsNoRotate(n this.source.getPixelRatio(n Math.max(n this.source.getClosestLevel(),n 0n )n ),n falsen ).x * this._scaleSpring.current.value;nn var optimalRatio = this.immediateRender ? 1 : targetZeroRatio;n var levelOpacity = Math.min(1, (currentRenderPixelRatio - 0.5) / 0.5);n var levelVisibility = optimalRatio / Math.abs(n optimalRatio - targetRenderPixelRation );nn // Update the level and keep track of 'best' tile to loadn bestTile = updateLevel(n this,n haveDrawn,n drawLevel,n level,n levelOpacity,n levelVisibility,n drawArea,n currentTime,n bestTilen );nn // Stop the loop if lower-res tiles would all be covered byn // already drawn tilesn if (providesCoverage(this.coverage, level)) {n break;n }n }nn // Perform the actual drawingn drawTiles(this, this.lastDrawn);nn // Load the new 'best' tilen if (bestTile && !bestTile.context2D) {n loadTile(this, bestTile, currentTime);n this._needsDraw = true;n this._setFullyLoaded(false);n } else {n this._setFullyLoaded(this._tilesLoading === 0);n }n },nn // privaten _getCornerTiles: function(level, topLeftBound, bottomRightBound) {n var leftX;n var rightX;n if (this.wrapHorizontal) {n leftX = $.positiveModulo(topLeftBound.x, 1);n rightX = $.positiveModulo(bottomRightBound.x, 1);n } else {n leftX = Math.max(0, topLeftBound.x);n rightX = Math.min(1, bottomRightBound.x);n }n var topY;n var bottomY;n var aspectRatio = 1 / this.source.aspectRatio;n if (this.wrapVertical) {n topY = $.positiveModulo(topLeftBound.y, aspectRatio);n bottomY = $.positiveModulo(bottomRightBound.y, aspectRatio);n } else {n topY = Math.max(0, topLeftBound.y);n bottomY = Math.min(aspectRatio, bottomRightBound.y);n }nn var topLeftTile = this.source.getTileAtPoint(level, new $.Point(leftX, topY));n var bottomRightTile = this.source.getTileAtPoint(level, new $.Point(rightX, bottomY));n var numTiles = this.source.getNumTiles(level);nn if (this.wrapHorizontal) {n topLeftTile.x += numTiles.x * Math.floor(topLeftBound.x);n bottomRightTile.x += numTiles.x * Math.floor(bottomRightBound.x);n }n if (this.wrapVertical) {n topLeftTile.y += numTiles.y * Math.floor(topLeftBound.y / aspectRatio);n bottomRightTile.y += numTiles.y * Math.floor(bottomRightBound.y / aspectRatio);n }nn return {n topLeft: topLeftTile,n bottomRight: bottomRightTile,n };n }n});nn/**n * @privaten * @innern * Updates all tiles at a given resolution level.n * @param {OpenSeadragon.TiledImage} tiledImage - Which TiledImage is being drawn.n * @param {Boolean} haveDrawnn * @param {Boolean} drawLeveln * @param {Number} leveln * @param {Number} levelOpacityn * @param {Number} levelVisibilityn * @param {OpenSeadragon.Point} viewportTL - The index of the most top-left visible tile.n * @param {OpenSeadragon.Point} viewportBR - The index of the most bottom-right visible tile.n * @param {Number} currentTimen * @param {OpenSeadragon.Tile} best - The current "best" tile to draw.n */nfunction updateLevel(tiledImage, haveDrawn, drawLevel, level, levelOpacity,n levelVisibility, drawArea, currentTime, best) {nn var topLeftBound = drawArea.getBoundingBox().getTopLeft();n var bottomRightBound = drawArea.getBoundingBox().getBottomRight();nn if (tiledImage.viewer) {n /**n * - Needs documentation -n *n * @event update-leveln * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {OpenSeadragon.TiledImage} tiledImage - Which TiledImage is being drawn.n * @property {Object} havedrawnn * @property {Object} leveln * @property {Object} opacityn * @property {Object} visibilityn * @property {OpenSeadragon.Rect} drawArean * @property {Object} topleft deprecated, use drawArea insteadn * @property {Object} bottomright deprecated, use drawArea insteadn * @property {Object} currenttimen * @property {Object} bestn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n tiledImage.viewer.raiseEvent('update-level', {n tiledImage: tiledImage,n havedrawn: haveDrawn,n level: level,n opacity: levelOpacity,n visibility: levelVisibility,n drawArea: drawArea,n topleft: topLeftBound,n bottomright: bottomRightBound,n currenttime: currentTime,n best: bestn });n }nn resetCoverage(tiledImage.coverage, level);n resetCoverage(tiledImage.loadingCoverage, level);nn //OK, a new drawing so do your calculationsn var cornerTiles = tiledImage._getCornerTiles(level, topLeftBound, bottomRightBound);n var topLeftTile = cornerTiles.topLeft;n var bottomRightTile = cornerTiles.bottomRight;n var numberOfTiles = tiledImage.source.getNumTiles(level);nn var viewportCenter = tiledImage.viewport.pixelFromPoint(n tiledImage.viewport.getCenter());n for (var x = topLeftTile.x; x <= bottomRightTile.x; x++) {n for (var y = topLeftTile.y; y <= bottomRightTile.y; y++) {nn // Optimisation disabled with wrapping because getTileBounds does notn // work correctly with x and y outside of the number of tilesn if (!tiledImage.wrapHorizontal && !tiledImage.wrapVertical) {n var tileBounds = tiledImage.source.getTileBounds(level, x, y);n if (drawArea.intersection(tileBounds) === null) {n // This tile is outside of the viewport, no need to draw itn continue;n }n }nn best = updateTile(n tiledImage,n drawLevel,n haveDrawn,n x, y,n level,n levelOpacity,n levelVisibility,n viewportCenter,n numberOfTiles,n currentTime,n bestn );nn }n }nn return best;n}nn/**n * @privaten * @innern * Update a single tile at a particular resolution level.n * @param {OpenSeadragon.TiledImage} tiledImage - Which TiledImage is being drawn.n * @param {Boolean} haveDrawnn * @param {Boolean} drawLeveln * @param {Number} xn * @param {Number} yn * @param {Number} leveln * @param {Number} levelOpacityn * @param {Number} levelVisibilityn * @param {OpenSeadragon.Point} viewportCentern * @param {Number} numberOfTilesn * @param {Number} currentTimen * @param {OpenSeadragon.Tile} best - The current "best" tile to draw.n */nfunction updateTile( tiledImage, haveDrawn, drawLevel, x, y, level, levelOpacity, levelVisibility, viewportCenter, numberOfTiles, currentTime, best){nn var tile = getTile(n x, y,n level,n tiledImage,n tiledImage.source,n tiledImage.tilesMatrix,n currentTime,n numberOfTiles,n tiledImage._worldWidthCurrent,n tiledImage._worldHeightCurrentn ),n drawTile = drawLevel;nn if( tiledImage.viewer ){n /**n * - Needs documentation -n *n * @event update-tilen * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {OpenSeadragon.TiledImage} tiledImage - Which TiledImage is being drawn.n * @property {OpenSeadragon.Tile} tilen * @property {?Object} userData - Arbitrary subscriber-defined object.n */n tiledImage.viewer.raiseEvent( 'update-tile', {n tiledImage: tiledImage,n tile: tilen });n }nn setCoverage( tiledImage.coverage, level, x, y, false );nn var loadingCoverage = tile.loaded || tile.loading || isCovered(tiledImage.loadingCoverage, level, x, y);n setCoverage(tiledImage.loadingCoverage, level, x, y, loadingCoverage);nn if ( !tile.exists ) {n return best;n }nn if ( haveDrawn && !drawTile ) {n if ( isCovered( tiledImage.coverage, level, x, y ) ) {n setCoverage( tiledImage.coverage, level, x, y, true );n } else {n drawTile = true;n }n }nn if ( !drawTile ) {n return best;n }nn positionTile(n tile,n tiledImage.source.tileOverlap,n tiledImage.viewport,n viewportCenter,n levelVisibility,n tiledImagen );nn if (!tile.loaded) {n if (tile.context2D) {n setTileLoaded(tiledImage, tile);n } else {n var imageRecord = tiledImage._tileCache.getImageRecord(tile.cacheKey);n if (imageRecord) {n var image = imageRecord.getImage();n setTileLoaded(tiledImage, tile, image);n }n }n }nn if ( tile.loaded ) {n var needsDraw = blendTile(n tiledImage,n tile,n x, y,n level,n levelOpacity,n currentTimen );nn if ( needsDraw ) {n tiledImage._needsDraw = true;n }n } else if ( tile.loading ) {n // the tile is already in the download queuen tiledImage._tilesLoading++;n } else if (!loadingCoverage) {n best = compareTiles( best, tile );n }nn return best;n}nn/**n * @privaten * @innern * Obtains a tile at the given location.n * @param {Number} xn * @param {Number} yn * @param {Number} leveln * @param {OpenSeadragon.TiledImage} tiledImagen * @param {OpenSeadragon.TileSource} tileSourcen * @param {Object} tilesMatrix - A '3d' dictionary [level][y] –> Tile.n * @param {Number} timen * @param {Number} numTilesn * @param {Number} worldWidthn * @param {Number} worldHeightn * @returns {OpenSeadragon.Tile}n */nfunction getTile(n x, y,n level,n tiledImage,n tileSource,n tilesMatrix,n time,n numTiles,n worldWidth,n worldHeightn) {n var xMod,n yMod,n bounds,n sourceBounds,n exists,n url,n ajaxHeaders,n context2D,n tile;nn if ( !tilesMatrix[ level ] ) {n tilesMatrix[ level ] = {};n }n if ( !tilesMatrix[ level ][ x ] ) {n tilesMatrix[ level ][ x ] = {};n }nn if ( !tilesMatrix[ level ][ x ][ y ] ) {n xMod = ( numTiles.x + ( x % numTiles.x ) ) % numTiles.x;n yMod = ( numTiles.y + ( y % numTiles.y ) ) % numTiles.y;n bounds = tileSource.getTileBounds( level, xMod, yMod );n sourceBounds = tileSource.getTileBounds( level, xMod, yMod, true );n exists = tileSource.tileExists( level, xMod, yMod );n url = tileSource.getTileUrl( level, xMod, yMod );nn // Headers are only applicable if loadTilesWithAjax is setn if (tiledImage.loadTilesWithAjax) {n ajaxHeaders = tileSource.getTileAjaxHeaders( level, xMod, yMod );n // Combine tile AJAX headers with tiled image AJAX headers (if applicable)n if ($.isPlainObject(tiledImage.ajaxHeaders)) {n ajaxHeaders = $.extend({}, tiledImage.ajaxHeaders, ajaxHeaders);n }n } else {n ajaxHeaders = null;n }nn context2D = tileSource.getContext2D ?n tileSource.getContext2D(level, xMod, yMod) : undefined;nn bounds.x += ( x - xMod ) / numTiles.x;n bounds.y += (worldHeight / worldWidth) * (( y - yMod ) / numTiles.y);nn tile = new $.Tile(n level,n x,n y,n bounds,n exists,n url,n context2D,n tiledImage.loadTilesWithAjax,n ajaxHeaders,n sourceBoundsn );nn if (xMod === numTiles.x - 1) {n tile.isRightMost = true;n }nn if (yMod === numTiles.y - 1) {n tile.isBottomMost = true;n }nn tilesMatrix[ level ][ x ][ y ] = tile;n }nn tile = tilesMatrix[ level ][ x ][ y ];n tile.lastTouchTime = time;nn return tile;n}nn/**n * @privaten * @innern * Dispatch a job to the ImageLoader to load the Image for a Tile.n * @param {OpenSeadragon.TiledImage} tiledImagen * @param {OpenSeadragon.Tile} tilen * @param {Number} timen */nfunction loadTile( tiledImage, tile, time ) {n tile.loading = true;n tiledImage._imageLoader.addJob({n src: tile.url,n loadWithAjax: tile.loadWithAjax,n ajaxHeaders: tile.ajaxHeaders,n crossOriginPolicy: tiledImage.crossOriginPolicy,n ajaxWithCredentials: tiledImage.ajaxWithCredentials,n callback: function( image, errorMsg, tileRequest ){n onTileLoad( tiledImage, tile, time, image, errorMsg, tileRequest );n },n abort: function() {n tile.loading = false;n }n });n}nn/**n * @privaten * @innern * Callback fired when a Tile's Image finished downloading.n * @param {OpenSeadragon.TiledImage} tiledImagen * @param {OpenSeadragon.Tile} tilen * @param {Number} timen * @param {Image} imagen * @param {String} errorMsgn * @param {XMLHttpRequest} tileRequestn */nfunction onTileLoad( tiledImage, tile, time, image, errorMsg, tileRequest ) {n if ( !image ) {n $.console.log( "Tile %s failed to load: %s - error: %s", tile, tile.url, errorMsg );n /**n * Triggered when a tile fails to load.n *n * @event tile-load-failedn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Tile} tile - The tile that failed to load.n * @property {OpenSeadragon.TiledImage} tiledImage - The tiled image the tile belongs to.n * @property {number} time - The time in milliseconds when the tile load began.n * @property {string} message - The error message.n * @property {XMLHttpRequest} tileRequest - The XMLHttpRequest used to load the tile if available.n */n tiledImage.viewer.raiseEvent("tile-load-failed", {n tile: tile,n tiledImage: tiledImage,n time: time,n message: errorMsg,n tileRequest: tileRequestn });n tile.loading = false;n tile.exists = false;n return;n }nn if ( time < tiledImage.lastResetTime ) {n $.console.log( "Ignoring tile %s loaded before reset: %s", tile, tile.url );n tile.loading = false;n return;n }nn var finish = function() {n var cutoff = tiledImage.source.getClosestLevel();n setTileLoaded(tiledImage, tile, image, cutoff, tileRequest);n };nn // Check if we're mid-update; this can happen on IE8 because image load events forn // cached images happen immediately theren if ( !tiledImage._midDraw ) {n finish();n } else {n // Wait until after the update, in case caching unloads any tilesn window.setTimeout( finish, 1);n }n}nn/**n * @privaten * @innern * @param {OpenSeadragon.TiledImage} tiledImagen * @param {OpenSeadragon.Tile} tilen * @param {Image} imagen * @param {Number} cutoffn */nfunction setTileLoaded(tiledImage, tile, image, cutoff, tileRequest) {n var increment = 0;nn function getCompletionCallback() {n increment++;n return completionCallback;n }nn function completionCallback() {n increment–;n if (increment === 0) {n tile.loading = false;n tile.loaded = true;n if (!tile.context2D) {n tiledImage._tileCache.cacheTile({n image: image,n tile: tile,n cutoff: cutoff,n tiledImage: tiledImagen });n }n tiledImage._needsDraw = true;n }n }nn /**n * Triggered when a tile has just been loaded in memory. That means that then * image has been downloaded and can be modified before being drawn to the canvas.n *n * @event tile-loadedn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {Image} image - The image of the tile.n * @property {OpenSeadragon.TiledImage} tiledImage - The tiled image of the loaded tile.n * @property {OpenSeadragon.Tile} tile - The tile which has been loaded.n * @property {XMLHttpRequest} tiledImage - The AJAX request that loaded this tile (if applicable).n * @property {function} getCompletionCallback - A function giving a callback to calln * when the asynchronous processing of the image is done. The image will ben * marked as entirely loaded when the callback has been called once for eachn * call to getCompletionCallback.n */n tiledImage.viewer.raiseEvent("tile-loaded", {n tile: tile,n tiledImage: tiledImage,n tileRequest: tileRequest,n image: image,n getCompletionCallback: getCompletionCallbackn });n // In case the completion callback is never called, we at least force it once.n getCompletionCallback()();n}nn/**n * @privaten * @innern * @param {OpenSeadragon.Tile} tilen * @param {Boolean} overlapn * @param {OpenSeadragon.Viewport} viewportn * @param {OpenSeadragon.Point} viewportCentern * @param {Number} levelVisibilityn * @param {OpenSeadragon.TiledImage} tiledImagen */nfunction positionTile( tile, overlap, viewport, viewportCenter, levelVisibility, tiledImage ){n var boundsTL = tile.bounds.getTopLeft();nn boundsTL.x *= tiledImage._scaleSpring.current.value;n boundsTL.y *= tiledImage._scaleSpring.current.value;n boundsTL.x += tiledImage._xSpring.current.value;n boundsTL.y += tiledImage._ySpring.current.value;nn var boundsSize = tile.bounds.getSize();nn boundsSize.x *= tiledImage._scaleSpring.current.value;n boundsSize.y *= tiledImage._scaleSpring.current.value;nn var positionC = viewport.pixelFromPointNoRotate(boundsTL, true),n positionT = viewport.pixelFromPointNoRotate(boundsTL, false),n sizeC = viewport.deltaPixelsFromPointsNoRotate(boundsSize, true),n sizeT = viewport.deltaPixelsFromPointsNoRotate(boundsSize, false),n tileCenter = positionT.plus( sizeT.divide( 2 ) ),n tileSquaredDistance = viewportCenter.squaredDistanceTo( tileCenter );nn if ( !overlap ) {n sizeC = sizeC.plus( new $.Point( 1, 1 ) );n }nn if (tile.isRightMost && tiledImage.wrapHorizontal) {n sizeC.x += 0.75; // Otherwise Firefox and Safari show seamsn }nn if (tile.isBottomMost && tiledImage.wrapVertical) {n sizeC.y += 0.75; // Otherwise Firefox and Safari show seamsn }nn tile.position = positionC;n tile.size = sizeC;n tile.squaredDistance = tileSquaredDistance;n tile.visibility = levelVisibility;n}nn/**n * @privaten * @innern * Updates the opacity of a tile according to the time it has been on screenn * to perform a fade-in.n * Updates coverage once a tile is fully opaque.n * Returns whether the fade-in has completed.n *n * @param {OpenSeadragon.TiledImage} tiledImagen * @param {OpenSeadragon.Tile} tilen * @param {Number} xn * @param {Number} yn * @param {Number} leveln * @param {Number} levelOpacityn * @param {Number} currentTimen * @returns {Boolean}n */nfunction blendTile( tiledImage, tile, x, y, level, levelOpacity, currentTime ){n var blendTimeMillis = 1000 * tiledImage.blendTime,n deltaTime,n opacity;nn if ( !tile.blendStart ) {n tile.blendStart = currentTime;n }nn deltaTime = currentTime - tile.blendStart;n opacity = blendTimeMillis ? Math.min( 1, deltaTime / ( blendTimeMillis ) ) : 1;nn if ( tiledImage.alwaysBlend ) {n opacity *= levelOpacity;n }nn tile.opacity = opacity;nn tiledImage.lastDrawn.push( tile );nn if ( opacity == 1 ) {n setCoverage( tiledImage.coverage, level, x, y, true );n tiledImage._hasOpaqueTile = true;n } else if ( deltaTime < blendTimeMillis ) {n return true;n }nn return false;n}nn/**n * @privaten * @innern * Returns true if the given tile provides coverage to lower-level tiles ofn * lower resolution representing the same content. If neither x nor y isn * given, returns true if the entire visible level provides coverage.n *n * Note that out-of-bounds tiles provide coverage in this sense, sincen * there's no content that they would need to cover. Tiles at non-existentn * levels that are within the image bounds, however, do not.n *n * @param {Object} coverage - A '3d' dictionary [level][y] –> Boolean.n * @param {Number} level - The resolution level of the tile.n * @param {Number} x - The X position of the tile.n * @param {Number} y - The Y position of the tile.n * @returns {Boolean}n */nfunction providesCoverage( coverage, level, x, y ) {n var rows,n cols,n i, j;nn if ( !coverage[ level ] ) {n return false;n }nn if ( x === undefined || y === undefined ) {n rows = coverage[ level ];n for ( i in rows ) {n if ( rows.hasOwnProperty( i ) ) {n cols = rows[ i ];n for ( j in cols ) {n if ( cols.hasOwnProperty( j ) && !cols[ j ] ) {n return false;n }n }n }n }nn return true;n }nn return (n coverage[ level ][ x] === undefined ||n coverage[ level ][ x ][ y ] === undefined ||n coverage[ level ][ x ][ y ] === truen );n}nn/**n * @privaten * @innern * Returns true if the given tile is completely covered by higher-leveln * tiles of higher resolution representing the same content. If neither xn * nor y is given, returns true if the entire visible level is covered.n *n * @param {Object} coverage - A '3d' dictionary [level][y] –> Boolean.n * @param {Number} level - The resolution level of the tile.n * @param {Number} x - The X position of the tile.n * @param {Number} y - The Y position of the tile.n * @returns {Boolean}n */nfunction isCovered( coverage, level, x, y ) {n if ( x === undefined || y === undefined ) {n return providesCoverage( coverage, level + 1 );n } else {n return (n providesCoverage( coverage, level + 1, 2 * x, 2 * y ) &&n providesCoverage( coverage, level + 1, 2 * x, 2 * y + 1 ) &&n providesCoverage( coverage, level + 1, 2 * x + 1, 2 * y ) &&n providesCoverage( coverage, level + 1, 2 * x + 1, 2 * y + 1 )n );n }n}nn/**n * @privaten * @innern * Sets whether the given tile provides coverage or not.n *n * @param {Object} coverage - A '3d' dictionary [level][y] –> Boolean.n * @param {Number} level - The resolution level of the tile.n * @param {Number} x - The X position of the tile.n * @param {Number} y - The Y position of the tile.n * @param {Boolean} covers - Whether the tile provides coverage.n */nfunction setCoverage( coverage, level, x, y, covers ) {n if ( !coverage[ level ] ) {n $.console.warn(n "Setting coverage for a tile before its level's coverage has been reset: %s",n leveln );n return;n }nn if ( !coverage[ level ][ x ] ) {n coverage[ level ][ x ] = {};n }nn coverage[ level ][ x ][ y ] = covers;n}nn/**n * @privaten * @innern * Resets coverage information for the given level. This should be calledn * after every draw routine. Note that at the beginning of the next drawn * routine, coverage for every visible tile should be explicitly set.n *n * @param {Object} coverage - A '3d' dictionary [level][y] –> Boolean.n * @param {Number} level - The resolution level of tiles to completely reset.n */nfunction resetCoverage( coverage, level ) {n coverage[ level ] = {};n}nn/**n * @privaten * @innern * Determines whether the 'last best' tile for the area is better than then * tile in question.n *n * @param {OpenSeadragon.Tile} previousBestn * @param {OpenSeadragon.Tile} tilen * @returns {OpenSeadragon.Tile} The new best tile.n */nfunction compareTiles( previousBest, tile ) {n if ( !previousBest ) {n return tile;n }nn if ( tile.visibility > previousBest.visibility ) {n return tile;n } else if ( tile.visibility == previousBest.visibility ) {n if ( tile.squaredDistance < previousBest.squaredDistance ) {n return tile;n }n }nn return previousBest;n}nn/**n * @privaten * @innern * Draws a TiledImage.n * @param {OpenSeadragon.TiledImage} tiledImagen * @param {OpenSeadragon.Tile[]} lastDrawn - An unordered list of Tiles drawn last frame.n */nfunction drawTiles( tiledImage, lastDrawn ) {n if (tiledImage.opacity === 0 || (lastDrawn.length === 0 && !tiledImage.placeholderFillStyle)) {n return;n }nn var tile = lastDrawn;n var useSketch;nn if (tile) {n useSketch = tiledImage.opacity < 1 ||n (tiledImage.compositeOperation &&n tiledImage.compositeOperation !== 'source-over') ||n (!tiledImage._isBottomItem() && tile._hasTransparencyChannel());n }nn var sketchScale;n var sketchTranslate;nn var zoom = tiledImage.viewport.getZoom(true);n var imageZoom = tiledImage.viewportToImageZoom(zoom);nn if (lastDrawn.length > 1 &&n imageZoom > tiledImage.smoothTileEdgesMinZoom &&n !tiledImage.iOSDevice &&n tiledImage.getRotation(true) % 360 === 0 && // TODO: support tile edge smoothing with tiled image rotation.n $.supportsCanvas) {n // When zoomed in a lot (>100%) the tile edges are visible.n // So we have to composite them at ~100% and scale them up together.n // Note: Disabled on iOS devices per default as it causes a native crashn useSketch = true;n sketchScale = tile.getScaleForEdgeSmoothing();n sketchTranslate = tile.getTranslationForEdgeSmoothing(sketchScale,n tiledImage._drawer.getCanvasSize(false),n tiledImage._drawer.getCanvasSize(true));n }nn var bounds;n if (useSketch) {n if (!sketchScale) {n // Except when edge smoothing, we only clean the part of then // sketch canvas we are going to use for performance reasons.n bounds = tiledImage.viewport.viewportToViewerElementRectangle(n tiledImage.getClippedBounds(true))n .getIntegerBoundingBox()n .times($.pixelDensityRatio);n }n tiledImage._drawer._clear(true, bounds);n }nn // When scaling, we must rotate only when blending the sketch canvas ton // avoid interpolationn if (!sketchScale) {n if (tiledImage.viewport.degrees !== 0) {n tiledImage._drawer._offsetForRotation({n degrees: tiledImage.viewport.degrees,n useSketch: useSketchn });n } else {n if(tiledImage._drawer.viewer.viewport.flipped) {n tiledImage._drawer._flip({});n }n }n if (tiledImage.getRotation(true) % 360 !== 0) {n tiledImage._drawer._offsetForRotation({n degrees: tiledImage.getRotation(true),n point: tiledImage.viewport.pixelFromPointNoRotate(n tiledImage._getRotationPoint(true), true),n useSketch: useSketchn });n }n }nn var usedClip = false;n if ( tiledImage._clip ) {n tiledImage._drawer.saveContext(useSketch);nn var box = tiledImage.imageToViewportRectangle(tiledImage._clip, true);n box = box.rotate(-tiledImage.getRotation(true), tiledImage._getRotationPoint(true));n var clipRect = tiledImage._drawer.viewportToDrawerRectangle(box);n if (sketchScale) {n clipRect = clipRect.times(sketchScale);n }n if (sketchTranslate) {n clipRect = clipRect.translate(sketchTranslate);n }n tiledImage._drawer.setClip(clipRect, useSketch);nn usedClip = true;n }nn if ( tiledImage.placeholderFillStyle && tiledImage._hasOpaqueTile === false ) {n var placeholderRect = tiledImage._drawer.viewportToDrawerRectangle(tiledImage.getBounds(true));n if (sketchScale) {n placeholderRect = placeholderRect.times(sketchScale);n }n if (sketchTranslate) {n placeholderRect = placeholderRect.translate(sketchTranslate);n }nn var fillStyle = null;n if ( typeof tiledImage.placeholderFillStyle === "function" ) {n fillStyle = tiledImage.placeholderFillStyle(tiledImage, tiledImage._drawer.context);n }n else {n fillStyle = tiledImage.placeholderFillStyle;n }nn tiledImage._drawer.drawRectangle(placeholderRect, fillStyle, useSketch);n }nn for (var i = lastDrawn.length - 1; i >= 0; i–) {n tile = lastDrawn[ i ];n tiledImage._drawer.drawTile( tile, tiledImage._drawingHandler, useSketch, sketchScale, sketchTranslate );n tile.beingDrawn = true;nn if( tiledImage.viewer ){n /**n * - Needs documentation -n *n * @event tile-drawnn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.n * @property {OpenSeadragon.TiledImage} tiledImage - Which TiledImage is being drawn.n * @property {OpenSeadragon.Tile} tilen * @property {?Object} userData - Arbitrary subscriber-defined object.n */n tiledImage.viewer.raiseEvent( 'tile-drawn', {n tiledImage: tiledImage,n tile: tilen });n }n }nn if ( usedClip ) {n tiledImage._drawer.restoreContext( useSketch );n }nn if (!sketchScale) {n if (tiledImage.getRotation(true) % 360 !== 0) {n tiledImage._drawer._restoreRotationChanges(useSketch);n }n if (tiledImage.viewport.degrees !== 0) {n tiledImage._drawer._restoreRotationChanges(useSketch);n } else{n if(tiledImage._drawer.viewer.viewport.flipped) {n tiledImage._drawer._flip({});n }n }n }nn if (useSketch) {n if (sketchScale) {n if (tiledImage.viewport.degrees !== 0) {n tiledImage._drawer._offsetForRotation({n degrees: tiledImage.viewport.degrees,n useSketch: falsen });n }n if (tiledImage.getRotation(true) % 360 !== 0) {n tiledImage._drawer._offsetForRotation({n degrees: tiledImage.getRotation(true),n point: tiledImage.viewport.pixelFromPointNoRotate(n tiledImage._getRotationPoint(true), true),n useSketch: falsen });n }n }n tiledImage._drawer.blendSketch({n opacity: tiledImage.opacity,n scale: sketchScale,n translate: sketchTranslate,n compositeOperation: tiledImage.compositeOperation,n bounds: boundsn });n if (sketchScale) {n if (tiledImage.getRotation(true) % 360 !== 0) {n tiledImage._drawer._restoreRotationChanges(false);n }n if (tiledImage.viewport.degrees !== 0) {n tiledImage._drawer._restoreRotationChanges(false);n }n }n }n drawDebugInfo( tiledImage, lastDrawn );n}nn/**n * @privaten * @innern * Draws special debug information for a TiledImage if in debug mode.n * @param {OpenSeadragon.TiledImage} tiledImagen * @param {OpenSeadragon.Tile[]} lastDrawn - An unordered list of Tiles drawn last frame.n */nfunction drawDebugInfo( tiledImage, lastDrawn ) {n if( tiledImage.debugMode ) {n for ( var i = lastDrawn.length - 1; i >= 0; i– ) {n var tile = lastDrawn[ i ];n try {n tiledImage._drawer.drawDebugInfo(n tile, lastDrawn.length, i, tiledImage);n } catch(e) {n $.console.error(e);n }n }n }n}nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - TileCachen *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn// private classnvar TileRecord = function( options ) {n $.console.assert( options, "[TileCache.cacheTile] options is required" );n $.console.assert( options.tile, "[TileCache.cacheTile] options.tile is required" );n $.console.assert( options.tiledImage, "[TileCache.cacheTile] options.tiledImage is required" );n this.tile = options.tile;n this.tiledImage = options.tiledImage;n};nn// private classnvar ImageRecord = function(options) {n $.console.assert( options, "[ImageRecord] options is required" );n $.console.assert( options.image, "[ImageRecord] options.image is required" );n this._image = options.image;n this._tiles = [];n};nnImageRecord.prototype = {n destroy: function() {n this._image = null;n this._renderedContext = null;n this._tiles = null;n },nn getImage: function() {n return this._image;n },nn getRenderedContext: function() {n if (!this._renderedContext) {n var canvas = document.createElement( 'canvas' );n canvas.width = this._image.width;n canvas.height = this._image.height;n this._renderedContext = canvas.getContext('2d');n this._renderedContext.drawImage( this._image, 0, 0 );n //since we are caching the prerendered image on a canvasn //allow the image to not be held in memoryn this._image = null;n }n return this._renderedContext;n },nn setRenderedContext: function(renderedContext) {n $.console.error("ImageRecord.setRenderedContext is deprecated. " +n "The rendered context should be created by the ImageRecord " +n "itself when calling ImageRecord.getRenderedContext.");n this._renderedContext = renderedContext;n },nn addTile: function(tile) {n $.console.assert(tile, '[ImageRecord.addTile] tile is required');n this._tiles.push(tile);n },nn removeTile: function(tile) {n for (var i = 0; i < this._tiles.length; i++) {n if (this._tiles === tile) {n this._tiles.splice(i, 1);n return;n }n }nn $.console.warn(’ trying to remove unknown tile', tile);n },nn getTileCount: function() {n return this._tiles.length;n }n};nn/**n * @class TileCachen * @memberof OpenSeadragonn * @classdesc Stores all the tiles displayed in a {@link OpenSeadragon.Viewer}.n * You generally won't have to interact with the TileCache directly.n * @param {Object} options - Configuration for this TileCache.n * @param {Number} [options.maxImageCacheCount] - See maxImageCacheCount inn * {@link OpenSeadragon.Options} for details.n */n$.TileCache = function( options ) {n options = options || {};nn this._maxImageCacheCount = options.maxImageCacheCount || $.DEFAULT_SETTINGS.maxImageCacheCount;n this._tilesLoaded = [];n this._imagesLoaded = [];n this._imagesLoadedCount = 0;n};nn/** @lends OpenSeadragon.TileCache.prototype */n$.TileCache.prototype = {n /**n * @returns {Number} The total number of tiles that have been loaded byn * this TileCache.n */n numTilesLoaded: function() {n return this._tilesLoaded.length;n },nn /**n * Caches the specified tile, removing an old tile if necessary to stay under then * maxImageCacheCount specified on construction. Note that if multiple tiles referencen * the same image, there may be more tiles than maxImageCacheCount; the goal is to keepn * the number of images below that number. Note, as well, that even the number of imagesn * may temporarily surpass that number, but should eventually come back down to the max specified.n * @param {Object} options - Tile info.n * @param {OpenSeadragon.Tile} options.tile - The tile to cache.n * @param {String} options.tile.cacheKey - The unique key used to identify this tile in the cache.n * @param {Image} options.image - The image of the tile to cache.n * @param {OpenSeadragon.TiledImage} options.tiledImage - The TiledImage that owns that tile.n * @param {Number} [options.cutoff=0] - If adding this tile goes over the cache max count, thisn * function will release an old tile. The cutoff option specifies a tile level at or below whichn * tiles will not be released.n */n cacheTile: function( options ) {n $.console.assert( options, "[TileCache.cacheTile] options is required" );n $.console.assert( options.tile, "[TileCache.cacheTile] options.tile is required" );n $.console.assert( options.tile.cacheKey, "[TileCache.cacheTile] options.tile.cacheKey is required" );n $.console.assert( options.tiledImage, "[TileCache.cacheTile] options.tiledImage is required" );nn var cutoff = options.cutoff || 0;n var insertionIndex = this._tilesLoaded.length;nn var imageRecord = this._imagesLoaded;n if (!imageRecord) {n $.console.assert( options.image, "[TileCache.cacheTile] options.image is required to create an ImageRecord" );n imageRecord = this._imagesLoaded = new ImageRecord({n image: options.imagen });nn this._imagesLoadedCount++;n }nn imageRecord.addTile(options.tile);n options.tile.cacheImageRecord = imageRecord;nn // Note that just because we're unloading a tile doesn't necessarily meann // we're unloading an image. With repeated calls it should sort itself out, though.n if ( this._imagesLoadedCount > this._maxImageCacheCount ) {n var worstTile = null;n var worstTileIndex = -1;n var worstTileRecord = null;n var prevTile, worstTime, worstLevel, prevTime, prevLevel, prevTileRecord;nn for ( var i = this._tilesLoaded.length - 1; i >= 0; i– ) {n prevTileRecord = this._tilesLoaded[ i ];n prevTile = prevTileRecord.tile;nn if ( prevTile.level <= cutoff || prevTile.beingDrawn ) {n continue;n } else if ( !worstTile ) {n worstTile = prevTile;n worstTileIndex = i;n worstTileRecord = prevTileRecord;n continue;n }nn prevTime = prevTile.lastTouchTime;n worstTime = worstTile.lastTouchTime;n prevLevel = prevTile.level;n worstLevel = worstTile.level;nn if ( prevTime < worstTime ||n ( prevTime == worstTime && prevLevel > worstLevel ) ) {n worstTile = prevTile;n worstTileIndex = i;n worstTileRecord = prevTileRecord;n }n }nn if ( worstTile && worstTileIndex >= 0 ) {n this._unloadTile(worstTileRecord);n insertionIndex = worstTileIndex;n }n }nn this._tilesLoaded[ insertionIndex ] = new TileRecord({n tile: options.tile,n tiledImage: options.tiledImagen });n },nn /**n * Clears all tiles associated with the specified tiledImage.n * @param {OpenSeadragon.TiledImage} tiledImagen */n clearTilesFor: function( tiledImage ) {n $.console.assert(tiledImage, '[TileCache.clearTilesFor] tiledImage is required');n var tileRecord;n for ( var i = 0; i < this._tilesLoaded.length; ++i ) {n tileRecord = this._tilesLoaded[ i ];n if ( tileRecord.tiledImage === tiledImage ) {n this._unloadTile(tileRecord);n this._tilesLoaded.splice( i, 1 );n i–;n }n }n },nn // privaten getImageRecord: function(cacheKey) {n $.console.assert(cacheKey, '[TileCache.getImageRecord] cacheKey is required');n return this._imagesLoaded;n },nn // privaten _unloadTile: function(tileRecord) {n $.console.assert(tileRecord, '[TileCache._unloadTile] tileRecord is required');n var tile = tileRecord.tile;n var tiledImage = tileRecord.tiledImage;nn tile.unload();n tile.cacheImageRecord = null;nn var imageRecord = this._imagesLoaded;n imageRecord.removeTile(tile);n if (!imageRecord.getTileCount()) {n imageRecord.destroy();n delete this._imagesLoaded;n this._imagesLoadedCount–;n }nn /**n * Triggered when a tile has just been unloaded from memory.n *n * @event tile-unloadedn * @memberof OpenSeadragon.Viewern * @type {object}n * @property {OpenSeadragon.TiledImage} tiledImage - The tiled image of the unloaded tile.n * @property {OpenSeadragon.Tile} tile - The tile which has been unloaded.n */n tiledImage.viewer.raiseEvent("tile-unloaded", {n tile: tile,n tiledImage: tiledImagen });n }n};nn}( OpenSeadragon ));n”,“/*n * OpenSeadragon - Worldn *n * Copyright (C) 2009 CodePlex Foundationn * Copyright (C) 2010-2013 OpenSeadragon contributorsn *n * Redistribution and use in source and binary forms, with or withoutn * modification, are permitted provided that the following conditions aren * met:n *n * - Redistributions of source code must retain the above copyright notice,n * this list of conditions and the following disclaimer.n *n * - Redistributions in binary form must reproduce the above copyrightn * notice, this list of conditions and the following disclaimer in then * documentation and/or other materials provided with the distribution.n *n * - Neither the name of CodePlex Foundation nor the names of itsn * contributors may be used to endorse or promote products derived fromn * this software without specific prior written permission.n *n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORSn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTn * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITEDn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.n */nn(function( $ ){nn/**n * @class Worldn * @memberof OpenSeadragonn * @extends OpenSeadragon.EventSourcen * @classdesc Keeps track of all of the tiled images in the scene.n * @param {Object} options - World options.n * @param {OpenSeadragon.Viewer} options.viewer - The Viewer that owns this World.n **/n$.World = function( options ) {n var _this = this;nn $.console.assert( options.viewer, "[World] options.viewer is required" );nn $.EventSource.call( this );nn this.viewer = options.viewer;n this._items = [];n this._needsDraw = false;n this._autoRefigureSizes = true;n this._needsSizesFigured = false;n this._delegatedFigureSizes = function(event) {n if (_this._autoRefigureSizes) {n _this._figureSizes();n } else {n _this._needsSizesFigured = true;n }n };nn this._figureSizes();n};nn$.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.World.prototype */{n /**n * Add the specified item.n * @param {OpenSeadragon.TiledImage} item - The item to add.n * @param {Number} [options.index] - Index for the item. If not specified, goes at the top.n * @fires OpenSeadragon.World.event:add-itemn * @fires OpenSeadragon.World.event:metrics-changen */n addItem: function( item, options ) {n $.console.assert(item, "[World.addItem] item is required");n $.console.assert(item instanceof $.TiledImage, "[World.addItem] only TiledImages supported at this time");nn options = options || {};n if (options.index !== undefined) {n var index = Math.max(0, Math.min(this._items.length, options.index));n this._items.splice(index, 0, item);n } else {n this._items.push( item );n }nn if (this._autoRefigureSizes) {n this._figureSizes();n } else {n this._needsSizesFigured = true;n }nn this._needsDraw = true;nn item.addHandler('bounds-change', this._delegatedFigureSizes);n item.addHandler('clip-change', this._delegatedFigureSizes);nn /**n * Raised when an item is added to the World.n * @event add-itemn * @memberOf OpenSeadragon.Worldn * @type {object}n * @property {OpenSeadragon.Viewer} eventSource - A reference to the World which raised the event.n * @property {OpenSeadragon.TiledImage} item - The item that has been added.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'add-item', {n item: itemn } );n },nn /**n * Get the item at the specified index.n * @param {Number} index - The item's index.n * @returns {OpenSeadragon.TiledImage} The item at the specified index.n */n getItemAt: function( index ) {n $.console.assert(index !== undefined, "[World.getItemAt] index is required");n return this._items[ index ];n },nn /**n * Get the index of the given item or -1 if not present.n * @param {OpenSeadragon.TiledImage} item - The item.n * @returns {Number} The index of the item or -1 if not present.n */n getIndexOfItem: function( item ) {n $.console.assert(item, "[World.getIndexOfItem] item is required");n return $.indexOf( this._items, item );n },nn /**n * @returns {Number} The number of items used.n */n getItemCount: function() {n return this._items.length;n },nn /**n * Change the index of a item so that it appears over or under others.n * @param {OpenSeadragon.TiledImage} item - The item to move.n * @param {Number} index - The new index.n * @fires OpenSeadragon.World.event:item-index-changen */n setItemIndex: function( item, index ) {n $.console.assert(item, "[World.setItemIndex] item is required");n $.console.assert(index !== undefined, "[World.setItemIndex] index is required");nn var oldIndex = this.getIndexOfItem( item );nn if ( index >= this._items.length ) {n throw new Error( "Index bigger than number of layers." );n }nn if ( index === oldIndex || oldIndex === -1 ) {n return;n }nn this._items.splice( oldIndex, 1 );n this._items.splice( index, 0, item );n this._needsDraw = true;nn /**n * Raised when the order of the indexes has been changed.n * @event item-index-changen * @memberOf OpenSeadragon.Worldn * @type {object}n * @property {OpenSeadragon.World} eventSource - A reference to the World which raised the event.n * @property {OpenSeadragon.TiledImage} item - The item whose index hasn * been changedn * @property {Number} previousIndex - The previous index of the itemn * @property {Number} newIndex - The new index of the itemn * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'item-index-change', {n item: item,n previousIndex: oldIndex,n newIndex: indexn } );n },nn /**n * Remove an item.n * @param {OpenSeadragon.TiledImage} item - The item to remove.n * @fires OpenSeadragon.World.event:remove-itemn * @fires OpenSeadragon.World.event:metrics-changen */n removeItem: function( item ) {n $.console.assert(item, "[World.removeItem] item is required");nn var index = $.indexOf(this._items, item );n if ( index === -1 ) {n return;n }nn item.removeHandler('bounds-change', this._delegatedFigureSizes);n item.removeHandler('clip-change', this._delegatedFigureSizes);n item.destroy();n this._items.splice( index, 1 );n this._figureSizes();n this._needsDraw = true;n this._raiseRemoveItem(item);n },nn /**n * Remove all items.n * @fires OpenSeadragon.World.event:remove-itemn * @fires OpenSeadragon.World.event:metrics-changen */n removeAll: function() {n // We need to make sure any pending images are canceled so the world items don't get messed upn this.viewer._cancelPendingImages();n var item;n var i;n for (i = 0; i < this._items.length; i++) {n item = this._items;n item.removeHandler('bounds-change', this._delegatedFigureSizes);n item.removeHandler('clip-change', this._delegatedFigureSizes);n item.destroy();n }nn var removedItems = this._items;n this._items = [];n this._figureSizes();n this._needsDraw = true;nn for (i = 0; i < removedItems.length; i++) {n item = removedItems;n this._raiseRemoveItem(item);n }n },nn /**n * Clears all tiles and triggers updates for all items.n */n resetItems: function() {n for ( var i = 0; i < this._items.length; i++ ) {n this._items.reset();n }n },nn /**n * Updates (i.e. animates bounds of) all items.n */n update: function() {n var animated = false;n for ( var i = 0; i < this._items.length; i++ ) {n animated = this._items.update() || animated;n }nn return animated;n },nn /**n * Draws all items.n */n draw: function() {n for ( var i = 0; i < this._items.length; i++ ) {n this._items.draw();n }nn this._needsDraw = false;n },nn /**n * @returns {Boolean} true if any items need updating.n */n needsDraw: function() {n for ( var i = 0; i < this._items.length; i++ ) {n if ( this._items.needsDraw() ) {n return true;n }n }n return this._needsDraw;n },nn /**n * @returns {OpenSeadragon.Rect} The smallest rectangle that encloses all items, in viewport coordinates.n */n getHomeBounds: function() {n return this._homeBounds.clone();n },nn /**n * To facilitate zoom constraints, we keep track of the pixel density of then * densest item in the World (i.e. the item whose content size to viewport sizen * ratio is the highest) and save it as this "content factor".n * @returns {Number} the number of content units per viewport unit.n */n getContentFactor: function() {n return this._contentFactor;n },nn /**n * As a performance optimization, setting this flag to false allows the bounds-change event handlern * on tiledImages to skip calculations on the world bounds. If a lot of images are going to be positioned inn * rapid succession, this is a good idea. When finished, setAutoRefigureSizes should be called with truen * or the system may behave oddly.n * @param {Boolean} [value] The value to which to set the flag.n */n setAutoRefigureSizes: function(value) {n this._autoRefigureSizes = value;n if (value & this._needsSizesFigured) {n this._figureSizes();n this._needsSizesFigured = false;n }n },nn /**n * Arranges all of the TiledImages with the specified settings.n * @param {Object} options - Specifies how to arrange.n * @param {Boolean} [options.immediately=false] - Whether to animate to the new arrangement.n * @param {String} [options.layout] - See collectionLayout in {@link OpenSeadragon.Options}.n * @param {Number} [options.rows] - See collectionRows in {@link OpenSeadragon.Options}.n * @param {Number} [options.columns] - See collectionColumns in {@link OpenSeadragon.Options}.n * @param {Number} [options.tileSize] - See collectionTileSize in {@link OpenSeadragon.Options}.n * @param {Number} [options.tileMargin] - See collectionTileMargin in {@link OpenSeadragon.Options}.n * @fires OpenSeadragon.World.event:metrics-changen */n arrange: function(options) {n options = options || {};n var immediately = options.immediately || false;n var layout = options.layout || $.DEFAULT_SETTINGS.collectionLayout;n var rows = options.rows || $.DEFAULT_SETTINGS.collectionRows;n var columns = options.columns || $.DEFAULT_SETTINGS.collectionColumns;n var tileSize = options.tileSize || $.DEFAULT_SETTINGS.collectionTileSize;n var tileMargin = options.tileMargin || $.DEFAULT_SETTINGS.collectionTileMargin;n var increment = tileSize + tileMargin;n var wrap;n if (!options.rows && columns) {n wrap = columns;n } else {n wrap = Math.ceil(this._items.length / rows);n }n var x = 0;n var y = 0;n var item, box, width, height, position;nn this.setAutoRefigureSizes(false);n for (var i = 0; i < this._items.length; i++) {n if (i && (i % wrap) === 0) {n if (layout === 'horizontal') {n y += increment;n x = 0;n } else {n x += increment;n y = 0;n }n }nn item = this._items;n box = item.getBounds();n if (box.width > box.height) {n width = tileSize;n } else {n width = tileSize * (box.width / box.height);n }nn height = width * (box.height / box.width);n position = new $.Point(x + ((tileSize - width) / 2),n y + ((tileSize - height) / 2));nn item.setPosition(position, immediately);n item.setWidth(width, immediately);nn if (layout === 'horizontal') {n x += increment;n } else {n y += increment;n }n }n this.setAutoRefigureSizes(true);n },nn // privaten _figureSizes: function() {n var oldHomeBounds = this._homeBounds ? this._homeBounds.clone() : null;n var oldContentSize = this._contentSize ? this._contentSize.clone() : null;n var oldContentFactor = this._contentFactor || 0;nn if (!this._items.length) {n this._homeBounds = new $.Rect(0, 0, 1, 1);n this._contentSize = new $.Point(1, 1);n this._contentFactor = 1;n } else {n var item = this._items;n var bounds = item.getBounds();n this._contentFactor = item.getContentSize().x / bounds.width;n var clippedBounds = item.getClippedBounds().getBoundingBox();n var left = clippedBounds.x;n var top = clippedBounds.y;n var right = clippedBounds.x + clippedBounds.width;n var bottom = clippedBounds.y + clippedBounds.height;n for (var i = 1; i < this._items.length; i++) {n item = this._items;n bounds = item.getBounds();n this._contentFactor = Math.max(this._contentFactor,n item.getContentSize().x / bounds.width);n clippedBounds = item.getClippedBounds().getBoundingBox();n left = Math.min(left, clippedBounds.x);n top = Math.min(top, clippedBounds.y);n right = Math.max(right, clippedBounds.x + clippedBounds.width);n bottom = Math.max(bottom, clippedBounds.y + clippedBounds.height);n }nn this._homeBounds = new $.Rect(left, top, right - left, bottom - top);n this._contentSize = new $.Point(n this._homeBounds.width * this._contentFactor,n this._homeBounds.height * this._contentFactor);n }nn if (this._contentFactor !== oldContentFactor ||n !this._homeBounds.equals(oldHomeBounds) ||n !this._contentSize.equals(oldContentSize)) {n /**n * Raised when the home bounds or content factor change.n * @event metrics-changen * @memberOf OpenSeadragon.Worldn * @type {object}n * @property {OpenSeadragon.World} eventSource - A reference to the World which raised the event.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent('metrics-change', {});n }n },nn // privaten _raiseRemoveItem: function(item) {n /**n * Raised when an item is removed.n * @event remove-itemn * @memberOf OpenSeadragon.Worldn * @type {object}n * @property {OpenSeadragon.World} eventSource - A reference to the World which raised the event.n * @property {OpenSeadragon.TiledImage} item - The item's underlying item.n * @property {?Object} userData - Arbitrary subscriber-defined object.n */n this.raiseEvent( 'remove-item', { item: item } );n }n});nn}( OpenSeadragon ));n”]}