2014-06-21 17:25:00 +00:00
/* build: `node build.js modules=ALL exclude=gestures,cufon,json minifier=uglifyjs` */ /*! Fabric.js Copyright 2008-2014, Printio (Juriy Zaytsev, Maxim Chernyak) */ var fabric = fabric || { version : "1.4.7" } ; typeof exports != "undefined" && ( exports . fabric = fabric ) , typeof document != "undefined" && typeof window != "undefined" ? ( fabric . document = document , fabric . window = window ) : ( fabric . document = require ( "jsdom" ) . jsdom ( "<!DOCTYPE html><html><head></head><body></body></html>" ) , fabric . window = fabric . document . createWindow ( ) ) , fabric . isTouchSupported = "ontouchstart" in fabric . document . documentElement , fabric . isLikelyNode = typeof Buffer != "undefined" && typeof window == "undefined" , fabric . SHARED _ATTRIBUTES = [ "display" , "transform" , "fill" , "fill-opacity" , "fill-rule" , "opacity" , "stroke" , "stroke-dasharray" , "stroke-linecap" , "stroke-linejoin" , "stroke-miterlimit" , "stroke-opacity" , "stroke-width" ] , function ( ) { function e ( e , t ) { if ( ! this . _ _eventListeners [ e ] ) return ; t ? fabric . util . removeFromArray ( this . _ _eventListeners [ e ] , t ) : this . _ _eventListeners [ e ] . length = 0 } function t ( e , t ) { this . _ _eventListeners || ( this . _ _eventListeners = { } ) ; if ( arguments . length === 1 ) for ( var n in e ) this . on ( n , e [ n ] ) ; else this . _ _eventListeners [ e ] || ( this . _ _eventListeners [ e ] = [ ] ) , this . _ _eventListeners [ e ] . push ( t ) ; return this } function n ( t , n ) { if ( ! this . _ _eventListeners ) return ; if ( arguments . length === 0 ) this . _ _eventListeners = { } ; else if ( arguments . length === 1 && typeof arguments [ 0 ] == "object" ) for ( var r in t ) e . call ( this , r , t [ r ] ) ; else e . call ( this , t , n ) ; return this } function r ( e , t ) { if ( ! this . _ _eventListeners ) return ; var n = this . _ _eventListeners [ e ] ; if ( ! n ) return ; for ( var r = 0 , i = n . length ; r < i ; r ++ ) n [ r ] . call ( this , t || { } ) ; return this } fabric . Observable = { observe : t , stopObserving : n , fire : r , on : t , off : n , trigger : r } } ( ) , fabric . Collection = { add : function ( ) { this . _objects . push . apply ( this . _objects , arguments ) ; for ( var e = 0 , t = arguments . length ; e < t ; e ++ ) this . _onObjectAdded ( arguments [ e ] ) ; return this . renderOnAddRemove && this . renderAll ( ) , this } , insertAt : function ( e , t , n ) { var r = this . getObjects ( ) ; return n ? r [ t ] = e : r . splice ( t , 0 , e ) , this . _onObjectAdded ( e ) , this . renderOnAddRemove && this . renderAll ( ) , this } , remove : function ( ) { var e = this . getObjects ( ) , t ; for ( var n = 0 , r = arguments . length ; n < r ; n ++ ) t = e . indexOf ( arguments [ n ] ) , t !== - 1 && ( e . splice ( t , 1 ) , this . _onObjectRemoved ( arguments [ n ] ) ) ; return this . renderOnAddRemove && this . renderAll ( ) , this } , forEachObject : function ( e , t ) { var n = this . getObjects ( ) , r = n . length ; while ( r -- ) e . call ( t , n [ r ] , r , n ) ; return this } , getObjects : function ( e ) { return typeof e == "undefined" ? this . _objects : this . _objects . filter ( function ( t ) { return t . type === e } ) } , item : function ( e ) { return this . getObjects ( ) [ e ] } , isEmpty : function ( ) { return this . getObjects ( ) . length === 0 } , size : function ( ) { return this . getObjects ( ) . length } , contains : function ( e ) { return this . getObjects ( ) . indexOf ( e ) > - 1 } , complexity : function ( ) { return this . getObjects ( ) . reduce ( function ( e , t ) { return e += t . complexity ? t . complexity ( ) : 0 , e } , 0 ) } } , function ( e ) { var t = Math . sqrt , n = Math . atan2 , r = Math . PI / 180 ; fabric . util = { removeFromArray : function ( e , t ) { var n = e . indexOf ( t ) ; return n !== - 1 && e . splice ( n , 1 ) , e } , getRandomInt : function ( e , t ) { return Math . floor ( Math . random ( ) * ( t - e + 1 ) ) + e } , degreesToRadians : function ( e ) { return e * r } , radiansToDegrees : function ( e ) { return e / r } , rotatePoint : function ( e , t , n ) { var r = Math . sin ( n ) , i = Math . cos ( n ) ; e . subtractEquals ( t ) ; var s = e . x * i - e . y * r , o = e . x * r + e . y * i ; return ( new fabric . Point ( s , o ) ) . addEquals ( t ) } , toFixed : function ( e , t ) { return parseFloat ( Number ( e ) . toFixed ( t ) ) } , falseFunction : function ( ) { return ! 1 } , getKlass : function ( e , t ) { return e = fabric . util . string . camelize ( e . charAt ( 0 ) . toUpperCase ( ) + e . slice ( 1 ) ) , fabric . util . resolveNamespace ( t ) [ e ] } , resolveNamespace : function ( t ) { if ( ! t ) return fabric ; var n = t . split ( "." ) , r = n . length , i = e || fabric . window ; for ( var s = 0 ; s < r ; ++ s ) i = i [ n [ s ] ] ; return i } , loadImage : function ( e , t , n , r ) { if ( ! e ) { t && t . call ( n , e ) ; return } var i = fabric . util . createImage ( ) ; i . onload = function ( ) { t && t . call ( n , i ) , i = i . onload = i . onerror = null } , i . onerror = function ( ) { fabric . log ( "Error loading " + i . src ) , t && t . call ( n , null , ! 0 ) , i = i . onload = i . onerror = null } , e . indexOf ( "data" ) !== 0 && typeof r != "undefined" && ( i . crossOrigin = r ) , i . src = e } , enlivenObjects : function ( e , t , n , r ) { function i ( ) { ++ o === u && t && t ( s ) } e = e || [ ] ; var s = [ ] , o = 0 , u = e . length ; if ( !
. options ) ; this . reviver && this . reviver ( t , r ) , this . instances . splice ( n , 0 , r ) , this . checkIfDone ( ) } } , fabric . ElementsParser . prototype . createCallback = function ( e , t ) { var n = this ; return function ( r ) { n . reviver && n . reviver ( t , r ) , n . instances . splice ( e , 0 , r ) , n . checkIfDone ( ) } } , fabric . ElementsParser . prototype . checkIfDone = function ( ) { -- this . numElements === 0 && ( this . instances = this . instances . filter ( function ( e ) { return e != null } ) , fabric . resolveGradients ( this . instances ) , this . callback ( this . instances ) ) } , function ( e ) { "use strict" ; function n ( e , t ) { this . x = e , this . y = t } var t = e . fabric || ( e . fabric = { } ) ; if ( t . Point ) { t . warn ( "fabric.Point is already defined" ) ; return } t . Point = n , n . prototype = { constructor : n , add : function ( e ) { return new n ( this . x + e . x , this . y + e . y ) } , addEquals : function ( e ) { return this . x += e . x , this . y += e . y , this } , scalarAdd : function ( e ) { return new n ( this . x + e , this . y + e ) } , scalarAddEquals : function ( e ) { return this . x += e , this . y += e , this } , subtract : function ( e ) { return new n ( this . x - e . x , this . y - e . y ) } , subtractEquals : function ( e ) { return this . x -= e . x , this . y -= e . y , this } , scalarSubtract : function ( e ) { return new n ( this . x - e , this . y - e ) } , scalarSubtractEquals : function ( e ) { return this . x -= e , this . y -= e , this } , multiply : function ( e ) { return new n ( this . x * e , this . y * e ) } , multiplyEquals : function ( e ) { return this . x *= e , this . y *= e , this } , divide : function ( e ) { return new n ( this . x / e , this . y / e ) } , divideEquals : function ( e ) { return this . x /= e , this . y /= e , this } , eq : function ( e ) { return this . x === e . x && this . y === e . y } , lt : function ( e ) { return this . x < e . x && this . y < e . y } , lte : function ( e ) { return this . x <= e . x && this . y <= e . y } , gt : function ( e ) { return this . x > e . x && this . y > e . y } , gte : function ( e ) { return this . x >= e . x && this . y >= e . y } , lerp : function ( e , t ) { return new n ( this . x + ( e . x - this . x ) * t , this . y + ( e . y - this . y ) * t ) } , distanceFrom : function ( e ) { var t = this . x - e . x , n = this . y - e . y ; return Math . sqrt ( t * t + n * n ) } , midPointFrom : function ( e ) { return new n ( this . x + ( e . x - this . x ) / 2 , this . y + ( e . y - this . y ) / 2 ) } , min : function ( e ) { return new n ( Math . min ( this . x , e . x ) , Math . min ( this . y , e . y ) ) } , max : function ( e ) { return new n ( Math . max ( this . x , e . x ) , Math . max ( this . y , e . y ) ) } , toString : function ( ) { return this . x + "," + this . y } , setXY : function ( e , t ) { this . x = e , this . y = t } , setFromPoint : function ( e ) { this . x = e . x , this . y = e . y } , swap : function ( e ) { var t = this . x , n = this . y ; this . x = e . x , this . y = e . y , e . x = t , e . y = n } } } ( typeof exports != "undefined" ? exports : this ) , function ( e ) { "use strict" ; function n ( e ) { this . status = e , this . points = [ ] } var t = e . fabric || ( e . fabric = { } ) ; if ( t . Intersection ) { t . warn ( "fabric.Intersection is already defined" ) ; return } t . Intersection = n , t . Intersection . prototype = { appendPoint : function ( e ) { this . points . push ( e ) } , appendPoints : function ( e ) { this . points = this . points . concat ( e ) } } , t . Intersection . intersectLineLine = function ( e , r , i , s ) { var o , u = ( s . x - i . x ) * ( e . y - i . y ) - ( s . y - i . y ) * ( e . x - i . x ) , a = ( r . x - e . x ) * ( e . y - i . y ) - ( r . y - e . y ) * ( e . x - i . x ) , f = ( s . y - i . y ) * ( r . x - e . x ) - ( s . x - i . x ) * ( r . y - e . y ) ; if ( f !== 0 ) { var l = u / f , c = a / f ; 0 <= l && l <= 1 && 0 <= c && c <= 1 ? ( o = new n ( "Intersection" ) , o . points . push ( new t . Point ( e . x + l * ( r . x - e . x ) , e . y + l * ( r . y - e . y ) ) ) ) : o = new n } else u === 0 || a === 0 ? o = new n ( "Coincident" ) : o = new n ( "Parallel" ) ; return o } , t . Intersection . intersectLinePolygon = function ( e , t , r ) { var i = new n , s = r . length ; for ( var o = 0 ; o < s ; o ++ ) { var u = r [ o ] , a = r [ ( o + 1 ) % s ] , f = n . intersectLineLine ( e , t , u , a ) ; i . appendPoints ( f . points ) } return i . points . length > 0 && ( i . status = "Intersection" ) , i } , t . Intersection . intersectPolygonPolygon = function ( e , t ) { var r = new n , i = e . length ; for ( var s = 0 ; s < i ; s ++ ) { var o = e [ s ] , u = e [ ( s + 1 ) % i ] , a = n . intersectLinePolygon ( o , u , t ) ; r . appendPoints ( a . points ) } return r . points . length > 0 && ( r . status = "Intersection" ) , r } , t . Intersection . intersectPolygonRectangle = function ( e , r , i ) { var s = r . min ( i ) , o = r . max ( i ) , u = new t . Point ( o . x , s . y ) , a = new t . Point ( s . x , o . y ) , f = n . intersectLinePolygon ( s , u , e ) , l = n . intersectLinePolygon ( u , o , e ) , c = n . intersectLinePolygon ( o , a , e ) , h = n . intersectLinePolygon ( a , s , e ) , p = new n ; return p . appendPoints ( f . points ) , p . appendPoints ( l . points ) , p . appendPoints ( c . points ) , p . appendPoints ( h . points ) , p . points . length > 0 && ( p . status = "Intersection" ) , p } } ( typeof exports != "undefined" ? exports : this ) , function ( e ) { "use strict" ; function n ( e ) { e ? this . _tryParsingColor ( e ) : this . setSource ( [ 0 , 0 , 0 , 1 ] ) } function r ( e , t , n ) { return n < 0 && ( n += 1 ) , n > 1 && ( n -= 1 ) , n < 1 / 6 ? e + ( t - e ) * 6 * n : n < . 5 ? t : n < 2 / 3 ? e + ( t - e ) * ( 2 / 3 - n ) * 6 : e } var t = e . fabric || ( e .
( e . x , e . y ) , n = fabric . util . getRandomInt ( Math . max ( 0 , this . width - 20 ) , this . width + 20 ) / 2 , r = ( new fabric . Color ( this . color ) ) . setAlpha ( fabric . util . getRandomInt ( 0 , 100 ) / 100 ) . toRgba ( ) ; return t . radius = n , t . fill = r , this . points . push ( t ) , t } } ) , fabric . SprayBrush = fabric . util . createClass ( fabric . BaseBrush , { width : 10 , density : 20 , dotWidth : 1 , dotWidthVariance : 1 , randomOpacity : ! 1 , optimizeOverlapping : ! 0 , initialize : function ( e ) { this . canvas = e , this . sprayChunks = [ ] } , onMouseDown : function ( e ) { this . sprayChunks . length = 0 , this . canvas . clearContext ( this . canvas . contextTop ) , this . _setShadow ( ) , this . addSprayChunk ( e ) , this . render ( ) } , onMouseMove : function ( e ) { this . addSprayChunk ( e ) , this . render ( ) } , onMouseUp : function ( ) { var e = this . canvas . renderOnAddRemove ; this . canvas . renderOnAddRemove = ! 1 ; var t = [ ] ; for ( var n = 0 , r = this . sprayChunks . length ; n < r ; n ++ ) { var i = this . sprayChunks [ n ] ; for ( var s = 0 , o = i . length ; s < o ; s ++ ) { var u = new fabric . Rect ( { width : i [ s ] . width , height : i [ s ] . width , left : i [ s ] . x + 1 , top : i [ s ] . y + 1 , originX : "center" , originY : "center" , fill : this . color } ) ; this . shadow && u . setShadow ( this . shadow ) , t . push ( u ) } } this . optimizeOverlapping && ( t = this . _getOptimizedRects ( t ) ) ; var a = new fabric . Group ( t , { originX : "center" , originY : "center" } ) ; this . canvas . add ( a ) , this . canvas . fire ( "path:created" , { path : a } ) , this . canvas . clearContext ( this . canvas . contextTop ) , this . _resetShadow ( ) , this . canvas . renderOnAddRemove = e , this . canvas . renderAll ( ) } , _getOptimizedRects : function ( e ) { var t = { } , n ; for ( var r = 0 , i = e . length ; r < i ; r ++ ) n = e [ r ] . left + "" + e [ r ] . top , t [ n ] || ( t [ n ] = e [ r ] ) ; var s = [ ] ; for ( n in t ) s . push ( t [ n ] ) ; return s } , render : function ( ) { var e = this . canvas . contextTop ; e . fillStyle = this . color , e . save ( ) ; for ( var t = 0 , n = this . sprayChunkPoints . length ; t < n ; t ++ ) { var r = this . sprayChunkPoints [ t ] ; typeof r . opacity != "undefined" && ( e . globalAlpha = r . opacity ) , e . fillRect ( r . x , r . y , r . width , r . width ) } e . restore ( ) } , addSprayChunk : function ( e ) { this . sprayChunkPoints = [ ] ; var t , n , r , i = this . width / 2 ; for ( var s = 0 ; s < this . density ; s ++ ) { t = fabric . util . getRandomInt ( e . x - i , e . x + i ) , n = fabric . util . getRandomInt ( e . y - i , e . y + i ) , this . dotWidthVariance ? r = fabric . util . getRandomInt ( Math . max ( 1 , this . dotWidth - this . dotWidthVariance ) , this . dotWidth + this . dotWidthVariance ) : r = this . dotWidth ; var o = { x : t , y : n , width : r } ; this . randomOpacity && ( o . opacity = fabric . util . getRandomInt ( 0 , 100 ) / 100 ) , this . sprayChunkPoints . push ( o ) } this . sprayChunks . push ( this . sprayChunkPoints ) } } ) , fabric . PatternBrush = fabric . util . createClass ( fabric . PencilBrush , { getPatternSrc : function ( ) { var e = 20 , t = 5 , n = fabric . document . createElement ( "canvas" ) , r = n . getContext ( "2d" ) ; return n . width = n . height = e + t , r . fillStyle = this . color , r . beginPath ( ) , r . arc ( e / 2 , e / 2 , e / 2 , 0 , Math . PI * 2 , ! 1 ) , r . closePath ( ) , r . fill ( ) , n } , getPatternSrcFunction : function ( ) { return String ( this . getPatternSrc ) . replace ( "this.color" , '"' + this . color + '"' ) } , getPattern : function ( ) { return this . canvas . contextTop . createPattern ( this . source || this . getPatternSrc ( ) , "repeat" ) } , _setBrushStyles : function ( ) { this . callSuper ( "_setBrushStyles" ) , this . canvas . contextTop . strokeStyle = this . getPattern ( ) } , createPath : function ( e ) { var t = this . callSuper ( "createPath" , e ) ; return t . stroke = new fabric . Pattern ( { source : this . source || this . getPatternSrcFunction ( ) } ) , t } } ) , function ( ) { var e = fabric . util . getPointer , t = fabric . util . degreesToRadians , n = fabric . util . radiansToDegrees , r = Math . atan2 , i = Math . abs , s = . 5 ; fabric . Canvas = fabric . util . createClass ( fabric . StaticCanvas , { initialize : function ( e , t ) { t || ( t = { } ) , this . _initStatic ( e , t ) , this . _initInteractive ( ) , this . _createCacheCanvas ( ) , fabric . Canvas . activeInstance = this } , uniScaleTransform : ! 1 , centeredScaling : ! 1 , centeredRotation : ! 1 , interactive : ! 0 , selection : ! 0 , selectionColor : "rgba(100, 100, 255, 0.3)" , selectionDashArray : [ ] , selectionBorderColor : "rgba(255, 255, 255, 0.3)" , selectionLineWidth : 1 , hoverCursor : "move" , moveCursor : "move" , defaultCursor : "default" , freeDrawingCursor : "crosshair" , rotationCursor : "crosshair" , containerClass : "canvas-container" , perPixelTargetFind : ! 1 , targetFindTolerance : 0 , skipTargetFind : ! 1 , _initInteractive : function ( ) { this . _currentTransform = null , this . _groupSelector = null , this . _initWrapperElement ( ) , this . _createUpperCanvas ( ) , this . _initEventListeners ( ) , this . freeDrawingBrush = fabric . PencilBrush && new fabric . PencilBrush ( this ) , this . calcOffset ( ) } , _resetCurrentTransform : func
( e ) } , transform : function ( e , t ) { e . globalAlpha = this . opacity ; var n = t ? this . _getLeftTopCoords ( ) : this . getCenterPoint ( ) ; e . translate ( n . x , n . y ) , e . rotate ( s ( this . angle ) ) , e . scale ( this . scaleX * ( this . flipX ? - 1 : 1 ) , this . scaleY * ( this . flipY ? - 1 : 1 ) ) } , toObject : function ( e ) { var n = t . Object . NUM _FRACTION _DIGITS , i = { type : this . type , originX : this . originX , originY : this . originY , left : r ( this . left , n ) , top : r ( this . top , n ) , width : r ( this . width , n ) , height : r ( this . height , n ) , fill : this . fill && this . fill . toObject ? this . fill . toObject ( ) : this . fill , stroke : this . stroke && this . stroke . toObject ? this . stroke . toObject ( ) : this . stroke , strokeWidth : r ( this . strokeWidth , n ) , strokeDashArray : this . strokeDashArray , strokeLineCap : this . strokeLineCap , strokeLineJoin : this . strokeLineJoin , strokeMiterLimit : r ( this . strokeMiterLimit , n ) , scaleX : r ( this . scaleX , n ) , scaleY : r ( this . scaleY , n ) , angle : r ( this . getAngle ( ) , n ) , flipX : this . flipX , flipY : this . flipY , opacity : r ( this . opacity , n ) , shadow : this . shadow && this . shadow . toObject ? this . shadow . toObject ( ) : this . shadow , visible : this . visible , clipTo : this . clipTo && String ( this . clipTo ) , backgroundColor : this . backgroundColor } ; return this . includeDefaultValues || ( i = this . _removeDefaultValues ( i ) ) , t . util . populateWithProperties ( this , i , e ) , i } , toDatalessObject : function ( e ) { return this . toObject ( e ) } , _removeDefaultValues : function ( e ) { var n = t . util . getKlass ( e . type ) . prototype , r = n . stateProperties ; return r . forEach ( function ( t ) { e [ t ] === n [ t ] && delete e [ t ] } ) , e } , toString : function ( ) { return "#<fabric." + i ( this . type ) + ">" } , get : function ( e ) { return this [ e ] } , _setObject : function ( e ) { for ( var t in e ) this . _set ( t , e [ t ] ) } , set : function ( e , t ) { return typeof e == "object" ? this . _setObject ( e ) : typeof t == "function" && e !== "clipTo" ? this . _set ( e , t ( this . get ( e ) ) ) : this . _set ( e , t ) , this } , _set : function ( e , n ) { var i = e === "scaleX" || e === "scaleY" ; return i && ( n = this . _constrainScale ( n ) ) , e === "scaleX" && n < 0 ? ( this . flipX = ! this . flipX , n *= - 1 ) : e === "scaleY" && n < 0 ? ( this . flipY = ! this . flipY , n *= - 1 ) : e === "width" || e === "height" ? this . minScaleLimit = r ( Math . min ( . 1 , 1 / Math . max ( this . width , this . height ) ) , 2 ) : e === "shadow" && n && ! ( n instanceof t . Shadow ) && ( n = new t . Shadow ( n ) ) , this [ e ] = n , this } , toggle : function ( e ) { var t = this . get ( e ) ; return typeof t == "boolean" && this . set ( e , ! t ) , this } , setSourcePath : function ( e ) { return this . sourcePath = e , this } , render : function ( e , n ) { if ( this . width === 0 || this . height === 0 || ! this . visible ) return ; e . save ( ) , this . _setupFillRule ( e ) , this . _transform ( e , n ) , this . _setStrokeStyles ( e ) , this . _setFillStyles ( e ) ; var r = this . transformMatrix ; r && this . group && ( e . translate ( - this . group . width / 2 , - this . group . height / 2 ) , e . transform ( r [ 0 ] , r [ 1 ] , r [ 2 ] , r [ 3 ] , r [ 4 ] , r [ 5 ] ) ) , this . _setShadow ( e ) , this . clipTo && t . util . clipContext ( this , e ) , this . _render ( e , n ) , this . clipTo && e . restore ( ) , this . _removeShadow ( e ) , this . _restoreFillRule ( e ) , this . active && ! n && ( this . drawBorders ( e ) , this . drawControls ( e ) ) , e . restore ( ) } , _transform : function ( e , t ) { var n = this . transformMatrix ; n && ! this . group && e . setTransform ( n [ 0 ] , n [ 1 ] , n [ 2 ] , n [ 3 ] , n [ 4 ] , n [ 5 ] ) , t || this . transform ( e ) } , _setStrokeStyles : function ( e ) { this . stroke && ( e . lineWidth = this . strokeWidth , e . lineCap = this . strokeLineCap , e . lineJoin = this . strokeLineJoin , e . miterLimit = this . strokeMiterLimit , e . strokeStyle = this . stroke . toLive ? this . stroke . toLive ( e ) : this . stroke ) } , _setFillStyles : function ( e ) { this . fill && ( e . fillStyle = this . fill . toLive ? this . fill . toLive ( e ) : this . fill ) } , _setShadow : function ( e ) { if ( ! this . shadow ) return ; e . shadowColor = this . shadow . color , e . shadowBlur = this . shadow . blur , e . shadowOffsetX = this . shadow . offsetX , e . shadowOffsetY = this . shadow . offsetY } , _removeShadow : function ( e ) { if ( ! this . shadow ) return ; e . shadowColor = "" , e . shadowBlur = e . shadowOffsetX = e . shadowOffsetY = 0 } , _renderFill : function ( e ) { if ( ! this . fill ) return ; this . fill . toLive && ( e . save ( ) , e . translate ( - this . width / 2 + this . fill . offsetX || 0 , - this . height / 2 + this . fill . offsetY || 0 ) ) , this . fillRule === "destination-over" ? e . fill ( "evenodd" ) : e . fill ( ) , this . fill . toLive && e . restore ( ) , this . shadow && ! this . shadow . affectStroke && this . _removeShadow ( e ) } , _renderStroke : function ( e ) { if ( ! this . stroke ) return ; e . save ( ) , this . strokeDashArray ? ( 1 & this . strokeDashArray . length && this . strokeDashArray . push . apply ( this . strokeDashArray , this . strokeDashArray ) , o ? ( e . setLineDash ( this . strokeDashArray ) , this . _stroke && this . _stroke ( e ) ) : this . _renderDashedStroke && this . _renderDa
( ) , '"/>' ) , e ? e ( t . join ( "" ) ) : t . join ( "" ) } , complexity : function ( ) { return 1 } } ) , t . Rect . ATTRIBUTE _NAMES = t . SHARED _ATTRIBUTES . concat ( "x y rx ry width height" . split ( " " ) ) , t . Rect . fromElement = function ( e , r ) { if ( ! e ) return null ; var s = t . parseAttributes ( e , t . Rect . ATTRIBUTE _NAMES ) ; s = i ( s ) ; var o = new t . Rect ( n ( r ? t . util . object . clone ( r ) : { } , s ) ) ; return o . _normalizeLeftTopProperties ( s ) , o } , t . Rect . fromObject = function ( e ) { return new t . Rect ( e ) } } ( typeof exports != "undefined" ? exports : this ) , function ( e ) { "use strict" ; var t = e . fabric || ( e . fabric = { } ) , n = t . util . toFixed ; if ( t . Polyline ) { t . warn ( "fabric.Polyline is already defined" ) ; return } t . Polyline = t . util . createClass ( t . Object , { type : "polyline" , points : null , initialize : function ( e , t , n ) { t = t || { } , this . set ( "points" , e ) , this . callSuper ( "initialize" , t ) , this . _calcDimensions ( n ) } , _calcDimensions : function ( e ) { return t . Polygon . prototype . _calcDimensions . call ( this , e ) } , toObject : function ( e ) { return t . Polygon . prototype . toObject . call ( this , e ) } , toSVG : function ( e ) { var t = [ ] , r = this . _createBaseSVGMarkup ( ) ; for ( var i = 0 , s = this . points . length ; i < s ; i ++ ) t . push ( n ( this . points [ i ] . x , 2 ) , "," , n ( this . points [ i ] . y , 2 ) , " " ) ; return r . push ( "<polyline " , 'points="' , t . join ( "" ) , '" style="' , this . getSvgStyles ( ) , '" transform="' , this . getSvgTransform ( ) , '"/>' ) , e ? e ( r . join ( "" ) ) : r . join ( "" ) } , _render : function ( e ) { var t ; e . beginPath ( ) , e . moveTo ( this . points [ 0 ] . x , this . points [ 0 ] . y ) ; for ( var n = 0 , r = this . points . length ; n < r ; n ++ ) t = this . points [ n ] , e . lineTo ( t . x , t . y ) ; this . _renderFill ( e ) , this . _renderStroke ( e ) } , _renderDashedStroke : function ( e ) { var n , r ; e . beginPath ( ) ; for ( var i = 0 , s = this . points . length ; i < s ; i ++ ) n = this . points [ i ] , r = this . points [ i + 1 ] || n , t . util . drawDashedLine ( e , n . x , n . y , r . x , r . y , this . strokeDashArray ) } , complexity : function ( ) { return this . get ( "points" ) . length } } ) , t . Polyline . ATTRIBUTE _NAMES = t . SHARED _ATTRIBUTES . concat ( ) , t . Polyline . fromElement = function ( e , n ) { if ( ! e ) return null ; n || ( n = { } ) ; var r = t . parsePointsAttribute ( e . getAttribute ( "points" ) ) , i = t . parseAttributes ( e , t . Polyline . ATTRIBUTE _NAMES ) ; return t . util . normalizePoints ( r , n ) , new t . Polyline ( r , t . util . object . extend ( i , n ) , ! 0 ) } , t . Polyline . fromObject = function ( e ) { var n = e . points ; return new t . Polyline ( n , e , ! 0 ) } } ( typeof exports != "undefined" ? exports : this ) , function ( e ) { "use strict" ; var t = e . fabric || ( e . fabric = { } ) , n = t . util . object . extend , r = t . util . array . min , i = t . util . array . max , s = t . util . toFixed ; if ( t . Polygon ) { t . warn ( "fabric.Polygon is already defined" ) ; return } t . Polygon = t . util . createClass ( t . Object , { type : "polygon" , points : null , initialize : function ( e , t , n ) { t = t || { } , this . points = e , this . callSuper ( "initialize" , t ) , this . _calcDimensions ( n ) } , _calcDimensions : function ( e ) { var t = this . points , n = r ( t , "x" ) , s = r ( t , "y" ) , o = i ( t , "x" ) , u = i ( t , "y" ) ; this . width = o - n || 1 , this . height = u - s || 1 , this . minX = n , this . minY = s ; if ( e ) return ; var a = this . width / 2 + this . minX , f = this . height / 2 + this . minY ; this . points . forEach ( function ( e ) { e . x -= a , e . y -= f } , this ) } , toObject : function ( e ) { return n ( this . callSuper ( "toObject" , e ) , { points : this . points . concat ( ) } ) } , toSVG : function ( e ) { var t = [ ] , n = this . _createBaseSVGMarkup ( ) ; for ( var r = 0 , i = this . points . length ; r < i ; r ++ ) t . push ( s ( this . points [ r ] . x , 2 ) , "," , s ( this . points [ r ] . y , 2 ) , " " ) ; return n . push ( "<polygon " , 'points="' , t . join ( "" ) , '" style="' , this . getSvgStyles ( ) , '" transform="' , this . getSvgTransform ( ) , '"/>' ) , e ? e ( n . join ( "" ) ) : n . join ( "" ) } , _render : function ( e ) { var t ; e . beginPath ( ) , e . globalAlpha = this . group ? e . globalAlpha * this . opacity : this . opacity , e . moveTo ( this . points [ 0 ] . x , this . points [ 0 ] . y ) ; for ( var n = 0 , r = this . points . length ; n < r ; n ++ ) t = this . points [ n ] , e . lineTo ( t . x , t . y ) ; this . _renderFill ( e ) ; if ( this . stroke || this . strokeDashArray ) e . closePath ( ) , this . _renderStroke ( e ) } , _renderDashedStroke : function ( e ) { var n , r ; e . beginPath ( ) ; for ( var i = 0 , s = this . points . length ; i < s ; i ++ ) n = this . points [ i ] , r = this . points [ i + 1 ] || this . points [ 0 ] , t . util . drawDashedLine ( e , n . x , n . y , r . x , r . y , this . strokeDashArray ) ; e . closePath ( ) } , complexity : function ( ) { return this . points . length } } ) , t . Polygon . ATTRIBUTE _NAMES = t . SHARED _ATTRIBUTES . concat ( ) , t . Polygon . fromElement = function ( e , r ) { if ( ! e ) return null ; r || ( r = { } ) ; var i = t . parsePointsAttribute ( e . getAttribute ( "points" ) ) , s = t . parseAttributes ( e , t . Polygon . ATTRIBUTE _NAMES ) ; return t . util . normalizePoints ( i , r ) , new t . Polygon ( i , n ( s , r ) , ! 0 ) } , t . Polygon . fromObject = function ( e ) { retu
( t . Image . filters . BaseFilter , { type : "Multiply" , initialize : function ( e ) { e = e || { } , this . color = e . color || "#000000" } , applyTo : function ( e ) { var n = e . getContext ( "2d" ) , r = n . getImageData ( 0 , 0 , e . width , e . height ) , i = r . data , s = i . length , o , u ; u = ( new t . Color ( this . color ) ) . getSource ( ) ; for ( o = 0 ; o < s ; o += 4 ) i [ o ] *= u [ 0 ] / 255 , i [ o + 1 ] *= u [ 1 ] / 255 , i [ o + 2 ] *= u [ 2 ] / 255 ; n . putImageData ( r , 0 , 0 ) } , toObject : function ( ) { return n ( this . callSuper ( "toObject" ) , { color : this . color } ) } } ) , t . Image . filters . Multiply . fromObject = function ( e ) { return new t . Image . filters . Multiply ( e ) } } ( typeof exports != "undefined" ? exports : this ) , function ( e ) { "use strict" ; var t = e . fabric || ( e . fabric = { } ) , n = t . util . object . extend , r = t . util . object . clone , i = t . util . toFixed , s = t . StaticCanvas . supports ( "setLineDash" ) ; if ( t . Text ) { t . warn ( "fabric.Text is already defined" ) ; return } var o = t . Object . prototype . stateProperties . concat ( ) ; o . push ( "fontFamily" , "fontWeight" , "fontSize" , "text" , "textDecoration" , "textAlign" , "fontStyle" , "lineHeight" , "textBackgroundColor" , "useNative" , "path" ) , t . Text = t . util . createClass ( t . Object , { _dimensionAffectingProps : { fontSize : ! 0 , fontWeight : ! 0 , fontFamily : ! 0 , textDecoration : ! 0 , fontStyle : ! 0 , lineHeight : ! 0 , stroke : ! 0 , strokeWidth : ! 0 , text : ! 0 } , _reNewline : /\r?\n/ , type : "text" , fontSize : 40 , fontWeight : "normal" , fontFamily : "Times New Roman" , textDecoration : "" , textAlign : "left" , fontStyle : "" , lineHeight : 1.3 , textBackgroundColor : "" , path : null , useNative : ! 0 , stateProperties : o , stroke : null , shadow : null , initialize : function ( e , t ) { t = t || { } , this . text = e , this . _ _skipDimension = ! 0 , this . setOptions ( t ) , this . _ _skipDimension = ! 1 , this . _initDimensions ( ) , this . setCoords ( ) } , _initDimensions : function ( ) { if ( this . _ _skipDimension ) return ; var e = t . util . createCanvasElement ( ) ; this . _render ( e . getContext ( "2d" ) ) } , toString : function ( ) { return "#<fabric.Text (" + this . complexity ( ) + '): { "text": "' + this . text + '", "fontFamily": "' + this . fontFamily + '" }>' } , _render : function ( e ) { var t = this . group && this . group . type === "path-group" ; t && ! this . transformMatrix ? e . translate ( - this . group . width / 2 + this . left , - this . group . height / 2 + this . top ) : t && this . transformMatrix && e . translate ( - this . group . width / 2 , - this . group . height / 2 ) , typeof Cufon == "undefined" || this . useNative === ! 0 ? this . _renderViaNative ( e ) : this . _renderViaCufon ( e ) } , _renderViaNative : function ( e ) { var n = this . text . split ( this . _reNewline ) ; this . transform ( e , t . isLikelyNode ) , this . _setTextStyles ( e ) , this . width = this . _getTextWidth ( e , n ) , this . height = this . _getTextHeight ( e , n ) , this . clipTo && t . util . clipContext ( this , e ) , this . _renderTextBackground ( e , n ) , this . _translateForTextAlign ( e ) , this . _renderText ( e , n ) , this . textAlign !== "left" && this . textAlign !== "justify" && e . restore ( ) , this . _renderTextDecoration ( e , n ) , this . clipTo && e . restore ( ) , this . _setBoundaries ( e , n ) , this . _totalLineHeight = 0 } , _renderText : function ( e , t ) { e . save ( ) , this . _setShadow ( e ) , this . _renderTextFill ( e , t ) , this . _renderTextStroke ( e , t ) , this . _removeShadow ( e ) , e . restore ( ) } , _translateForTextAlign : function ( e ) { this . textAlign !== "left" && this . textAlign !== "justify" && ( e . save ( ) , e . translate ( this . textAlign === "center" ? this . width / 2 : this . width , 0 ) ) } , _setBoundaries : function ( e , t ) { this . _boundaries = [ ] ; for ( var n = 0 , r = t . length ; n < r ; n ++ ) { var i = this . _getLineWidth ( e , t [ n ] ) , s = this . _getLineLeftOffset ( i ) ; this . _boundaries . push ( { height : this . fontSize * this . lineHeight , width : i , left : s } ) } } , _setTextStyles : function ( e ) { this . _setFillStyles ( e ) , this . _setStrokeStyles ( e ) , e . textBaseline = "alphabetic" , this . skipTextAlign || ( e . textAlign = this . textAlign ) , e . font = this . _getFontDeclaration ( ) } , _getTextHeight : function ( e , t ) { return this . fontSize * t . length * this . lineHeight } , _getTextWidth : function ( e , t ) { var n = e . measureText ( t [ 0 ] || "|" ) . width ; for ( var r = 1 , i = t . length ; r < i ; r ++ ) { var s = e . measureText ( t [ r ] ) . width ; s > n && ( n = s ) } return n } , _renderChars : function ( e , t , n , r , i ) { t [ e ] ( n , r , i ) } , _renderTextLine : function ( e , t , n , r , i , s ) { i -= this . fontSize / 4 ; if ( this . textAlign !== "justify" ) { this . _renderChars ( e , t , n , r , i , s ) ; return } var o = t . measureText ( n ) . width , u = this . width ; if ( u > o ) { var a = n . split ( /\s+/ ) , f = t . measureText ( n . replace ( /\s+/g , "" ) ) . width , l = u - f , c = a . length - 1 , h = l / c , p = 0 ; for ( var d = 0 , v = a . length ; d < v ; d ++ ) this . _renderChars ( e , t , a [ d ] , r + p , i , s ) , p += t . measureText ( a [ d ] ) . width + h } else this . _renderChars ( e , t , n , r , i , s ) } , _getLeftOffset : function ( ) { return t . isLikelyNode ? 0 : - this . wid
: function ( ) { this . on ( "dblclick" , function ( e ) { this . selectWord ( this . getSelectionStartFromPointer ( e . e ) ) } ) , this . on ( "tripleclick" , function ( e ) { this . selectLine ( this . getSelectionStartFromPointer ( e . e ) ) } ) } , initMousedownHandler : function ( ) { this . on ( "mousedown" , function ( e ) { var t = this . canvas . getPointer ( e . e ) ; this . _ _mousedownX = t . x , this . _ _mousedownY = t . y , this . _ _isMousedown = ! 0 , this . hiddenTextarea && this . canvas && this . canvas . wrapperEl . appendChild ( this . hiddenTextarea ) , this . selected && this . setCursorByClick ( e . e ) , this . isEditing && ( this . _ _selectionStartOnMouseDown = this . selectionStart , this . initDelayedCursor ( ! 0 ) ) } ) } , initMousemoveHandler : function ( ) { this . on ( "mousemove" , function ( e ) { if ( ! this . _ _isMousedown || ! this . isEditing ) return ; var t = this . getSelectionStartFromPointer ( e . e ) ; t >= this . _ _selectionStartOnMouseDown ? ( this . setSelectionStart ( this . _ _selectionStartOnMouseDown ) , this . setSelectionEnd ( t ) ) : ( this . setSelectionStart ( t ) , this . setSelectionEnd ( this . _ _selectionStartOnMouseDown ) ) } ) } , _isObjectMoved : function ( e ) { var t = this . canvas . getPointer ( e ) ; return this . _ _mousedownX !== t . x || this . _ _mousedownY !== t . y } , initMouseupHandler : function ( ) { this . on ( "mouseup" , function ( e ) { this . _ _isMousedown = ! 1 ; if ( this . _isObjectMoved ( e . e ) ) return ; this . _ _lastSelected && ( this . enterEditing ( ) , this . initDelayedCursor ( ! 0 ) ) , this . selected = ! 0 } ) } , setCursorByClick : function ( e ) { var t = this . getSelectionStartFromPointer ( e ) ; e . shiftKey ? t < this . selectionStart ? ( this . setSelectionEnd ( this . selectionStart ) , this . setSelectionStart ( t ) ) : this . setSelectionEnd ( t ) : ( this . setSelectionStart ( t ) , this . setSelectionEnd ( t ) ) } , _getLocalRotatedPointer : function ( e ) { var t = this . canvas . getPointer ( e ) , n = new fabric . Point ( t . x , t . y ) , r = new fabric . Point ( this . left , this . top ) , i = fabric . util . rotatePoint ( n , r , fabric . util . degreesToRadians ( - this . angle ) ) ; return this . getLocalPointer ( e , i ) } , getSelectionStartFromPointer : function ( e ) { var t = this . _getLocalRotatedPointer ( e ) , n = this . text . split ( this . _reNewline ) , r = 0 , i = 0 , s = 0 , o = 0 , u ; for ( var a = 0 , f = n . length ; a < f ; a ++ ) { s += this . _getHeightOfLine ( this . ctx , a ) * this . scaleY ; var l = this . _getWidthOfLine ( this . ctx , a , n ) , c = this . _getLineLeftOffset ( l ) ; i = c * this . scaleX , this . flipX && ( n [ a ] = n [ a ] . split ( "" ) . reverse ( ) . join ( "" ) ) ; for ( var h = 0 , p = n [ a ] . length ; h < p ; h ++ ) { var d = n [ a ] [ h ] ; r = i , i += this . _getWidthOfChar ( this . ctx , d , a , this . flipX ? p - h : h ) * this . scaleX ; if ( s <= t . y || i <= t . x ) { o ++ ; continue } return this . _getNewSelectionStartFromOffset ( t , r , i , o + a , p ) } if ( t . y < s ) return this . _getNewSelectionStartFromOffset ( t , r , i , o + a , p , h ) } if ( typeof u == "undefined" ) return this . text . length } , _getNewSelectionStartFromOffset : function ( e , t , n , r , i , s ) { var o = e . x - t , u = n - e . x , a = u > o ? 0 : 1 , f = r + a ; return this . flipX && ( f = i - f ) , f > this . text . length && ( f = this . text . length ) , s === i && f -- , f } } ) , fabric . util . object . extend ( fabric . IText . prototype , { initHiddenTextarea : function ( ) { this . hiddenTextarea = fabric . document . createElement ( "textarea" ) , this . hiddenTextarea . setAttribute ( "autocapitalize" , "off" ) , this . hiddenTextarea . style . cssText = "position: absolute; top: 0; left: -9999px" , fabric . document . body . appendChild ( this . hiddenTextarea ) , fabric . util . addListener ( this . hiddenTextarea , "keydown" , this . onKeyDown . bind ( this ) ) , fabric . util . addListener ( this . hiddenTextarea , "keypress" , this . onKeyPress . bind ( this ) ) , fabric . util . addListener ( this . hiddenTextarea , "copy" , this . copy . bind ( this ) ) , fabric . util . addListener ( this . hiddenTextarea , "paste" , this . paste . bind ( this ) ) , ! this . _clickHandlerInitialized && this . canvas && ( fabric . util . addListener ( this . canvas . upperCanvasEl , "click" , this . onClick . bind ( this ) ) , this . _clickHandlerInitialized = ! 0 ) } , _keysMap : { 8 : "removeChars" , 13 : "insertNewline" , 37 : "moveCursorLeft" , 38 : "moveCursorUp" , 39 : "moveCursorRight" , 40 : "moveCursorDown" , 46 : "forwardDelete" } , _ctrlKeysMap : { 65 : "selectAll" , 88 : "cut" } , onClick : function ( ) { this . hiddenTextarea && this . hiddenTextarea . focus ( ) } , onKeyDown : function ( e ) { if ( ! this . isEditing ) return ; if ( e . keyCode in this . _keysMap ) this [ this . _keysMap [ e . keyCode ] ] ( e ) ; else { if ( ! ( e . keyCode in this . _ctrlKeysMap && ( e . ctrlKey || e . metaKey ) ) ) return ; this [ this . _ctrlKeysMap [ e . keyCode ] ] ( e ) } e . stopPropagation ( ) , this . canvas && this . canvas . renderAll ( ) } , forwardDelete : function ( e ) { this . selectionStart === this . selectionEnd && this . moveCursorRight ( e ) , this . removeChars ( e ) } , copy : function ( e ) { var t