{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/components/modal.js","webpack:///./node_modules/tingle.js/dist/tingle.min.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/productTileComponent/productTile.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/components/productSlider.js","webpack:///(webpack)/buildin/global.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/productDetail.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/productTileComponent/productTileCarousel.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/product/quickView.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/util/form.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/product/notify.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/product/productBox.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/customCarousel.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/customize.js","webpack:///(webpack)/node_modules/buffer/index.js","webpack:///./node_modules/base64-js/index.js","webpack:///./node_modules/ieee754/index.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/util/common.js","webpack:///./node_modules/isarray/index.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/personalization/generateSvgForOTP.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/personalization/selectors.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/personalization/classes.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/product/detail.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/product/smartGiftHelper.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/product/sizePanel.js","webpack:///./assets/scripts/util/url.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/analytics/helpers/helper.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/findYourSize/findYourSize.js","webpack:///./assets/scripts/product/scalaPay.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/product/base.js","webpack:///./assets/scripts/product/klarna.js","webpack:///./cartridges/app_intimissimi/cartridge/client/default/js/product/wishlistHeart.js","webpack:///./node_modules/fabric/dist/fabric.js"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","installedModules","34","7","10","__webpack_require__","exports","module","l","e","promises","installedChunkData","promise","Promise","resolve","reject","onScriptComplete","script","document","createElement","charset","timeout","nc","setAttribute","src","p","jsonpScriptSrc","error","Error","event","onerror","onload","clearTimeout","chunk","errorType","type","realSrc","target","message","name","request","undefined","setTimeout","head","appendChild","all","m","c","d","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","oe","err","console","jsonpArray","window","oldJsonpFunction","slice","s","footer","cssClass","modalOptions","closeMethods","onClose","modal","destroy","onOpen","$","addClass","beforeClose","removeClass","tingle","selectorID","contentModal","getElementById","setContent","innerHTML","html","ModalShowHide","selector","newModalType","toPropagateClick","classToPreventHide","this","$el","_scrollposition","isOpenTypeCustom","isOpen","events","_scrollPosition","pageYOffset","parent","scrollTo","on","hasClass","closest","hide","stopPropagation","define","beforeOpen","stickyFooter","closeLabel","opts","init","modalBoxFooter","style","width","modalBox","clientWidth","left","offsetLeft","classList","add","indexOf","display","forEach","modalCloseBtn","modalCloseBtnIcon","modalCloseBtnLabel","modalBoxContent","_events","clickCloseBtn","close","clickOverlay","resize","checkOverflow","keyboardNav","addEventListener","which","clientX","parentElement","contains","a","removeEventListener","arguments","h","transition","OTransition","MozTransition","WebkitTransition","body","insertBefore","firstChild","addFooter","parentNode","removeChild","open","removeProperty","removeAttribute","top","setStickyFooter","remove","getContent","setFooterContent","getFooterContent","isOverflow","clientHeight","addFooterBtn","split","warn","innerHeight","PRODUCT_GRID_PLP","initProdTileCarousel","initSlotCarousel","each","element","children","QUICKADD_BUTTON","off","openQuickAdd","PREVENT_DEFAULT","preventDefault","onResizeFunction","QUICKADD_CLOSE","QUICKADD_PROCEEDBUTTON","QUICKADD_SIZEBUTTON","isOpened","STYLE_QUICKADD_SIZEBUTTON_SELECTED","QUICKADD_MODAL_OPEN","containerClassName","Foundation","MediaQuery","atLeast","currentTarget","trigger","$this","url","$modal","siblings","$modalForSlider","isCompletePromo","after","genericAjaxCall","then","newDOMModal","clone","empty","find","closeQuickAddShoppable","prepareAddToCart","searchSelectedSize","openQuickAddShoppable","first","$quickAddOutsideModal","eq","prepend","analytics","item_list_id","item_list_name","index","slideDown","start","css","complete","closeQuickAdd","forceLockScroll","exc","forceUnlockScroll","slideUp","closeQuickButton","closeAllQuickAdd","allQAopen","selectSize","sizeButton","prepareData","form","pid","quantity","GTMItemListName","GTMItemListId","GTMIndex","addToCartUrl","$productContainer","makeAddToCart","attr","dataValue","response","append","history","scrollRestoration","animate","scrollTop","handlePostCartAdd","slick","slidesToShow","slidesToScroll","infinite","variableWidth","responsive","breakpoint","settings","g","Function","slideIndex","fixedBarDescription","ticking","fixedElement","scrollStopperElement","additionalBar","sliderTrack","stopperElement","stopperElement2","fixedHTMLElement","additionalBarHTML","getComputedStyle","position","scrollStopperElement2","bottom","right","marginTop","marginLeft","zIndex","onScroll","unwrap","requestTick","bottomBar","stopper","stopper2","r1","getBoundingClientRect","r2","r3","r4","height","raf","update","automaticScroll","show","scrollToTop","scrollIntoView","behavior","updatePickableContentPositioning","hideServiceMenuAfterTimeout","mouseZoomOnImage","pageH","imgH","clientY","originalEvent","showStickyBottomBarMobile","addToCartCTA","addToCartStickyBar","addToCartCTATop","offset","addToCartCTABottom","outerHeight","viewportTop","viewportBottom","isFooterHidden","showSlides","mobile","zoomModal","parseInt","slides","getElementsByClassName","prev","next","selectedProductColor","productColor","processInclude","require","Product","run","ScalaPay","Klarna","loadKlarnaWidgetAndObservers","ready","stickyBarManager","enqueueTask","productSlider","querySelectorAll","anchor","targetElement","querySelector","getAttribute","offsetTop","_lazyloadCache","lazyload","$domElement","ajax","newModalFromString","__webpack_public_path__","ll_script","base","findinstore","fs","launch","sizeModal","newModalFromSelector","$sizeModalElement","removeAttr","$target","sizeValue","selectedSizes","splice","prop","join","htmlContent","modalContent","content","crossSellItems","decodeURIComponent","computeCurrentlyVisibleImage","timer","previousPosition","headerHeight","is","zoomInLabel","zoomOutLabel","onscroll","scrollYPos","scrollY","scrollYMaxDeadzone","documentElement","scrollHeight","$mainHeader","$breadCrumbsContainer","onScrollFunction","evt","closeAllOpenMenus","container","product","isFreeGist","modalBigContent","calculateTopOffset","$element","showOrHideStickyBar","scrollPosition","duration","video","isPlaying","pause","play","containerClass","$tileCarousel","IMAGE_CONTAINER_CAROUSEL_CLASS","lazyloadclass","lazyVideos","lazyVideoObserver","IntersectionObserver","entries","isIntersecting","source","videoSource","tagName","dataset","load","unobserve","lazyVideo","observe","previousLabel","nextLabel","lazyLoad","draggable","dots","accessibility","arrows","addToCartFromListing","promoId","spinner","options","dataType","success","localStorage","setItem","stop","showQuickview","observeQuickBuy","selectedValueUrl","replace","productUrl","method","renderedTemplate","getItem","click","destroyModal","log","fillModalElement","newModal","available","comingSoon","id","addInputClearIcon","inputItem","$inputFieldContainer","clearIconTopPos","formElement","payload","selects","chosen","disable_search","ariaLabel","fields","keys","feedbackElement","Array","isArray","val","firstNameIdList","lastNameIdList","firstNameId","lastNameId","parents","swapFirstLastName","parentSelector","fieldErrors","cardFieldSelector","cardTypeSelector","cleave","Cleave","creditCard","onCreditCardTypeChanged","creditCardTypes","amex","cardType","visa","mastercard","discover","jcb","diners","unknown","wasAmexSelected","serializedArray","serializeArray","item","getRawValue","param","actualDiv","notifyMeAction","notifyMeDiv","paramUrl","isComingSoon","size","innerText","selectedColor","selectedSize","quickAddFlow","trim","replaceAll","color","rsp","FormHelpers","sku","productName","cta","text","email","isValid","test","validateEmail","queryString","analyticsSku","dataForm","owner","messageComingSoon","availability","duplicate","startCarouselTileImageFunction","carousel","swipe","swipeToSlide","touchMove","gotoPDP","startCarouselTileImage","afterAttributesSelectionEvent","additionalData","$container","newPriceData","price","doubleCurrency","checkCarouselLength","carouselContainer","carouselWidth","outerWidth","carouselItemsNumber","carouselItemsWidth","carouselItemsWidthSum","scroll","carouselScrolled","scrollLeft","carouselScroll","el","dir","customizePosition","customizeSide","customizeText","customizeFont","customizePattern","customizeColor","allowedCharactersRegex","canvas","canvasText","canvasRect","canvasGroup","canvasImage","topBack","leftBack","badWords","loadingTime","isStepTwo","rectColor","switchDisable","initText","textInput","SELECTORS","fontsButtons","colorsButtons","initVariables","pixelText","initCanvas","imageToLoad","imgFront","fabric","StaticCanvas","enableRetinaScaling","transformX","transformY","translateY","personalizationCanvas","transformOrigin","transform","zoomButton","canvasRatio","Textbox","originX","originY","fontSize","lineHeight","fontFamily","textAlign","fill","Rect","strokeDashArray","stroke","strokeWidth","imageUrl","Image","fromURL","img","set","selectable","hasRotatingPoint","scaleToWidth","Group","renderAll","initForm","updateCanvasElem","elem","choicePosition","page","mainChoice","showOtherSide","stepOne","stepTwo","termsBottomDesktop","CLASSES","pageStepOne","pageStepTwo","selectPosition","pos","imgBack","hotspotOne","hotspotTwo","clear","updateCanvas","runPersonalizationListener","defer","imagesNumber","loadComplete","sizePanel","jQuery","Deferred","one","imageFront","imageBack","topPercentage","leftPercentage","topBackPercentage","leftBackPercentage","$position1","$position2","appendTo","backChoicePosition","action","personalizeAddToCart","canvasOptions","svgAllFormat","generateSvgForOTP","base64FullSVG","personalizationFullSVG","base64TextFullSVG","personalizationTextSVG","base64TextSmallSVG","personalizationSmallSVG","readyToOrder","termsAndConditionsModal","analyticsCustomizeAction","pageClose","positionChoice","badWordsFlag","includes","toLowerCase","match","editTextOnCanvas","colorName","scaleValue","toggleClass","base64","ieee754","kMaxLength","Buffer","TYPED_ARRAY_SUPPORT","createBuffer","that","RangeError","Uint8Array","__proto__","arg","encodingOrOffset","allocUnsafe","from","TypeError","ArrayBuffer","array","byteOffset","byteLength","fromArrayLike","fromArrayBuffer","string","encoding","isEncoding","actual","write","fromString","obj","isBuffer","len","checked","copy","buffer","fromObject","assertSize","toString","isView","loweredCase","utf8ToBytes","base64ToBytes","slowToString","end","hexSlice","utf8Slice","asciiSlice","latin1Slice","base64Slice","utf16leSlice","swap","b","bidirectionalIndexOf","isNaN","arrayIndexOf","lastIndexOf","arr","indexSize","arrLength","valLength","String","read","buf","readUInt16BE","foundIndex","found","j","hexWrite","Number","remaining","strLen","parsed","substr","utf8Write","blitBuffer","asciiWrite","str","byteArray","charCodeAt","asciiToBytes","latin1Write","base64Write","ucs2Write","units","hi","lo","utf16leToBytes","fromByteArray","Math","min","res","secondByte","thirdByte","fourthByte","tempCodePoint","firstByte","codePoint","bytesPerSequence","codePoints","MAX_ARGUMENTS_LENGTH","fromCharCode","apply","decodeCodePointsArray","SlowBuffer","alloc","INSPECT_MAX_BYTES","global","foo","subarray","typedArraySupport","poolSize","_augment","species","configurable","allocUnsafeSlow","_isBuffer","compare","x","y","concat","list","swap16","swap32","swap64","equals","inspect","max","thisStart","thisEnd","thisCopy","targetCopy","isFinite","toJSON","_arr","ret","out","toHex","bytes","checkOffset","ext","checkInt","objectWriteUInt16","littleEndian","objectWriteUInt32","checkIEEE754","writeFloat","noAssert","writeDouble","newBuf","sliceLen","readUIntLE","mul","readUIntBE","readUInt8","readUInt16LE","readUInt32LE","readUInt32BE","readIntLE","pow","readIntBE","readInt8","readInt16LE","readInt16BE","readInt32LE","readInt32BE","readFloatLE","readFloatBE","readDoubleLE","readDoubleBE","writeUIntLE","writeUIntBE","writeUInt8","floor","writeUInt16LE","writeUInt16BE","writeUInt32LE","writeUInt32BE","writeIntLE","limit","sub","writeIntBE","writeInt8","writeInt16LE","writeInt16BE","writeInt32LE","writeInt32BE","writeFloatLE","writeFloatBE","writeDoubleLE","writeDoubleBE","targetStart","code","INVALID_BASE64_RE","Infinity","leadSurrogate","toByteArray","stringtrim","base64clean","dst","b64","lens","getLens","validLen","placeHoldersLen","tmp","Arr","_byteLength","curByte","revLookup","uint8","extraBytes","parts","maxChunkLength","len2","encodeChunk","lookup","num","output","isLE","mLen","nBytes","eLen","eMax","eBias","nBits","NaN","rt","abs","LN2","task","requestAnimationFrame","hideSpinner","include","map","htmlMap","params","newUrl","encodeURIComponent","cookie","filter","expires","days","date","Date","setTime","getTime","toGMTString","pop","navigator","maxTouchPoints","msMaxTouchPoints","newCanvas","createSvgFromCanvas","scaleRatio","setDimensions","getWidth","getHeight","setZoom","canvasToConvert","svg","toSVG","canvasNode","active","handleDetailsTabs","clickedTab","openQuickView","modalClass","setMinHeightPromoPanel","_array","maxHeight","_array2","maxHeightTitle","selectedVariation","k","productType","variationAttributes","variationAttribute","attributeId","values","selected","getProductVariationGroup","requestUrl","isSizeChange","promotionId","$result","$completePromoData","$completePromoSection","$completePromoProducts","$completePromoContainer","$completeLookData","$completeLookSection","$completeLookProducts","quickview","mustAdd","removeNulls","updatePrimaryImagesSlide","enableImageSlideHeightObservers","imgNode","MutationObserver","mutationsList","observer","mutation","attributeName","attributes","childList","subtree","slickNode","initializePrimaryImagesSlider","primaryImages","carouselItems","ProductHelpers","showSpinner","updateAttribute","updateAddToCart","updateAvailability","getCrossSellItems","afterUpdateImages","recentlyViewedItems","buyNowQuichview","suggedtedProductsPDP","observeCurtainTap","removeNullCrossSell","pdpCrossSell","handleAccordionsInPDP","changeAddToBagButton","button","items","$buyNowCta","orderable","initProductTile","cs","$csItem","image","$detailsAccordionShipping","$detailsAccordionDescription","basketBeforeRemovedProduct","basketObserverEnabled","basketAlreadyFetched","methods","getPidValue","isSizeSelected","addSmartGift","enableAnalyticsBasketObserver","openSizePanel","Types","SMARTGIFT","analyticsDataButton","skus","basketButtonsSelector","SGBasket","getSkus","getSkusQuantity","eachSuggestion","dataSuggestion","suggestionLength","suggestionItem","infoSuggestion","imgSuggestion","hrefSuggestion","skuCode","title","skuUrl","href","recommendedItems","location","nameEng","addRecommendedItems","addItem","state","basket","removedProduct","targetWidgetNode","_self","nodeName","setAnalyticsProductIndex","getBasket","stopImmediatePropagation","productIndex","triggerRemoveProduct","idName","infoURL","sizeDisplayValue","ADDTOCART","ADDTOCART_BUNDLE","PERSONALIZE","WISHILIST","operation","$sizeElements","bundleQuantity","stopSpinner","needle","qsKeyToUpdate","urlObject","URL","searchParams","qsKey","qsValue","replaceState","testEnabled","productGenderMap","1","2","3","4","5","6","brandsMapping","ListType","getSkuCodes","substring","formatStringForAnalytics","formatStringProductPropertyIfExists","avoidFormatting","getFormatSkuForAnalytics","formatFloatProductPropertyIfExists","parseFloat","formatIntegerProductPropertyIfExists","stringOrNotAvailable","numberOrZero","getStringAnalyticsValueFromStorage","sessionStorage","formattedSku","toUpperCase","skuComponents","isTestEnabled","getAvailableListTypes","listingItemsBaseClass","types","getSkuComponents","getProductGender","sapCategoryCode","categoryCode","getProductBaseInfo","colorObject","promo","promotions","enabled","appliedPromotions","components","formatProductForAnalytics","formatStringProductSalePropertyIfExists","checkPage","formatString","format4DigitNumber","number","insertParameter","encodeURI","kvp","search","insertParam","existsParameter","hasParam","pushObject","dataLayer","getFormatSku","formatNameForAnalytics","formatSkus","formattedSkus","getProductNameEngFromPdp","getFormatedNewsletterPreferenceBrands","brandsStr","brand","getListId","provider","getProductList","getGrandTotal","getAppliedCoupon","coupon","getUpsellingMessage","upsellingMessage","vals","getBeginCheckoutData","context","upselling_message","currency","helperData","getTypeOfAccount","typeOfAccount","storeGtmData","item_id","item_variant","JSON","stringify","getGtmData","GTMData","GTMItem","parse","setBonusProductData","calculateTableFromPdpESFRLU","underbrowSize","cupSize","suggestedSizes","initialCupSize","initialUnderBrowSize","arrSizes","PrevUnderbrowSize","prevCupSize","inputUnderbrowSize","inputCupSize","jsonUnderbrowTable","FindYourSizeData","findYourSizeData","underbrowTable","country","jsonCircTable","FindYourSizeDataCirc","findYourSizeDataCirc","circTable","eu","to","it","es","fr","us","gb","pt","hk","lu","firstElementChild","calculateTableFromPdp","calculateTableFromPdpUS","calculateTableFromPdpUK","calculateTableFromPdpHK","calculateTableFromPdpPT","calculateTableFromPdpEU","suggestedSizesString","calculateBraSizeFromPdp","unit","focus","formatAmount","forceChange","oldText","updatePrice","setInterval","clearInterval","updatedText","currentPage","availableAPI","scalaPayWidget","loadWidget","checkWidget","prepareObservers","shadowRoot","order","scalaPayLabel","showPaymentMethod","scalaPaySettings","widgetText","payment","isEligible","totals","scalapayTotals","paymentPageWidgetText","isApplicablePaymentMethod","billing","applicablePaymentMethods","ID","toggle","isMiniCartOpen","attributeSelectQuickAdd","imagesShouldUpdate","handleVariantResponseQuickAdd","updateOptions","updateQuantities","quantities","selectedQuantity","activatePromoAnimationMessage","reactivatePromoAnimationMessage","pdpCalloutMsgText","attributeSelect","ignoreCTA","prevObject","analyticsPromotion","isSize","variation","handleVariantResponse","handleVariationUrlsSelectSizeModal","variationUrls","handlePromotionTag","handleVariationUrlsSelectNotifyModal","handleVariationComingSoonNotifyModal","handleVariationComingSoon","handleVariationWishlistModal","updateImageSaveForLater","getPID","promoContainer","promoMessage","promoLoyaltyMessage","selectorPrefix","onSaleSelected","saleType","discountValue","calloutMsg","totalQuantityPrice","handleInexistentSizeQuickView","handleWishlistContainer","responseJSON","redirectUrl","current_url","pathname","localized_error_page","protocol","host","afterSizeSelection","getQuantitySelector","getQuantitySelected","updateAttrs","attrs","variantType","attrsWithSwatches","attrValue","$attrValue","$swatchAnchor","displayValue","displayName","images","swatch","outerHTML","isSoldout","processSwatchValues","$attr","resetUrl","$attrValueMobile","variationUrl","selectedSizeSpan","lowAvailability","disabled","$sizeSelectorContainer","processNonSwatchValues","updateScanTrustLink","$productAuthenticity","scanTrustUrlWithParams","availabilityValue","availabilityMessages","messages","resources","info_selectforstock","isSizeInexistent","option","$optionEl","valueEl","updateColorFamily","colorFamily","updatePrices","priceSelector","priceInfoSelector","$oldPriceInfoSelector","$regularPriceInfoDiscountSelector","$oldPriceInfoDiscountSelector","$pricePercentage","$priceSelector","$priceInfoSelector","$priceInfoInSaleContainerSelector","$priceInfoInSaleContainerSelector2","$omnibusPricelForSpecificCountries","onSalesInfoPrice","replaceWith","currentCountryOmnibus","isRegularOmnibusCountry","sales","formattedPriceInfo","tooltip_omnibus","oldPriceOmnibus","priceInfoDiscountValue","formatted","$doubleCurrencyContainer","innerContent","New","isGreen","small","partTypes","comp","percentage","material","endTag","mainComposition","primaryImageUrls","selectedProductUrl","large","idx","$carouselInner","$imgContainer","resizedUrls","sizes","scaleWidth","$imgContainerDesktop","$imgZoomModal","$imgZoomModalMobile","newCarouselSlideHtml","$galleryItemContainer","$zoomTemplate","videoUrl","videoURL","tmpl","$secondItem","insertAfter","videoBlock","autoplay","videoListener","updatePrimaryImagesSlider","careAndMaintenance","countryEnabled","PersonalizationEnabledCountries","isPersonalizedVal","positions","showButton","updateModelSize","modelSize","promotionClass","cleanId","allocation","comingSoons","customizations","personalizationImgTop","personalizationImgDown","link","linkPlp","optionsHtml","getAddToCartUrl","$html","parseHTML","$results","cookies","cookieSizebaySessionId","startsWith","urlSessionId","fetch","ok","json","createCookie","callSizebayAPI","brandURL","currentCountry","permaURL","urlSizebay","has","device","referrerURL","referrerPolicy","headers","accept","tenant_id","referer","hostname","updateQuantityPicker","calculateWatchedTime","currentTime","triggerVideoInteractionEvent","fullPageLoad","$videoBlockContainer","$videoPlayMiniatureIcon","percentageWatched","firstPlayback","watchedFullVideo","videoStartInSeconds","videoEndInSeconds","myVideo","onended","onplaying","onpause","loop","paused","reorderSwatches","$swatchContainer","$soldoutColorsContainers","$lastNonSoldoutColorContainer","not","last","freeGiftDetailsModal","bonusProductModal","colorAttribute","colorAttributeQuickAddListing","sizeAttribute","sizeAttributeQuickAddListing","sizeAttributeQuickAddPDP","sizeAttributeSet","addToCart","careAndMaintenanceClick","personalizationButton","sizeTU","quickAddListener","NotifyHelper","notifyMeModal","checkSoldoutAvailability","SmartGiftHelper","registerAttributionTokenSending","loadGoogleRecommendations","createNextPageToken","description","firstPart","firstPartSplit","firstPartSKU","productId","colorValue","updateProductDetailUrl","$productTile","selectedValue","isPdp","isPeronalizePage","sizeData","skuData","decodeURI","splitSkuData","$sizeSelected","$button","$input","newValue","pidsObj","setPids","_openStickySizeSelectorModal","isPersonalizedProduct","personalizationTextFont","personalizationText","personalizationTextColor","personalizationColorPref","PersonalizationColor","personalizationColor","personalizationColorJson","alt","personalizationPositionKey","customizationClassPref","CustomizationClass","customizationClass","customizationClassJson","category","uniqueIdentifiers","random","personalizedObj","isDate","isLove","uniqueIdentifier","qty","pidSet","uid","buttonAdd","childProducts","uuid","completePromoItems","completePromoItemsLabel","quantityTotal","cart","numItems","cartModel","showQuickAddItems","sizeChecked","quantitySelected","attributesUpdateUrl","attributionToken","$googleConfig","servingConfig","nodeToAppendTo","cgid","route","$googleAttributionToken","previousPageToken","searchTerm","getElementsByTagName","round","KlarnaOnsiteService","eventName","displayMessageAndChangeIcon","icon","isAddAction","wishlistTotal","sender","updateAriaLabelForWishlistLink","blur","closeNotification","showWishlistNotification","newItems","oldItems","oldIdx","updateWishlistInternalState","addDefinitelyToWishlist","productID","btn","addURL","removeURL","optionId","optionVal","shouldAdd","isAdding","added","labelAddWishlist","labelRemoveWishlist","checkItemInWishlist","itemCode","highlightIconsForAllItemsInWishlist","itemsInWishlist","plpWishlist","productDetailWishlist","moveToWishlistHelper","$btn","moveToWishlistHelperSaveForLater","addToWishlist","$clickedButton","$inputToClick","_","sqrt","atan2","PiBy180","PiBy2","couldUseAttachEvent","parseEl","supportsOpacity","supportsFilters","reOpacity","setOpacity","proto","toFixed","degreesToRadians","originXOffset","originYOffset","version","HTMLDocument","Document","implementation","createHTMLDocument","virtualWindow","JSDOM","features","FetchExternalResources","jsdomImplForWrapper","implForWrapper","nodeCanvas","Canvas","DOMParser","copyGLTo2DDrawImage","gl","pipelineState","glCanvas","targetCanvas","ctx","getContext","translate","scale","sourceY","drawImage","copyGLTo2DPutImageData","dWidth","destinationWidth","dHeight","destinationHeight","numBytes","u8","imageBuffer","u8Clamped","Uint8ClampedArray","readPixels","RGBA","UNSIGNED_BYTE","imgData","ImageData","putImageData","isTouchSupported","isLikelyNode","SHARED_ATTRIBUTES","DPI","reNum","rePathCommand","reNonWord","fontPaths","iMatrix","svgNS","perfLimitSizeTotal","maxCacheSideLimit","minCacheSideLimit","charWidthsCache","textureSize","disableStyleCopyPaste","enableGLFiltering","devicePixelRatio","webkitDevicePixelRatio","mozDevicePixelRatio","browserShadowBlurConstant","arcToSegmentsCache","boundsOfCurveCache","cachesBoundsOfCurve","forceGLPutImageData","initFilterBackend","isWebglSupported","maxTextureSize","WebglFilterBackend","tileSize","Canvas2dFilterBackend","_removeEventListener","handler","__eventListeners","eventListener","util","stopObserving","fire","listenersForEvent","Observable","Collection","_objects","_onObjectAdded","renderOnAddRemove","requestRenderAll","insertAt","nonSplicing","objects","somethingRemoved","_onObjectRemoved","forEachObject","callback","getObjects","isEmpty","complexity","reduce","memo","current","CommonMethods","_setOptions","_initGradient","filler","colorStops","Gradient","_initPattern","Pattern","_initClipping","clipTo","functionBody","getFunctionBody","_setObject","_set","PI","cos","angle","sin","sign","removeFromArray","getRandomInt","degrees","radiansToDegrees","radians","rotatePoint","point","origin","subtractEquals","v","rotateVector","Point","addEquals","vector","transformPoint","ignoreOffset","makeBoundingBoxFromPoints","points","xPoints","minX","yPoints","minY","invertTransform","fractionDigits","parseUnit","exec","Text","DEFAULT_SVG_FONT_SIZE","falseFunction","getKlass","namespace","camelize","charAt","resolveNamespace","getSvgAttributes","loadImage","crossOrigin","createImage","onLoadCallback","loadImageInDom","div","enlivenObjects","reviver","enlivenedObjects","numLoadedObjects","numTotalObjects","onLoaded","enlivenPatterns","patterns","numLoadedPatterns","numPatterns","enlivenedPatterns","pattern","groupSVGElements","elements","path","centerPoint","sourcePath","populateWithProperties","destination","properties","drawDashedLine","x2","y2","da","dx","dy","rot","dc","di","draw","save","moveTo","rotate","restore","createCanvasElement","copyCanvasElement","toDataURL","canvasEl","format","quality","clipContext","receiver","beginPath","clip","multiplyTransformMatrices","is2x2","qrDecompose","denom","scaleX","scaleY","skewX","skewY","translateX","calcRotateMatrix","theta","calcDimensionsMatrix","scaleMatrix","flipX","flipY","multiply","tan","composeMatrix","matrix","customTransformMatrix","resetObjectTransform","saveObjectTransform","fn","isTransparent","tolerance","_isTransparent","imageData","getImageData","parsePreserveAspectRatioAttribute","attribute","align","meetOrSlice","aspectRatioAttrs","alignX","alignY","clearFabricFontCache","limitDimsByArea","ar","maximumArea","roughWidth","perfLimitSizeY","capValue","findScaleToFit","findScaleToCover","matrixToSVG","NUM_FRACTION_DIGITS","_join","arcToSegments","toX","toY","rx","ry","sweep","rotateX","argsString","th","sinTh","cosTh","fromX","fromY","px","py","rx2","ry2","py2","px2","pl","root","cx","cy","cx1","cy1","mTheta","calcVectorAngle","dtheta","segments","ceil","result","mDelta","mT","th3","segmentToBezier","th2","costh2","sinth2","costh3","sinth3","ux","uy","vx","vy","ta","tb","getBoundsOfCurve","x0","y0","x1","y1","x3","y3","t1","t2","b2ac","sqrtb2ac","tvalues","bounds","mt","jlen","drawArc","fx","fy","coords","segs","segsNorm","bezierCurveTo","getBoundsOfArc","tx","ty","bound","byProperty","condition","invoke","args","value1","value2","extend","deep","Element","getWholeChar","character","capitalize","firstLetterOnly","escapeXml","graphemeSplit","textstring","chr","graphemes","emptyFunction","IS_DONTENUM_BUGGY","addMethods","klass","superclass","constructor","returnValue","valueOf","Subclass","callSuper","methodName","parentMethod","_this","superClassMethod","createClass","initialize","subclasses","attachEvent","addListener","removeListener","getPointer","getScrollLeftTop","_evt","touchProp","changedTouches","getTouchInfo","opacity","currentStyle","hasLayout","zoom","setStyle","styles","elementStyle","cssText","styleFloat","_slice","sliceCanConvertNodelists","getElementStyle","selectProp","toArray","arrayLike","childNodes","makeElement","className","htmlFor","docElement","nodeType","defaultView","makeElementUnselectable","onselectstart","unselectable","makeElementSelectable","getScript","headEl","scriptEl","loading","onreadystatechange","readyState","getById","wrapElement","wrapper","replaceChild","getElementOffset","docElem","scrollLeftTop","doc","ownerDocument","box","offsetAttributes","borderLeftWidth","borderTopWidth","paddingLeft","paddingTop","clientLeft","clientTop","getNodeCanvas","impl","_canvas","_image","cleanUpJsdomNode","_currentSrc","_attributes","_classList","emptyFn","onComplete","xhr","XMLHttpRequest","parameters","addParamToUrl","setRequestHeader","send","noop","defaultEasing","_requestAnimFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","_cancelAnimFrame","cancelAnimationFrame","requestAnimFrame","timestamp","time","finish","onChange","abort","easing","startValue","endValue","byValue","onStart","tick","ticktime","timePerc","valuePerc","cancelAnimFrame","animateColor","fromColor","toColor","startColor","Color","getSource","endColor","begin","posValue","colorEasing","normalize","asin","elastic","easeInBounce","easeOutBounce","ease","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInSine","easeOutSine","easeInOutSine","easeInExpo","easeOutExpo","easeInOutExpo","easeInCirc","easeOutCirc","easeInOutCirc","easeInElastic","easeOutElastic","easeInOutElastic","easeInBack","easeOutBack","easeInOutBack","easeInOutBounce","attributesMap","visibility","colorAttributes","fSize","cPath","normalizeAttr","normalizeValue","parentAttributes","transformMatrix","parseTransformAttribute","visible","fillIndex","strokeIndex","getSvgRegex","RegExp","_getMultipleNodes","nodeNames","nodeList","nodeArray","elementMatchesRule","selectors","firstMatching","parentMatching","selectorMatches","doesSomeParentMatch","matcher","classNames","elementById","node","nodelist","svgValidTagNamesRegEx","svgViewBoxElementsRegEx","svgInvalidAncestorsRegEx","svgValidParentsRegEx","cssRules","gradientDefs","clipPaths","skewMatrix","commaWsp","reTransformList","reTransform","attributeValue","matrices","translateMatrix","rotateMatrix","multiplierX","multiplierY","combinedMatrix","reViewBoxAttrValue","applyViewboxTransform","viewBoxWidth","viewBoxHeight","viewBoxAttr","widthAttr","heightAttr","preserveAspectRatio","missingViewBox","missingDimAttr","toBeParsed","parsedDim","widthDiff","heightDiff","viewboxTransform","createElementNS","recursivelyParseGradientsXlink","gradient","xlinkAttr","referencedGradient","hasAttribute","referenceClone","cloneNode","parseSVGDocument","parsingOptions","xlink","el2","currentTrans","oldLength","el3","setAttributeNS","nodeValue","parseUseDirectives","svgUid","__uid","descendants","selectNodes","hasAncestorWithNodeName","getGradientDefs","getCSSRules","parseElements","instances","reFontDeclaration","parseFontDeclaration","oStyle","fontStyle","fontWeight","elList","parseAttributes","parentFontSize","ownAttributes","cssAttrs","rule","getGlobalStylesForElement","parseStyleAttribute","normalizedAttr","normalizedValue","normalizedStyle","font","mergedAttrs","setAlpha","getAlpha","toRgba","_setStrokeFillOpacity","ElementsParser","pair","parseStyleString","parseStyleObject","parsePointsAttribute","parsedPoints","allRules","styleContents","textContent","ruleObj","propertyValuePairs","_rule","loadSVGFromURL","xml","responseXML","ActiveXObject","responseText","async","loadXML","results","_options","allElements","loadSVGFromString","parser","parseFromString","regexUrl","numElements","createObjects","createObject","findTag","fromElement","createCallback","checkIfDone","resolveGradient","_originalElement","_removeTransformMatrix","resolveClipPath","extractPropertyDefinition","storage","regex","lastIndex","gradientDef","opacityAttr","createClipPathCallback","_newObj","fillRule","clipRule","usingElement","objTransformInv","gTransform","clipPath","calcTransformMatrix","clipPathTag","clipPathOwner","setPositionByOrigin","scalarAdd","scalar","scalarAddEquals","subtract","scalarSubtract","scalarSubtractEquals","multiplyEquals","divide","divideEquals","lt","lte","gt","gte","lerp","distanceFrom","midPointFrom","setXY","setX","setY","setFromPoint","Intersection","status","appendPoint","appendPoints","intersectLineLine","a1","a2","b1","b2","uaT","ubT","uB","ua","ub","intersectLinePolygon","inter","intersectPolygonPolygon","points1","points2","intersectPolygonRectangle","topRight","bottomLeft","inter1","inter2","inter3","inter4","_tryParsingColor","setSource","hue2rgb","q","colorNameMap","sourceFromHex","sourceFromRgb","sourceFromHsl","_rgbToHsl","_source","toRgb","toHsl","hsl","toHsla","toHexa","alpha","toGrayscale","average","currentAlpha","toBlackWhite","threshold","overlayWith","otherColor","otherSource","reRGBa","reHSLa","reHex","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgrey","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","fromRgb","fromSource","fromRgba","fromHsl","fromHsla","fromHex","isShortNotation","isRGBa","oColor","getColorStop","multiplier","colorAlpha","keyValuePairs","__convertPercentUnitsToValues","instance","svgOptions","gradientUnits","propValue","finalValue","offsetX","offsetY","gradientTransform","addColorStop","toObject","propertiesToInclude","markup","commonAttributes","needsSwap","withViewport","additionalTransform","sort","pathOffset","reverse","minRadius","percentageShift","colorStop","toLive","stops","createLinearGradient","createRadialGradient","colorStopEls","getLinearCoords","getRadialCoords","forObject","repeat","patternTransform","setOptions","patternSource","patternWidth","patternHeight","patternOffsetX","patternOffsetY","patternImgSrc","naturalWidth","naturalHeight","createPattern","Shadow","affectStroke","includeDefaultValues","nonScaling","_parseShadow","shadow","shadowStr","offsetsAndBlur","reOffsetsAndBlur","fBoxX","fBoxY","CANVAS_INIT_ERROR","renderAndResetBound","renderAndReset","requestRenderAllBound","_initStatic","backgroundColor","backgroundImage","overlayColor","overlayImage","stateful","controlsAboveOverlay","allowTouchScrolling","imageSmoothingEnabled","viewportTransform","backgroundVpt","overlayVpt","onBeforeScaleRotate","vptCoords","skipOffscreen","cb","_createLowerCanvas","_initOptions","_setImageSmoothing","interactive","_initRetinaScaling","setOverlayImage","setBackgroundImage","setBackgroundColor","setOverlayColor","calcOffset","_isRetinaScaling","getRetinaScaling","__initRetinaScaling","lowerCanvasEl","contextContainer","upperCanvasEl","contextTop","_offset","__setBgOverlayImage","__setBgOverlayColor","webkitImageSmoothingEnabled","mozImageSmoothingEnabled","msImageSmoothingEnabled","oImageSmoothingEnabled","_createCanvasElement","_applyCanvasStyle","setWidth","setHeight","dimensions","cssValue","cssOnly","_setBackstoreDimension","hasLostContext","backstoreOnly","_setCssDimension","_isCurrentlyDrawing","freeDrawingBrush","_setBrushStyles","cacheCanvasEl","wrapperEl","getZoom","setViewportTransform","vpt","activeObject","_activeObject","group","setCoords","calcViewportBoundaries","zoomToPoint","before","absolutePan","relativePan","getElement","setupState","clearContext","clearRect","_hasITextHandlers","_mouseUpITextHandler","_iTextInstances","canvasToDrawOn","renderCanvas","isRendering","iVpt","tl","br","tr","bl","cancelRequestedRender","_renderBackground","_renderObjects","drawControls","shouldCache","_transformDone","renderCache","forClipping","drawClipPathOnCanvas","_renderOverlay","globalCompositeOperation","zoomX","zoomY","_cacheCanvas","cacheTranslationX","cacheTranslationY","render","_renderBackgroundOrOverlay","needsVpt","lineTo","closePath","fillStyle","getCenter","centerObjectH","_centerObject","getCenterPoint","centerObjectV","centerObject","center","viewportCenterObject","vpCenter","getVpCenter","viewportCenterObjectH","viewportCenterObjectV","toDatalessJSON","toDatalessObject","_toObjectMethod","_toObjects","_toObject","__serializeBgOverlay","excludeFromExport","originalValue","bgImage","overlay","background","svgViewportTransformation","_setSVGPreamble","_setSVGHeader","clipPathId","_setSVGBgOverlayColor","_setSVGBgOverlayImage","_setSVGObjects","suppressPreamble","viewBox","createSVGFontFacesMarkup","createSVGRefElementsMarkup","createSVGClipPathMarkup","toClipPathSVG","shouldTransform","row","rowIndex","charIndex","fontList","_setSVGObject","finalWidth","finalHeight","sendToBack","objs","activeSelection","unshift","bringToFront","sendBackwards","intersecting","newIdx","objsMoved","_findNewLowerIndex","intersectsWithObject","isContainedWithinObject","bringForward","_findNewUpperIndex","dispose","DataURLExporter","EMPTY_JSON","supports","setLineDash","createPNGStream","createJPEGStream","BaseBrush","strokeLineCap","strokeLineJoin","strokeMiterLimit","setShadow","strokeStyle","lineWidth","lineCap","miterLimit","lineJoin","_saveAndTransform","_setShadow","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY","needsFullRender","_resetShadow","PencilBrush","decimate","_points","_drawSegment","p1","p2","midPoint","quadraticCurveTo","onMouseDown","pointer","_isMainEvent","_prepareForDrawing","_captureDrawingPath","_render","onMouseMove","oldEnd","onMouseUp","_finalizeAndAddPath","_reset","_addPoint","pointerPoint","convertPointsToSVGPath","multSignX","multSignY","manyPoints","createPath","pathData","Path","decimatePoints","distance","adjustedDistance","lastPoint","newPoints","CircleBrush","drawDot","addPoint","dot","arc","radius","originalRenderOnAddRemove","circles","circle","Circle","circleRadius","circleColor","SprayBrush","density","dotWidth","dotWidthVariance","randomOpacity","optimizeOverlapping","sprayChunks","addSprayChunk","sprayChunkPoints","rects","ilen","sprayChunk","rect","_getOptimizedRects","uniqueRects","uniqueRectsArray","globalAlpha","fillRect","PatternBrush","getPatternSrc","patternCanvas","patternCtx","getPatternSrcFunction","getPattern","topLeft","_getLeftTopCoords","supportLineDash","STROKE_OFFSET","_initInteractive","_createCacheCanvas","uniScaleTransform","uniScaleKey","centeredScaling","centeredRotation","centeredKey","altActionKey","selection","selectionKey","altSelectionKey","selectionColor","selectionDashArray","selectionBorderColor","selectionLineWidth","selectionFullyContained","hoverCursor","moveCursor","defaultCursor","freeDrawingCursor","rotationCursor","notAllowedCursor","perPixelTargetFind","targetFindTolerance","skipTargetFind","isDrawingMode","preserveObjectStacking","snapAngle","snapThreshold","stopContextMenu","fireRightClick","fireMiddleClick","targets","_hoveredTarget","_hoveredTargets","_currentTransform","_groupSelector","_initWrapperElement","_createUpperCanvas","_initEventListeners","_chooseObjectsToRender","objsToRender","activeGroupObjects","activeObjects","getActiveObjects","contextTopDirty","renderTopLayer","_drawSelection","renderTop","_resetCurrentTransform","original","_shouldCenterTransform","mouseXSign","mouseYSign","containsPoint","xy","_normalizePointer","_findTargetCorner","invertedM","vptPointer","restorePointerVpt","isTargetTransparent","normalizedPointer","targetRelativeX","targetRelativeY","_cacheContext","contextCache","originalColor","selectionBackgroundColor","_renderControls","hasBorders","transparentCorners","_isSelectionKeyPressed","_shouldClearSelection","evented","centerTransform","altKey","_getOriginFromCorner","corner","_getActionFromCorner","alreadySelected","_setupCurrentTransform","ex","ey","lastX","lastY","shiftKey","_beforeTransform","_translateObject","newLeft","newTop","moveX","moveY","_changeSkewTransformOrigin","mouseMove","by","origins","0","skew","originA","originB","flipSign","skewSign","_skewObject","skewed","lockSkewingX","lockSkewingY","actualMouseByOrigin","constraintPosition","actualMouseByCenter","toLocalPoint","lastMouseByCenter","dim","_getTransformedDimensions","translateToOriginPoint","_setObjectSkew","localMouse","_dim","newDim","dimNoSkew","otherBy","_otherBy","_by","newDimMouse","atan","_scaleObject","lockScalingX","lockScalingY","lockScalingFlip","scaled","_setLocalMouse","_setObjectScale","forbidScalingX","forbidScalingY","changeX","changeY","newScaleX","newScaleY","w","getMinWidth","_scaleObjectEqually","_flipObject","dist","lastDist","signX","signY","padding","_rotateObject","lockRotation","lastAngle","curAngle","hasRotated","rightAngleLocked","leftAngleLocked","setCursor","cursor","groupSelector","aleft","atop","_setLineDash","strokeRect","findTarget","skipGroup","activeTarget","activeTargetSubs","aObjects","_searchPossibleTargets","_checkTarget","globalPointer","isEditing","subTarget","objToCheck","pointerToUse","subTargetCheck","ignoreZoom","_absolutePointer","_pointer","cssScale","boundsWidth","boundsHeight","retinaScaling","lowerCanvasClass","_copyCanvasStyle","fromEl","toEl","getSelectionContext","getSelectionElement","getActiveObject","_discardActiveObject","_fireSelectionEvents","oldObjects","somethingChanged","removed","opt","oldObject","deselected","updated","setActiveObject","currentActives","_setActiveObject","onSelect","onDeselect","discardActiveObject","removeListeners","originalProperties","_realizeGroupTransformOnObject","_unwindGroupTransformOnObject","originalValues","realizeTransform","clearContextTop","cursorOffset","mr","mb","ml","addEventOptions","passive","checkClick","cursorMap","mainTouchId","_bindEvents","addOrRemove","_getEventPrefix","enablePointerEvents","functor","eventjsFunctor","canvasElement","eventTypePrefix","_onResize","_onMouseDown","_onMouseMove","_onMouseOut","_onMouseEnter","_onMouseWheel","_onContextMenu","_onDoubleClick","_onDragOver","_onDragEnter","_onDragLeave","_onDrop","_onTouchStart","eventjs","_onGesture","_onDrag","_onOrientationChange","_onShake","_onLongPress","_onMouseUp","_onTouchEnd","eventsBound","_simpleEventHandler","self","__onTransformGesture","__onDrag","__onMouseWheel","_target","hiddenTextarea","currentTransform","__onOrientationChange","__onShake","__onLongPress","_fireEnterLeaveEvents","_cacheTransformEventData","_handleEvent","_resetTransformEventData","getPointerId","identifier","pointerId","isPrimary","touches","__onMouseDown","__onMouseUp","_willAddMouseDown","__onMouseMove","_shouldRender","shouldRender","isClick","_onMouseUpInDrawingMode","_finalizeCurrentTransform","actionPerformed","_maybeGroupObjects","isMoving","_setCursorFromEvent","__corner","eventType","subTargets","absolutePointer","_scaling","hasStateChanged","_addEventOptions","_fire","_onMouseDownInDrawingMode","_onMouseMoveInDrawingMode","_previousPointer","shouldGroup","_shouldGroup","_handleGrouping","saveState","_transformObject","_fireOverOutEvents","fireSyntheticInOutEvents","oldTarget","evtOut","canvasEvtOut","evtIn","canvasEvtIn","_draggedoverTarget","config","inOpt","outOpt","inFires","targetChanged","previousTarget","nextTarget","reset","_beforeScaleTransform","_performTransformAction","_onScale","_isUniscalePossible","currentAction","getCornerCursor","actionIsDisabled","_getRotatedCornerCursor","_updateActiveSelection","_createActiveSelection","currentActiveObjects","removeWithUpdate","addWithUpdate","_createGroup","groupObjects","exitEditing","ActiveSelection","_groupSelectedObjects","aGroup","_collectObjects","currentObject","selectionX1Y1","selectionX2Y2","allowIntersect","intersectsWithRect","isContainedWithinRect","toCanvasElement","cropping","scaledWidth","scaledHeight","originalWidth","originalHeight","newZoom","vp","originalInteractive","newVp","originalRetina","originalContextTop","loadFromDatalessJSON","loadFromJSON","serialized","_enlivenObjects","_setBgOverlay","enlivenedCanvasClip","__setupCanvas","loaded","cbIfLoaded","__setBgOverlay","enlivedObject","_toDataURL","_toDataURLWithMultiplier","toDataURLWithMultiplier","cloneWithoutData","backgroundImageOpacity","backgroundImageStretch","supportsLineDash","objectCaching","cornerSize","borderColor","borderDashArray","cornerColor","cornerStrokeColor","cornerStyle","cornerDashArray","strokeDashOffset","borderOpacityWhenMoving","borderScaleFactor","minScaleLimit","hasControls","rotatingPointOffset","lockMovementX","lockMovementY","lockUniScaling","statefullCache","noScaleCache","strokeUniform","dirty","paintFirst","stateProperties","cacheProperties","inverted","absolutePositioned","_cacheProperties","_updateCacheCanvas","_limitCacheSize","dims","limitedDims","capped","_getCacheCanvasDimensions","objectScale","getTotalObjectScaling","neededX","neededY","drawingWidth","drawingHeight","minCacheSize","dimensionsChanged","cacheWidth","cacheHeight","zoomChanged","shouldRedraw","additionalWidth","additionalHeight","shouldResizeCanvas","canvasWidth","canvasHeight","sizeGrowing","setTransform","calcOwnMatrix","_removeDefaultValues","getObjectScaling","retina","getObjectOpacity","shouldConstrainValue","isChanged","groupNeedsUpdate","_constrainScale","isOnACache","setOnGroup","getViewportTransform","isNotVisible","isOnScreen","_setupCompositeOperation","drawSelectionBackground","_setOpacity","drawCacheOnCanvas","_removeCacheCanvas","drawObject","propertySet","isCacheDirty","hasStroke","hasFill","needsItsOwnCache","ownCaching","willDrawShadow","drawClipPathOnCache","originalFill","originalStroke","_setClippingProperties","_setStrokeStyles","_setFillStyles","_drawClipPath","skipCanvas","_getNonTransformedDimensions","_removeShadow","decl","lineDashOffset","dashArray","alternative","styleOverride","drawBorders","forActiveSelection","drawBordersInGroup","scaling","multX","multY","_applyPatternGradientTransform","_renderPaintInOrder","_renderStroke","_renderFill","_renderDashedStroke","_applyPatternForTransformedGradient","pCtx","pCanvas","_findCenterFromElement","_assignTransformMatrixProps","preserveAspectRatioOptions","cropX","cropY","objectForm","_fromObject","cloneAsImage","utils","origParams","originalGroup","originalShadow","withoutTransform","withoutShadow","boundingRect","getBoundingRect","shadowOffset","originalCanvas","isType","setGradient","setPatternFill","setColor","shouldCenterOrigin","_setOriginToCenter","_resetOrigin","centerH","viewportCenterH","centerV","viewportCenterV","viewportCenter","getLocalPointer","pClicked","objectLeftTop","createAccessors","extraParam","enlivedProps","translateToGivenOrigin","fromOriginX","fromOriginY","toOriginX","toOriginY","translateToCenterPoint","leftTop","getPointByOrigin","adjustPosition","offsetFrom","offsetTo","hypotFull","getScaledWidth","xFull","yFull","_originalOriginX","_originalOriginY","originPoint","multiplyMatrices","oCoords","aCoords","ownMatrixCache","matrixCache","getCoords","absolute","calculate","calcCoords","pointTL","pointBR","other","lines","_getImageLines","_findCrossPoints","_containsCenterOfCanvas","isPartiallyOnScreen","topline","rightline","bottomline","leftline","xi","iLine","xcount","lineKey","getScaledHeight","boundingRectFactor","scaleToHeight","_calcRotateMatrix","_calcTranslateMatrix","startMatrix","finalMatrix","cosP","sinP","cosPSinP","cosPMinusSinP","mtr","skipAbsolute","_setCornerCoords","transformMatrixKey","sep","prefix","cache","tMatrix","_calcDimensionsTransformMatrix","flipping","dimX","dimY","noSkew","_finalizeDimensions","bbox","_calculateCurrentDimensions","getSvgColorString","getSvgStyles","skipShadow","getSvgFilter","getSvgSpanStyles","useWhiteSpace","term","textDecoration","getSvgTextDecoration","deltaY","decoration","getSvgCommons","getSvgTransform","full","getSvgTransformMatrix","_setSVGBg","textBgRects","_getFillAttributes","_createBaseSVGMarkup","_toSVG","_createBaseClipPathSVGMarkup","objectMarkup","commonPieces","clipPathMarkup","noStyle","styleInfo","shadowInfo","withShadow","vectorEffect","absoluteClipPath","addPaintOrder","originalSet","saveProps","props","tmpObj","_isEqual","origValue","currentValue","firstPass","dashedPropertySet","_controlsVisibility","isControlVisible","newTheta","cornerHypotenuse","cosHalfOffset","sinHalfOffset","wh","drawRotatingPoint","rotateHeight","scaleOffset","_drawControl","control","controlName","_getControlsVisibility","setControlVisible","setControlsVisibility","FX_DURATION","fxCenterObjectH","callbacks","fxCenterObjectV","fxRemove","skipCallbacks","propsToAnimate","_animate","propPair","valueProgress","timeProgress","coordProps","makeEdgeToOriginGetter","propertyNames","originValues","axis1","axis2","dimension","nearest","farthest","Line","_setWidthHeight","_getLeftToOriginX","_getTopToOriginY","calcLinePoints","origStrokeStyle","xMult","yMult","ATTRIBUTE_NAMES","parsedAttributes","pi","startAngle","endAngle","setRadius","svgString","startX","startY","endX","endY","largeFlag","getRadiusX","getRadiusY","Triangle","widthBy2","heightBy2","piBy2","Ellipse","getRx","getRy","_initRxRy","isRounded","Polyline","_setPositionDimensions","correctLeftTop","calcDim","_calcDimensions","fromSVG","diffX","diffY","commonRender","fromElementGenerator","_class","Polygon","_toString","commandLengths","repeatedCommands","M","fromArray","_parsePath","_renderPathCommands","tempX","tempY","previous","subpathStartX","subpathStartY","controlX","controlY","_getOffsetTransform","digits","currentPath","coordsStr","coordsParsed","re","command","commandLength","repeatedCommand","klen","aX","aY","pathUrl","useSetOnGroup","isAlreadyGrouped","_updateObjectsACoords","_calcBounds","_updateObjectsCoords","_updateObjectCoords","objectLeft","objectTop","_restoreObjectsState","_includeDefaultValues","objsToObject","originalDefaults","_obj","ownCache","_restoreObjectState","toActiveSelection","ungroupOnCanvas","setObjectsCoords","onlyWidthHeight","iLen","jLen","_getBounds","minXY","maxXY","enlivedClipPath","toGroup","newGroup","childrenOverride","srcFromAttribute","_lastScaleX","_lastScaleY","_filterScalingX","_filterScalingY","minimumScaleTrigger","cacheKey","filters","_initElement","_element","setElement","removeTexture","_initConfig","applyFilters","resizeFilter","applyResizeFilters","backend","filterBackend","evictCachesForKey","setCrossOrigin","getOriginalSize","_stroke","filterObj","getSrc","hasCrop","strokeSvg","imageMarkup","getSvgSrc","origFill","filtered","setSrc","minimumScale","elementToFilter","_filteredEl","sourceWidth","sourceHeight","isNeutralState","imgElement","_needsResize","elementToDraw","elWidth","elHeight","sX","sY","sW","sH","maxDestW","maxDestH","_resetWidthHeight","CSS_CANVAS","_initFilters","pAR","rWidth","rHeight","pWidth","pHeight","_object","resizeFilters","imgOptions","_getAngleValueForStraighten","straighten","fxStraighten","straightenObject","fxStraightenObject","testPrecision","precision","fragmentSource","fragmentShader","createShader","FRAGMENT_SHADER","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","setupGLContext","captureGPUInfo","isSupported","getParameter","MAX_TEXTURE_SIZE","precisions","webGlPrecision","createWebGLCanvas","aPosition","Float32Array","chooseFastestCopyGLTo2DMethod","canUseImageData","canMeasurePerf","performance","canUseArrayBuffer","canUseUint8Clamped","copyGLTo2D","startTime","drawImageTime","testContext","now","glOptions","premultipliedAlpha","depth","stencil","antialias","clearColor","cachedTexture","getCachedTexture","sourceTexture","createTexture","targetTexture","originalTexture","passes","webgl","programCache","pass","tempFbo","createFramebuffer","bindFramebuffer","FRAMEBUFFER","applyTo","resizeCanvasIfNeeded","bindTexture","TEXTURE_2D","deleteTexture","deleteFramebuffer","clearWebGLCaches","textureCache","textureImageSource","texture","texParameteri","TEXTURE_MAG_FILTER","NEAREST","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","texImage2D","uniqueId","gpuInfo","renderer","vendor","getExtension","UNMASKED_RENDERER_WEBGL","UNMASKED_VENDOR_WEBGL","sourceElement","originalEl","originalImageData","BaseFilter","vertexSource","createProgram","vertexShader","VERTEX_SHADER","getShaderInfoLog","program","attachShader","linkProgram","getProgramParameter","LINK_STATUS","getProgramInfoLog","attributeLocations","getAttributeLocations","uniformLocations","getUniformLocations","uStepW","getUniformLocation","uStepH","getAttribLocation","sendAttributeData","aPositionData","attributeLocation","bindBuffer","ARRAY_BUFFER","enableVertexAttribArray","vertexAttribPointer","FLOAT","bufferData","STATIC_DRAW","_setupFrameBuffer","framebufferTexture2D","COLOR_ATTACHMENT0","_swapTextures","temp","main","mainParameter","applyToWebGL","applyTo2d","retrieveShader","shader","useProgram","uniform1f","sendUniformData","viewport","drawArrays","TRIANGLE_STRIP","bindAdditionalTexture","textureUnit","activeTexture","TEXTURE0","unbindAdditionalTexture","getMainParameter","setMainParameter","createHelpLayer","helpLayer","mainP","ColorMatrix","colorsOnly","uColorMatrix","uConstants","constants","uniformMatrix4fv","uniform4fv","Brightness","brightness","uBrightness","Convolute","opaque","Convolute_3_1","Convolute_3_0","Convolute_5_1","Convolute_5_0","Convolute_7_1","Convolute_7_0","Convolute_9_1","Convolute_9_0","dstOff","scx","scy","srcOff","wt","weights","side","halfSide","sw","sh","createImageData","alphaFac","uMatrix","uOpaque","uHalfSize","uSize","uniform1fv","Grayscale","lightness","luminosity","uMode","uniform1i","Invert","invert","uInvert","Noise","noise","rand","uNoise","uSeed","Pixelate","blocksize","_i","_j","_iLen","_jLen","uBlocksize","RemoveColor","useAlpha","lowC","highC","uLow","uHigh","Brownie","Vintage","Kodachrome","Technicolor","Polaroid","Sepia","BlackWhite","BlendColor","screen","diff","lighten","darken","exclusion","tint","buildSource","tg","alpha1","uColor","BlendImage","mask","TEXTURE1","calculateMatrix","canvas1","blendData","blendImage","uTransformMatrix","uImage","uniformMatrix3fv","Resize","resizeType","lanczosLobes","uDelta","uTaps","uniform2fv","horizontal","taps","filterWindow","getFilterWindow","generateShader","tempScale","getTaps","lobeFunction","lanczosCreate","offsets","fragmentSourceTOP","dW","dH","lobes","xx","rcpScaleX","rcpScaleY","newData","oW","oH","sliceByTwo","hermiteFastResize","bilinearFiltering","lanczosResize","tmpCanvas","mult","doneW","doneH","stepW","stepH","dX","dY","srcData","destImg","destData","lanczos","ratioX","ratioY","rcpRatioX","rcpRatioY","range2X","range2Y","cacheLanc","icenter","process","u","weight","fX","fY","xDiff","yDiff","chnl","origPix","w4","pixels","destImage","destPixels","ratioW","ratioH","ratioWHalf","ratioHHalf","img2","data2","weightsAlpha","gxR","gxG","gxB","gxA","centerY","yy","centerX","w0","Contrast","contrast","contrastF","uContrast","Saturation","saturation","adjust","uSaturation","Blur","aspectRatio","simpleBlur","canvas2","blurLayer1","blurLayer2","percent","ctx1","ctx2","nSamples","newImageData","delta","chooseRightDelta","blurScale","Gamma","gamma","rInv","gInv","bInv","rVals","gVals","bVals","uGamma","uniform3fv","Composed","subFilters","some","HueRotation","rotation","rad","aThird","aThirdSqtSin","OneMinusCos","_dimensionAffectingProps","_reNewline","_reSpacesAndTabs","_reSpaceAndTab","_reWords","underline","overline","linethrough","superscript","baseline","subscript","textBackgroundColor","_fontSizeFraction","_fontSizeMult","charSpacing","_measuringContext","_styleProperties","__charBounds","CACHE_FONT_SIZE","MIN_TEXT_WIDTH","__skipDimension","initDimensions","getMeasuringContext","_splitText","newLines","_splitTextIntoLines","textLines","_textLines","graphemeLines","_unwrappedTextLines","_unwrappedLines","_text","graphemeText","_clearCache","calcTextWidth","cursorWidth","enlargeSpaces","calcTextHeight","diffSpace","currentLineWidth","numberOfSpaces","accumulatedSpace","line","charBound","spaces","isEndOfWrapping","getLineWidth","kernedWidth","lineIndex","missingNewlineOffset","_setTextStyles","_renderTextLinesBackground","_renderTextDecoration","_renderText","_renderTextStroke","_renderTextFill","charStyle","forMeasuring","textBaseline","_getFontDeclaration","maxWidth","_renderTextLine","_renderChars","styleHas","heightOfLine","lineLeftOffset","lastColor","charBox","currentColor","lineTopOffset","leftOffset","_getLeftOffset","topOffset","_getTopOffset","boxStart","boxWidth","getHeightOfLine","_getLineLeftOffset","getValueOfPropertyAt","getFontCache","cacheProp","_applyCharStyles","styleDeclaration","_measureChar","_char","previousChar","prevCharStyle","coupleWidth","previousWidth","fontCache","couple","stylesAreEqual","fontMultiplier","measureText","getHeightOfChar","measureLine","lineInfo","_measureLine","_getWidthOfCharSpacing","grapheme","prevGrapheme","graphemeInfo","lineBounds","_getGraphemeBox","numOfSpaces","skipLeft","getCompleteStyleDeclaration","prevStyle","info","previousBox","__lineHeights","_renderTextCommon","lineHeights","isEmptyStyles","actualStyle","nextStyle","timeToRender","isJustify","charsToRender","shortCut","_renderChar","_hasStyleChanged","_getStyleDeclaration","fullDecl","shouldFill","shouldStroke","fillText","strokeText","setSuperscript","_setScript","setSubscript","schema","loc","get2DCursorLocation","setSelectionStyles","thisStyle","_hasStyleChangedForSvg","__lineWidths","_shouldClearDimensionCache","shouldClear","_forceClearCache","_size","_dy","lastDecoration","currentDecoration","currentFill","lastFill","styleObject","family","fontIsGeneric","genericFonts","newLine","newText","additionalProperties","needsDims","_key","parsedAnchor","textAnchor","originalStrokeWidth","textHeightScaleFactor","scaledDiff","textHeight","offX","p3","cleanStyle","letterCount","stylePropertyValue","stylesCount","allStyleObjectPropertiesMatch","graphemeCount","removeStyle","lineNum","charNum","_extendStyles","_getLineStyle","_setLineStyle","_setStyleDeclaration","selectionStart","skipWrapping","getSelectionStyles","startIndex","endIndex","selectionEnd","getStyleAtPosition","lineStyle","_deleteStyleDeclaration","_deleteLineStyle","parseDecoration","IText","editable","editingBorderColor","cursorColor","cursorDelay","cursorDuration","caching","_reSpace","_currentCursorOpacity","_selectionDirection","_abortCursorAnimation","__widthOfSpace","inCompositionMode","initBehavior","setSelectionStart","_updateAndFire","setSelectionEnd","_fireSelectionChanged","_updateTextarea","initDelayedCursor","cursorOffsetCache","renderCursorOrSelection","skipRestore","_clearTextArea","boundaries","_getCursorBoundaries","renderCursor","renderSelection","_getCursorBoundariesOffsets","cursorPosition","cursorLocation","charHeight","__isMousedown","startLine","endLine","startChar","endChar","realLineHeight","lineOffset","boxEnd","compositionColor","getCurrentCharFontSize","cp","_getCurrentCharIndex","getCurrentCharColor","initAddedHandler","initRemovedHandler","initCursorSelectionHandlers","initDoubleClickSimulation","mouseMoveHandler","_initCanvasHandlers","_removeCanvasHandlers","_tick","_currentTickState","_animateCursor","targetOpacity","completeMethod","tickState","isAborted","_onTickComplete","_cursorTimeout1","_currentTickCompleteState","restart","delay","abortCursorAnimation","_cursorTimeout2","selectAll","getSelectedText","findWordBoundaryLeft","startFrom","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","direction","selectWord","newSelectionStart","newSelectionEnd","selectLine","enterEditing","exitEditingOnOthers","initHiddenTextarea","_saveEditingProps","_setEditingProps","_textBeforeEdit","initMouseMoveHandler","getSelectionStartFromPointer","currentStart","currentEnd","__selectionStartOnMouseDown","restartCursorIfNeeded","fromStringToGraphemeSelection","smallerTextStart","graphemeStart","smallerTextEnd","fromGraphemeToStringSelection","newSelection","updateTextareaPosition","updateFromTextArea","_calcTextareaPosition","desiredPosition","compositionStart","upperCanvas","upperCanvasWidth","upperCanvasHeight","_savedProps","_restoreEditingProps","isTextChanged","_removeExtraneousStyles","removeStyleFromTo","styleObj","cursorStart","cursorEnd","lineStart","charStart","lineEnd","charEnd","shiftLineStyles","numericChar","clonedStyles","numericLine","insertNewlineStyleObject","copiedStyle","currentCharStyle","newLineStyles","somethingAdded","isEndOfLine","numIndex","styleCarriedOver","insertCharStyleObject","currentLineStyles","currentLineStylesCloned","numericIndex","newStyle","insertNewStyleBlock","insertedText","cursorLoc","addedLines","linesLength","setSelectionStartEndWithShift","setSelectionInBoundaries","__lastClickTime","__lastLastClickTime","__lastPointer","__newClickTime","newPointer","isTripleClick","_stopEvent","__lastIsEditing","__lastSelected","initMousedownHandler","initMouseupHandler","initClicks","doubleClickHandler","tripleClickHandler","_mouseDownHandler","setCursorByClick","_mouseDownHandlerBefore","mouseUpHandler","currentActive","mouseOffset","prevWidth","_getNewSelectionStartFromOffset","distanceBtwLastCharAndCursor","distanceBtwNextCharAndCursor","onKeyDown","onKeyUp","onInput","paste","onCompositionStart","onCompositionUpdate","onCompositionEnd","_clickHandlerInitialized","onClick","keysMap","9","27","33","35","36","37","38","39","40","ctrlKeysMapUp","67","88","ctrlKeysMapDown","65","keyCode","ctrlKey","metaKey","_copyDone","fromPaste","removedText","removeFrom","removeTo","nextText","charCount","nextCharCount","charDiff","textareaSelection","backDelete","copiedText","copiedTextStyle","compositionEnd","_getClipboardData","clipboardData","_getWidthBeforeCursor","widthBeforeCursor","getDownCursorOffset","isRight","selectionProp","_getSelectionForOffset","indexOnOtherLine","_getIndexOnLine","getUpCursorOffset","textBeforeCursor","charWidth","foundMatch","widthOfCharsOnLine","indexOnLine","leftEdge","rightEdge","offsetFromLeftEdge","moveCursorDown","_moveCursorUpOrDown","moveCursorUp","moveCursorWithShift","moveCursorWithoutShift","moveCursorLeft","_moveCursorLeftOrRight","_move","_moveLeft","_moveRight","moveCursorLeftWithoutShift","change","moveCursorLeftWithShift","moveCursorRight","actionName","moveCursorRightWithShift","moveCursorRightWithoutShift","changed","removeChars","insertChars","multipleSpacesRegex","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","lineTop","textSpans","textTopOffset","textLeftOffset","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","styleDecl","shouldUseWhitespace","styleProps","fillStyles","dySpan","_pushTextBgRect","fillColor","_getSVGLineTopOffset","lastHeight","minWidth","dynamicMinWidth","__cachedLines","_wordJoiners","splitByGrapheme","_styleMap","_generateStyleMap","textInfo","realLineCount","realLineCharCount","isWrapping","nextOffset","shouldLimit","mapNextLine","_wrapText","desiredWidth","wrapped","_wrapLine","_measureWord","word","charOffset","_line","reservedSpace","words","infix","wordWidth","infixWidth","largestWordWidth","lineJustStarted","additionalSpace","linesToKeep"],"mappings":"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","file":"productDetail.min.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t};\n\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t34: 0,\n \t\t7: 0,\n \t\t10: 0\n \t};\n\n\n\n \t// script path function\n \tfunction jsonpScriptSrc(chunkId) {\n \t\treturn __webpack_require__.p + \"chunk-\" + ({\"14\":\"findinstore\"}[chunkId]||chunkId) + \".min.js\"\n \t}\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tvar promises = [];\n\n\n \t\t// JSONP chunk loading for javascript\n\n \t\tvar installedChunkData = installedChunks[chunkId];\n \t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n \t\t\t// a Promise means \"currently loading\".\n \t\t\tif(installedChunkData) {\n \t\t\t\tpromises.push(installedChunkData[2]);\n \t\t\t} else {\n \t\t\t\t// setup Promise in chunk cache\n \t\t\t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n \t\t\t\t});\n \t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n \t\t\t\t// start chunk loading\n \t\t\t\tvar script = document.createElement('script');\n \t\t\t\tvar onScriptComplete;\n\n \t\t\t\tscript.charset = 'utf-8';\n \t\t\t\tscript.timeout = 120;\n \t\t\t\tif (__webpack_require__.nc) {\n \t\t\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t\t\t}\n \t\t\t\tscript.src = jsonpScriptSrc(chunkId);\n\n \t\t\t\t// create error before stack unwound to get useful stacktrace later\n \t\t\t\tvar error = new Error();\n \t\t\t\tonScriptComplete = function (event) {\n \t\t\t\t\t// avoid mem leaks in IE.\n \t\t\t\t\tscript.onerror = script.onload = null;\n \t\t\t\t\tclearTimeout(timeout);\n \t\t\t\t\tvar chunk = installedChunks[chunkId];\n \t\t\t\t\tif(chunk !== 0) {\n \t\t\t\t\t\tif(chunk) {\n \t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n \t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n \t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n \t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n \t\t\t\t\t\t\terror.type = errorType;\n \t\t\t\t\t\t\terror.request = realSrc;\n \t\t\t\t\t\t\tchunk[1](error);\n \t\t\t\t\t\t}\n \t\t\t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t\t\t}\n \t\t\t\t};\n \t\t\t\tvar timeout = setTimeout(function(){\n \t\t\t\t\tonScriptComplete({ type: 'timeout', target: script });\n \t\t\t\t}, 120000);\n \t\t\t\tscript.onerror = script.onload = onScriptComplete;\n \t\t\t\tdocument.head.appendChild(script);\n \t\t\t}\n \t\t}\n \t\treturn Promise.all(promises);\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n \tvar jsonpArray = window[\"tezConfigLoading\"] = window[\"tezConfigLoading\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 175);\n","import tingle from 'tingle.js';\n\n/* eslint-disable new-cap */\n\n/**\n * This function retrieves another page of content to display in the content search grid\n * @param {Boolean} footer - HTML string\n * @return {Tingle} - https://robinparisi.github.io/tingle/\n */\nconst newModal = (footer, cssClass = []) => {\n // set optionts\n const modalOptions = {\n closeMethods: ['overlay', 'button', 'escape'],\n cssClass,\n onClose: () => {\n modal.destroy();\n },\n onOpen: () => { $('html').addClass('html-tingle-enabled'); },\n beforeClose: () => {\n if (($('.jsPersonalizationToolModal.tingle-modal--visible').length <= 0) || ($('.tingle-modal.tingle-modal--visible').length < 2)) {\n $('html').removeClass('html-tingle-enabled');\n }\n return true;\n }\n };\n if (footer) { modalOptions.footer = true; };\n\n // create modal\n const modal = new tingle.modal(modalOptions);\n\n return modal;\n};\n\n/**\n * This function retrieves another page of content to display in the content search grid\n * @param {String} selectorID - ID of the modal DOM element to clone\n * @return {Tingle} - https://robinparisi.github.io/tingle/\n */\nconst newModalFromSelector = (selectorID, footer, cssClass = [], onClose = null) => {\n // set optionts\n const modalOptions = {\n closeMethods: ['overlay', 'escape'],\n cssClass,\n onClose: () => {\n modal.destroy();\n if (typeof onClose === 'function') {\n onClose();\n }\n },\n onOpen: () => { $('html').addClass('html-tingle-enabled'); },\n beforeClose: () => {\n if (($('.jsPersonalizationToolModal.tingle-modal--visible').length <= 0) || ($('.tingle-modal.tingle-modal--visible').length < 2)) {\n $('html').removeClass('html-tingle-enabled');\n }\n return true;\n }\n };\n if (footer) { modalOptions.footer = true; };\n\n // create modal\n const modal = new tingle.modal(modalOptions);\n\n // clone content\n if (selectorID) {\n const contentModal = document.getElementById(selectorID);\n if (contentModal) {\n modal.setContent(contentModal.innerHTML);\n }\n }\n\n return modal;\n};\n\n/**\n * This function retrieves another page of content to display in the content search grid\n * @param {String} html - HTML string\n * @return {Tingle} - https://robinparisi.github.io/tingle/\n */\nconst newModalFromString = (html, footer, cssClass = [], onOpen, onClose) => {\n // set optionts\n const modalOptions = {\n closeMethods: ['overlay', 'button', 'escape'],\n cssClass,\n onClose: () => {\n modal.destroy();\n if (typeof onClose === 'function') {\n onClose();\n }\n },\n onOpen: () => {\n $('html').addClass('html-tingle-enabled');\n if (typeof onOpen === 'function') {\n onOpen();\n }\n },\n beforeClose: () => {\n if (($('.jsPersonalizationToolModal.tingle-modal--visible').length <= 0) || ($('.tingle-modal.tingle-modal--visible').length < 2)) {\n $('html').removeClass('html-tingle-enabled');\n }\n return true;\n }\n };\n if (footer) { modalOptions.footer = true; };\n\n // create modal\n const modal = new tingle.modal(modalOptions);\n\n // add content\n if (html) {\n modal.setContent(html);\n }\n\n return modal;\n};\n\n/**\n * This function creates a modal starting from supplied options\n * @return {Tingle} - https://robinparisi.github.io/tingle/\n */\nconst newModalWithOptions = (modalOptions) => {\n // create modal\n const modal = new tingle.modal(modalOptions);\n\n return modal;\n};\n\n// modal with forced choice\nconst newModalWithSelector = (html, footer, cssClass = [], onOpen, onClose) => {\n // set optionts\n const modalOptions = {\n closeMethods: [],\n cssClass,\n onClose: () => {\n modal.destroy();\n if (typeof onClose === 'function') {\n onClose();\n }\n },\n onOpen: () => {\n $('html').addClass('html-tingle-enabled');\n if (typeof onOpen === 'function') {\n onOpen();\n }\n },\n beforeClose: () => {\n if (($('.jsPersonalizationToolModal.tingle-modal--visible').length <= 0) || ($('.tingle-modal.tingle-modal--visible').length < 2)) {\n $('html').removeClass('html-tingle-enabled');\n }\n return true;\n }\n };\n if (footer) { modalOptions.footer = true; };\n\n // create modal\n const modal = new tingle.modal(modalOptions);\n\n // add content\n if (html) {\n modal.setContent(html);\n }\n\n return modal;\n};\n\n/**\n * This class creates a modal without copying or moving any HTML,\n * but simply showing and hiding an existing Node.\n * This is to avoid problems with manipulated elements such as Google Maps\n */\nclass ModalShowHide {\n constructor (selector = '', newModalType, toPropagateClick, classToPreventHide) {\n this.$el = $(selector);\n this.selector = selector;\n this._scrollposition = 0;\n this.toPropagateClick = toPropagateClick;\n this.classToPreventHide = classToPreventHide;\n if (newModalType) {\n this.isOpenTypeCustom = false;\n } else {\n this.isOpen = false;\n }\n\n this.events();\n }\n\n show (newModalType) {\n if (newModalType) {\n if (this.isOpenTypeCustom) {\n return;\n }\n this.isOpenTypeCustom = true;\n } else {\n if (this.isOpen) {\n return;\n }\n this.isOpen = true;\n }\n\n // mimic tingle scroll lock\n this._scrollPosition = window.pageYOffset;\n $('body').addClass('tingle-enabled');\n $('html').addClass('html-tingle-enabled');\n this.$el.parent('.tingle-modal').addClass('tingle-modal--visible');\n }\n\n hide (newModalType) {\n if (newModalType) {\n if (!this.isOpenTypeCustom) {\n return;\n }\n this.isOpenTypeCustom = false;\n } else {\n if (!this.isOpen) {\n return;\n }\n this.isOpen = false;\n }\n\n // mimic tingle scroll lock\n if (($('.jsPersonalizationToolModal.tingle-modal--visible').length <= 0) || ($('.tingle-modal.tingle-modal--visible').length < 2)) {\n $('body').removeClass('tingle-enabled');\n $('html').removeClass('html-tingle-enabled');\n window.scrollTo(0, this._scrollPosition);\n }\n this.$el.parent('.tingle-modal').removeClass('tingle-modal--visible');\n }\n\n events () {\n $('body').on('click', '.tingle-modal', (e) => {\n if ($(e.target).hasClass('tingle-modal') || !$(e.target).closest(this.classToPreventHide)) {\n var newModalType = $(e.target).data('modalType') || null;\n this.hide(newModalType);\n e.stopPropagation();\n }\n });\n $('body').on('click', '.modal-close', (e) => {\n var newModalType = $(e.target).data('modalType') || null;\n this.hide(newModalType);\n e.stopPropagation();\n });\n\n if (!this.toPropagateClick) {\n $('body').on('click', this.selector, (e) => {\n e.stopPropagation();\n });\n }\n }\n};\n\nexport {\n newModal,\n newModalFromSelector,\n newModalFromString,\n newModalWithOptions,\n ModalShowHide,\n newModalWithSelector\n};\n","!function(t,o){\"function\"==typeof define&&define.amd?define(o):\"object\"==typeof exports?module.exports=o():t.tingle=o()}(this,function(){function t(t){var o={onClose:null,onOpen:null,beforeOpen:null,beforeClose:null,stickyFooter:!1,footer:!1,cssClass:[],closeLabel:\"Close\",closeMethods:[\"overlay\",\"button\",\"escape\"]};this.opts=r({},o,t),this.init()}function o(){this.modalBoxFooter&&(this.modalBoxFooter.style.width=this.modalBox.clientWidth+\"px\",this.modalBoxFooter.style.left=this.modalBox.offsetLeft+\"px\")}function e(){this.modal=document.createElement(\"div\"),this.modal.classList.add(\"tingle-modal\"),0!==this.opts.closeMethods.length&&this.opts.closeMethods.indexOf(\"overlay\")!==-1||this.modal.classList.add(\"tingle-modal--noOverlayClose\"),this.modal.style.display=\"none\",this.opts.cssClass.forEach(function(t){\"string\"==typeof t&&this.modal.classList.add(t)},this),this.opts.closeMethods.indexOf(\"button\")!==-1&&(this.modalCloseBtn=document.createElement(\"button\"),this.modalCloseBtn.classList.add(\"tingle-modal__close\"),this.modalCloseBtnIcon=document.createElement(\"span\"),this.modalCloseBtnIcon.classList.add(\"tingle-modal__closeIcon\"),this.modalCloseBtnIcon.innerHTML=\"×\",this.modalCloseBtnLabel=document.createElement(\"span\"),this.modalCloseBtnLabel.classList.add(\"tingle-modal__closeLabel\"),this.modalCloseBtnLabel.innerHTML=this.opts.closeLabel,this.modalCloseBtn.appendChild(this.modalCloseBtnIcon),this.modalCloseBtn.appendChild(this.modalCloseBtnLabel)),this.modalBox=document.createElement(\"div\"),this.modalBox.classList.add(\"tingle-modal-box\"),this.modalBoxContent=document.createElement(\"div\"),this.modalBoxContent.classList.add(\"tingle-modal-box__content\"),this.modalBox.appendChild(this.modalBoxContent),this.opts.closeMethods.indexOf(\"button\")!==-1&&this.modal.appendChild(this.modalCloseBtn),this.modal.appendChild(this.modalBox)}function s(){this.modalBoxFooter=document.createElement(\"div\"),this.modalBoxFooter.classList.add(\"tingle-modal-box__footer\"),this.modalBox.appendChild(this.modalBoxFooter)}function i(){this._events={clickCloseBtn:this.close.bind(this),clickOverlay:l.bind(this),resize:this.checkOverflow.bind(this),keyboardNav:n.bind(this)},this.opts.closeMethods.indexOf(\"button\")!==-1&&this.modalCloseBtn.addEventListener(\"click\",this._events.clickCloseBtn),this.modal.addEventListener(\"mousedown\",this._events.clickOverlay),window.addEventListener(\"resize\",this._events.resize),document.addEventListener(\"keydown\",this._events.keyboardNav)}function n(t){this.opts.closeMethods.indexOf(\"escape\")!==-1&&27===t.which&&this.isOpen()&&this.close()}function l(t){this.opts.closeMethods.indexOf(\"overlay\")!==-1&&!d(t.target,\"tingle-modal\")&&t.clientX=t},t.prototype.checkOverflow=function(){this.modal.classList.contains(\"tingle-modal--visible\")&&(this.isOverflow()?this.modal.classList.add(\"tingle-modal--overflow\"):this.modal.classList.remove(\"tingle-modal--overflow\"),!this.isOverflow()&&this.opts.stickyFooter?this.setStickyFooter(!1):this.isOverflow()&&this.opts.stickyFooter&&(o.call(this),this.setStickyFooter(!0)))},{modal:t}});","import {initProdTileCarousel} from './productTileCarousel';\nimport {forceLockScroll, forceUnlockScroll, preventDefault, genericAjaxCall} from '../util/common';\nexport {initProductTile, initSlotCarousel, closeAllQuickAdd};\n\n// SELECTOR ELEMENT CLASS USED LIST\nconst PREVENT_DEFAULT = '.js-prevent-link';\nconst PRODUCT_GRID_PLP = '.js-plp-productGrid';\nconst PRODUCT_TILE = '.js-prodTile';\nconst QUICKADD_BUTTON = '.js-prodTile-quickAdd-button';\nconst QUICKADD_CLOSE = '.js-prodTile-quickAdd-modal-closeQuickAdd';\nconst QUICKADD_MODAL = '.js-prodTile-quickAdd-modal';\nconst QUICKADD_MODAL_OVERFLOW = '.js-prodTile-quickAdd-modal-overflow';\nconst QUICKADD_MODAL_SLIDER = '.js-quickAdd-modal-container';\nconst QUICKADD_PROCEEDBUTTON = '.js-prodTile-quickAdd-modal-confirmButton';\nconst QUICKADD_SIZEBUTTON = '.js-prodTile-quickAdd-modal-sizes-button';\nconst QUICKADD_SIZEBUTTON_SELECTED = '.js-prodTile-quickAdd-modal-size_selected';\nconst QUICKADD_SIZESELECTED_LABEL = '.js-prodTile-quickAdd-modal-sizeSelected';\n\nlet isOpened = false;\n\n// LIST OF STYLE CLASS USED\nconst STYLE_QUICKADD_SIZEBUTTON_SELECTED =\n 'cc-prodTile-quickAdd-modal-sizes-button_selected js-prodTile-quickAdd-modal-size_selected';\nconst QUICKADD_MODAL_OPEN = 'js-prodTile-quickAdd-modal_open';\n\nfunction initProductTile() {\n if ($('.page').data('action') === 'Search-Show') {\n initOnlyPLP();\n } else {\n initProdTileCarousel();\n $(QUICKADD_BUTTON).off('click').on('click', openQuickAdd);\n $(PRODUCT_TILE).off('click').on('click', PREVENT_DEFAULT, preventDefault);\n }\n\n if ($('.js-suggestedProducts-container').length) {\n initSlotCarousel('.js-suggestedProducts-container');\n }\n\n if ($('.js-completeLook').length) {\n initSlotCarousel('.js-completeLook');\n }\n\n if ($('.js-completePromo').length) {\n initSlotCarousel('.js-completePromo');\n }\n\n $(window).on('resize', onResizeFunction);\n}\n\nfunction initSlotCarousel(containerClassName) {\n $(containerClassName)\n .off('click')\n .on('click', QUICKADD_BUTTON, openQuickAdd)\n .on('click', PREVENT_DEFAULT, preventDefault);\n\n if ($('.js-site-search').hasClass('cc-site-search_open') && !Foundation.MediaQuery.atLeast('large')) {\n $('.js-prodTile-quickAdd-modal').addClass('js-quickAdd-modal-container');\n }\n}\n\nfunction initOnlyPLP() {\n if ($(PRODUCT_GRID_PLP).length > 0) {\n initProdTileCarousel(PRODUCT_GRID_PLP);\n initSlotCarousel(PRODUCT_GRID_PLP);\n removeGridFullBanner();\n }\n}\n\nfunction removeGridFullBanner () {\n $('.cc-gridFullBanner-wrp').each(function (i, element) {\n if ($(element).children().length <= 0) {\n $(element).remove();\n }\n });\n}\n\nfunction openQuickAdd(e) {\n if (e.currentTarget.classList.contains('analytics-sizeBox') &&\n e.currentTarget.classList.contains('js-prodTile-quickAdd-button')) {\n $('body').trigger('product:selectSize', e.currentTarget);\n }\n e.preventDefault();\n e.stopPropagation();\n\n let $this = $(this);\n let url = $(this).data('url');\n let $modal = $(this).siblings(QUICKADD_MODAL);\n let $modalForSlider = $(QUICKADD_MODAL_SLIDER);\n let isCompletePromo = false;\n\n // Needed because we have two modals in position fixed one inside the other\n if ($('.js-site-search').hasClass('cc-site-search_open') && !Foundation.MediaQuery.atLeast('large')) {\n $('.js-site-search').after($modalForSlider);\n }\n\n if ($(this).closest('.js-hpShoppable').length > 0) {\n if (Foundation.MediaQuery.atLeast('large')) {\n openQuickAddShoppable($this, url, $modal);\n return;\n } else {\n $modal = $modalForSlider.first();\n }\n } else if (\n $(this).closest('.cc-emCarouselEditProd').length > 0 &&\n !Foundation.MediaQuery.atLeast('large')\n ) {\n $modal = $modalForSlider.first();\n } else {\n if (\n $(this).closest('.slick-track').length &&\n $modalForSlider.length &&\n !Foundation.MediaQuery.atLeast('large')\n ) {\n $modal = $modalForSlider.first();\n } else if (\n $(this).closest('.cc-completeYourPromo-productCards, .cc-productCarousel-coreMedia').length > 0 &&\n !Foundation.MediaQuery.atLeast('large')\n ) {\n let $quickAddOutsideModal = $('.js-quickAdd-modal-container').eq(0).clone();\n if ($('body > .js-quickAdd-modal-container').length === 0) {\n $('body').prepend($quickAddOutsideModal);\n }\n\n if ($(this).closest('.cc-completeYourPromo-productCards').length > 0) {\n isCompletePromo = true;\n }\n\n $modal = $('body > .js-quickAdd-modal-container');\n }\n }\n\n const analytics = $this.closest('.js-prodTile').find('.analytics.productListingItem').data();\n $modal.data('item_list_id', analytics.item_list_id);\n $modal.data('item_list_name', analytics.item_list_name);\n $modal.data('index', analytics.index);\n\n genericAjaxCall(url, null, null, false).then(function (data) {\n var newDOMModal = $(data).clone();\n $modal.empty().html(newDOMModal);\n\n $modal.slideDown({\n start: function () {\n $modal.css({display: 'flex'}).addClass(QUICKADD_MODAL_OPEN);\n $('body').addClass('veiled-for-small-only');\n if (isCompletePromo) {\n $('body').addClass('veiled-for-small-only_higher');\n }\n },\n complete: function () {\n $modal.on('click', QUICKADD_CLOSE, {modal: $modal}, closeQuickAdd);\n $modal.on('click', QUICKADD_SIZEBUTTON, {modal: $modal}, prepareAddToCart);\n searchSelectedSize($modal);\n if (!Foundation.MediaQuery.atLeast('large')) {\n forceLockScroll();\n // closeDrawerWithGesture($modal); comment for the moment\n }\n },\n });\n });\n}\n\nfunction openQuickAddShoppable($this, url, $modal) {\n if (!isOpened || !$modal.hasClass('quickAdd-opened')) {\n isOpened = true;\n // Handle the button rotation when opens in shoppable image banner\n $this.addClass('cm-rotateQuickAddButton');\n genericAjaxCall(url, null, null, true).then(function (data) {\n var newDOMModal = $(data).clone();\n $modal.empty().html(newDOMModal);\n $modal\n .closest('.cc-emShoppable__productCard')\n .addClass('cc-emShoppable__productCard--opened quickAdd-opened');\n $modal.addClass('cc-customModalOpened');\n $('.cc-emShoppableVideo__productCard:not(.cc-active)').removeClass('cc-emShoppable__productCard--opened quickAdd-opened');\n $('.cc-emShoppableVideo__productCard:not(.cc-active)').find('.js-prodTile-quickAdd-modal').removeClass('cc-customModalOpened');\n $this.on('click', {modal: $modal}, closeQuickAddShoppable);\n $modal.on('click', QUICKADD_SIZEBUTTON, {modal: $modal}, prepareAddToCart);\n searchSelectedSize($modal);\n });\n }\n}\n\nfunction closeQuickAdd(e, $modal) {\n try {\n e.preventDefault();\n } catch (exc) {}\n\n if (!Foundation.MediaQuery.atLeast('large')) {\n forceUnlockScroll();\n }\n\n var modal = $modal ? $modal : e.data.modal;\n\n modal.slideUp({\n complete: function () {\n modal.removeClass(QUICKADD_MODAL_OPEN);\n $('body').removeClass('veiled-for-small-only veiled-for-small-only_higher');\n },\n });\n modal.off('click', QUICKADD_CLOSE).off('click', QUICKADD_SIZEBUTTON);\n modal.find(QUICKADD_PROCEEDBUTTON).off('click');\n}\n\nfunction closeQuickAddShoppable(e) {\n try {\n e.preventDefault();\n e.stopPropagation();\n } catch (exc) {}\n\n let $modal = e.data.modal;\n isOpened = false;\n // Handle the button rotation when closes in shoppable image banner\n const closeQuickButton = $(e.currentTarget);\n if (closeQuickButton.hasClass('cm-rotateQuickAddButton')) {\n closeQuickButton.removeClass('cm-rotateQuickAddButton');\n }\n\n $modal\n .closest('.cc-emShoppable__productCard')\n .removeClass('cc-emShoppable__productCard--opened quickAdd-opened');\n $modal.removeClass('cc-customModalOpened');\n $(QUICKADD_BUTTON).off('click');\n $modal.off('click', QUICKADD_CLOSE).off('click', QUICKADD_SIZEBUTTON);\n $modal.find(QUICKADD_PROCEEDBUTTON).off('click');\n}\n\nfunction closeDrawerWithGesture(modal) {\n var modalContainer = modal;\n\n const scrollElement = modalContainer.find(QUICKADD_MODAL_OVERFLOW)[0];\n\n var hammertime = new Hammer(modalContainer[0]);\n hammertime.get('swipe').set({direction: Hammer.DIRECTION_VERTICAL});\n hammertime.get('pan').set({direction: Hammer.DIRECTION_VERTICAL});\n\n const isScrollable = scrollElement.scrollHeight > scrollElement.clientHeight;\n\n var startY,\n scrollTop = 0;\n\n if (isScrollable) {\n let actionStart = false;\n hammertime.on('panstart', function (e) {\n actionStart = true;\n startY = e.deltaY - scrollElement.offsetTop;\n scrollTop = scrollElement.scrollTop;\n });\n hammertime.on('panend', function (e) {\n actionStart = false;\n });\n hammertime.on('panmove', function (e) {\n if (!actionStart) {\n return;\n }\n const y = e.deltaY - scrollElement.offsetTop;\n const scroll = y - startY;\n scrollElement.scrollTop = scrollTop - scroll;\n });\n }\n\n hammertime.on('swipedown', function (e) {\n if (isScrollable && (scrollElement.scrollTop !== 0 || scrollTop > 30)) {\n return;\n }\n\n closeQuickAdd(e, modal);\n hammertime.off('swipedown panmove panend panstart').destroy();\n });\n}\n\n/**\n * function for close all the quickadd open with screen device is in large breakpoint\n */\nfunction closeAllQuickAdd() {\n let allQAopen = $('.' + QUICKADD_MODAL_OPEN);\n if (allQAopen.length > 0) {\n allQAopen.each(function () {\n closeQuickAdd(null, $(this));\n });\n }\n}\n\nfunction searchSelectedSize($modal) {\n var selectSize = $modal.find(QUICKADD_SIZEBUTTON_SELECTED);\n if (selectSize.length) {\n $modal.find(QUICKADD_SIZESELECTED_LABEL).empty().html(selectSize.data('name'));\n }\n}\n\nfunction prepareAddToCart(e) {\n var sizeButton = $(this);\n if (sizeButton.hasClass('notifyMe')) {\n return;\n }\n e.data.modal.find(QUICKADD_SIZEBUTTON).removeClass(STYLE_QUICKADD_SIZEBUTTON_SELECTED);\n sizeButton.addClass(STYLE_QUICKADD_SIZEBUTTON_SELECTED);\n\n const prepareData = {\n form: {\n pid: sizeButton.data('pid'),\n quantity: 1,\n GTMItemListName: e.data.modal.data('item_list_name'),\n GTMItemListId: e.data.modal.data('item_list_id'),\n GTMIndex: e.data.modal.data('index')\n },\n addToCartUrl: sizeButton.data('url'),\n modal: e.data.modal,\n $productContainer: sizeButton.closest('.js-prodTile')\n };\n\n searchSelectedSize(e.data.modal);\n\n if (Foundation.MediaQuery.atLeast('large')) {\n // desktop version\n makeAddToCart({data: prepareData});\n } else {\n // mobile version\n e.data.modal\n .find(QUICKADD_PROCEEDBUTTON)\n .attr('disabled', false)\n .on('click', prepareData, makeAddToCart);\n }\n}\n\nfunction makeAddToCart(e) {\n let $modal = e.data.modal;\n var dataValue = e.data;\n genericAjaxCall(dataValue.addToCartUrl, 'POST', dataValue.form).then(function (data) {\n if (data.error === false) {\n $('body').trigger('product:didChangeSizeQuickAddToCart', {\n ...data,\n form: dataValue.form,\n $productContainer: dataValue.$productContainer\n });\n\n $('body').trigger('product:afterAddToCart', {\n ...data,\n form: dataValue.form,\n $productContainer: dataValue.$productContainer,\n });\n handlePostCartAdd(data);\n\n if ($modal.closest('.js-hpShoppable').length > 0) {\n if (Foundation.MediaQuery.atLeast('large')) {\n closeQuickAddShoppable(e);\n return;\n }\n }\n\n closeAllQuickAdd();\n }\n });\n}\n\nfunction handlePostCartAdd(response) {\n $('body').trigger('count:update', response);\n // show add to cart toast\n if (response.error) {\n return;\n }\n if ($('.add-to-cart-messages').length === 0) {\n $('body').append('
');\n }\n if ($('.page[data-action=\"Cart-Show\"]').length > 0) {\n if (history.scrollRestoration) {\n history.scrollRestoration = 'manual';\n }\n $('html').animate({scrollTop: 0}, 500);\n }\n}\n\nfunction onResizeFunction() {\n closeAllQuickAdd();\n forceUnlockScroll();\n}\n","export default function () {\n // QuickView\n $('.js-carousel-select-color-quickview').slick({\n slidesToShow: 6,\n slidesToScroll: 2,\n infinite: false,\n variableWidth: true,\n responsive: [\n {\n breakpoint: 769,\n settings: {\n slidesToShow: 10,\n slidesToScroll: 2\n }\n },\n {\n breakpoint: 640,\n settings: {\n slidesToShow: 6,\n slidesToScroll: 2\n }\n }\n ]\n\n });\n}\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n"," import Product, {\n crossSellItems,\n computeCurrentlyVisibleImage,\n closeAllOpenMenus,\n} from './product/detail';\n// import findinstore from './product/findinstore';\nimport {processInclude, enqueueTask} from './util/common';\nimport {newModalFromString, newModalFromSelector} from './components/modal';\nimport productSlider from './components/productSlider';\nimport ScalaPay from 'product/scalaPay';\nimport Klarna from 'product/klarna';\nvar slideIndex = 0;\n\nfunction setupZoomHandler(elm) {\n var hammertime = new Hammer(elm, {});\n hammertime.get('pinch').set({\n enable: true,\n });\n let posX = 0;\n let posY = 0;\n let scale = 1;\n let lastScale = 1;\n let lastPosX = 0;\n let lastPosY = 0;\n let maxPosX = 0;\n let maxPosY = 0;\n let transform = '';\n let el = elm;\n\n hammertime.on('doubletap pan pinch panend pinchend', function (ev) {\n if (ev.type === 'doubletap') {\n transform = 'translate3d(0, 0, 0) ' + 'scale3d(2, 2, 1) ';\n scale = 2;\n lastScale = 2;\n try {\n if (\n window\n .getComputedStyle(el, null)\n .getPropertyValue('-webkit-transform')\n .toString() != 'matrix(1, 0, 0, 1, 0, 0)'\n ) {\n transform = 'translate3d(0, 0, 0) ' + 'scale3d(1, 1, 1) ';\n scale = 1;\n lastScale = 1;\n }\n } catch (err) {}\n el.style.webkitTransform = transform;\n transform = '';\n }\n\n // pan\n if (scale !== 1) {\n posX = lastPosX + ev.deltaX;\n posY = lastPosY + ev.deltaY;\n maxPosX = Math.ceil(((scale - 1) * el.clientWidth) / 2);\n maxPosY = Math.ceil(((scale - 1) * el.clientHeight) / 2);\n if (posX > maxPosX) {\n posX = maxPosX;\n }\n if (posX < -maxPosX) {\n posX = -maxPosX;\n }\n if (posY > maxPosY) {\n posY = maxPosY;\n }\n if (posY < -maxPosY) {\n posY = -maxPosY;\n }\n }\n\n // pinch\n if (ev.type === 'pinch') {\n scale = Math.max(0.999, Math.min(lastScale * ev.scale, 4));\n }\n if (ev.type === 'pinchend') {\n lastScale = scale;\n }\n\n // panend\n if (ev.type === 'panend') {\n lastPosX = posX < maxPosX ? posX : maxPosX;\n lastPosY = posY < maxPosY ? posY : maxPosY;\n }\n\n if (scale !== 1) {\n transform =\n 'translate3d(' +\n posX +\n 'px,' +\n posY +\n 'px, 0) ' +\n 'scale3d(' +\n scale +\n ', ' +\n scale +\n ', 1)';\n }\n\n if (transform) {\n el.style.webkitTransform = transform;\n }\n });\n}\n\nclass FixedBarSecondary {\n constructor() {\n this.ticking = false;\n this.fixedElement = '';\n this.scrollStopperElement = '';\n }\n\n init(fixedElement, additionalBar, sliderTrack, stopperElement, stopperElement2) {\n const fixedHTMLElement = document.getElementById(fixedElement);\n if (!fixedHTMLElement) {\n return;\n }\n\n const additionalBarHTML = document.getElementById(additionalBar);\n if (!additionalBarHTML) {\n return;\n }\n\n const sliderTrackHTML = document.getElementById(sliderTrack);\n if (!sliderTrackHTML) {\n return;\n }\n\n const computedPosition = window.getComputedStyle(fixedHTMLElement).position;\n if (computedPosition === 'sticky') {\n $(fixedHTMLElement).unwrap();\n return;\n }\n\n this.fixedElement = fixedElement;\n this.additionalBar = additionalBar;\n this.scrollStopperElement = stopperElement;\n this.scrollStopperElement2 = stopperElement2;\n this.sliderTrack = sliderTrack;\n\n fixedHTMLElement.style.position = 'fixed';\n fixedHTMLElement.style.bottom = null;\n fixedHTMLElement.style.top = null;\n fixedHTMLElement.style.left = null;\n fixedHTMLElement.style.right = null;\n fixedHTMLElement.style.marginTop = null;\n fixedHTMLElement.style.marginLeft = '0';\n fixedHTMLElement.style.zIndex = '995';\n\n additionalBarHTML.style.position = 'fixed';\n additionalBarHTML.style.marginLeft = '0';\n additionalBarHTML.style.bottom = '0';\n additionalBarHTML.style.zIndex = '995';\n\n $('.overlay-pdp-mobile').css('z-index', '900');\n\n window.addEventListener('scroll', this.onScroll.bind(this));\n }\n\n onScroll() {\n this.requestTick();\n }\n\n update() {\n this.ticking = false;\n\n const bottomBar = document.getElementById(this.fixedElement);\n const additionalBar = document.getElementById(this.additionalBar);\n const stopper = document.getElementById(this.scrollStopperElement);\n const stopper2 = document.getElementById(this.scrollStopperElement2);\n\n const sliderTrack = document.getElementById(this.sliderTrack);\n\n bottomBar.style.position = 'fixed';\n bottomBar.style.bottom = null;\n bottomBar.style.top = null;\n bottomBar.style.left = null;\n bottomBar.style.right = null;\n bottomBar.style.marginTop = null;\n bottomBar.style.marginLeft = '0';\n bottomBar.style.zIndex = '995';\n\n additionalBar.style.position = 'fixed';\n additionalBar.style.marginLeft = '0';\n additionalBar.style.bottom = '0';\n additionalBar.style.zIndex = '995';\n\n $('.overlay-pdp-mobile').css('z-index', '900');\n\n const r1 = bottomBar.getBoundingClientRect();\n const r2 = stopper.getBoundingClientRect();\n\n const r3 = additionalBar.getBoundingClientRect();\n const r4 = stopper2.getBoundingClientRect();\n\n if (r1.bottom > r2.bottom + r3.height) {\n bottomBar.style.position = 'absolute';\n\n bottomBar.style.left = '0';\n bottomBar.style.right = '0';\n\n bottomBar.style.bottom = '-2rem';\n\n sliderTrack.style.display = 'none';\n\n additionalBar.style.zIndex = '996';\n $('.overlay-pdp-mobile').css('z-index', '996');\n\n // Additional Bar\n if (r3.bottom > r4.bottom) {\n additionalBar.style.position = 'relative';\n additionalBar.style.bottom = '18px';\n }\n } else {\n sliderTrack.style.display = 'block';\n }\n }\n\n requestTick() {\n if (!this.ticking) {\n window.raf(this.update.bind(this));\n }\n this.ticking = true;\n }\n}\n\nconst fixedBarDescription = new FixedBarSecondary();\n\nlet automaticScroll = false;\nlet show = false;\n\nfunction scrollToTop() {\n // QA-2326 - avoid scrolling on quick add/view\n if ($('.quickview-modal').length > 0) {\n return;\n }\n\n if (Foundation.MediaQuery.atLeast('medium')) {\n $('html').animate(\n {\n scrollTop: 0,\n },\n 400\n );\n return;\n }\n\n automaticScroll = true;\n $('.primary-images')[0].scrollIntoView({\n behavior: 'smooth',\n });\n}\n\n// Moves around in page the picker contents for\nfunction updatePickableContentPositioning() {\n /*\n let mobileContainer = $('.js-pickable-content-mobile-container');\n let desktopContainer = $('.js-pickable-content-desktop-container');\n mobileContainer.removeClass('hide');\n\n if (Foundation.MediaQuery.atLeast('medium')) {\n if (mobileContainer.children().length > 0) {\n // Move to desktop container\n mobileContainer.children().detach().appendTo(desktopContainer);\n }\n } else {\n if (desktopContainer.children().length > 0) {\n // Move to mobile container\n desktopContainer.children().detach().appendTo(mobileContainer);\n }\n }\n */\n}\n\nfunction masterProduct() {\n var selectedProductColor = $('.color-variation .selected');\n var productColor = $('.color-variation');\n if (selectedProductColor.length === 0 && productColor.length > 0) {\n productColor.first().trigger('click');\n }\n}\n\nfunction adjustCloseIcon(closeIcon) {\n return closeIcon.css({\n top: 0,\n right: 0,\n width: window.innerWidth + 'px',\n 'font-size': (window.innerWidth * 10) / 100 + 'px',\n padding: (window.innerWidth * 2) / 100 + 'px ' + (window.innerWidth * 5) / 100 + 'px 0 0',\n });\n}\n\nconst hideServiceMenuAfterTimeout = function () {\n $('nav[role=\"navigation\"]').removeClass('show');\n $('.icon-container').removeClass('at-top');\n $('.js-breadcrumb').removeClass('show');\n};\n\ndocument.addEventListener('DOMContentLoaded', () => {\n processInclude(require('./findYourSize/findYourSize'));\n processInclude(require('./product/wishlistHeart'));\n Product.run();\n // findinstore.run();\n ScalaPay.run();\n Klarna.loadKlarnaWidgetAndObservers();\n\n // Start window observers for containers\n updatePickableContentPositioning();\n masterProduct();\n $(window).resize(updatePickableContentPositioning);\n // Add to cart sticky\n addToCartSticky();\n\n if (!Foundation.MediaQuery.atLeast('medium')) {\n fixedBarDescription.init(\n 'descriptionSidebar',\n 'menuSelectBarMobile',\n 'bottomSpacer2',\n 'bottomSpacer3'\n );\n }\n // Enqueue non critical task to be executed after DOMContentLoaded\n enqueueTask(productSlider);\n\n document.querySelectorAll('.js-offset-anchor').forEach(anchor => {\n anchor.addEventListener('click', function (e) {\n e.preventDefault();\n const targetElement = document.querySelector(this.getAttribute('href'));\n const offset = $('.js-pdpStickyBar').outerHeight() * 1.2;\n window.scrollTo({\n top: targetElement.offsetTop - offset,\n behavior: 'smooth'\n });\n });\n });\n\n let _lazyloadCache = {};\n function lazyload($domElement) {\n if (!$domElement.hasClass('js-lazyload')) {\n return new Promise(function (resolve, reject) {\n resolve('');\n });\n }\n let url = $domElement.data('lazyurl');\n if (!url) {\n return new Promise(function (resolve, reject) {\n reject(new Error('data-lazyurl not provided'));\n });\n }\n if (_lazyloadCache[url]) {\n return new Promise(function (resolve, reject) {\n resolve(_lazyloadCache[url]);\n });\n }\n return $.ajax(url).then(function (data) {\n _lazyloadCache[url] = data;\n return data;\n });\n }\n\n // Modal PDP Find Your Size\n $('.js-linkModalFindYourSize').on('click', function (e) {\n e.preventDefault();\n lazyload($(e.currentTarget)).then(function (data) {\n // create and open confirmation modal\n const modal = newModalFromString(data, '', ['cc-findYourSizeModal']);\n $(modal.modalBox).addClass('rightModalAttribute rightModalAttribute_sizeMedium');\n modal.open();\n\n $('.js-findYourSizeModal-close').on('click', function (e) {\n e.preventDefault();\n modal.close();\n });\n });\n });\n\n $('body').on('click', '.js-find-in-store-btn', (e) => {\n e.preventDefault();\n const isSizeSelected = () => {\n if ($(e.currentTarget).hasClass('js-find-in-store-btn-notify-me')) {\n // size always selected in plp before cta is clicked\n return true;\n } else {\n return $('[data-attr=\"size\"] input:checked').length > 0;\n }\n };\n if (isSizeSelected()) {\n __webpack_public_path__ = window.ll_script.base;\n import(/* webpackChunkName: \"findinstore\" */ './product/rf_findinstore').then(\n (findinstore) => {\n let fs = findinstore.default;\n fs.run();\n $('.findinstore-data-container').data('type', 'Pickup');\n fs.launch();\n }\n );\n } else {\n // If no size is selected, enable attribute selectors, open modal to choose one\n let sizeModal = newModalFromSelector('fis-select-size', false, [\n 'fis-select-size-modal',\n ]);\n const $sizeModalElement = $(sizeModal.modalBox);\n $sizeModalElement.find('.size-selector').removeAttr('disabled').removeClass('notifyMe');\n $sizeModalElement.find('.notifyIcon').remove();\n $sizeModalElement.on('click', '.modal__closeIcon', (e) => {\n sizeModal.close();\n sizeModal.destroy();\n });\n\n sizeModal.open();\n $('.js-find-in-store-btn').data('size-value', '');\n $('body.tingle-enabled').css('overflow', 'unset');\n $sizeModalElement.on('click', 'button.size-selector', (e) => {\n const $target = $(e.currentTarget);\n const sizeValue = $(e.currentTarget).data('attr-value');\n let selectedSizes = $('.js-find-in-store-btn').data('size-value');\n if (selectedSizes && selectedSizes !== '') {\n selectedSizes = selectedSizes.split('_');\n } else {\n selectedSizes = [];\n }\n if ($target.hasClass('selected')) {\n $target.removeClass('selected');\n selectedSizes.splice(selectedSizes.indexOf(sizeValue), 1);\n } else if ($target.closest('ul').find('button.selected').length < 3) {\n $target.addClass('selected');\n selectedSizes.push(sizeValue);\n }\n\n $('.fis-select-size-modal .find-in-store-size-select-btn').prop(\n 'disabled',\n selectedSizes.length === 0\n );\n $('.js-find-in-store-btn').data('size-value', selectedSizes.join('_'));\n e.stopPropagation();\n });\n\n $sizeModalElement.on('click', '.find-in-store-size-select-btn', (e) => {\n e.stopPropagation();\n $('body').trigger('find-in-store-size-select-btn:click', e);\n __webpack_public_path__ = window.ll_script.base;\n import(/* webpackChunkName: \"findinstore\" */ './product/rf_findinstore').then(\n (findinstore) => {\n let fs = findinstore.default;\n fs.run();\n $('.findinstore-data-container').data('type', 'Pickup');\n fs.launch();\n sizeModal.close();\n // sizeModal.destroy();\n }\n );\n });\n }\n $('body').trigger('product:moreInfoToggle', 'find_in_store');\n if ($(e.currentTarget).closest('.notifyMeModal').length === 0) {\n $('body').trigger('product-find-in-store:click', { 'isDispo': $(e.currentTarget).hasClass('analytics-searchNearestStore') });\n }\n });\n\n $('body').on('click', '.js-linkModalFindYourSizePlp', function (e) {\n e.preventDefault();\n const htmlContent = $('.js-ModalFindYourSizePlp').html();\n // create and open confirmation modal\n const modal = newModalFromString(htmlContent, false);\n $(modal.modal).addClass('wrapperModalFindYourSizePlp');\n modal.open();\n $(modal.modalBox)\n .find('.close')\n .on('click', function (e) {\n modal.close();\n });\n\n $('.js-inside-close-modal, #continue-shopping').on('click', function (e) {\n e.preventDefault();\n modal.close();\n });\n\n $('[data-dismiss=\"modalBigContent\"]').on('click', function (e) {\n e.preventDefault();\n modal.close();\n });\n });\n\n $('body').on('click', '.js-modal-made-in', function (e) {\n e.preventDefault();\n const _openModal = (modalContent) => {\n const modal = newModalFromString(modalContent, false, [\n 'ca-madeInModal',\n 'js-madeInModal',\n ]);\n $(modal.modalBox).addClass('rightModalAttribute rightModalAttribute_sizeMedium');\n modal.open();\n $(modal.modalBox).find('.js-madeInModal-close').removeClass('show-for-large');\n $(modal.modalBox)\n .find('.js-madeInModal-close, .js-madeInModal-back')\n .on('click', function (e) {\n if (Foundation.MediaQuery.atLeast('large')) {\n $(modal.modalBox)\n .addClass('cc-modalClosing')\n .on(\n 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd',\n function () {\n modal.close();\n }\n );\n } else {\n modal.close();\n }\n });\n $('.js-inside-close-modal,.js-close-modal').on('click', function (e) {\n e.preventDefault();\n modal.close();\n });\n };\n lazyload($(e.currentTarget)).then(function (data) {\n _openModal(data.content);\n });\n });\n\n enqueueTask(function () {\n crossSellItems(decodeURIComponent($('.container').data('pid')));\n });\n computeCurrentlyVisibleImage();\n\n window.addEventListener('scroll', computeCurrentlyVisibleImage.bind(this));\n\n let previousPosition = 0;\n let timer;\n\n const headerHeight = $('.js-mainHeader').outerHeight();\n /*\n * Logic to show/hide the various bars on scroll:\n * - at page top: show both header and service menu\n * - when scrolling up: show only service menu\n * - when scrolling down: do not show anything\n * This logic must not be applied when the scroll is automatic\n */\n const onScrollFunction = function () {\n if (automaticScroll === true) {\n automaticScroll = false;\n return;\n }\n if (timer) {\n clearTimeout(timer);\n }\n\n const scrollYPos = window.scrollY;\n const scrollYMaxDeadzone =\n (document.documentElement.scrollHeight - document.documentElement.clientHeight) * 0.95;\n const $mainHeader = $('.js-mainHeader-container');\n const $breadCrumbsContainer = $('.js-breadcrumb');\n\n showStickyBottomBarMobile();\n\n if (scrollYPos === 0) {\n $mainHeader.addClass('cc-isVisible');\n $breadCrumbsContainer.addClass('cc-isVisible');\n show = true;\n } else if (scrollYPos > headerHeight && !show) {\n if (scrollYPos < previousPosition && scrollYPos < scrollYMaxDeadzone) {\n timer = setTimeout(hideServiceMenuAfterTimeout, 5000);\n $mainHeader.addClass('cc-isVisible');\n $breadCrumbsContainer.addClass('cc-isVisible');\n show = true;\n } else {\n $mainHeader.removeClass('cc-isVisible');\n $breadCrumbsContainer.removeClass('cc-isVisible');\n }\n }\n previousPosition = window.scrollY;\n };\n\n if (Foundation.MediaQuery.is('large')) {\n $(document).on('click', '.productImageCarouselItem', function (e) {\n $('html').css({'overflow-y': 'hidden'});\n\n var n = parseInt($(this).attr('data-index'));\n var modal = document.getElementById('zoomModal');\n $(modal).find('.js-zoomModal-imagesWrapper').addClass('loaded');\n modal.classList.add('opened');\n showSlides((slideIndex = n));\n setTimeout(function loaded() {\n $(modal).find('.js-zoomModal-imagesWrapper').addClass('loaded');\n }, 1000)\n });\n $('.js-next-image').on('click', (e) => {\n showSlides((slideIndex += 1));\n });\n $('.js-prev-image').on('click', (e) => {\n showSlides((slideIndex -= 1));\n });\n $('.js-zoomModal-close').on('click', (e) => {\n $('html').css({'overflow-y': ''});\n var modal = document.getElementById('zoomModal');\n modal.classList.remove('opened');\n $(modal).find('.js-zoomModal-imagesWrapper').removeClass('loaded');\n $('.js-images-slide').removeClass('zoomed');\n });\n $('body').on('click', '.js-zoomModal-zoom:not(zoomed), .js-images-slide:not(zoomed)', function (e) {\n var zoomInLabel = $('.js-zoomModal-zoom').attr('data-label-zoom-in');\n var zoomOutLabel = $('.js-zoomModal-zoom').attr('data-label-zoom-out');\n $('body').on('click', '.js-zoomModal-zoom.zoomed, .js-zoomModal-close, .js-images-slide.zoomed', function () {\n $('.js-zoomModal-zoom').removeClass('zoomed').attr('aria-label', zoomInLabel);\n $('.js-images-slide').removeClass('zoomed');\n $('.js-images-slide.js-active').off('mousemove', mouseZoomOnImage);\n\n var length = parseInt($('#zoomModal').data('numberOfImages'), 10);\n var slides = document.getElementsByClassName('js-images-slide');\n for (var i = 0; i < length; i++) {\n slides[i].style.marginTop = '';\n }\n });\n $('.js-zoomModal-zoom').addClass('zoomed').attr('aria-label', zoomOutLabel);\n $('.js-images-slide').addClass('zoomed');\n mouseZoomOnImage(e);\n $('body').on('mousemove', '.js-images-slide.js-active', mouseZoomOnImage);\n });\n }\n\n if ($('.js-intProductDetail').length) {\n automaticScroll = true;\n\n // modal tap image only mobile\n if (!Foundation.MediaQuery.is('large')) {\n $('.js-linkModalProductImageCarousel').on('click', function (e) {\n var n = parseInt($(this).attr('data-index'));\n $('html').css({'overflow-y': 'hidden'});\n\n var n = parseInt($(this).attr('data-index'));\n var modal = document.getElementById('zoomModal-mobile');\n modal.classList.add('opened');\n showSlides(slideIndex = n, true);\n setTimeout(function loaded() {\n $(modal).find('.js-zoomModalMobile-imagesWrapper').addClass('loaded');\n }, 1000)\n });\n $('.js-next-image').on('click', e => {\n showSlides(slideIndex += 1, true);\n });\n $('.js-prev-image').on('click', e => {\n showSlides(slideIndex -= 1, true);\n });\n $('.js-zoomModalMobile-close').on('click', e => {\n $('html').css({'overflow-y': ''});\n var modal = document.getElementById('zoomModal-mobile');\n $(modal).find('.js-zoomModal-imagesWrapper').removeClass('loaded');\n modal.classList.remove('opened');\n $('.js-images-slide').removeClass('zoomed');\n });\n $('body').on('click', '.js-zoomModalMobile-zoom:not(zoomed), .js-images-slide:not(zoomed)', function (e) {\n var zoomInLabel = $('.js-zoomModalMobile-zoom').attr('data-label-zoom-in');\n var zoomOutLabel = $('.js-zoomModalMobile-zoom').attr('data-label-zoom-out');\n $('body').on('click', '.js-zoomModalMobile-zoom.zoomed, .js-zoomModalMobile-close, .js-images-slide.zoomed', function () {\n $('.js-zoomModalMobile-zoom').removeClass('zoomed').attr('aria-label', zoomInLabel);\n $('.js-images-slide').removeClass('zoomed');\n });\n $('.js-zoomModalMobile-zoom').addClass('zoomed').attr('aria-label', zoomOutLabel);\n $('.js-images-slide').addClass('zoomed');\n });\n\n /* Sticky bottom bar in mobile version */\n const addToCartCTA = $('.js-addToCartWrapper');\n const addToCartStickyBar = $('.js-addToCartStickyBar');\n $(addToCartStickyBar).html($(addToCartCTA).html());\n showStickyBottomBarMobile();\n }\n\n window.onscroll = () => {\n onScrollFunction();\n };\n }\n\n $(document).on('product:afterAttributeSelect', (evt, data) => {\n if (data.type === 'color') {\n if ($('.page[data-action=\"Product-Show\"]').length > 0) {\n closeAllOpenMenus();\n scrollToTop();\n }\n if ($(data.container).hasClass('product-freegift')) {\n data.data.product.isFreeGist = true;\n }\n $('body').trigger('product:didChangeColorForProductDetails', data.data.product); // For analytics\n\n }\n });\n\n // Scroll images on miniature click\n $('body').on('click', '#miniatureVerticalImgRealContainer .slide', (e) => {\n scrollToTop();\n });\n});\n\nfunction mouseZoomOnImage(e) {\n var pageH = window.innerHeight;\n var imgH = $('.js-images-slide.js-active').height();\n var position = e.clientY;\n var off = -(imgH - pageH) * (position / pageH);\n if (e.originalEvent.type === 'mousemove') {\n $(this).css({\n marginTop: off + 'px',\n });\n } else if (e.originalEvent.type === 'click') {\n $('.js-images-slide.js-active')[0].style.marginTop = off + 'px';\n }\n}\n\nfunction showStickyBottomBarMobile() {\n /* Sticky bottom bar in mobile version */\n const addToCartCTA = $('.js-addToCartWrapper');\n const addToCartStickyBar = $('.js-addToCartStickyBar');\n const addToCartCTATop = $(addToCartCTA).offset().top;\n const addToCartCTABottom = addToCartCTATop + $(addToCartCTA).outerHeight();\n const viewportTop = $(window).scrollTop();\n const viewportBottom = viewportTop + $(window).height();\n\n const isFooterHidden = $(window).scrollTop() + $(window).height() > $('.js-footer').offset().top;\n\n if ((addToCartCTABottom > viewportTop && addToCartCTATop < viewportBottom) || isFooterHidden) {\n $(addToCartStickyBar).css({\n bottom: '-' + $(addToCartStickyBar).outerHeight() + 'px',\n transition: 'all 0.5s ease',\n });\n } else {\n $(addToCartStickyBar).css({bottom: '0', transition: 'all 0.5s ease'});\n }\n}\n\nfunction showSlides (n, mobile) {\n var zoomModal;\n\n if (mobile) {\n zoomModal = $('#zoomModal-mobile');\n } else {\n zoomModal = $('#zoomModal');\n }\n\n var length = parseInt(zoomModal.data('numberOfImages'), 10);\n var slides = $(zoomModal)[0].getElementsByClassName('js-images-slide');\n\n var slideIndex = (length + (n % length)) % length;\n var prev = (length + ((n - 1) % length)) % length;\n var next = (length + ((n + 1) % length)) % length;\n\n slides[prev].classList.add('js-prev');\n slides[slideIndex].classList.add('js-active');\n slides[next].classList.add('js-next');\n\n for (var i = 0; i < length; i++) {\n if (i != slideIndex) {\n slides[i].classList.remove('js-active');\n }\n if (i != prev) {\n slides[i].classList.remove('js-prev');\n }\n if (i != next) {\n slides[i].classList.remove('js-next');\n }\n }\n\n zoomModal.find('.js-zoomModal-imageCount').html((slideIndex + 1) + '/' + length);\n\n if (length > 1) {\n $('.prev').removeClass('hidden');\n $('.next').removeClass('hidden');\n } else {\n $('.prev').addClass('hidden');\n $('.next').addClass('hidden');\n }\n}\n\n// Modal Smart Gift Rules\n$('.js-smart-gift-rules').on('click', function (e) {\n e.preventDefault();\n const htmlContent = $($(this).data('target')).html();\n // create and open confirmation modal\n const modalBigContent = newModalFromString(htmlContent, false);\n modalBigContent.setContent(document.querySelector('.js-smart-gift-rules-modal').innerHTML);\n $('.tingle-modal').addClass('wrapperModal');\n $('.wrapperModal').addClass('smartGiftModal');\n modalBigContent.open();\n $(modalBigContent.modalBox)\n .find('.close')\n .on('click', function (e) {\n modalBigContent.close();\n });\n\n $('.js-inside-close-modal').on('click', function (e) {\n e.preventDefault();\n modalBigContent.close();\n });\n\n $('[data-dismiss=\"modalBigContent\"]').on('click', function (e) {\n e.preventDefault();\n modalBigContent.close();\n });\n\n $('body').on('click', '.check-dispo-store-availability', (e) => {\n $('.js-change-store.find-in-store-btn').trigger('click');\n })\n});\n\n// Add to cart sticky\nlet lastScroll = 0;\nfunction addToCartSticky() {\n $(document).ready(function () {\n $(window).on('scroll', stickyBarManager);\n });\n}\nfunction getScrollPosition() {\n let scrollPosition = $(window).scrollTop();\n if ($('.js-mainHeader')) {\n scrollPosition += $('.js-mainHeader').height();\n }\n return scrollPosition;\n}\nfunction setCompleteTheLookButtonPosition() {\n if (Foundation.MediaQuery.atLeast('large')) {\n $('.primary-images .complete-look-button').css('top', window.innerHeight - 60);\n }\n}\nfunction getCtaPosition() {\n let ctaPosition = 0;\n if ($('.js-intProductDetail.js-isSoldOut').length) {\n ctaPosition = calculateTopOffset($('.button.js-find-in-store-btn'));\n } else {\n ctaPosition = calculateTopOffset($('.js-add-to-cart.button'));\n }\n return ctaPosition;\n}\nfunction calculateTopOffset($element) {\n if ($element.length > 0)\n return $element.offset().top + $element.outerHeight();\n}\nfunction showStickyBar() {\n $('.js-pdpStickyBar').slideDown({duration: 250});\n $('.js-mainHeader').addClass('visibility-hidden');\n}\nfunction hideStickyBar() {\n $('.js-pdpStickyBar').slideUp({duration: 250});\n $('.js-mainHeader').removeClass('visibility-hidden');\n}\nfunction showOrHideStickyBar() {\n if (getScrollPosition() >= getCtaPosition()) {\n showStickyBar();\n } else {\n hideStickyBar();\n }\n}\nfunction stickyBarManager() {\n showOrHideStickyBar();\n}\n\nconst video = document.querySelector('.js-textileBanner-videoContainer-video');\nlet isPlaying = true;\n\nfunction togglePlayPause() {\n $('#js-textileBanner-playPauseButton').on('click', function (e) {\n e.preventDefault();\n if (isPlaying) {\n video.pause();\n $('.js-textileBanner-playPauseButton_play').removeClass('hidden');\n $('.js-textileBanner-playPauseButton_pause').addClass('hidden');\n } else {\n video.play();\n $('.js-textileBanner-playPauseButton_pause').removeClass('hidden');\n $('.js-textileBanner-playPauseButton_play').addClass('hidden');\n }\n isPlaying = !isPlaying;\n });\n}\ntogglePlayPause();\n","export {initProdTileCarousel, unslickProdTileCarousel};\n\nconst IMAGE_CONTAINER_CAROUSEL_CLASS = '.js-prodTile-imageContainer-carousel';\n\nfunction initProdTileCarousel (containerClass) {\n const $tileCarousel = containerClass\n ? $(containerClass + ' ' + IMAGE_CONTAINER_CAROUSEL_CLASS)\n : $(IMAGE_CONTAINER_CAROUSEL_CLASS);\n\n if ($tileCarousel) {\n loadLazyVideo();\n $tileCarousel.on('init', function () {\n $(this).find('.slick-arrow').addClass('js-prevent-link');\n $(this).find('.slick-dots').addClass('js-prevent-link');\n\n var previousLabel = $('.js-fetch-slick-previous-label').data('label');\n $(this).find('.slick-arrow.slick-prev').attr('aria-label', previousLabel);\n var nextLabel = $('.js-fetch-slick-next-label').data('label');\n $(this).find('.slick-arrow.slick-next').attr('aria-label', nextLabel);\n });\n $tileCarousel.slick({\n lazyLoad: 'ondemand',\n draggable: true,\n dots: true,\n accessibility: false,\n arrows: true,\n responsive: [\n {\n breakpoint: 1023,\n settings: {\n arrows: false,\n },\n },\n ],\n });\n }\n}\n\nfunction unslickProdTileCarousel (containerClass) {\n const $tileCarousel = containerClass\n ? $(containerClass + ' ' + IMAGE_CONTAINER_CAROUSEL_CLASS + '.slick-initialized')\n : $(IMAGE_CONTAINER_CAROUSEL_CLASS + '.slick-initialized');\n\n if ($tileCarousel) {\n $tileCarousel.slick('unslick');\n }\n}\n\nfunction loadLazyVideo () {\n const lazyloadclass = 'js-customLazyload';\n let lazyVideos = [].slice.call(document.querySelectorAll('.' + lazyloadclass));\n\n let lazyVideoObserver = new IntersectionObserver(function (entries) {\n entries.forEach(function (video) {\n if (video.isIntersecting) {\n for (let source in video.target.children) {\n let videoSource = video.target.children[source];\n if (\n typeof videoSource.tagName === 'string' &&\n videoSource.tagName === 'SOURCE'\n ) {\n videoSource.src = videoSource.dataset.src;\n }\n }\n\n video.target.load();\n video.target.classList.remove(lazyloadclass);\n lazyVideoObserver.unobserve(video.target);\n }\n });\n });\n\n lazyVideos.forEach(function (lazyVideo) {\n lazyVideoObserver.observe(lazyVideo);\n });\n}\n","// import tingle from 'tingle.js';\n// import ProductHelpers from './base';\nimport { newModal } from '../components/modal';\nimport productSlider from '../components/productSlider';\n// let wishlist = require('./wishlistHeart');\n\n/**\n * replaces the content in the modal window on for the selected product variation.\n * @param {string} productUrl - url to be used for going to the product details page\n * @param {string} selectedValueUrl - url to be used to retrieve a new product model\n */\nconst fillModalElement = (productUrl, selectedValueUrl, modal) => {\n $.ajax({\n url: selectedValueUrl,\n method: 'GET',\n dataType: 'json',\n success: html => {\n modal.setContent(html.renderedTemplate);\n $('.product-quickview .carousel-inner').slick({\n arrows: true,\n dots: false\n });\n productSlider();\n // wishlist.highlightIconsForAllItemsInWishlist();\n modal.open();\n\n localStorage.setItem('prevlisttype', localStorage.getItem('listtype'));\n localStorage.setItem('listtype', 'landing');\n localStorage.setItem('prevlisttypeforcart', localStorage.getItem('listtypeforcart'));\n localStorage.setItem('listtypeforcart', 'landing');\n $('body').trigger('product:productLanding');\n\n if (document.getElementById('TU')) {\n document.getElementById('TU').click();\n }\n $(modal.modalBox)\n .find('.close-custom')\n .on('click', function (e) {\n modal.close();\n modal.destroy();\n });\n\n const destroyModal = () => {\n try {\n modal.close();\n modal.destroy();\n } catch (e) {};\n // remove the event listener to manage cases where the modal\n // is opened two or more times, (removes console error)\n $(document).off('product:afterAddToCart', destroyModal);\n };\n\n $(document).on('product:afterAddToCart', destroyModal);\n },\n error: err => {\n console.log('Error:', err);\n }\n });\n};\n\nconst addToCartFromListing = (pid, promoId, $productContainer) => {\n $.spinner().start();\n var form = {\n pid: pid,\n quantity: 1,\n options: [],\n promoId: promoId\n };\n var url = $('#tileAddToCartUrl').data('url');\n $.ajax({\n url: url,\n type: 'post',\n dataType: 'json',\n data: form,\n success: function (response) {\n if (response) {\n $('.js-mainHeader-minicart').trigger('count:update', response);\n localStorage.setItem('lastClickedPosition', '');\n localStorage.setItem('listtype', 'listing');\n // $(\"body, html\").animate({ scrollTop: 0 }, 500, 'swing');\n $('body').trigger('product:afterAddToCart', {\n ...response,\n form,\n $productContainer\n });\n $('body').trigger('product:afterQuickBuyListing', response);\n } else {\n console.error('Ajax: Empty Response');\n }\n $.spinner().stop();\n },\n error: function (err) {\n console.error('ErrorCase: ' + err.message);\n $.spinner().stop();\n }\n });\n};\n\nclass QuickView {\n run () {\n this.showQuickview();\n this.observeQuickBuy();\n }\n\n showQuickview () {\n $('body').on('click', '.quickview', function (e) {\n e.stopPropagation();\n e.preventDefault();\n const selectedValueUrl = $(this).attr('href');\n const productUrl = selectedValueUrl.replace('Product-ShowQuickView', 'Product-Show');\n const modal = newModal(false, ['quickview-modal']);\n fillModalElement(productUrl, selectedValueUrl, modal);\n\n // trigger for analytics product detail event\n const target = $(this).closest('.product');\n if (target.length > 0) {\n $('body').trigger('product:analyticsProductDetails', target);\n }\n });\n }\n\n observeQuickBuy () {\n $('body').on('click', '.js-quick-buy-sizes-item-select', function (e) {\n e.preventDefault();\n if ($(this).hasClass('disable') || !$(this).data('variant')) {\n return false;\n }\n var url = $(this).data('variant');\n\n var pid = $(e.currentTarget).data('pid');\n $(`.js-quick-buy-sizes-item[data-pid=\"${pid}\"]`).attr('variant', url);\n });\n $('body').on('click', '.js-quick-buy-sizes-item', function (e) {\n e.preventDefault();\n\n var url = $(this).attr('variant');\n $.spinner().start();\n $.ajax({\n url: url,\n type: 'GET',\n dataType: 'json',\n success: function (response) {\n $.spinner().stop();\n const $productContainer = $(e.target);\n if (response.product.available && !response.product.comingSoon) {\n addToCartFromListing(response.product.id, false, $productContainer);\n } else {\n $('body').trigger('product:afterAddToCartFailed', {\n ...response,\n $productContainer\n });\n }\n },\n error: function (err) {\n console.error('ErrorCase: ' + err.message);\n $.spinner().stop();\n }\n });\n });\n }\n}\n// const quickView = new QuickView();\nexport default QuickView;\nexport { addToCartFromListing };\n","/**\n * Remove all validation. Should be called every time before revalidating form\n * @param {element} form - Form to be cleared\n * @returns {void}\n */\nconst clearFormErrors = (form) => {\n $(form).find('.form-control.is-invalid').removeClass('is-invalid');\n $(form).find('.login-form-error').empty();\n $(form).find('.login-form-error').removeClass('login-form-error-block');\n $(form)\n .find('.login-form-error-generic')\n .removeClass('login-form-error-block')\n .addClass('hidden');\n};\n\n// If ja-JP language set, swap name and last name input form\nconst swapFirstLastName = () => {\n if ($('meta[http-equiv=content-language]').attr('content') != 'ja-JP') {\n return;\n }\n\n var firstNameIdList = [\n 'shippingFirstName', // 'Checkout' page\n 'nameformemail', // 'Send us an e-mail' page\n 'registration-form-fname', // 'Register' page\n 'billingFirstName', // 'Edit Billing' page\n 'firstName', // 'Add Address' page\n 'name-frm', // 'Fiscal code calc' modal\n ];\n\n var lastNameIdList = [\n 'shippingLastName',\n 'secondnameformemail',\n 'registration-form-lname',\n 'billingLastName',\n 'lastName',\n 'surname-frm',\n ];\n\n for (var i = 0; i < firstNameIdList.length; i++) {\n var firstNameId = firstNameIdList[i];\n var lastNameId = lastNameIdList[i];\n\n // Skip to next loop if one input doesn't exist\n if (!$('#' + firstNameId).length || !$('#' + lastNameId).length) {\n continue;\n }\n\n // Check two inputs are next to each other\n if (\n $('#' + firstNameId)\n .parents('.cell')\n .next('.cell')\n .find('#' + lastNameId)\n .length\n ) {\n $('#' + lastNameId)\n .closest('.cell')\n .after($('#' + firstNameId).closest('.cell'));\n\n // Adjust padding on 'Register' page\n if (i == 2) {\n $('#' + firstNameId)\n .parents('.register-form-final-padding-right')\n .removeClass('register-form-final-padding-right')\n .addClass('register-form-final-padding-left');\n $('#' + lastNameId)\n .parents('.register-form-final-padding-left')\n .removeClass('register-form-final-padding-left')\n .addClass('register-form-final-padding-right');\n }\n }\n }\n};\n\nexport const addInputClearIcon = (inputItem) => {\n var $inputFieldContainer = $(inputItem).closest(\n '.form-fields-item__label:not(.form-fields-item__label--select)'\n );\n var clearIconTopPos =\n $(inputItem).outerHeight() / 2 +\n ($('.form-fields-item__input-label', $inputFieldContainer).length > 0\n ? $('.form-fields-item__input-label', $inputFieldContainer).outerHeight(true)\n : 0);\n\n if ($inputFieldContainer.find('.form-fields-item__clearIcon').length === 0) {\n $inputFieldContainer.append('');\n }\n $('.form-fields-item__clearIcon', $inputFieldContainer).css('top', clearIconTopPos);\n\n if (inputItem.value !== '') {\n $(inputItem).addClass('cc-isPrefilled');\n }\n\n $(inputItem)\n .on('focus', function () {\n $inputFieldContainer.addClass('focused');\n $(this).removeClass('cc-isPrefilled');\n })\n .on('blur', function () {\n $inputFieldContainer.removeClass('focused');\n });\n};\nclass FormHelpers {\n init(formElement, payload) {\n // clear form validation first\n clearFormErrors(formElement);\n $('.alert', formElement).remove();\n\n // Chosen select\n if (Foundation.MediaQuery.atLeast('medium')) {\n const selects = $('select.chosen, select.custom-select');\n selects.chosen({ disable_search: true });\n selects.each(function () {\n const ariaLabel = $(this).attr('aria-label');\n \n $(this).next('.chosen-container')\n .find('.chosen-search-input')\n .attr('aria-label', ariaLabel);\n });\n }\n\n if (typeof payload === 'object' && payload.fields) {\n Object.keys(payload.fields).forEach(function (key) {\n if (payload.fields[key]) {\n var feedbackElement = $(formElement)\n .find('[name=\"' + key + '\"]')\n .parent()\n .children('.invalid-feedback');\n\n if (feedbackElement.length > 0) {\n if (Array.isArray(payload[key])) {\n feedbackElement.html(payload.fields[key].join('
'));\n } else {\n feedbackElement.html(payload.fields[key]);\n }\n feedbackElement.siblings('.form-control').addClass('is-invalid');\n feedbackElement.show();\n }\n }\n });\n }\n if (payload && payload.error) {\n $(formElement).find('.login-form-error').html(payload.error.join('
'));\n $(formElement).find('.login-form-error').addClass('login-form-error-block');\n }\n\n $('input[type=text], input[type=email], input[type=number]').each(function (index, inputItem) {\n if ($(inputItem).attr('name') !== 'q') {\n addInputClearIcon(inputItem);\n }\n });\n\n $('.form-fields-item__clearIcon').on('click touchstart', function (e) {\n $(e.currentTarget).siblings('.form-fields-item__input-field').val('');\n });\n\n swapFirstLastName();\n }\n\n /**\n * Display error messages and highlight form fields with errors.\n * @param {string} parentSelector - the form which contains the fields\n * @param {Object} fieldErrors - the fields with errors\n */\n loadFormErrors(parentSelector, fieldErrors) {\n // eslint-disable-line\n // Display error messages and highlight form fields with errors.\n $.each(fieldErrors, (attr) => {\n $('*[name=' + attr + ']', parentSelector)\n .addClass('is-invalid')\n .siblings('.invalid-feedback')\n .html(fieldErrors[attr])\n .show();\n });\n if (fieldErrors.length) {\n $(`*[name=${fieldErrors[0]}]`).trigger('focus');\n }\n }\n\n /**\n * Clear the form errors.\n * @param {string} parentSelector - the parent form selector.\n */\n clearPreviousErrors(parentSelector) {\n $(parentSelector).find('.form-control.is-invalid').removeClass('is-invalid');\n $('.error-message').hide();\n }\n\n handleAmexNumber(cardFieldSelector, cardTypeSelector) {\n var cleave = new Cleave(cardFieldSelector, {\n creditCard: true,\n onCreditCardTypeChanged: (type) => {\n const creditCardTypes = {\n amex: 'Amex',\n };\n\n const cardType =\n creditCardTypes[\n Object.keys(creditCardTypes).indexOf(type) > -1 ? type : 'unknown'\n ];\n $(cardTypeSelector).val(cardType);\n $('.card-number-wrapper').attr('data-type', type);\n if (type === 'visa' || type === 'mastercard' || type === 'discover') {\n $('#securityCode').attr('maxlength', 3);\n } else {\n $('#securityCode').attr('maxlength', 4);\n }\n },\n });\n\n $(cardFieldSelector).data('cleave', cleave);\n }\n handleCreditCardNumber(cardFieldSelector, cardTypeSelector) {\n var cleave = new Cleave(cardFieldSelector, {\n creditCard: true,\n onCreditCardTypeChanged: (type) => {\n const creditCardTypes = {\n visa: 'Visa',\n mastercard: 'Master Card',\n amex: 'Amex',\n discover: 'Discover',\n jcb: 'jcb',\n diners: 'diners',\n unknown: 'Unknown',\n };\n\n const cardType =\n creditCardTypes[\n Object.keys(creditCardTypes).indexOf(type) > -1 ? type : 'unknown'\n ];\n $(cardTypeSelector).val(cardType);\n $('.card-number-wrapper').attr('data-type', type);\n if (type === 'visa' || type === 'mastercard' || type === 'discover') {\n $('#securityCode').attr('maxlength', 3);\n } else {\n $('#securityCode').attr('maxlength', 4);\n }\n },\n });\n\n $(cardFieldSelector).data('cleave', cleave);\n }\n\n serializeData(form, wasAmexSelected) {\n const serializedArray = form.serializeArray();\n\n serializedArray.forEach((item) => {\n if (item.name.indexOf('cardNumber') > -1) {\n if (wasAmexSelected === true) {\n item.value = $('#cardNumberAmex').data('cleave').getRawValue(); // eslint-disable-line\n } else {\n item.value = $('#cardNumber').data('cleave').getRawValue(); // eslint-disable-line\n }\n }\n });\n\n return $.param(serializedArray);\n }\n}\n\nconst formHelpers = new FormHelpers();\nexport default formHelpers;\n","'use strict';\n\nimport { newModalFromString } from '../components/modal';\nimport FormHelpers, { addInputClearIcon } from '../util/form';\n\n/**\n * Checks if the email value entered is correct format\n * @param {string} email - email string to check if valid\n * @returns {boolean} Whether email is valid\n */\nfunction validateEmail (email) {\n var regex = /^[\\w.%+-]+@[\\w.-]+\\.[\\w]{2,6}$/;\n return regex.test(email);\n}\n\nclass NotifyHelper {\n notifyMeModal () {\n $('body').on('click', '.js-intProductDetail-size-item', (e) => {\n if (!$(e.currentTarget).find('.notifyMe').length) {\n return;\n }\n e.preventDefault();\n let actualDiv = $(e.currentTarget).find('.notifyMe');\n this.notifyMeAction(actualDiv);\n });\n\n $('body').on('click', '.notifyMe', (e) => {\n e.preventDefault();\n this.notifyMeAction(e.currentTarget);\n });\n }\n\n notifyMeAction (notifyMeDiv) {\n var paramUrl = $(notifyMeDiv).siblings().attr('data-variation-url');\n if (!paramUrl) {\n paramUrl = $(notifyMeDiv).siblings().attr('data-url');\n }\n if ($('.js-notifyMeModal').length > 0 || $(notifyMeDiv).hasClass('js-size-personalizable')) {\n return;\n }\n if ($(notifyMeDiv).hasClass('notifyPopup')) {\n $('.js-prod-select-size-modal').remove();\n paramUrl = $(notifyMeDiv).attr('data-url');\n }\n $('.js-notifyMeModal-titleNotComingSoon').removeClass('hidden');\n $('.js-notifyMeModal-subTitleNotComingSoon').removeClass('hidden');\n $('.js-notifyMeModal-titleComingSoon').addClass('hidden');\n $('.js-notifyMeModal-subTitleComingSoon').addClass('hidden');\n let isComingSoon = $(notifyMeDiv).siblings().attr('data-iscomingsoon') == 'true';\n if (isComingSoon) {\n $('.js-notifyMeModal-titleNotComingSoon').addClass('hidden');\n $('.js-notifyMeModal-subTitleNotComingSoon').addClass('hidden');\n $('.js-notifyMeModal-titleComingSoon').removeClass('hidden');\n $('.js-notifyMeModal-subTitleComingSoon').removeClass('hidden');\n }\n $('.js-notifyMeModal-toHide').removeClass('hidden');\n $('.js-notifyMeModal-toShow').addClass('hidden');\n $('.js-notifyMeModal-notifyBtn').parent().removeClass('hidden');\n $('.continueShopping').addClass('hidden');\n $('.js-notifyMeModal-emailError').addClass('hidden');\n $('.js-notifyMeModal-duplicateError').addClass('hidden');\n const htmlContent = $($(this).data('target')).html();\n // create and open confirmation modal\n const modal = newModalFromString(htmlContent, false, [\n 'cc-notifyMeModal',\n 'js-notifyMeModal',\n ]);\n if ($('.page').data('action') !== 'Product-Show') {\n $(modal.modalBox).addClass(\n 'cc-hide-findInStoreButton'\n );\n }\n $(modal.modalBox).addClass(\n 'rightModalAttribute cc-notifyMeModal-modalBox rightModalAttribute_sizeMedium'\n );\n let size = $(notifyMeDiv).innerText;\n $('.sizeNotify').html(size);\n\n let quickAddFlow = $(notifyMeDiv).hasClass('notifyMeQuickAdd');\n // Retrieve images from correct SKU (e.g: big cup models)\n var url = $('#notifyMeModalImageUrl').val();\n var pid;\n var selectedColor;\n var selectedSize;\n\n if (quickAddFlow) {\n pid = $(notifyMeDiv).data('pid');\n selectedColor = $(notifyMeDiv).data('color').split(' - ')[1]\n ? $(notifyMeDiv).data('color').split(' - ')[1].trim()\n : '';\n selectedSize = $(notifyMeDiv).data('value');\n } else {\n pid = decodeURIComponent($('.product-detail').attr('data-variant-pid'));\n selectedColor = $('[data-attr=\"color\"] .swatch-value.selected').data('attr-value');\n selectedSize =\n $(notifyMeDiv).closest('label').find('input').data('size-id') + '';\n selectedSize = selectedSize.replaceAll('/', '\\\\/');\n $('[data-attr=\"size\"] #' + selectedSize).prop('checked', true);\n }\n\n $.ajax({\n url: url,\n type: 'GET',\n data: {\n pid: pid,\n color: selectedColor,\n size: selectedSize,\n },\n }).then(function (rsp) {\n modal.setContent(rsp.renderedTemplate);\n\n if ($('.quickview-modal').hasClass('tingle-modal--visible') && !$('.quickview-modal').hasClass('js-notifyMe-modal')) {\n $('.quickview-modal').remove();\n }\n\n modal.open();\n if ($('.js-complete-your-promo-quick-view').length > 0) {\n $(modal.modalBox).find('#findInStore-modal').addClass('hide');\n }\n // Enable addInputClearIcon inside class FormHelpers\n FormHelpers.init($('.js-notifyMeModal'));\n // Call addInputClearIcon for the current or every future input in this modal.\n $('input[type=text],input[type=email]').each(function (index, inputItem) {\n addInputClearIcon(inputItem);\n });\n });\n\n $(modal.modalBox).on('click', '.js-notifyMeModal-close', (e) => {\n modal.close();\n modal.destroy();\n });\n\n $(modal.modalBox).on('click', '.continue-shopping-link', (e) => {\n e.preventDefault();\n let sku = $('div.notifyMeModal').data('master-pid') || '';\n let productName = $('.analytics.product').data('name') || '';\n productName = productName.replace(/\\s\\s+/g, ' ').split(' ').join('_');\n $('body').trigger('soldout:popupActions', {\n cta: $(e.currentTarget).data('analytics-action'),\n productName: productName,\n size: $('.sizeNotify').text().trim(),\n sku,\n });\n modal.close();\n modal.destroy();\n });\n\n $(modal.modalBox).on('click', '.analytics-notify-popup-actions', (e) => {\n e.preventDefault();\n let sku = $('div.notifyMeModal').data('master-pid') || '';\n let productName = $('.analytics.product').data('name') || '';\n productName = productName.replace(/\\s\\s+/g, ' ').split(' ').join('_');\n $('body').trigger('soldout:popupActions', {\n cta: $(e.currentTarget).data('analytics-action'),\n productName: productName,\n size: $('.sizeNotify').text().trim(),\n sku,\n });\n });\n\n $(modal.modalBox).on('click', '.js-notifyMeModal-notifyBtn', (e) => {\n let email = $('#emailNotify').val();\n let isValid = validateEmail(email);\n let type = !isComingSoon ? 'back-in-stock' : 'coming-soon';\n let queryString = paramUrl.split('Product-Variation')[1];\n let productName = $('.analytics.product.hidden').attr('data-item_name') || '';\n let analyticsSku = $('div.notifyMeModal').data('master-pid') || '';\n productName = productName.replace(/\\s\\s+/g, ' ').split(' ').join('_');\n\n if (isValid) {\n let dataForm = {\n sku: $('#skuNotify').val(),\n owner: email,\n type: type,\n };\n let url = $('.notify-url').val();\n $.spinner().start();\n $.ajax({\n url: url + queryString,\n method: 'POST',\n dataType: 'json',\n data: dataForm,\n success: (data) => {\n $.spinner().stop();\n if (data.success) {\n $('.js-notifyMeModal-toHide').addClass('hidden');\n if (isComingSoon) {\n $('#messageGreen').addClass('hidden');\n $('#comingSoonGreen').removeClass('hidden');\n }\n $('#comingSoonGreen').text(data.messageComingSoon);\n $('#messageGreen').text(data.message);\n $('.js-notifyMeModal-toShow').removeClass('hidden');\n $('.js-notifyMeModal-notifyBtn').addClass('hidden');\n $(\n '.js-notifyMeModal-titleNotComingSoon,.js-notifyMeModal-titleComingSoon'\n ).addClass('hidden');\n $(\n '.js-notifyMeModal-subTitleNotComingSoon, .js-notifyMeModal-subTitleComingSoon'\n ).addClass('hidden');\n $('.continueShopping').removeClass('hidden');\n $('.js-notifyMeModal-emailError').addClass('hidden');\n $('.js-notifyMeModal-duplicateError').addClass('hidden');\n if (!Foundation.MediaQuery.atLeast('medium')) {\n $('.subtitleHide').addClass('hidden');\n }\n $('body').trigger('soldout:notify', {\n size: $('.sizeNotify').text().trim(),\n productName: productName,\n sku: analyticsSku,\n availability: 'product_notify_me',\n });\n } else {\n if (data.duplicate) {\n $('.js-notifyMeModal-duplicateError').removeClass('hidden');\n }\n }\n },\n error: () => {\n $.spinner().stop();\n },\n });\n } else {\n $('.js-notifyMeModal-emailError').removeClass('hidden');\n }\n });\n }\n}\n\nconst notifyHelper = new NotifyHelper();\nexport default notifyHelper;\n","export const startCarouselTileImageFunction = (element) => {\n var carousel = element ? $(element) : $('.js-tileImageCarousel');\n carousel.on('init', function (event, slick) {\n $(this).find('.tile-image').removeClass('hide');\n $(this).find('.slick-arrow').addClass('js-prevent-link');\n });\n carousel.slick({\n responsive: [\n {\n settings: {\n draggable: false,\n swipe: false,\n swipeToSlide: false,\n touchMove: false,\n accessibility: false,\n arrows: false\n }\n }\n ]\n });\n};\n\nclass ProductBox {\n run () {\n this.gotoPDP();\n this.startCarouselTileImage();\n this.afterAttributesSelectionEvent();\n }\n\n gotoPDP () {\n $(document).on('click', '.product-tile', function (evt) {\n if (evt.target.classList.contains('js-prevent-link')) {\n evt.preventDefault();\n }\n });\n }\n\n startCarouselTileImage () {\n startCarouselTileImageFunction();\n\n $('body').on('click', '.product .js-tileImageCarousel .slick-arrow', function (e) {\n e.preventDefault();\n e.stopPropagation();\n });\n }\n\n afterAttributesSelectionEvent () {\n $(document).on('product:afterAttributeSelect', (evt, additionalData) => {\n const $container = additionalData.container;\n var newPriceData = additionalData.data.product.price.html;\n if (additionalData.data.product.doubleCurrency && additionalData.data.product.doubleCurrency.html) {\n newPriceData += additionalData.data.product.doubleCurrency.html;\n }\n $container.find('.price-container').html(newPriceData);\n });\n }\n}\n\n// const productBox = new ProductBox();\nexport default ProductBox;\n","'use strict';\n\nconst checkCarouselLength = (carouselContainer) => {\n if ($(carouselContainer).length > 0) {\n $(carouselContainer).each(function () {\n const carousel = $(this);\n let carouselWidth = parseInt($(carousel).outerWidth());\n let carouselItemsNumber = $(carousel).children().length;\n let carouselItemsWidth = parseInt($(carousel).children().outerWidth());\n let carouselItemsWidthSum = carouselItemsWidth * carouselItemsNumber;\n if ((carouselItemsWidthSum + 16) <= carouselWidth) {\n $(this).closest('.cc-em').find('.cc-em__carouselCustom__arrows').hide();\n $(this).addClass('cc-em__carouselCustom_center');\n } else {\n $(this).closest('.cc-em').find('.cc-em__carouselCustom__arrows').show();\n $(this).removeClass('cc-em__carouselCustom_center');\n }\n\n $(this).scroll(function () {\n carouselWidth = parseInt($(carousel).outerWidth());\n carouselItemsNumber = $(carousel).children().length;\n carouselItemsWidth = parseInt($(carousel).children().outerWidth());\n carouselItemsWidthSum = carouselItemsWidth * carouselItemsNumber;\n let carouselScrolled = $(carousel).scrollLeft();\n\n if (carouselScrolled < 1) {\n $(carousel).closest('.cc-em').find('.js-carouselCustom__arrowLeft').addClass('cc-disabled');\n } else if (carouselScrolled >= (carouselItemsWidthSum - carouselWidth + 16)) {\n $(carousel).closest('.cc-em').find('.js-carouselCustom__arrowRight').addClass('cc-disabled');\n } else {\n $(carousel).closest('.cc-em').find('.js-carouselCustom__arrowLeft').removeClass('cc-disabled');\n $(carousel).closest('.cc-em').find('.js-carouselCustom__arrowRight').removeClass('cc-disabled');\n }\n });\n });\n }\n};\n$(document).ready(function () {\n // Custom Carousel\n function carouselScroll (el, dir) {\n const carousel = $(el).closest('.cc-em').find('.cc-em__carouselCustom');\n const carouselItemsWidth = parseInt($(carousel).children().outerWidth());\n let carouselScrolled = $(carousel).scrollLeft();\n\n if (dir === 'right') {\n $(carousel).scrollLeft(carouselScrolled + carouselItemsWidth);\n } else {\n $(carousel).scrollLeft(carouselScrolled - carouselItemsWidth);\n }\n }\n\n $(document).on('click', '.js-carouselCustom__arrowLeft', function () {\n carouselScroll(this, 'left');\n });\n\n $(document).on('click', '.js-carouselCustom__arrowRight', function () {\n carouselScroll(this, 'right');\n });\n $('body').on('common:checkCarouselLength', function (e, data) {\n checkCarouselLength(data.name);\n });\n});\n\nexport {\n checkCarouselLength,\n};\n","import { fabric } from 'fabric';\nimport { generateSvgForOTP } from './personalization/generateSvgForOTP';\nimport {\n newModalFromString\n} from './components/modal';\nimport sizePanel from './product/sizePanel';\nimport SELECTORS from './personalization/selectors';\nimport CLASSES from './personalization/classes';\n\nlet customizePosition, customizeSide, customizeText, customizeFont, customizePattern, customizeColor, allowedCharactersRegex, canvas, canvasText, canvasRect, canvasGroup, canvasImage, top, left, topBack, leftBack, badWords, loadingTime, isStepTwo, rectColor, switchDisable;\n\nfunction initText () {\n const { textInput, fontsButtons, colorsButtons } = SELECTORS;\n $(textInput).val('');\n $(fontsButtons).removeClass('active');\n $(fontsButtons).first().addClass('active');\n $(colorsButtons).removeClass('active');\n $(colorsButtons).first().addClass('active');\n\n customizePosition = '0';\n customizeText = '';\n customizeFont = '\"Didot\",Times,serif';\n customizePattern = '1';\n customizeColor = '#000000';\n allowedCharactersRegex = $(textInput).data('regex-pattern');\n}\n\nfunction initVariables () {\n customizeSide = '0';\n top = parseInt($(SELECTORS.pixelText).attr('top-desktop'));\n left = parseInt($(SELECTORS.pixelText).attr('left-desktop'));\n topBack = parseInt($(SELECTORS.pixelText).attr('top-desktop-back'));\n leftBack = parseInt($(SELECTORS.pixelText).attr('left-desktop-back'));\n switchDisable = $(SELECTORS.pixelText).attr('switch-disable') === 'true';\n badWords = [];\n loadingTime = 300;\n isStepTwo = false;\n rectColor = '#3C3738';\n\n initText();\n}\n\n/**\n * @function initCanvas - Init the canvas\n * @returns {void}\n */\nfunction initCanvas (imageToLoad = SELECTORS.imgFront) {\n canvas = new fabric.StaticCanvas('personalization-canvas', {\n width: 2000,\n height: 3000,\n enableRetinaScaling: false\n });\n\n let transformX = left / canvas.width * 100;\n let transformY = top / canvas.height * 100;\n let translateY = transformY < 25 ? 0 : transformY > 75 ? -50 : 25 - transformY;\n\n $(SELECTORS.personalizationCanvas).css({\n transformOrigin: transformX + '% ' + transformY + '%',\n transform: 'scale(1)',\n top: isStepTwo ? translateY + '%' : '0'\n });\n\n $(SELECTORS.zoomButton).removeClass('active');\n\n const canvasRatio = 7.125; // canvas ratio calculated based on the design dimensions of the image (2000/355)\n canvasText = new fabric.Textbox(customizeText, {\n top: top,\n left: left,\n originX: 'center',\n originY: 'center',\n width: canvasRatio * 48,\n fontSize: canvasRatio * 10,\n lineHeight: canvasRatio * 15,\n fontFamily: customizeFont,\n textAlign: 'center',\n fill: customizeColor,\n });\n\n if (isStepTwo) {\n canvasRect = new fabric.Rect({\n strokeDashArray: [canvasRatio * 5, canvasRatio * 5],\n top: top,\n left: left,\n originX: 'center',\n originY: 'center',\n width: canvasRatio * 48,\n height: canvasRatio * 26,\n fill: '',\n stroke: rectColor,\n strokeWidth: canvasRatio * 1\n });\n }\n\n let imageUrl = $(imageToLoad).attr('src');\n fabric.Image.fromURL(imageUrl, function (img) {\n canvasImage = img.set({\n top: 0,\n selectable: false,\n hasRotatingPoint: true,\n width: canvas.width,\n height: canvas.height\n });\n canvasImage.scaleToWidth(canvas.width);\n\n if (isStepTwo) {\n canvasGroup = new fabric.Group([canvasImage, canvasText, canvasRect], {});\n } else {\n canvasGroup = new fabric.Group([canvasImage, canvasText], {});\n }\n canvas.add(canvasGroup);\n\n setTimeout(() => {\n canvas.renderAll();\n }, loadingTime);\n });\n}\n\n/**\n * @function initForm - Saves customization values inside the submit form inputs\n */\nfunction initForm () {\n $('.form-position').val(customizePosition);\n $('.form-text').val(customizeText);\n $('.form-font').val(customizeFont);\n $('.form-pattern').val(customizePattern);\n $('.form-color').val(customizeColor);\n $('.form-color-selected-circle-src').val($('#imageColor').attr('src'));\n}\n\n/**\n * @function updateCanvasElem - Update the canvas element based on a property and value\n * @param {Object} elem - Canvas element\n * @param {String} property - Property to update\n * @param {*} value - Value to set\n */\nfunction updateCanvasElem (elem, property, value) {\n if (elem) {\n elem.set(property, value);\n\n setTimeout(() => {\n canvas.renderAll();\n }, loadingTime);\n }\n};\n\n/**\n * @function waitToLoadAllImages - Wait for all images to load\n * @returns {Promise} - Promise that resolves when all images are loaded\n */\nfunction waitToLoadAllImages () {\n let defer = jQuery.Deferred();\n let imagesNumber = $('.js-personalization-image').length;\n let loadComplete = 0;\n $('.js-personalization-image').one('load', function () {\n loadComplete++;\n if (loadComplete === imagesNumber) {\n defer.resolve(true);\n }\n }).on('error', function () {\n loadComplete++;\n if (loadComplete === imagesNumber) {\n defer.resolve(true);\n }\n }).each(function () {\n if (this.complete) {\n $(this).trigger('load');\n } else if (this.error) {\n $(this).error();\n }\n });\n return defer.promise();\n};\n\n/**\n * @function runPersonalizationListener - Init the canvas, add event listeners on the modal elements and init the form\n */\nfunction runPersonalizationListener () {\n initVariables();\n sizePanel.init('#size-panel-mobile-pers');\n $('#size').attr('size-attribute', $('[data-attr=\"size\"] input:checked').attr('id'));\n\n waitToLoadAllImages().then(function () {\n initCanvas();\n positionChoice();\n });\n\n initForm();\n\n $('#input-type1').on('input', function () {\n editTextOnCanvas();\n });\n\n /**\n * Change the color of the text on the canvas\n */\n $(document).on('click', '.js-choice-editor .cc-choice-pattern_item', function (e) {\n customizePattern = $(this).find('img').attr('src');\n customizeColor = $(this).find('img').attr('alt');\n let colorName = $(this).find('img').data('name');\n $('.js-color-value').text(colorName);\n $('.js-customizePage').find('.js-choice-editor .cc-choice-pattern_item.active').removeClass('active');\n $(this).addClass('active');\n\n updateCanvasElem(canvasText, 'fill', customizeColor);\n\n e.stopPropagation();\n });\n\n /**\n * Select one of the 2 available hotspost\n */\n $(document).off('click', '.js-customizePage .js-positionChoice-1, .js-customizePage .js-positionChoice-2');\n $(document).on('click', '.js-customizePage .js-positionChoice-1, .js-customizePage .js-positionChoice-2', function (e) {\n isStepTwo = true;\n if ($(this).hasClass('js-positionChoice-1')) {\n selectPosition(1);\n } else if ($(this).hasClass('js-positionChoice-2')) {\n selectPosition(2);\n }\n choicePosition();\n $('.js-customizePage .js-positionChoice-1, .js-customizePage .js-positionChoice-2').hide();\n e.stopPropagation();\n });\n\n onZoomButtonClick();\n}\n\n/**\n * @function onZoomButtonClick - Add event listener on the zoom button, to zoom in/out the canvas\n */\nfunction onZoomButtonClick () {\n $(SELECTORS.zoomButton).on('click', function (e) {\n const $this = $(this);\n const scaleValue = $this.hasClass('active') ? 1 : 1.9;\n\n $(SELECTORS.personalizationCanvas).css({\n transform: 'scale(' + scaleValue + ')'\n });\n\n $this.toggleClass('active');\n e.stopPropagation();\n });\n}\n\n/**\n * @function editTextOnCanvas - Update the text on the canvas\n */\nfunction editTextOnCanvas () {\n customizeText = $('#input-type1').val();\n let badWordsFlag = false;\n\n if (badWords.includes(customizeText.toLowerCase())) {\n badWordsFlag = true;\n customizeText = '';\n $('.js-personalizeButtonModal').attr('disabled', true);\n $('.content-input-err').removeClass('hidden');\n } else {\n $('.js-personalizeButtonModal').attr('disabled', false);\n $('.content-input-err').addClass('hidden');\n }\n if (customizeText === undefined || customizeText === '') {\n $('.js-personalizeButtonModal').attr('disabled', true);\n $('.content-input-err-cyrillic').addClass('hidden');\n } else {\n $('.js-personalizeButtonModal').attr('disabled', false);\n\n if (!badWordsFlag) {\n const isRegexValid = customizeText.toLowerCase().match(allowedCharactersRegex);\n if (!isRegexValid) {\n $('.js-personalizeButtonModal').attr('disabled', true);\n $('.content-input-err-cyrillic').removeClass('hidden');\n } else {\n $('.js-personalizeButtonModal').attr('disabled', false);\n $('.content-input-err-cyrillic').addClass('hidden');\n }\n }\n }\n\n updateCanvasElem(canvasText, 'text', customizeText);\n\n if (customizeText !== '') {\n updateCanvasElem(canvasRect, 'stroke', '');\n } else {\n updateCanvasElem(canvasRect, 'stroke', rectColor);\n }\n}\n\n/**\n * @function updateCanvas - Re-load the canvas with a new image\n * @param {String} imageToLoad - Selector of the image tag to use for the canvas\n */\nfunction updateCanvas (imageToLoad) {\n canvas.clear();\n initCanvas(imageToLoad);\n}\n\n/**\n * @function choicePosition - Go to step 2, function is called after clicking on the hotspot\n */\nlet choicePosition = function () {\n const { page, mainChoice, showOtherSide, stepOne, stepTwo, termsBottomDesktop, footer, zoomButton } = SELECTORS;\n\n if (customizePosition !== '0') {\n $(mainChoice).addClass('visible');\n $(stepOne + ', ' + termsBottomDesktop).removeClass('cc-visible');\n $(stepTwo + ', ' + footer).addClass('cc-visible');\n $(showOtherSide).removeClass('back').addClass('hide');\n $(zoomButton).removeClass('hide');\n $(page).removeClass(CLASSES.pageStepOne).addClass(CLASSES.pageStepTwo);\n }\n};\n\n/**\n * @function backChoicePosition - Go back to step 1, function is called after clicking on the back button\n */\nlet backChoicePosition = function () {\n const { page, mainChoice, hotspotOne, hotspotTwo, stepOne, stepTwo, termsBottomDesktop, footer, showOtherSide, zoomButton } = SELECTORS;\n isStepTwo = false;\n if (customizeSide !== '0') {\n $(showOtherSide).removeClass('hide');\n\n if (customizeSide === '1') {\n $(showOtherSide).addClass('back').removeClass('front');\n } else {\n $(showOtherSide).addClass('front').removeClass('back');\n }\n } else {\n $(hotspotOne).removeClass('hide');\n $(hotspotTwo).removeClass('hide');\n }\n const imageToLoad = customizeSide === '1' || customizeSide === '0' ? $(SELECTORS.imgFront) : $(SELECTORS.imgBack);\n\n canvas.clear();\n initText();\n initCanvas(imageToLoad);\n\n $(mainChoice).removeClass('visible');\n $(stepOne + ', ' + termsBottomDesktop).addClass('cc-visible');\n $(stepTwo + ', ' + footer).removeClass('cc-visible');\n $(page).addClass(CLASSES.pageStepOne).removeClass(CLASSES.pageStepTwo);\n $(hotspotOne + ', ' + hotspotTwo).show();\n $(zoomButton).removeClass('active').addClass('hide');\n};\n\n/**\n * @function selectPosition - Select if we are using the image front or back\n * @param {Number} pos - 1: front, 2: back\n */\nfunction selectPosition (pos) {\n const { imgFront, imgBack, pixelText, hotspotOne, hotspotTwo, showOtherSide } = SELECTORS;\n let imageToLoad = $(imgFront);\n if (pos === 1 || pos === 0) {\n top = parseInt($(pixelText).attr('top-desktop'));\n left = parseInt($(pixelText).attr('left-desktop'));\n customizePosition = pos;\n $(showOtherSide).addClass('back').removeClass('front');\n $(hotspotOne).removeClass('hide');\n if (pos !== 0) {\n $(hotspotTwo).addClass('hide');\n }\n } else {\n top = parseInt($(pixelText).attr('top-desktop-back'));\n left = parseInt($(pixelText).attr('left-desktop-back'));\n imageToLoad = $(imgBack);\n customizePosition = '2';\n $(showOtherSide).addClass('front').removeClass('back');\n $(hotspotOne).addClass('hide');\n $(hotspotTwo).removeClass('hide');\n }\n\n updateCanvas(imageToLoad);\n}\n\n/**\n * @function positionChoice - Add event listeners on the position buttons\n */\nfunction positionChoice () {\n const imageFront = $('#img-url-front').attr('data-url').replace(/&/g, '&');\n const imageBack = $('#img-url-back').attr('data-url').replace(/&/g, '&');\n const topPercentage = (top / canvas.height) * 100;\n const leftPercentage = (left / canvas.width) * 100;\n const topBackPercentage = (topBack / canvas.height) * 100;\n const leftBackPercentage = (leftBack / canvas.width) * 100;\n\n if (imageBack !== '') {\n let $position1 = $('').html($('.cordinates-spot-icon i').html()).addClass('js-pers-hotspotBtn js-positionChoice-1 cc-pers-hotspotBtn');\n let $position2 = $('').html($('.cordinates-spot-icon i').html()).addClass('js-pers-hotspotBtn js-positionChoice-2 cc-pers-hotspotBtn');\n $position1.css({'position': 'absolute', 'top': topPercentage + '%', 'left': leftPercentage + '%', 'display': 'flex'}).appendTo('.js-section-module_result_image');\n $position2.css({'position': 'absolute', 'top': topBackPercentage + '%', 'left': leftBackPercentage + '%', 'display': 'flex'}).appendTo('.js-section-module_result_image');\n $position1.data('position', '1');\n $position2.data('position', '2');\n\n if (imageFront !== imageBack && !switchDisable) {\n $('.js-show-other-side').removeClass('hide').addClass('back');\n selectPosition(1);\n customizeSide = '1';\n } else {\n $('.js-show-other-side').addClass('hide');\n selectPosition(0);\n customizeSide = '0';\n }\n } else {\n let $position1 = $('').html($('.cordinates-spot-icon i').html()).addClass('js-pers-hotspotBtn js-positionChoice-1 cc-pers-hotspotBtn');\n $position1.css({'position': 'absolute', 'top': topPercentage + '%', 'left': leftPercentage + '%', 'display': 'flex'}).appendTo('.js-section-module_result_image');\n selectPosition(0);\n customizeSide = '0';\n $position1.data('position', '1');\n }\n\n /**\n * Add event listener on go back button (return to step 1);\n */\n $(document).off('click', '.cc-customizePage-topbar .js-page-back');\n $(document).on('click', '.cc-customizePage-topbar .js-page-back', function (e) {\n backChoicePosition();\n e.stopPropagation();\n $('body').trigger('customize:actions', {\n action: 'back',\n pid: $('.js-customizePage').data('pid')\n });\n });\n\n // Cambio Fronte/Retro\n $(document).off('click', '.js-show-other-side .js-other-side-btn');\n $(document).on('click', '.js-show-other-side .js-other-side-btn', function (e) {\n if ($(this).closest('.js-show-other-side').hasClass('front')) {\n $(this).closest('.js-show-other-side').removeClass('front').addClass('back');\n selectPosition(1);\n customizeSide = '1';\n } else {\n $(this).closest('.js-show-other-side').removeClass('back').addClass('front');\n selectPosition(2);\n customizeSide = '2';\n }\n });\n\n $(document).on('click', '.js-choice-editor .cc-choice-item', function (e) {\n customizeFont = $(this).data('font');\n $('.form-font').val(customizeFont);\n\n $('.js-choice-editor .cc-choice-item.active').removeClass('active');\n $(this).addClass('active');\n $('#input-type1').css('font-family', customizeFont);\n\n updateCanvasElem(canvasText, 'fontFamily', customizeFont);\n e.stopPropagation();\n });\n\n /**\n * Creates new canvas for the export and populates data for add to cart\n */\n $(document).on('click', SELECTORS.personalizeAddToCart, function (e) {\n initForm();\n\n $.spinner().start();\n\n let canvasOptions = {\n top: top,\n left: left,\n customizeText: customizeText,\n customizeFont: customizeFont,\n customizeColor: customizeColor,\n imageToLoad: customizeSide === '1' || customizeSide === '0' ? $(SELECTORS.imgFront) : $(SELECTORS.imgBack)\n };\n let svgAllFormat = generateSvgForOTP(canvasOptions);\n let base64FullSVG = svgAllFormat.personalizationFullSVG;\n $('#base64').attr('data-fullSVG', base64FullSVG);\n let base64TextFullSVG = svgAllFormat.personalizationTextSVG;\n $('#base64').attr('data-fullTextSVG', base64TextFullSVG);\n let base64TextSmallSVG = svgAllFormat.personalizationSmallSVG;\n $('#base64').attr('data-smallSVG', base64TextSmallSVG);\n $.spinner().stop();\n\n let size = $('#size').attr('size-attribute').replace('/', '~');\n if (size !== '') {\n $('#' + size).attr('checked', true);\n }\n\n // Update modal add-to-cart\n $('body').on('product:updateAddToCart', (e, response) => {\n if (!response.product.readyToOrder || !response.product.available || response.product.comingSoon) {\n if (this.sizeModal && this.sizeModal.modal) {\n $(this.sizeModal.modalBox).find('button.js-add-to-cart').attr('disabled', true);\n }\n } else if (this.sizeModal && this.sizeModal.modal) {\n $(this.sizeModal.modalBox).find('button.js-add-to-cart').attr('disabled', false);\n }\n });\n\n // Close the modal when a product is added to the cart\n $('body').on('product:afterAddToCart', (e) => {\n if (this.sizeModal && this.sizeModal.modal) {\n this.sizeModal.close();\n this.sizeModal.destroy();\n }\n });\n\n $('.js-personalizeButtonCheckout.js-add-to-cart').trigger('click');\n });\n\n // Modal Customize Terms\n $(SELECTORS.termsAndConditionsModal).on('click', function (e) {\n e.preventDefault();\n const htmlContent = $($(this).data('target')).html();\n // create and open confirmation modal\n const modal = newModalFromString(htmlContent, false);\n $('.tingle-modal:not(.jsPersonalizationToolModal)').addClass('cc-modalCustomizeTerms');\n $('.cc-modalCustomizeTerms .tingle-modal-box').addClass('cc-modalCustomizeTerms-container rightModalAttribute');\n $('.cc-modalCustomizeTerms .tingle-modal-box__content').addClass('cc-modalCustomizeTerms-container-modal');\n modal.open();\n modal.setContent(document.querySelector('.js-ModalCustomizeTerms').innerHTML);\n $(modal.modalBox)\n .find('.close')\n .on('click', function (e) {\n modal.close();\n });\n\n $('.js-inside-close-modal, [data-dismiss=\"modalBigContent\"]').on('click', function (e) {\n e.preventDefault();\n modal.close();\n });\n });\n\n $(SELECTORS.analyticsCustomizeAction).on('click', function (e) {\n let pid = $('.js-customizePage').data('pid');\n let action = $(e.currentTarget).data('action');\n $('body').trigger('customize:actions', {action: action, pid: pid});\n });\n\n $(SELECTORS.pageClose).on('click', function (e) {\n $('body').trigger('customize:actions', {\n action: 'close', \n pid: $('.js-customizePage').data('pid')\n });\n $('.jsPersonalizationToolModal .tingle-modal__close').trigger('click');\n initVariables();\n sizePanel.init();\n });\n\n // Hot spot selection - define \"position\" attribute\n $('body').on('click', '.js-pers-hotspotBtn', e => {\n customizePosition = $(e.currentTarget).data('position');\n $('.form-position').val(customizePosition);\n });\n};\n\nmodule.exports = {\n runPersonalizationListener: runPersonalizationListener,\n};\n","/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n * incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n ? global.TYPED_ARRAY_SUPPORT\n : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n return arr.foo() === 42 && // typed array instances can be augmented\n typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n } catch (e) {\n return false\n }\n}\n\nfunction kMaxLength () {\n return Buffer.TYPED_ARRAY_SUPPORT\n ? 0x7fffffff\n : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n if (kMaxLength() < length) {\n throw new RangeError('Invalid typed array length')\n }\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = new Uint8Array(length)\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n if (that === null) {\n that = new Buffer(length)\n }\n that.length = length\n }\n\n return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n return new Buffer(arg, encodingOrOffset, length)\n }\n\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new Error(\n 'If encoding is specified then the first argument must be a string'\n )\n }\n return allocUnsafe(this, arg)\n }\n return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n arr.__proto__ = Buffer.prototype\n return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number')\n }\n\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return fromArrayBuffer(that, value, encodingOrOffset, length)\n }\n\n if (typeof value === 'string') {\n return fromString(that, value, encodingOrOffset)\n }\n\n return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n Buffer.prototype.__proto__ = Uint8Array.prototype\n Buffer.__proto__ = Uint8Array\n if (typeof Symbol !== 'undefined' && Symbol.species &&\n Buffer[Symbol.species] === Buffer) {\n // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true\n })\n }\n}\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be a number')\n } else if (size < 0) {\n throw new RangeError('\"size\" argument must not be negative')\n }\n}\n\nfunction alloc (that, size, fill, encoding) {\n assertSize(size)\n if (size <= 0) {\n return createBuffer(that, size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(that, size).fill(fill, encoding)\n : createBuffer(that, size).fill(fill)\n }\n return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n assertSize(size)\n that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) {\n for (var i = 0; i < size; ++i) {\n that[i] = 0\n }\n }\n return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8'\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('\"encoding\" must be a valid string encoding')\n }\n\n var length = byteLength(string, encoding) | 0\n that = createBuffer(that, length)\n\n var actual = that.write(string, encoding)\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n that = that.slice(0, actual)\n }\n\n return that\n}\n\nfunction fromArrayLike (that, array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0\n that = createBuffer(that, length)\n for (var i = 0; i < length; i += 1) {\n that[i] = array[i] & 255\n }\n return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\\'offset\\' is out of bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\\'length\\' is out of bounds')\n }\n\n if (byteOffset === undefined && length === undefined) {\n array = new Uint8Array(array)\n } else if (length === undefined) {\n array = new Uint8Array(array, byteOffset)\n } else {\n array = new Uint8Array(array, byteOffset, length)\n }\n\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = array\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n that = fromArrayLike(that, array)\n }\n return that\n}\n\nfunction fromObject (that, obj) {\n if (Buffer.isBuffer(obj)) {\n var len = checked(obj.length) | 0\n that = createBuffer(that, len)\n\n if (that.length === 0) {\n return that\n }\n\n obj.copy(that, 0, 0, len)\n return that\n }\n\n if (obj) {\n if ((typeof ArrayBuffer !== 'undefined' &&\n obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n if (typeof obj.length !== 'number' || isnan(obj.length)) {\n return createBuffer(that, 0)\n }\n return fromArrayLike(that, obj)\n }\n\n if (obj.type === 'Buffer' && isArray(obj.data)) {\n return fromArrayLike(that, obj.data)\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n // Note: cannot use `length < kMaxLength()` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= kMaxLength()) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + kMaxLength().toString(16) + ' bytes')\n }\n return length | 0\n}\n\nfunction SlowBuffer (length) {\n if (+length != length) { // eslint-disable-line eqeqeq\n length = 0\n }\n return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n throw new TypeError('Arguments must be Buffers')\n }\n\n if (a === b) return 0\n\n var x = a.length\n var y = b.length\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i]\n y = b[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.concat = function concat (list, length) {\n if (!isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i\n if (length === undefined) {\n length = 0\n for (i = 0; i < list.length; ++i) {\n length += list[i].length\n }\n }\n\n var buffer = Buffer.allocUnsafe(length)\n var pos = 0\n for (i = 0; i < list.length; ++i) {\n var buf = list[i]\n if (!Buffer.isBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos)\n pos += buf.length\n }\n return buffer\n}\n\nfunction byteLength (string, encoding) {\n if (Buffer.isBuffer(string)) {\n return string.length\n }\n if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n string = '' + string\n }\n\n var len = string.length\n if (len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n case undefined:\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) return utf8ToBytes(string).length // assume utf8\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0\n start >>>= 0\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8'\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase()\n loweredCase = true\n }\n }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n var i = b[n]\n b[n] = b[m]\n b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1)\n }\n return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3)\n swap(this, i + 1, i + 2)\n }\n return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7)\n swap(this, i + 1, i + 6)\n swap(this, i + 2, i + 5)\n swap(this, i + 3, i + 4)\n }\n return this\n}\n\nBuffer.prototype.toString = function toString () {\n var length = this.length | 0\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n var str = ''\n var max = exports.INSPECT_MAX_BYTES\n if (this.length > 0) {\n str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n if (this.length > max) str += ' ... '\n }\n return ''\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n if (!Buffer.isBuffer(target)) {\n throw new TypeError('Argument must be a Buffer')\n }\n\n if (start === undefined) {\n start = 0\n }\n if (end === undefined) {\n end = target ? target.length : 0\n }\n if (thisStart === undefined) {\n thisStart = 0\n }\n if (thisEnd === undefined) {\n thisEnd = this.length\n }\n\n if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n throw new RangeError('out of range index')\n }\n\n if (thisStart >= thisEnd && start >= end) {\n return 0\n }\n if (thisStart >= thisEnd) {\n return -1\n }\n if (start >= end) {\n return 1\n }\n\n start >>>= 0\n end >>>= 0\n thisStart >>>= 0\n thisEnd >>>= 0\n\n if (this === target) return 0\n\n var x = thisEnd - thisStart\n var y = end - start\n var len = Math.min(x, y)\n\n var thisCopy = this.slice(thisStart, thisEnd)\n var targetCopy = target.slice(start, end)\n\n for (var i = 0; i < len; ++i) {\n if (thisCopy[i] !== targetCopy[i]) {\n x = thisCopy[i]\n y = targetCopy[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n // Empty buffer means no match\n if (buffer.length === 0) return -1\n\n // Normalize byteOffset\n if (typeof byteOffset === 'string') {\n encoding = byteOffset\n byteOffset = 0\n } else if (byteOffset > 0x7fffffff) {\n byteOffset = 0x7fffffff\n } else if (byteOffset < -0x80000000) {\n byteOffset = -0x80000000\n }\n byteOffset = +byteOffset // Coerce to Number.\n if (isNaN(byteOffset)) {\n // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n byteOffset = dir ? 0 : (buffer.length - 1)\n }\n\n // Normalize byteOffset: negative offsets start from the end of the buffer\n if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n if (byteOffset >= buffer.length) {\n if (dir) return -1\n else byteOffset = buffer.length - 1\n } else if (byteOffset < 0) {\n if (dir) byteOffset = 0\n else return -1\n }\n\n // Normalize val\n if (typeof val === 'string') {\n val = Buffer.from(val, encoding)\n }\n\n // Finally, search either indexOf (if dir is true) or lastIndexOf\n if (Buffer.isBuffer(val)) {\n // Special case: looking for empty string/buffer always fails\n if (val.length === 0) {\n return -1\n }\n return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n } else if (typeof val === 'number') {\n val = val & 0xFF // Search for a byte value [0-255]\n if (Buffer.TYPED_ARRAY_SUPPORT &&\n typeof Uint8Array.prototype.indexOf === 'function') {\n if (dir) {\n return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n } else {\n return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n }\n }\n return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n }\n\n throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n var indexSize = 1\n var arrLength = arr.length\n var valLength = val.length\n\n if (encoding !== undefined) {\n encoding = String(encoding).toLowerCase()\n if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n encoding === 'utf16le' || encoding === 'utf-16le') {\n if (arr.length < 2 || val.length < 2) {\n return -1\n }\n indexSize = 2\n arrLength /= 2\n valLength /= 2\n byteOffset /= 2\n }\n }\n\n function read (buf, i) {\n if (indexSize === 1) {\n return buf[i]\n } else {\n return buf.readUInt16BE(i * indexSize)\n }\n }\n\n var i\n if (dir) {\n var foundIndex = -1\n for (i = byteOffset; i < arrLength; i++) {\n if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n if (foundIndex === -1) foundIndex = i\n if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n } else {\n if (foundIndex !== -1) i -= i - foundIndex\n foundIndex = -1\n }\n }\n } else {\n if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n for (i = byteOffset; i >= 0; i--) {\n var found = true\n for (var j = 0; j < valLength; j++) {\n if (read(arr, i + j) !== read(val, j)) {\n found = false\n break\n }\n }\n if (found) return i\n }\n }\n\n return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; ++i) {\n var parsed = parseInt(string.substr(i * 2, 2), 16)\n if (isNaN(parsed)) return i\n buf[offset + i] = parsed\n }\n return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n // Buffer#write(string)\n if (offset === undefined) {\n encoding = 'utf8'\n length = this.length\n offset = 0\n // Buffer#write(string, encoding)\n } else if (length === undefined && typeof offset === 'string') {\n encoding = offset\n length = this.length\n offset = 0\n // Buffer#write(string, offset[, length][, encoding])\n } else if (isFinite(offset)) {\n offset = offset | 0\n if (isFinite(length)) {\n length = length | 0\n if (encoding === undefined) encoding = 'utf8'\n } else {\n encoding = length\n length = undefined\n }\n // legacy write(string, encoding, offset, length) - remove in v0.13\n } else {\n throw new Error(\n 'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n )\n }\n\n var remaining = this.length - offset\n if (length === undefined || length > remaining) length = remaining\n\n if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n throw new RangeError('Attempt to write outside buffer bounds')\n }\n\n if (!encoding) encoding = 'utf8'\n\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'hex':\n return hexWrite(this, string, offset, length)\n\n case 'utf8':\n case 'utf-8':\n return utf8Write(this, string, offset, length)\n\n case 'ascii':\n return asciiWrite(this, string, offset, length)\n\n case 'latin1':\n case 'binary':\n return latin1Write(this, string, offset, length)\n\n case 'base64':\n // Warning: maxLength not taken into account in base64Write\n return base64Write(this, string, offset, length)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return ucs2Write(this, string, offset, length)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\nfunction base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction utf8Slice (buf, start, end) {\n end = Math.min(buf.length, end)\n var res = []\n\n var i = start\n while (i < end) {\n var firstByte = buf[i]\n var codePoint = null\n var bytesPerSequence = (firstByte > 0xEF) ? 4\n : (firstByte > 0xDF) ? 3\n : (firstByte > 0xBF) ? 2\n : 1\n\n if (i + bytesPerSequence <= end) {\n var secondByte, thirdByte, fourthByte, tempCodePoint\n\n switch (bytesPerSequence) {\n case 1:\n if (firstByte < 0x80) {\n codePoint = firstByte\n }\n break\n case 2:\n secondByte = buf[i + 1]\n if ((secondByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n if (tempCodePoint > 0x7F) {\n codePoint = tempCodePoint\n }\n }\n break\n case 3:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n codePoint = tempCodePoint\n }\n }\n break\n case 4:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n fourthByte = buf[i + 3]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n codePoint = tempCodePoint\n }\n }\n }\n }\n\n if (codePoint === null) {\n // we did not generate a valid codePoint so insert a\n // replacement char (U+FFFD) and advance only 1 byte\n codePoint = 0xFFFD\n bytesPerSequence = 1\n } else if (codePoint > 0xFFFF) {\n // encode to utf16 (surrogate pair dance)\n codePoint -= 0x10000\n res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n codePoint = 0xDC00 | codePoint & 0x3FF\n }\n\n res.push(codePoint)\n i += bytesPerSequence\n }\n\n return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n var len = codePoints.length\n if (len <= MAX_ARGUMENTS_LENGTH) {\n return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n }\n\n // Decode in chunks to avoid \"call stack size exceeded\".\n var res = ''\n var i = 0\n while (i < len) {\n res += String.fromCharCode.apply(\n String,\n codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n )\n }\n return res\n}\n\nfunction asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i] & 0x7F)\n }\n return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i])\n }\n return ret\n}\n\nfunction hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; ++i) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n var len = this.length\n start = ~~start\n end = end === undefined ? len : ~~end\n\n if (start < 0) {\n start += len\n if (start < 0) start = 0\n } else if (start > len) {\n start = len\n }\n\n if (end < 0) {\n end += len\n if (end < 0) end = 0\n } else if (end > len) {\n end = len\n }\n\n if (end < start) end = start\n\n var newBuf\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n newBuf = this.subarray(start, end)\n newBuf.__proto__ = Buffer.prototype\n } else {\n var sliceLen = end - start\n newBuf = new Buffer(sliceLen, undefined)\n for (var i = 0; i < sliceLen; ++i) {\n newBuf[i] = this[i + start]\n }\n }\n\n return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n checkOffset(offset, byteLength, this.length)\n }\n\n var val = this[offset + --byteLength]\n var mul = 1\n while (byteLength > 0 && (mul *= 0x100)) {\n val += this[offset + --byteLength] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return ((this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16)) +\n (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] * 0x1000000) +\n ((this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var i = byteLength\n var mul = 1\n var val = this[offset + --i]\n while (i > 0 && (mul *= 0x100)) {\n val += this[offset + --i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n if (!(this[offset] & 0x80)) return (this[offset])\n return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset] | (this[offset + 1] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset + 1] | (this[offset] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16) |\n (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] << 24) |\n (this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var mul = 1\n var i = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var i = byteLength - 1\n var mul = 1\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffffffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset + 3] = (value >>> 24)\n this[offset + 2] = (value >>> 16)\n this[offset + 1] = (value >>> 8)\n this[offset] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = 0\n var mul = 1\n var sub = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = byteLength - 1\n var mul = 1\n var sub = 0\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n if (value < 0) value = 0xff + value + 1\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n this[offset + 2] = (value >>> 16)\n this[offset + 3] = (value >>> 24)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (value < 0) value = 0xffffffff + value + 1\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (targetStart >= target.length) targetStart = target.length\n if (!targetStart) targetStart = 0\n if (end > 0 && end < start) end = start\n\n // Copy 0 bytes; we're done\n if (end === start) return 0\n if (target.length === 0 || this.length === 0) return 0\n\n // Fatal error conditions\n if (targetStart < 0) {\n throw new RangeError('targetStart out of bounds')\n }\n if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length) end = this.length\n if (target.length - targetStart < end - start) {\n end = target.length - targetStart + start\n }\n\n var len = end - start\n var i\n\n if (this === target && start < targetStart && targetStart < end) {\n // descending copy from end\n for (i = len - 1; i >= 0; --i) {\n target[i + targetStart] = this[i + start]\n }\n } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n // ascending copy from start\n for (i = 0; i < len; ++i) {\n target[i + targetStart] = this[i + start]\n }\n } else {\n Uint8Array.prototype.set.call(\n target,\n this.subarray(start, start + len),\n targetStart\n )\n }\n\n return len\n}\n\n// Usage:\n// buffer.fill(number[, offset[, end]])\n// buffer.fill(buffer[, offset[, end]])\n// buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n // Handle string cases:\n if (typeof val === 'string') {\n if (typeof start === 'string') {\n encoding = start\n start = 0\n end = this.length\n } else if (typeof end === 'string') {\n encoding = end\n end = this.length\n }\n if (val.length === 1) {\n var code = val.charCodeAt(0)\n if (code < 256) {\n val = code\n }\n }\n if (encoding !== undefined && typeof encoding !== 'string') {\n throw new TypeError('encoding must be a string')\n }\n if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n } else if (typeof val === 'number') {\n val = val & 255\n }\n\n // Invalid ranges are not set to a default, so can range check early.\n if (start < 0 || this.length < start || this.length < end) {\n throw new RangeError('Out of range index')\n }\n\n if (end <= start) {\n return this\n }\n\n start = start >>> 0\n end = end === undefined ? this.length : end >>> 0\n\n if (!val) val = 0\n\n var i\n if (typeof val === 'number') {\n for (i = start; i < end; ++i) {\n this[i] = val\n }\n } else {\n var bytes = Buffer.isBuffer(val)\n ? val\n : utf8ToBytes(new Buffer(val, encoding).toString())\n var len = bytes.length\n for (i = 0; i < end - start; ++i) {\n this[i + start] = bytes[i % len]\n }\n }\n\n return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n // Node converts strings with length < 2 to ''\n if (str.length < 2) return ''\n // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n while (str.length % 4 !== 0) {\n str = str + '='\n }\n return str\n}\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n units = units || Infinity\n var codePoint\n var length = string.length\n var leadSurrogate = null\n var bytes = []\n\n for (var i = 0; i < length; ++i) {\n codePoint = string.charCodeAt(i)\n\n // is surrogate component\n if (codePoint > 0xD7FF && codePoint < 0xE000) {\n // last char was a lead\n if (!leadSurrogate) {\n // no lead yet\n if (codePoint > 0xDBFF) {\n // unexpected trail\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n } else if (i + 1 === length) {\n // unpaired lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n }\n\n // valid lead\n leadSurrogate = codePoint\n\n continue\n }\n\n // 2 leads in a row\n if (codePoint < 0xDC00) {\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n leadSurrogate = codePoint\n continue\n }\n\n // valid surrogate pair\n codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n } else if (leadSurrogate) {\n // valid bmp char, but last char was a lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n }\n\n leadSurrogate = null\n\n // encode utf8\n if (codePoint < 0x80) {\n if ((units -= 1) < 0) break\n bytes.push(codePoint)\n } else if (codePoint < 0x800) {\n if ((units -= 2) < 0) break\n bytes.push(\n codePoint >> 0x6 | 0xC0,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x10000) {\n if ((units -= 3) < 0) break\n bytes.push(\n codePoint >> 0xC | 0xE0,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x110000) {\n if ((units -= 4) < 0) break\n bytes.push(\n codePoint >> 0x12 | 0xF0,\n codePoint >> 0xC & 0x3F | 0x80,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else {\n throw new Error('Invalid code point')\n }\n }\n\n return bytes\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n if ((units -= 2) < 0) break\n\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n for (var i = 0; i < length; ++i) {\n if ((i + offset >= dst.length) || (i >= src.length)) break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction isnan (val) {\n return val !== val // eslint-disable-line no-self-compare\n}\n","'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n var len = b64.length\n\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf('=')\n if (validLen === -1) validLen = len\n\n var placeHoldersLen = validLen === len\n ? 0\n : 4 - (validLen % 4)\n\n return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n var tmp\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n var curByte = 0\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0\n ? validLen - 4\n : validLen\n\n var i\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)]\n arr[curByte++] = (tmp >> 16) & 0xFF\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] +\n lookup[num >> 12 & 0x3F] +\n lookup[num >> 6 & 0x3F] +\n lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xFF0000) +\n ((uint8[i + 1] << 8) & 0xFF00) +\n (uint8[i + 2] & 0xFF)\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(\n uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)\n ))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n parts.push(\n lookup[tmp >> 2] +\n lookup[(tmp << 4) & 0x3F] +\n '=='\n )\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3F] +\n lookup[(tmp << 2) & 0x3F] +\n '='\n )\n }\n\n return parts.join('')\n}\n","exports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var nBits = -7\n var i = isLE ? (nBytes - 1) : 0\n var d = isLE ? -1 : 1\n var s = buffer[offset + i]\n\n i += d\n\n e = s & ((1 << (-nBits)) - 1)\n s >>= (-nBits)\n nBits += eLen\n for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & ((1 << (-nBits)) - 1)\n e >>= (-nBits)\n nBits += mLen\n for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity)\n } else {\n m = m + Math.pow(2, mLen)\n e = e - eBias\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n var i = isLE ? 0 : (nBytes - 1)\n var d = isLE ? 1 : -1\n var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n value = Math.abs(value)\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0\n e = eMax\n } else {\n e = Math.floor(Math.log(value) / Math.LN2)\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--\n c *= 2\n }\n if (e + eBias >= 1) {\n value += rt / c\n } else {\n value += rt * Math.pow(2, 1 - eBias)\n }\n if (value * c >= 2) {\n e++\n c /= 2\n }\n\n if (e + eBias >= eMax) {\n m = 0\n e = eMax\n } else if (e + eBias >= 1) {\n m = ((value * c) - 1) * Math.pow(2, mLen)\n e = e + eBias\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n e = 0\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = (e << mLen) | m\n eLen += mLen\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128\n}\n","/**\n * Core SFRA function for run everything everywhere\n * @param {Function || Object} include - stuff to run\n */\nconst processInclude = (include) => {\n if (typeof include === 'function') {\n include();\n } else if (typeof include === 'object') {\n Object.keys(include).forEach(function (key) {\n if (typeof include[key] === 'function') {\n include[key]();\n }\n });\n }\n};\n\n// Enqueues tasks to be executed afterwards\nfunction enqueueTask(task) {\n window.requestAnimationFrame(task);\n}\n\n/**\n * Parses the html for a modal window\n * @param {string} html - representing the body and footer of the modal window\n *\n * @return {Object} - Object with properties body and footer.\n */\nconst parseHtml = (html, map) => {\n const el = document.createElement('div');\n el.innerHTML = html;\n\n let htmlMap = {};\n for (var key in map) {\n if (map.hasOwnProperty(key)) {\n htmlMap[key] = el.querySelector(map[key]);\n }\n }\n\n return htmlMap;\n};\n\n/**\n * appends params to a url\n * @param {string} url - Original url\n * @param {Object} params - Parameters to append\n * @returns {string} result url with appended parameters\n */\nconst appendToUrl = (url, params) => {\n var newUrl = url;\n newUrl +=\n (newUrl.indexOf('?') !== -1 ? '&' : '?') +\n Object.keys(params)\n .map(function (key) {\n return key + '=' + encodeURIComponent(params[key]);\n })\n .join('&');\n\n return newUrl;\n};\n\nconst lockScroll = () => {\n $('body, html').css('overflow-y', 'hidden');\n};\n\nconst unlockScroll = () => {\n $('body, html').css('overflow-y', '');\n};\n\n/**\n * function for force lock scroll when open a modal or a drawer.\n * CAN CREATE SOME ISSUE WITH TOUCH EVENT - CHECK ON REAL DEVICE\n * the event is for prevent scrolling in iOS device\n */\nfunction forceLockScroll() {\n $('body, html,.page')\n .css({'overflow-y': 'hidden', 'touch-action': 'none'})\n .on('touchmove', preventDefault);\n}\n\nfunction forceUnlockScroll() {\n $('body, html,.page')\n .css({'overflow-y': '', 'touch-action': ''})\n .off('touchmove', preventDefault);\n}\n\nfunction preventDefault(e) {\n e.preventDefault();\n}\n\nconst cookieExists = (name) => {\n return document.cookie.split(';').filter((item) => {\n return item.trim().indexOf(`${name}=`) === 0;\n }).length;\n};\n\nconst createCookie = (name, value = false, days = 0) => {\n var expires;\n if (days) {\n var date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toGMTString();\n } else {\n expires = '';\n }\n document.cookie = name + '=' + value + expires + '; path=/';\n};\n\nconst getCookie = (name) => {\n var value = '; ' + document.cookie;\n var parts = value.split('; ' + name + '=');\n if (parts.length == 2) return parts.pop().split(';').shift();\n return '';\n};\n\nconst deleteCookie = (name) => {\n document.cookie = name + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';\n};\n\nconst isTouchDevice = () => {\n return (\n 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0\n );\n};\n\n/**\n * Generic Ajax Call\n * @param {string} url - url for the ajax call\n * @param {string} method - default GET (is possible to use POST,PUT)\n * @param {object} data - use in POST method\n * @param {boolean} hideSpinner - default false, use true to hide the spinner\n * @returns Promise with the response of the ajax call\n */\nfunction genericAjaxCall(url, method = 'GET', data = {}, hideSpinner = false) {\n if (!url) {\n console.error('Missing Url in ajax call');\n return;\n }\n if (hideSpinner !== true) {\n $.spinner().start();\n }\n return new Promise((resolve, reject) => {\n $.ajax({\n url: url,\n method: method,\n data: data,\n success: function (response) {\n if (hideSpinner !== true) {\n $.spinner().stop();\n }\n resolve(response);\n },\n error: function (error) {\n if (hideSpinner !== true) {\n $.spinner().stop();\n }\n console.error(error);\n reject(error);\n },\n });\n });\n}\n\nexport {\n appendToUrl,\n cookieExists,\n createCookie,\n deleteCookie,\n enqueueTask,\n forceLockScroll,\n forceUnlockScroll,\n genericAjaxCall,\n getCookie,\n isTouchDevice,\n lockScroll,\n parseHtml,\n preventDefault,\n processInclude,\n unlockScroll,\n};\n","var toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n","import { fabric } from 'fabric';\n\n/**\n * @function createSvgFromCanvas - create svg from canvas\n * @param {Object} canvasToConvert - fabric canvas object\n * @returns {String} encodeSVG\n */\nfunction createSvgFromCanvas (canvasToConvert) {\n let svg = canvasToConvert.toSVG().toString().replace(/&(?!amp;)/g, '&').replace(/https:\\/\\//g, 'http://');\n let encodeSVG = encodeURIComponent(svg);\n return encodeSVG;\n}\n\n/**\n * @function generateSvgForOTP - generate svg for otp and return svgAllFormat\n * @param {Object} canvasOptions - canvas options to create canvas elements\n * @returns {Object} svgAllFormat\n */\nexport function generateSvgForOTP (canvasOptions) {\n let svgAllFormat = {};\n let top = canvasOptions.top;\n let left = canvasOptions.left;\n let customizeText = canvasOptions.customizeText;\n let customizeFont = canvasOptions.customizeFont;\n let customizeColor = canvasOptions.customizeColor;\n let imageToLoad = canvasOptions.imageToLoad;\n\n let newCanvas = new fabric.StaticCanvas('rebuildCanvas', {\n width: 2000,\n height: 3000,\n });\n\n const canvasRatio = 7.125; // canvas ratio calculated based on the design dimensions of the image (2000/355)\n let canvasText = new fabric.Textbox(customizeText, {\n top: top,\n left: left,\n originX: 'center',\n originY: 'center',\n width: canvasRatio * 48,\n fontSize: canvasRatio * 10,\n lineHeight: canvasRatio * 15,\n fontFamily: customizeFont,\n textAlign: 'center',\n fill: customizeColor,\n });\n\n let img = $(imageToLoad)[0];\n let canvasImage = new fabric.Image(img, {\n top: 0,\n selectable: false,\n hasRotatingPoint: true,\n width: 2000,\n height: 3000\n });\n canvasImage.scaleToWidth(2000);\n\n let canvasGroup = new fabric.Group([canvasImage, canvasText], {});\n newCanvas.add(canvasGroup);\n\n // FULL TEXT SVG\n svgAllFormat.personalizationFullSVG = createSvgFromCanvas(newCanvas);\n\n // HALF SIZE SVG\n let scaleRatio = Math.min(0.5);\n newCanvas.setDimensions({ width: newCanvas.getWidth() * scaleRatio, height: newCanvas.getHeight() * scaleRatio });\n newCanvas.setZoom(scaleRatio);\n svgAllFormat.personalizationSmallSVG = createSvgFromCanvas(newCanvas);\n\n // ONLY TEXT SVG\n canvasGroup.remove(canvasImage);\n newCanvas.clear();\n newCanvas.add(canvasGroup);\n let personalizationTextSVG = createSvgFromCanvas(newCanvas);\n svgAllFormat.personalizationTextSVG = personalizationTextSVG;\n\n return svgAllFormat;\n}\n","const SELECTORS = {\n page: '.js-customizePage',\n personalizationCanvas: '#personalization-canvas',\n mainChoice: '.js-sectionMainChoice',\n imgFront: '#img-object-front',\n imgBack: '#img-object-back',\n pixelText: '#pixel-text',\n canvasNode: '.js-customize-canvas',\n textInput: '.js-input-type1',\n fontsButtons: '.js-choice-editor .cc-choice-item',\n colorsButtons: '.js-choice-editor .cc-choice-pattern_item',\n showOtherSide: '.js-show-other-side',\n hotspotOne: '.js-customizePage .js-positionChoice-1',\n hotspotTwo: '.js-customizePage .js-positionChoice-2',\n stepOne: '.js-customize-step1',\n stepTwo: '.js-customize-step2',\n termsBottomDesktop: 'js-termsCondition--bottom-desktop',\n footer: '.js-customize-footer',\n zoomButton: '.js-zoom-button',\n termsAndConditionsModal: '.js-linkModalCustomizeTerms',\n analyticsCustomizeAction: '.js-analyticsCustomizeAction',\n pageClose: '.js-customizePage-icon_pageClose',\n personalizeAddToCart: '.js-personalizeButtonModal',\n};\n\nexport default SELECTORS;\n","const CLASSES = {\n active: 'active',\n pageStepOne: 'cc-customizePage--step-one',\n pageStepTwo: 'cc-customizePage--step-two',\n};\n\nexport default CLASSES;\n","import ProductHelpers, {activatePromoAnimationMessage} from './base';\nimport {newModal, newModalFromString} from '../components/modal';\nimport {initSlotCarousel, initProductTile} from '../productTileComponent/productTile';\nimport {checkCarouselLength} from '../customCarousel';\n\nfunction isPortionOfElementInContainer(el, container) {\n const rect = el.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n // DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 }\n const windowHeight =\n (window.innerHeight || document.documentElement.clientHeight) - containerRect.top;\n // http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap\n const vertInView = rect.top <= windowHeight && rect.top + 0.66 * rect.height >= 0;\n return vertInView;\n}\n\nfunction computeCurrentlyVisibleImage() {}\n\nconst handleDetailsTabs = (clickedTab) => {\n $('.js-detailsPopup-tabContent, .js-detailsPopup-tabLink').removeClass('cc-currentTab');\n $(\n '.js-detailsPopup-tabContent#' +\n clickedTab +\n ', .js-detailsPopup-tabLink[data-tab=' +\n clickedTab +\n ']'\n ).addClass('cc-currentTab');\n};\n\nconst openQuickView = (url, modalClass) => {\n const modal = newModal(false, ['quickview-modal']);\n $.ajax({\n url: url,\n method: 'GET',\n dataType: 'json',\n success: (html) => {\n modal.setContent(html.renderedTemplate);\n if (Foundation.MediaQuery.atLeast('large')) {\n $('.product-quickview .carousel-inner').slick({\n arrows: true,\n dots: false,\n slidesToShow: 1,\n });\n }\n\n // QuickView\n $('.product-quickview .js-carousel-select-color-quickview')\n .slick({\n slidesToShow: 6,\n slidesToScroll: 2,\n infinite: false,\n responsive: [\n {\n breakpoint: 769,\n settings: {\n slidesToShow: 10,\n slidesToScroll: 2,\n },\n },\n {\n breakpoint: 640,\n settings: {\n slidesToShow: 6,\n slidesToScroll: 2,\n },\n },\n ],\n })\n .slick('setPosition');\n\n $('body').trigger('product:crossSellLoaded', true);\n\n $('.product-quickview .js-carousel-select-size')\n .slick({\n slidesToShow: 1.2,\n slidesToScroll: 1,\n infinite: false,\n })\n .slick('setPosition');\n\n if (modalClass) {\n $(modal.modalBox).find('.product-quickview').addClass(modalClass);\n }\n\n modal.open();\n $(modal.modalBox)\n .find('.close-custom')\n .on('click', function (e) {\n modal.close();\n modal.destroy();\n });\n $('body').on('product:afterAddToCart', function (data) {\n modal.close();\n modal.destroy();\n });\n },\n error: (err) => {\n console.log('Error:', err);\n },\n });\n};\n\nconst setMinHeightPromoPanel = (container) => {\n var _array = [];\n $(container)\n .find('div.promo-message.js-promo-container')\n .each(function () {\n _array.push($(this).innerHeight());\n });\n var maxHeight = Math.max.apply(Math, _array);\n $(container)\n .find('div.promo-message.js-promo-container')\n .each(function () {\n $(this).css('min-height', maxHeight);\n });\n\n var _array2 = [];\n $(container)\n .find('.product-tile__name')\n .each(function () {\n _array2.push($(this).innerHeight());\n });\n var maxHeightTitle = Math.max.apply(Math, _array2);\n $(container)\n .find('.product-tile__name')\n .each(function () {\n $(this).css('min-height', maxHeightTitle);\n });\n};\n\nconst getProductVariationGroup = (product, type) => {\n if (typeof product === 'string') {\n return product.trim();\n }\n\n if (type === 'size') {\n return product.id;\n }\n\n // size and color have already been selected. In this case, the variation\n // group is built with the style of the product, 'color' and the selected\n // color variation\n let pid = '';\n if (product.productType === 'variant') {\n pid = product.id.split(' ')[0].trim();\n } else if (product.productType === 'variationGroup') {\n // in this case the user only chose the color, and not the size\n pid = product.id.split('_')[0].trim();\n }\n let selectedVariation;\n\n for (let k in product.variationAttributes) {\n const variationAttribute = product.variationAttributes[k];\n if (variationAttribute.attributeId === 'color') {\n for (let j in variationAttribute.values) {\n if (variationAttribute.values[j].selected === true) {\n selectedVariation = variationAttribute.values[j].value;\n break;\n }\n }\n }\n // If a size is selected and selectable, retrieve its recommendation instead of variant color's one\n if (variationAttribute.attributeId === 'size') {\n for (let j in variationAttribute.values) {\n if (\n variationAttribute.values[j].selected === true &&\n variationAttribute.values[j].selectable === true\n ) {\n return product.id;\n }\n }\n }\n }\n\n return pid + '_color_' + selectedVariation;\n};\n\nconst crossSellItems = (product, type) => {\n if (!document.getElementById('crossSellItemsBaseUrl')) {\n return;\n }\n const pid = getProductVariationGroup(product, type);\n let requestUrl = document.getElementById('crossSellItemsBaseUrl').value;\n let isSizeChange = type === 'size';\n const promotionId = $('.marketing-messages.pdp .marketing-budge').data('promotion-id');\n $.ajax({\n url: requestUrl,\n method: 'GET',\n data: {\n pid: pid,\n promotionId: promotionId,\n },\n success: (data) => {\n const $result = $(data);\n\n const $completePromoData = $result.find('#completePromoProducts');\n const $completePromoSection = $('.js-completePromo');\n const $completePromoProducts = $completePromoSection.find('.crossSellContainer');\n $completePromoProducts.empty();\n if ($completePromoData.length) {\n $completePromoProducts.empty().append($completePromoData.html());\n $completePromoSection\n .find('.promo-budge-container')\n .empty()\n .append($('.marketing-messages.pdp .marketing-budge:first').text().trim());\n const $completePromoContainer = $result.find('#completePromoContainer');\n if ($completePromoContainer.length) {\n $completePromoSection\n .find('.js-completePromo-grid-info-description')\n .removeClass('hidden')\n .html($completePromoContainer.find('.js-promoDetails-description').html());\n $completePromoSection\n .find('.js-completePromo-grid-info-budge')\n .removeClass('hidden')\n .html($completePromoContainer.find('.js-promoDetails-calloutMsg').html());\n } else {\n $completePromoSection.find('.promo-more-info').addClass('hidden');\n }\n $completePromoSection.removeClass('hidden');\n checkCarouselLength('.js-promoCarousel');\n } else {\n $completePromoSection.addClass('hidden');\n }\n\n const $completeLookData = $result.find('#completeLookProducts');\n const $completeLookSection = $('.js-completeLook');\n const $completeLookProducts = $completeLookSection.find('.crossSellContainer');\n $completeLookProducts.empty();\n if ($completeLookData.length) {\n $completeLookProducts.empty().append($completeLookData.html());\n $completeLookSection.removeClass('hidden');\n checkCarouselLength('.js-lookCarousel');\n } else {\n $completeLookSection.addClass('hidden');\n }\n\n if ($completePromoData.length && $completeLookData.length) {\n $('.recommended-products-pdp').addClass('hidden');\n } else {\n $('.recommended-products-pdp').removeClass('hidden');\n }\n\n $('body').on(\n 'click',\n '.js-completePromo .crossSellContainer .js-pdp-link, .js-completeLook .crossSellContainer .js-pdp-link',\n (evt) => {\n // Open QuickView only not mobile\n\n evt.preventDefault();\n const url = evt.currentTarget.dataset.quickview;\n // Completa il tuo look\n let modalClass;\n if ($(evt.currentTarget).closest('.js-completeLook').length) {\n modalClass = 'complete-look-quick-view';\n }\n openQuickView(url, modalClass);\n\n /*\n else {\n if ($(evt.currentTarget).closest('.product').find('.add-to-cart-quick-add').attr('data-size-available') !== 'true') {\n evt.preventDefault();\n evt.stopPropagation();\n $(evt.currentTarget).closest('.product').find('.product-detail-quick-add').find('.js-panel-opener-size-quick-add').trigger('click', { mustAdd: true });\n }\n }\n */\n }\n );\n\n $('.js-completeLook .product-detail-quick-add .add-to-cart-quick-add').on(\n 'click',\n (e) => {\n if (\n $(e.currentTarget).attr('data-size-available') !== 'true' &&\n Foundation.MediaQuery.is('large')\n ) {\n e.preventDefault();\n e.stopPropagation();\n $(e.currentTarget)\n .closest('.product-detail-quick-add')\n .find('.js-panel-opener-size-quick-add')\n .trigger('click', {mustAdd: true});\n } else if (!Foundation.MediaQuery.is('large')) {\n e.preventDefault();\n e.stopPropagation();\n openQuickView(\n $(e.currentTarget)\n .closest('.product')\n .find('.js-pdp-link')\n .data('quickview'),\n 'complete-look-quick-view'\n );\n }\n }\n );\n\n setTimeout(function () {\n setMinHeightPromoPanel('.js-completePromo');\n setMinHeightPromoPanel('.js-completeLook');\n }, 300);\n $('body').trigger('product:crossSellLoaded', isSizeChange);\n },\n error: () => {\n $.spinner().stop();\n $('body').trigger('product:crossSellError');\n },\n });\n};\n\nconst openCurtain = () => {\n $('.overlay-pdp-mobile').show();\n $('#esw-fab').addClass('ui-eswback');\n};\n\nconst closeCurtain = () => {\n $('.overlay-pdp-mobile').hide();\n $('#esw-fab').removeClass('ui-eswback');\n};\n\nfunction closeAllOpenMenus() {\n if (Foundation.MediaQuery.atLeast('medium')) {\n return;\n }\n // Close open menus\n $('.js-select-size-for-mobile').addClass('hidden').removeClass('open');\n $('.js-select-color-for-mobile').addClass('hidden').removeClass('open');\n $('.js-panel-opener-color').removeClass('on');\n $('.js-panel-opener-size').removeClass('on');\n closeCurtain();\n}\n\nfunction removeNulls(el) {\n var price = el.find('.analytics').data('price');\n if (\n !price ||\n price == null ||\n price === 'null' ||\n price === '' ||\n price === 0 ||\n price == '0.00'\n ) {\n el.css('display', 'none');\n return true;\n }\n return false;\n}\n\nconst updatePrimaryImagesSlide = () => {\n let height = $('.primary-images .slick-active').outerHeight();\n $('.primary-images .slick-list').outerHeight(height);\n $('#miniatureVerticalImg .slide').removeClass('active');\n let index = $('.primary-images .slick-active').data('index');\n $(`#miniatureVerticalImg .slide[data-index=\"${index}\"]`).addClass('active');\n};\n\nconst enableImageSlideHeightObservers = () => {\n let imgNode = $('.primary-images .slick-list .carousel-item:first-child img');\n if (imgNode.length) {\n let config = {attributes: true, childList: true, subtree: true};\n let callback = function (mutationsList, observer) {\n for (let index = 0; index < mutationsList.length; index++) {\n let mutation = mutationsList[index];\n if (\n mutation.type === 'attributes' &&\n mutation.attributeName === 'class' &&\n mutation.target.classList.contains('lazyloaded')\n ) {\n updatePrimaryImagesSlide();\n }\n }\n };\n let observer = new MutationObserver(callback);\n observer.observe(imgNode[0], config);\n }\n let slickNode = $('.primary-images .slick-track');\n if (slickNode.length) {\n let config = {attributes: true, childList: true, subtree: true};\n let callback = function (mutationsList, observer) {\n for (let index = 0; index < mutationsList.length; index++) {\n let mutation = mutationsList[index];\n if (mutation.type === 'attributes' && mutation.attributeName === 'style') {\n updatePrimaryImagesSlide();\n }\n }\n };\n let observer = new MutationObserver(callback);\n observer.observe(slickNode[0], config);\n }\n};\n\nconst destroyPrimaryImagesSlider = () => {\n if (\n Foundation.MediaQuery.is('medium') &&\n $('.product-detail-keeper').length &&\n !$('.product-quickview.product-detail').length &&\n $('.primary-images').hasClass('slick-initialized')\n ) {\n $('.primary-images')\n .off('afterChange', updatePrimaryImagesSlide)\n .off('init', enableImageSlideHeightObservers)\n .slick('unslick');\n }\n};\n\nconst initializePrimaryImagesSlider = () => {\n if (\n $('.product-detail-keeper').length &&\n !$('.product-quickview.product-detail').length &&\n !$('.primary-images').hasClass('slick-initialized')\n ) {\n $('.primary-images').slick({\n arrows: false,\n dots: true,\n infinite: false,\n draggable: true,\n slidesToShow: 1,\n slidesToScroll: 1,\n responsive: [\n {\n breakpoint: 1023,\n settings: {\n slidesToShow: 1.4,\n slidesToScroll: 1,\n },\n },\n {\n breakpoint: 765,\n settings: {\n slidesToShow: 1.07,\n slidesToScroll: 1,\n },\n },\n ],\n });\n }\n\n const disableAutoScroll = () => {\n $('.primary-images').slick('slickPause');\n $('body').off('touchstart', this);\n };\n $('body').on('touchstart', disableAutoScroll);\n};\n\nconst updatePrimaryImagesSlider = (primaryImages) => {\n if (\n Foundation.MediaQuery.is('medium') &&\n $('.product-detail-keeper').length &&\n !$('.product-quickview.product-detail').length\n ) {\n initializePrimaryImagesSlider();\n let carouselItems = $('.primary-images .carousel-item');\n if (carouselItems.length) {\n for (let i = primaryImages.length; i < carouselItems.length; i++) {\n $('.primary-images').slick('slickRemove', primaryImages.length);\n }\n }\n }\n};\n\nclass Product {\n run() {\n ProductHelpers.run();\n // this.updateAttributesAndDetails();\n this.showSpinner();\n this.updateAttribute();\n this.updateAddToCart();\n this.updateAvailability();\n // this.sizeChart();\n this.getCrossSellItems();\n this.afterUpdateImages();\n this.recentlyViewedItems();\n this.buyNowQuichview();\n this.suggedtedProductsPDP();\n this.observeCurtainTap();\n this.removeNullCrossSell();\n this.pdpCrossSell();\n this.handleAccordionsInPDP();\n this.changeAddToBagButton();\n initializePrimaryImagesSlider();\n }\n\n changeAddToBagButton() {\n $('body').on('click', '.js-add-to-cart', function (e) {\n var button = $(this);\n\n $('body').on('product:afterAddToCart', function () {\n button.addClass('clicked');\n setTimeout(() => {\n button.removeClass('clicked');\n }, 3000);\n });\n });\n }\n\n removeNullCrossSell() {\n $('body').on('product:crossSellLoaded', function (e) {\n let $container = $('.js-completePromo .crossSellContainer');\n let index = 0;\n let items = $container.find('.js-cross-product').length;\n $container.find('.js-cross-product').each(function () {\n if (removeNulls($(this))) {\n index++;\n }\n });\n if (index == items) {\n $('.js-completePromo').addClass('hidden');\n }\n\n $container = $('.js-completeLook .crossSellContainer');\n index = 0;\n items = $container.find('.js-cross-product').length;\n $container.find('.js-cross-product').each(function () {\n if (removeNulls($(this))) {\n index++;\n }\n });\n if (index == items) {\n $('.js-completeLook').addClass('hidden');\n }\n });\n $('body').on(\n 'listing:einsteinloadedSuggestedProducts listing:einsteinloaded',\n function (e) {\n let $container = $('.js-em__carouselCustom');\n let index = 0;\n $container.find('.cc-emCarouselEditProd__item').each(function () {\n if (removeNulls($(this))) {\n index++;\n }\n });\n if (index > 0) {\n localStorage.setItem('suggestedProductsWithNullPrice', index);\n }\n setMinHeightPromoPanel('.recommended-products-pdp');\n }\n );\n $('body').on('listing:einsteinloadedSuggestedProducts', function (e) {\n let $container = $('.js-em__carouselCustom');\n let index = 0;\n $container.find('.cc-emCarouselEditProd__item').each(function () {\n if (removeNulls($(this))) {\n index++;\n }\n });\n if (index > 0) {\n localStorage.setItem('suggestedProductsWithNullPrice', index);\n }\n setMinHeightPromoPanel('.recommended-products-pdp');\n });\n if ($('.suggested-products-slider.slick-initialized').length) {\n $('body').trigger('listing:einsteinloadedSuggestedProducts', {\n container: '.suggested-products-slider',\n type: 'suggested-products',\n });\n }\n }\n\n observeCurtainTap() {\n $('.overlay-pdp-mobile').on('click', function (e) {\n if ($(this).css('display') !== 'none' && !Foundation.MediaQuery.atLeast('medium')) {\n closeAllOpenMenus();\n }\n });\n }\n\n recentlyViewedItems() {\n $('body').on('click', '.recentlyviewed .js-pdp-link', (evt) => {\n if (Foundation.MediaQuery.is('medium')) {\n evt.preventDefault();\n const url = evt.currentTarget.dataset.quickview;\n openQuickView(url);\n\n // trigger for analytics product detail event\n const target = $(evt.currentTarget).closest('.product');\n if (target.length > 0) {\n $('body').trigger('product:analyticsProductDetails', target);\n }\n }\n });\n }\n\n buyNowQuichview() {\n $('body').on('click', 'button.add-to-cart-quick-view', (e) => {\n e.preventDefault();\n openQuickView($(e.currentTarget).data('url'));\n });\n }\n\n suggedtedProductsPDP() {\n $('body').on('click', '.pdp-recommendations .js-pdp-link', (e) => {\n const $buyNowCta = $(e.currentTarget)\n .closest('.product')\n .find('.add-to-cart-quick-view');\n if ($buyNowCta.length) {\n e.preventDefault();\n e.stopPropagation();\n $buyNowCta.trigger('click');\n }\n });\n }\n\n getCrossSellItems() {\n $('body').on('product:afterAttributeSelect', (e, data) => {\n if (data.container.hasClass('product-quickview')) {\n return;\n }\n if (data.type === 'color' || data.type === 'size') {\n crossSellItems(data.data.product, data.type);\n }\n });\n }\n\n afterUpdateImages() {\n $('body').on('product:afterAttributeSelect', (e) => {\n computeCurrentlyVisibleImage(e);\n });\n }\n\n showSpinner() {\n $('body').on('product:beforeAddToCart product:beforeAttributeSelect', () => {\n $.spinner().start();\n });\n }\n\n updateAttribute() {\n $('body').on('product:afterAttributeSelect', (e, response) => {\n if ($('.product-detail>.bundle-items').length) {\n response.container.data('pid', response.data.product.id);\n response.container.find('.product-id').text(response.data.product.id);\n } else if ($('.product-set-detail').eq(0)) {\n response.container.data('pid', response.data.product.id);\n response.container.find('.product-id').text(response.data.product.id);\n } else {\n $('.product-id').text(response.data.product.id);\n $('.product-detail:not(\".bundle-item\")').data('pid', response.data.product.id);\n }\n });\n }\n\n updateAddToCart() {\n $('body').on('product:updateAddToCart', function (e, response) {\n if (\n $('.page').data('action') === 'Product-Show' &&\n !response.product.comingSoon &&\n !response.product.availability.orderable &&\n !response.product.availability.available\n ) {\n $('button.js-add-to-cart', '#fis-select-size').prop('disabled', true);\n $('button.js-add-to-cart', '#fis-select-size').data('disabled', true);\n return;\n }\n $('button.js-add-to-cart, button.add-to-cart-global').prop(\n 'disabled',\n !response.product.available || response.product.comingSoon\n );\n $('button.js-add-to-cart, button.add-to-cart-global').data(\n 'disabled',\n !response.product.readyToOrder\n );\n });\n }\n\n pdpCrossSell() {\n $('.js-shopTheLook-button').on('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n let htmlContent = $('.pdp-buy-look-container').html();\n const modal = newModalFromString(htmlContent, false, [\n 'cc-pdpCrossSell',\n 'js-pdpCrossSell',\n ]);\n $(modal.modalBox).addClass(\n 'rightModalAttribute cc-pdpCrossSell-modalBox rightModalAttribute_sizeLarge'\n );\n modal.open();\n initProductTile();\n\n $(modal.modalBox).on('click', '.js-pdpCrossSell-close', (e) => {\n e.preventDefault();\n modal.close();\n modal.destroy();\n });\n $(modal.modalBox).on('click', '.color-variation', (e) => {\n e.preventDefault();\n modal.close();\n modal.destroy();\n });\n\n $('body').trigger('product:buyLookBtnAnalytics', true);\n });\n\n $('.pdp-buy-look-container').on('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n $('.js-shopTheLook-button').removeClass('hidden');\n $('.embedded-service').removeClass('hide-for-STL');\n $('.img-wrapper .cell.hide-for-large > .icon-container').css('opacity', '1');\n $('.pdp-buy-look-container').addClass('hidden');\n });\n\n $('.pdp-buy-look-container').on('click', '.cross-sell-item', (e) => {\n e.preventDefault();\n e.stopPropagation();\n openQuickView($(e.currentTarget).data('url'));\n });\n\n $('body').on('product:afterAttributeSelect', (e, d) => {\n if (d.type !== 'color' || d.container.hasClass('product-quickview')) {\n return;\n }\n $('.js-shopTheLook-button').addClass('hidden');\n $('.pdp-buy-look-container').addClass('hidden');\n var pdpCrossSell = d.data.product.pdpCrossSell;\n if (!pdpCrossSell) {\n return;\n }\n\n $('.cross-sell-item').addClass('hidden');\n pdpCrossSell.forEach((cs, i) => {\n const $csItem = $(`.cross-sell-item[data-index=\"${i}\"]`);\n $csItem.data('url', cs.url);\n $csItem.find('.image').attr('src', cs.image);\n $csItem.find('.name').text(cs.name);\n $csItem.removeClass('hidden');\n });\n $('.js-shopTheLook-button').removeClass('hidden');\n });\n }\n\n updateAvailability() {}\n\n handleAccordionsInPDP() {\n if ($('.js-intProductDetail-details').length > 0) {\n if (!Foundation.MediaQuery.atLeast('large')) {\n /* Shipping accordion */\n if ($('.js-details-accordion_shipping').length > 0) {\n var $detailsAccordionShipping = $('.js-details-accordion_shipping');\n $('.js-details-shipping-content', $detailsAccordionShipping)\n .removeClass('accordion-content-visible')\n .addClass('accordion-content');\n $('.js-details-title', $detailsAccordionShipping).addClass('accordion-title');\n }\n /* Description accordion */\n if ($('.js-details-accordion_description').length > 0) {\n var $detailsAccordionDescription = $('.js-details-accordion_description');\n $('.js-details-description-content', $detailsAccordionDescription)\n .removeClass('accordion-content-visible')\n .addClass('accordion-content');\n $('.js-details-title', $detailsAccordionDescription).addClass(\n 'accordion-title'\n );\n }\n } else {\n $('.js-accordionDetails')\n .removeClass('accordion-title')\n .on('click', function (e) {\n const htmlContent = $('.js-detailsPopup').html();\n const modal = newModalFromString(htmlContent, false, ['cc-detailsPopup']);\n $(modal.modalBox).addClass(\n 'rightModalAttribute cc-detailsPopup-modalBox rightModalAttribute_sizeMedium'\n );\n\n handleDetailsTabs($(e.currentTarget).data('tab'));\n\n modal.open();\n\n if ($('.pdp-size-box').hasClass('size-selected')) {\n $('#main-and-care-label').addClass('hidden');\n }\n\n $('.js-detailsPopup-tabLink').on('click', function (e) {\n handleDetailsTabs($(e.currentTarget).data('tab'));\n });\n\n $(modal.modalBox)\n .find('.js-detailsPopup-close')\n .on('click', function () {\n $(modal.modalBox)\n .addClass('cc-modalClosing')\n .on(\n 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd',\n function () {\n modal.close();\n }\n );\n });\n });\n }\n }\n }\n}\n\nconst product = new Product();\nexport default product;\nexport {\n crossSellItems,\n computeCurrentlyVisibleImage,\n activatePromoAnimationMessage,\n closeAllOpenMenus,\n initializePrimaryImagesSlider,\n updatePrimaryImagesSlider,\n destroyPrimaryImagesSlider,\n};\n","'use strict';\nimport {\n newModalFromString,\n newModalFromSelector\n} from '../components/modal';\nimport ProductHelpers from './base';\nimport sizePanel from './sizePanel';\n\nclass SmartGiftHelper {\n constructor () {\n this.basketBeforeRemovedProduct = [];\n this.basketObserverEnabled = false;\n this.basketAlreadyFetched = false;\n }\n\n run () {\n $('body').on('click', '.js-smart-gift', (e) => {\n let pid = ProductHelpers.methods.getPidValue($(e.currentTarget));\n if (!ProductHelpers.isSizeSelected()) {\n sizePanel.openSizePanel(sizePanel.Types.SMARTGIFT);\n } else {\n this.addSmartGift(pid);\n this.enableAnalyticsBasketObserver();\n }\n });\n\n let analyticsDataButton = {\n action: '',\n skus: '',\n quantity: ''\n };\n let basketButtonsSelector = '.sidebar-widget .sidebar-continue-shopping-button,';\n basketButtonsSelector += '.sidebar-widget .widget-summary-button';\n $('body').on('click', basketButtonsSelector, (event) => {\n if (SGBasket) {\n if ($(event.currentTarget).hasClass('sidebar-continue-shopping-button')) {\n analyticsDataButton.action = 'continue_shopping';\n } else if ($(event.currentTarget).hasClass('widget-summary-button')) {\n analyticsDataButton.action = 'prepare_my_gift';\n }\n analyticsDataButton.skus = this.getSkus();\n analyticsDataButton.quantity = this.getSkusQuantity();\n $('body').trigger('analytics:smartGiftBasketButtons', analyticsDataButton);\n }\n });\n\n $('body').on('click', '.sidebar-widget .SGBasketButton', () => {\n if (SGBasket) {\n $('body').trigger('analytics:smartGiftBasketIcon');\n }\n });\n\n $('body').on('click', '.smart-gift-rules-label, .js-smart-gift-rules', () => {\n $('body').trigger('analytics:smartGiftMoreInfo');\n });\n };\n\n addRecommendedItems(data){\n var eachSuggestion = $('.box-complete-yourlook .product');\n let dataSuggestion = [];\n var suggestionLength = eachSuggestion.length > 3 ? 3 : eachSuggestion.length;\n for (var i = 0; i < suggestionLength; i++){\n let suggestionItem = {};\n let infoSuggestion = eachSuggestion[i].querySelector('.productListingItem');\n let imgSuggestion = eachSuggestion[i].querySelector('.tile-image');\n let hrefSuggestion = eachSuggestion[i].querySelector('.product-tile');\n suggestionItem.skuCode = eachSuggestion[i].dataset.pid.replace('~', '/');\n suggestionItem.name = imgSuggestion.title;\n suggestionItem.price = infoSuggestion.dataset.price;\n suggestionItem.skuUrl = hrefSuggestion.href;\n suggestionItem.image = imgSuggestion.src || imgSuggestion.dataset.src;\n dataSuggestion.push(suggestionItem);\n }\n data.recommendedItems = dataSuggestion;\n };\n\n addSmartGift(pid){\n let data = {};\n data.skuCode = pid.replace('~', '/');\n data.name = $('h1[itemprop=\"name\"]').text();\n data.price = $('.product.analytics').data('price');\n data.skuUrl = window.location.href;\n data.image = $('.still-life-img').data('still-life');\n let nameEng = $('.product.analytics').data('name');\n data.nameEng = nameEng;\n\n this.addRecommendedItems(data);\n\n SGBasket.addItem(data);\n console.log(data);\n $('body').trigger('analytics:addSmartGift', { sku: data.skuCode, name: nameEng });\n };\n\n getSkus () {\n let skus = [];\n SGBasket.state.basket.forEach((element) => {\n skus.push(element.skuCode);\n });\n return skus;\n };\n\n getSkusQuantity () {\n return SGBasket.state.basket.length;\n };\n\n getBasket () {\n let basket = [];\n if (SGBasket) {\n SGBasket.state.basket.forEach((element) => {\n basket.push(element);\n });\n return basket;\n }\n };\n\n setAnalyticsProductIndex () {\n $('.product-list .sc-bxivhb .product-item-text-rmv').each(function (index) {\n $(this).attr('data-analytics-product-index', index);\n });\n };\n\n triggerRemoveProduct (removedProduct) {\n let productUrl = $('.product-detail.product-wrapper').data('variationInfo').replace('PID_PLACEHOLDER', removedProduct.skuCode);\n let nameEng = '';\n $.get({\n url: productUrl,\n success: data => {\n if (data.product && data.product.nameEng) {\n nameEng = data.product.nameEng;\n }\n $('body').trigger('analytics:smartGiftBasketRemoveProduct', {productName: nameEng, sku: removedProduct.skuCode});\n },\n error: function () {\n $.spinner().stop();\n }\n });\n };\n\n enableAnalyticsBasketObserver() {\n if (SGBasket && !this.basketObserverEnabled) {\n this.basketObserverEnabled = true;\n let targetWidgetNode = $('.SGBasket-widget')[0];\n if (targetWidgetNode) {\n let config = { attributes: true, childList: true, subtree: true };\n let _self = this;\n let callback = function (mutationsList, observer) {\n for (let index = 0; index < mutationsList.length; index++) {\n let mutation = mutationsList[index];\n if (mutation.type === 'attributes' &&\n mutation.target.nodeName === 'DIV' &&\n $(mutation.target).hasClass('showOverview') &&\n $(mutation.target).hasClass('show') &&\n !_self.basketAlreadyFetched) {\n _self.basketAlreadyFetched = true;\n _self.setAnalyticsProductIndex();\n _self.basketBeforeRemovedProduct = _self.getBasket();\n const clickedProduct = function (event) {\n event.stopImmediatePropagation();\n let productIndex = $(this).data('analyticsProductIndex');\n let removedProduct = _self.basketBeforeRemovedProduct.splice(productIndex, 1)[0];\n _self.triggerRemoveProduct(removedProduct);\n };\n $('.product-list .product-item-text-rmv').on('click', clickedProduct);\n } else if (mutation.type === 'attributes' &&\n mutation.target.nodeName === 'DIV' &&\n $(mutation.target).hasClass('showOverview') &&\n $(mutation.target).hasClass('hide')) {\n _self.basketAlreadyFetched = false;\n }\n }\n };\n let observer = new MutationObserver(callback);\n observer.observe(targetWidgetNode, config);\n }\n }\n };\n}\n\nconst smartGiftHelper = new SmartGiftHelper();\nexport default smartGiftHelper;\n","import { ModalShowHide } from '../components/modal';\n\nclass SizePanel {\n #mobileSizeModal;\n Types = {\n ADDTOCART: 'add_to_cart',\n ADDTOCART_BUNDLE: 'add_to_cart_bundle',\n PERSONALIZE: 'personalize',\n WISHILIST: 'wishlist',\n SMARTGIFT: 'smartgift'\n }\n\n init (idName = '#size-panel-mobile') {\n this.idName = idName\n this.#onPanelOpenerClick();\n this.#onNotifyMeSizeClicked();\n this.#onCloseSizeModalMobile();\n this.#mobileSizeModal = new ModalShowHide(this.idName);\n this.#mobileSizeModal.hide();\n }\n\n openSizePanel (operation) {\n if (Foundation.MediaQuery.atLeast('large')) {\n $('.js-page-size-box').addClass('cc-sizeBox-isOpen');\n } else {\n this.#mobileSizeModal.show();\n }\n $(this.idName).data('operation', operation);\n if (operation === this.Types.ADDTOCART_BUNDLE) {\n let $sizeElements = $(\"[data-attr='size'] input,[data-attr='size-mobile'] input\");\n let bundleQuantity = $('.js-add-to-cart-multipack').data('bundle-quantity');\n $sizeElements.each(function (element){\n if(parseInt($(this).attr('data-allocation'), 10) < parseInt(bundleQuantity, 10)) {\n $(this).closest('label').addClass('cc-no-bundle');\n }\n })\n } else {\n $('.cc-no-bundle').removeClass('cc-no-bundle');\n }\n if(operation === this.Types.WISHILIST) {\n $('.notifyMe,.wishlistOnly').addClass('select-size-for-wishlist');\n } else {\n $('.notifyMe,.wishlistOnly').removeClass('select-size-for-wishlist');\n }\n }\n\n #closeSizePanel () {\n if (Foundation.MediaQuery.atLeast('large')) {\n $('.pdp-size-box').removeClass('cc-sizeBox-isOpen');\n } else {\n this.#mobileSizeModal.hide();\n }\n $('.pdp-size-box .js-sizeBox-openPanel').removeClass('cc-sizeBox-openPanel_error');\n $('#newsletter-error-msg').hide();\n $(this.idName).data('operation', '');\n $('.notifyMe,.wishlistOnly').removeClass('select-size-for-wishlist');\n $('.cc-no-bundle').removeClass('cc-no-bundle');\n }\n\n #onPanelOpenerClick () {\n $('.pdp-size-box .js-sizeBox-openPanel').on('click', e => {\n if ($('.pdp-size-box').hasClass('cc-sizeBox-isOpen')) {\n this.#closeSizePanel();\n } else {\n this.openSizePanel();\n }\n });\n $('.js-pdpStickyBar-size-openPanel').on('click', e => {\n if ($('.js-pdpStickyBar-select').hasClass('cc-sizeBox-isOpen')) {\n $('.js-pdpStickyBar-select').removeClass('cc-sizeBox-isOpen');\n } else {\n $('.js-pdpStickyBar-select').addClass('cc-sizeBox-isOpen');\n }\n });\n }\n\n afterSizeSelection (data, type) {\n let operation = $(this.idName).data('operation');\n this.#closeSizePanel();\n let stopSpinner = true;\n let selectedSize = $('[data-attr=\"size\"] input:checked');\n if (!selectedSize.length) {\n $('.pdp-size-box').removeClass('size-selected');\n return stopSpinner;\n } else {\n $('#newsletter-error-msg').hide();\n }\n if (type !== 'size') {\n return stopSpinner;\n }\n let sizeDisplayValue = selectedSize.closest('label').find('.js-size-button__span').text();\n $('.pdp-size-box .js-sizeBox-openPanel').attr('aria-invalid', 'false');\n $('.pdp-size-box .selected-size-value').text(sizeDisplayValue);\n $('.pdp-size-box').addClass('size-selected');\n if ($('.js-add-to-cart-multipack').length > 0) {\n let bundleQuantity = $('.js-add-to-cart-multipack').data('bundle-quantity');\n if(parseInt($(selectedSize).attr('data-allocation'), 10) < parseInt(bundleQuantity, 10)) {\n $('.js-add-to-cart-multipack').attr('disabled', true);\n } else {\n $('.js-add-to-cart-multipack').removeAttr('disabled');\n }\n }\n\n stopSpinner = false;\n switch (operation) {\n case this.Types.ADDTOCART:\n $('#add-to-cart-cta-pdp').trigger('click');\n break;\n case this.Types.ADDTOCART_BUNDLE:\n $('#add-to-cart-multipack-cta-pdp').trigger('click');\n break;\n case this.Types.PERSONALIZE:\n $('#personalizeButton .persButt').trigger('click');\n break\n case this.Types.WISHILIST:\n $('body').trigger('wishlist:add-pid', {pid: data.product.id});\n break;\n case this.Types.SMARTGIFT:\n $('.add-to-cart-actions .js-smart-gift').trigger('click');\n $('#smartgiftButton').trigger('click');\n break;\n default:\n stopSpinner = true;\n }\n return stopSpinner;\n }\n\n #onNotifyMeSizeClicked () {\n const _self = this;\n $('.notifyMe,.wishlistOnly').on('click', (e) => {\n if (!$(e.currentTarget).hasClass('select-size-for-wishlist')) {\n return;\n }\n e.preventDefault();\n e.stopPropagation();\n $.spinner().start();\n const infoURL = $(e.currentTarget).closest('label').find('input').data('url');\n $.ajax({\n url: infoURL,\n type: 'get',\n dataType: 'json',\n success: function (data) {\n if (data.product.readyToOrder) {\n if ($(e.currentTarget).hasClass('wishlistOnly')) {\n let sizeDisplayValue = $(e.currentTarget).closest('label').find('.size-list-item-display-value').text();\n $('.pdp-size-box .selected-size-value').text(sizeDisplayValue);\n $('.pdp-size-box').addClass('size-selected');\n }\n const pid = encodeURIComponent(data.product.id)\n $('body').trigger('wishlist:add-pid', {pid: pid});\n } else {\n $.spinner().stop();\n _self.#closeSizePanel();\n }\n },\n error: function () {\n $.spinner().stop();\n _self.#closeSizePanel();\n }\n });\n });\n\n $('body').on('wishlist:update', () => {\n $.spinner().stop();\n _self.#closeSizePanel();\n });\n }\n\n #onCloseSizeModalMobile () {\n const _self = this;\n $('body').on('click', '.size-selector-mobile-modal', () => {\n _self.#closeSizePanel();\n });\n }\n}\n\nconst sizePanel = new SizePanel();\nexport default sizePanel;\n","'use strict';\n\n/**\n * Replace the URL query string color during color selection update in PDP.\n * @param {string} needle parameter to detect the key, e.g. \"_COL_\", \"_COLORI_\", etc.\n * @param {string} color new color to be submitted\n */\nconst updateProductDetailUrl = (needle, color) => {\n // Build url object\n var urlObject = new URL(window.location.href);\n var queryString = urlObject.searchParams;\n\n // Retrieve exact key name to be replaced\n var qsKeyToUpdate;\n for (var qsKey of queryString.keys()) {\n var qsValue = queryString.get(qsKey);\n if (qsKey.toLowerCase().indexOf(needle) !== -1 && qsValue) {\n qsKeyToUpdate = qsKey;\n break;\n }\n }\n\n // Cancel action if key is not found\n if (!qsKeyToUpdate) {\n return;\n }\n\n // Push new value to querystring key obtained above\n urlObject.searchParams.set(qsKeyToUpdate, color);\n // Replace current URL with new\n window.history.replaceState(null, document.title, urlObject.href);\n};\n\nexport {\n updateProductDetailUrl\n};\n","'use strict';\n\nvar testEnabled = false;\n\nlet productGenderMap = {\n 1: 'Woman',\n 2: 'Man',\n 3: 'Girl',\n 4: 'Boy',\n 5: 'Unisex',\n 6: 'Baby'\n};\n\nlet brandsMapping = {\n 'CALZEDONIA': 'clz',\n 'INTIMISSIMI': 'int',\n 'TEZENIS': 'tzn',\n 'FALCONERI': 'flc',\n 'SIGNORVINO': 'sgv',\n 'ATELIER_EME': 'eme'\n};\n\nvar ListType = {\n 'listing': {\n 'class': 'category',\n 'value': 'listing',\n 'associatedObject': '.search-results'\n },\n 'wishlist': {\n 'class': 'wishlist-container',\n 'value': 'wishlist',\n 'associatedObject': '.wishlistItemCards'\n },\n 'search': {\n 'class': 'search',\n 'value': 'search',\n 'associatedObject': '.search-results'\n },\n 'completeYourLook': {\n 'class': 'completeYourLook',\n 'value': 'complete_your_look',\n 'associatedObject': '.completeYourLookContainer'\n },\n 'recentlyViewed': {\n 'class': 'recentlyViewed',\n 'value': 'recently_viewed',\n 'associatedObject': '.recentlyViewedContainer'\n },\n 'suggestedProducts': {\n 'class': 'suggestedProducts',\n 'value': 'suggested_products',\n 'associatedObject': '.suggestedProductsContainer'\n },\n 'filteredProducts': {\n 'class': 'filteredProducts',\n 'value': 'filter_applied',\n 'associatedObject': '.filteredProducts'\n },\n 'bestSellers': {\n 'class': 'bestSellers',\n 'value': 'best_sellers',\n 'associatedObject': '.bestSellers'\n },\n 'cmBestSellers': {\n 'class': 'cmBestSellers',\n 'value': 'best_sellers',\n 'associatedObject': '.cm-bestsellerCarousel-carouselWrapper .cm-carouselCustom.js-plp-productGrid'\n },\n 'sortDecreasing': {\n 'class': 'sortDecreasing',\n 'value': 'sorting_decreasing_price',\n 'associatedObject': '.sortDecreasing'\n },\n 'sortIncreasing': {\n 'class': 'sortIncreasing',\n 'value': 'sorting_increasing_price',\n 'associatedObject': '.sortIncreasing'\n },\n 'newArrivals': {\n 'class': 'newArrivals',\n 'value': 'new_arrivals',\n 'associatedObject': '.newArrivals'\n },\n 'cmNewArrivals': {\n 'class': 'cmNewArrivals',\n 'value': 'new_arrivals',\n 'associatedObject': '.cm-productCarousel-cardWrp.cm-carouselCustom'\n },\n 'completeYourLookMiniCart': {\n 'class': 'completeYourLookMiniCart',\n 'value': 'complete_your_look_minicart',\n 'associatedObject': '.miniCartCrossSellContainer-carousel'\n },\n 'js-suggestedForYou': {\n 'class': 'js-suggestedForYou',\n 'value': 'suggested_for_you',\n 'associatedObject': '.js-slotCarousel_suggestedProducts-carousel'\n },\n 'js-completeThePromo': {\n 'class': 'completeThePromo',\n 'value': 'complete_your_look',\n 'associatedObject': '.js-completeThePromoContainer'\n },\n 'js-youMayAlsoLike': {\n 'class': 'js-youMayAlsoLike',\n 'value': 'you_may_also_like',\n 'associatedObject': '.js-youMayAlsoLikeContainer'\n }\n};\n\nfunction getProductGender (product) {\n if (product.sapCategoryCode) {\n let categoryCode = product.sapCategoryCode;\n return productGenderMap[parseInt(categoryCode[categoryCode.length - 1])];\n }\n return '';\n}\n\nfunction insertParam (key, value) {\n key = encodeURI(key); value = encodeURI(value);\n\n var kvp = document.location.search.substr(1).split('&');\n\n var i = kvp.length; var x; while (i--) {\n x = kvp[i].split('=');\n\n if (x[0] === key) {\n x[1] = value;\n kvp[i] = x.join('=');\n break;\n }\n }\n\n if (i < 0) { kvp[kvp.length] = [key, value].join('='); }\n\n // this will reload the page, it's likely better to store this until finished\n document.location.search = kvp.join('&');\n}\n\nfunction hasParam (key) {\n key = encodeURI(key);\n\n return document.location.search.substr(1).indexOf(key) !== -1;\n}\n\nfunction getSkuCodes (sku) {\n if (sku.length >= 13) {\n let style = sku.substring(0, 9).trim();\n let color = sku.substring(9, 13).trim();\n let size = sku.substring(13).trim().replace('~', '/');\n return { id: style, color: color, size: size };\n } else {\n let color = sku.split('_')[1];\n return { id: sku, color: color };\n }\n}\n\nfunction formatStringForAnalytics (str) {\n return ('' + str).split(' ').join('_').toLowerCase().replace(/-/g, '_');\n}\n\nfunction formatStringProductPropertyIfExists (product, property, avoidFormatting = false) {\n if (property in product) {\n if (property === 'item_sfcc') {\n product[property] = '' + getFormatSkuForAnalytics(product[property]);\n } else if (avoidFormatting) {\n product[property] = '' + product[property];\n } else {\n product[property] = formatStringForAnalytics(product[property]);\n }\n }\n return product;\n}\n\n/* function formatStringProductPricePropertyIfExists (product, property, avoidFormatting = false) {\n if (property in product) {\n if (avoidFormatting) {\n product[property] = '' + product[property];\n } else {\n product[property] = formatStringForAnalytics(product[property]);\n }\n if (product['discount'] && product['discount'] < 0) {\n product[property] = '0.00';\n product['discount'] = 0.00;\n }\n }\n return product;\n} */\n\nfunction formatStringProductSalePropertyIfExists (product, property, avoidFormatting = false) {\n if (property in product) {\n if (avoidFormatting) {\n product[property] = '' + product[property];\n } else {\n product[property] = formatStringForAnalytics(product[property]);\n }\n if (product['discount'] && parseFloat(product['discount'])) {\n product[property] = 'yes';\n }\n }\n return product;\n}\n\nfunction formatFloatProductPropertyIfExists (product, property) {\n if (property in product) {\n product[property] = (product[property] <= 0) ? 0.00 : parseFloat(product[property]);\n }\n return product;\n}\n\nfunction formatIntegerForAnalytics (value) {\n return parseInt(value);\n}\n\nfunction formatIntegerProductPropertyIfExists (product, property) {\n if (property in product) {\n product[property] = formatIntegerForAnalytics(product[property]);\n }\n return product;\n}\n\nfunction stringOrNotAvailable (s) {\n return (s !== null && typeof s !== 'undefined' && String(s)) || 'not_available';\n}\n\nfunction numberOrZero (n) {\n return parseFloat(n) || 0;\n}\n\nfunction getStringAnalyticsValueFromStorage (key) {\n return stringOrNotAvailable(window.sessionStorage.getItem(key));\n}\n\nfunction getNumberAnalyticsValueFromStorage (key) {\n return numberOrZero(window.sessionStorage.getItem(key));\n}\n\nfunction getFormatSkuForAnalytics (sku) {\n let id, color, size, formattedSku;\n if (sku.toLowerCase().indexOf('color') !== -1) { // variant group\n id = sku.split('_')[0].trim();\n color = sku.split('_')[2].trim();\n formattedSku = id + '_' + color;\n } else {\n if (sku.match('[^_]+_[^_]+_[^_]+')) {\n return sku.toUpperCase();\n }\n let skuComponents = getSkuCodes(sku);\n id = skuComponents.id;\n color = skuComponents.color;\n size = skuComponents.size;\n if (color && size) {\n formattedSku = id + '_' + color + '_' + size;\n } else { // master product\n formattedSku = id;\n }\n }\n return formattedSku.toUpperCase().replace(/_+/g, '_');\n}\n\nmodule.exports = {\n\n isTestEnabled () {\n return testEnabled;\n },\n\n getAvailableListTypes (listingItemsBaseClass) {\n let types = [];\n\n for (let key in ListType) {\n if (ListType.hasOwnProperty(key)) {\n if ($(listingItemsBaseClass + '.' + ListType[key].class).length > 0) {\n let item = ListType[key];\n types.push(item);\n }\n }\n }\n\n return types;\n },\n\n getSkuComponents (sku) {\n return getSkuCodes(sku);\n },\n\n getProductGender (product) {\n return getProductGender(product);\n },\n\n getProductBaseInfo (product) {\n let id = '';\n let color = '';\n let size = '';\n\n let colorObject = null;\n\n let promo = 'no_promotion';\n if ('promotions' in product && product.promotions && product.promotions.length > 0) {\n promo = product.promotions.map(function (el) { return el.enabled ? el.id : null; }).filter(function (el) { return el !== null; }).join('-');\n } else if ('appliedPromotions' in product && product.appliedPromotions && product.appliedPromotions.length > 0) {\n promo = product.appliedPromotions.map(function (el) { return el.name; }).join('-');\n }\n\n if (product.productType === 'variant') {\n let components = getSkuCodes(product.id);\n id = components.id;\n color = components.color;\n size = components.size;\n\n for (let k in product.variationAttributes) {\n const variationAttribute = product.variationAttributes[k];\n if (variationAttribute.attributeId === 'color') {\n if ('values' in variationAttribute) {\n for (let j in variationAttribute.values) {\n if (variationAttribute.values[j].selected === true) {\n colorObject = variationAttribute.values[j];\n break;\n }\n }\n } else {\n colorObject = variationAttribute;\n }\n break;\n }\n }\n } else if (product.productType === 'variationGroup') {\n // in this case the user only chose the color, and not the size\n id = product.id.split('_')[0].trim();\n color = product.id.split('_')[2].trim();\n\n let selectedVariation;\n\n for (let k in product.variationAttributes) {\n const variationAttribute = product.variationAttributes[k];\n if (variationAttribute.attributeId === 'color') {\n for (let j in variationAttribute.values) {\n if (variationAttribute.values[j].selected === true) {\n colorObject = variationAttribute.values[j];\n break;\n }\n }\n }\n if (selectedVariation !== undefined) {\n break;\n }\n }\n }\n\n return {\n id: id,\n color: color,\n colorObject: colorObject,\n size: size,\n promo: promo\n };\n },\n\n formatProductForAnalytics (product) {\n product = formatStringProductPropertyIfExists(product, 'item_name');\n product = formatStringProductPropertyIfExists(product, 'item_brand');\n product = formatStringProductPropertyIfExists(product, 'item_list_name');\n product = formatStringProductPropertyIfExists(product, 'item_list_id');\n product = formatStringProductPropertyIfExists(product, 'item_variant', true);\n product = formatFloatProductPropertyIfExists(product, 'price');\n product = formatStringProductPropertyIfExists(product, 'item_category');\n product = formatStringProductPropertyIfExists(product, 'item_category2');\n product = formatStringProductPropertyIfExists(product, 'item_category3');\n product = formatStringProductPropertyIfExists(product, 'item_category4');\n product = formatStringProductPropertyIfExists(product, 'item_category5');\n product = formatIntegerProductPropertyIfExists(product, 'quantity');\n product = formatStringProductPropertyIfExists(product, 'size', true);\n product = formatStringProductSalePropertyIfExists(product, 'item_on_sale');\n product = formatStringProductPropertyIfExists(product, 'item_availability');\n product = formatStringProductPropertyIfExists(product, 'coupon');\n product = formatStringProductPropertyIfExists(product, 'item_color');\n product = formatStringProductPropertyIfExists(product, 'item_sfcc');\n product = formatStringProductPropertyIfExists(product, 'item_customization');\n product = formatStringProductPropertyIfExists(product, 'item_sustainable');\n product = formatFloatProductPropertyIfExists(product, 'discount');\n return product;\n },\n\n checkPage (str) {\n return window.location.href.toLowerCase().indexOf(str) !== -1;\n },\n\n // Formatting\n formatString (str) {\n return formatStringForAnalytics(str);\n },\n\n format4DigitNumber (number) {\n if (number < 0) {\n return '0000';\n } else if (number < 10) {\n return '000' + number;\n } else if (number < 100) {\n return '00' + number;\n } else if (number < 1000) {\n return '0' + number;\n }\n return number.toString();\n },\n\n // URL Parameters\n insertParameter (key, value) {\n insertParam(key, value);\n },\n existsParameter (key) {\n return hasParam(key);\n },\n\n // Push on DataLayer\n push (pushObject, log = true) {\n // eslint-disable-next-line\n dataLayer.push(pushObject);\n\n if (log && testEnabled) {\n console.info(pushObject);\n }\n },\n\n log (data, inline = false) {\n if (!testEnabled) {\n return;\n }\n if (inline) {\n console.info('Analytics: ' + data);\n } else {\n console.info('Analytics: ');\n console.info(data);\n }\n },\n\n getFormatSku (sku) {\n return getFormatSkuForAnalytics(sku);\n },\n\n formatNameForAnalytics (name) {\n if (!name) {\n return '';\n }\n let formattedPlus = name.toLowerCase().replace(/[+]/g, '_plus_');\n let formattedName = formattedPlus.replace(/\\W/g, '_');\n let analyticsName = formattedName.split('_').filter((el) => { return el; }).join('_');\n return analyticsName;\n },\n\n formatSkus (skus) {\n let formattedSkus = '';\n for (let i = 0; i < skus.length; i++) {\n let formattedSku = getFormatSkuForAnalytics(skus[i]).replace(/\\W/g, '_');\n if (i === 0) {\n formattedSkus += formattedSku;\n } else {\n formattedSkus += '-' + formattedSku;\n }\n }\n return formattedSkus;\n },\n\n getProductNameEngFromPdp () {\n let nameEng = $('.analytics.product').data('name');\n return nameEng;\n },\n\n getFormatedNewsletterPreferenceBrands (list) {\n let brandsStr = '';\n for (let brand of list) {\n brandsStr += brandsMapping[brand] + '-';\n }\n\n brandsStr = brandsStr.substring(0, brandsStr.length - 1);\n\n return brandsStr;\n },\n\n getListId (container, provider) {\n let list = '';\n if (container && $(container).parents('.analytics-mini-cart').length > 0) {\n list = 'minicart';\n } else if ($(container).parents('.js-site-search-suggestions-products').length > 0) { // Search results\n list = 'plp';\n } else if ($('.page[data-action=\"Product-Show\"]').length > 0) {\n list = 'pdp';\n } else if ($('.page[data-action=\"Search-Show\"]').length > 0) {\n list = $('.page.js-page-home-gender').length > 0 ? 'home' : 'plp';\n } else if ($('.page[data-action=\"Cart-Show\"]').length > 0 || $('.page[data-action=\"Checkout-Begin\"]').length > 0) {\n list = 'cart';\n } else if ($('.page[data-action=\"Wishlist-Show\"]').length > 0) {\n list = 'wishlist';\n }\n\n if (list && provider && (list === 'pdp' || list === 'home' || list === 'cart')) {\n list = `${provider}_${list}`;\n }\n\n return list;\n },\n\n getProductList () {\n let items = [];\n let container = $('.analytics.checkout.checkout-product');\n\n for (let i = 0; i < container.length; i++) {\n let obj = container.eq(i).data();\n\n // Fix values for MEC-30160\n if (obj.item_list_name === 'not_available') {\n obj.item_list_name = 'listing'\n }\n \n if (obj.item_list_id === 'not_available') {\n obj.item_list_id = 'pdp'\n }\n\n if (obj.id !== 'PERS_PROD') {\n obj['quantity'] = obj.quantity;\n obj['index'] = i;\n items.push(this.formatProductForAnalytics(obj));\n }\n }\n return items;\n },\n\n getGrandTotal () {\n return $('.analytics-totals').data('grand-total');\n },\n\n getAppliedCoupon () {\n const coupon = [];\n $('#couponCode.coupon-code-field--applied').val() && coupon.push($('#couponCode.coupon-code-field--applied').val());\n $('.analytics-shipping-discount').length && coupon.push('shipping_discount');\n $('.analytics-order-discount').length && coupon.push('order_discount');\n return coupon.join(',');\n },\n\n getUpsellingMessage () {\n let upsellingMessage = 'no_message';\n const vals = [];\n $('.analytics-message').each(function () {\n if (vals.indexOf($(this).data('analytics-type')) === -1) {\n vals.push($(this).data('analytics-type'));\n }\n });\n if (vals.length > 0) {\n upsellingMessage = vals.join('-');\n }\n localStorage.setItem('upsellingMessage', upsellingMessage);\n return upsellingMessage;\n },\n\n getBeginCheckoutData (context) {\n return {\n upselling_message: this.getUpsellingMessage(),\n currency: context.helperData.currency,\n value: this.getGrandTotal(),\n coupon: this.getAppliedCoupon(),\n items: this.getProductList()\n };\n },\n\n getTypeOfAccount () {\n let typeOfAccount = 'only_registration';\n if ($('.loyalty-flag:checked').length === 1) {\n typeOfAccount = 'profile_loyalty';\n }\n return typeOfAccount;\n },\n storeGtmData (data) {\n if (data && data.item_list_name && data.item_list_id && (data.index || data.index === 0)) {\n if (data.item_id && data.item_variant) {\n window.sessionStorage.setItem('GTM_' + data.item_id + '_color_' + data.item_variant, JSON.stringify({'item_list_name': data.item_list_name, 'item_list_id': data.item_list_id, 'index': data.index}));\n }\n // Adding values for color change event\n window.sessionStorage.setItem('GTM_item_list_name', data.item_list_name);\n window.sessionStorage.setItem('GTM_item_list_id', data.item_list_id);\n window.sessionStorage.setItem('GTM_index', data.index);\n }\n },\n getGtmData (data) {\n const GTMData = {};\n if (data && data.item_id && data.item_variant) {\n const GTMItem = JSON.parse(window.sessionStorage.getItem('GTM_' + data.item_id + '_color_' + data.item_variant)) || {};\n GTMData.item_list_name = stringOrNotAvailable(GTMItem.item_list_name);\n GTMData.item_list_id = stringOrNotAvailable(GTMItem.item_list_id);\n GTMData.index = numberOrZero(GTMItem.index);\n } else {\n GTMData.item_list_name = getStringAnalyticsValueFromStorage('GTM_item_list_name');\n GTMData.item_list_id = getStringAnalyticsValueFromStorage('GTM_item_list_id');\n GTMData.index = getNumberAnalyticsValueFromStorage('GTM_index');\n }\n return GTMData;\n },\n setBonusProductData ($container, index) {\n $container.data('item_list_name', 'free_product');\n $container.data('item_list_id', this.getListId());\n $container.data('index', index);\n $container.data('discount', $container.data('price'));\n $container.data('price', 0);\n }\n};\n","$('body').on('click', '#calculateFromModalPdp', function (e) {\n e.preventDefault();\n\n var inputUnderbrowSize = $('#contact-form-question-underbrow-from-pdp').val();\n var inputCupSize = $('#contact-form-question-cup-from-pdp').val();\n\n if (inputUnderbrowSize != undefined && inputCupSize != undefined && inputUnderbrowSize != '' && inputCupSize != '') {\n var jsonUnderbrowTable = window.FindYourSizeData.findYourSizeData;\n var underbrowTable = JSON.parse(jsonUnderbrowTable);\n var intUnderbrowSize = $('#findYourSizeModal-size-form-inch:checked').length > 0 ? parseInt(inputUnderbrowSize / 0.393700) : parseInt(inputUnderbrowSize);\n var intCupSize = $('#findYourSizeModal-size-form-inch:checked').length > 0 ? parseInt(inputCupSize / 0.393700) : parseInt(inputCupSize);\n calculateBraSizeFromPdp(intUnderbrowSize, intCupSize, underbrowTable);\n } else {\n if (inputUnderbrowSize == undefined || inputUnderbrowSize == '') {\n $('#contact-form-question-underbrow-from-pdp').addClass('is-invalid-input');\n $('#errorUnderbrow').removeClass('hidden');\n }\n if (inputCupSize == undefined || inputCupSize == '') {\n $('#contact-form-question-cup-from-pdp').addClass('is-invalid-input');\n $('#errorCup').removeClass('hidden');\n }\n }\n});\n\n$('body').on('click', '.js-findYourSizeModal-measure-unit-items input', function (e) {\n let unit = $(this).data('unit');\n $('.js-findYourSizeModal-fieldset-item-unit').addClass('hidden');\n $('.js-findYourSizeModal-fieldset-item-unit.' + unit).removeClass('hidden');\n});\n\n$('body').on('focus', '#contact-form-question-underbrow-from-pdp', function (e) {\n e.preventDefault();\n $('#contact-form-question-underbrow-from-pdp').removeClass('is-invalid-input');\n $('#errorUnderbrow').addClass('hidden');\n});\n\n$('body').on('focus', '#contact-form-question-cup-from-pdp', function (e) {\n e.preventDefault();\n $('#contact-form-question-cup-from-pdp').removeClass('is-invalid-input');\n $('#errorCup').addClass('hidden');\n});\n\n$('input').focus(function () {\n $(this).next('span').css('display', 'block');\n});\n\nfunction calculateBraSizeFromPdp (inputUnderbrowSize, inputCupSize, underbrowTable) {\n var country = $('#countrySelector').attr('data-country');\n\n var jsonCircTable = window.FindYourSizeDataCirc.findYourSizeDataCirc;\n var circTable = JSON.parse(jsonCircTable);\n var underbrowSize;\n var cupSize;\n var eu = false;\n for (var key in underbrowTable) {\n if (inputUnderbrowSize >= underbrowTable[key].from && inputUnderbrowSize <= underbrowTable[key].to) {\n switch (country) {\n case 'it':\n underbrowSize = underbrowTable[key].it;\n break;\n case 'es':\n underbrowSize = underbrowTable[key].es;\n break;\n case 'fr':\n underbrowSize = underbrowTable[key].fr;\n break;\n case 'us':\n underbrowSize = underbrowTable[key].us;\n break;\n case 'gb':\n underbrowSize = underbrowTable[key].gb;\n break;\n case 'pt':\n underbrowSize = underbrowTable[key].pt;\n break;\n case 'hk':\n underbrowSize = underbrowTable[key].hk;\n break;\n case 'lu':\n underbrowSize = underbrowTable[key].lu;\n break;\n default:\n eu = true;\n underbrowSize = underbrowTable[key].eu;\n break;\n }\n break;\n }\n }\n\n if (eu == true) {\n country = 'eu';\n }\n for (var k in circTable[country + '_' + underbrowSize]) {\n if (inputCupSize >= circTable[country + '_' + underbrowSize][k].from && inputCupSize <= circTable[country + '_' + underbrowSize][k].to) {\n cupSize = k;\n break;\n }\n }\n\n if (underbrowSize != undefined && cupSize != undefined) {\n $('#measure-not-valid-from-pdp').hide();\n $('#bra-results-from-pdp').show();\n $('#suggested-sizes-from-pdp').show();\n $('#box-result-size-from-pdp').show();\n $('#box-result-size-from-pdp-measure-valid').show();\n document.getElementById('bra-results-from-pdp').firstElementChild.innerText = underbrowSize + cupSize;\n $('#box-message-size').removeAttr('hidden');\n var suggestedSizes;\n\n switch (country) {\n case 'it':\n suggestedSizes = calculateTableFromPdp(underbrowSize, cupSize);\n break;\n case 'es':\n suggestedSizes = calculateTableFromPdpESFRLU(underbrowSize, cupSize);\n break;\n case 'fr':\n suggestedSizes = calculateTableFromPdpESFRLU(underbrowSize, cupSize);\n break;\n case 'us':\n suggestedSizes = calculateTableFromPdpUS(underbrowSize, cupSize);\n break;\n case 'gb':\n suggestedSizes = calculateTableFromPdpUK(underbrowSize, cupSize);\n break;\n case 'hk':\n suggestedSizes = calculateTableFromPdpHK(underbrowSize, cupSize);\n break;\n case 'pt':\n suggestedSizes = calculateTableFromPdpPT(underbrowSize, cupSize);\n break;\n case 'lu':\n suggestedSizes = calculateTableFromPdpESFRLU(underbrowSize, cupSize);\n break;\n default:\n suggestedSizes = calculateTableFromPdpEU(underbrowSize, cupSize);\n break;\n }\n\n // $('#measure-not-valid-from-pdp').hide();\n // $('#bra-results-from-pdp').show();\n // $('#box-result-size-from-pdp').show();\n // $('#box-result-size-from-pdp-measure-valid').show();\n // document.getElementById('bra-results-from-pdp').innerHTML = underbrowSize+cupSize;\n // $('#box-message-size').removeAttr('hidden');\n // var suggestedSizes = calculateTableFromPdp(underbrowSize,cupSize);\n if(suggestedSizes.length !== 0){\n var suggestedSizesString = '';\n for (var i = 0; i < suggestedSizes.length; i++) {\n suggestedSizesString = suggestedSizesString.concat(suggestedSizes[i]);\n if (i != suggestedSizes.length - 1) {\n suggestedSizesString = suggestedSizesString.concat(',');\n } else {\n suggestedSizesString = suggestedSizesString.concat('.');\n }\n }\n document.getElementById('suggested-sizes-from-pdp').firstElementChild.innerText = suggestedSizesString;\n $('#bra-results-from-pdp').css('margin-bottom', '0');\n } else {\n $('#suggested-sizes-from-pdp').hide();\n $('#bra-results-from-pdp').css('margin-bottom', 'revert');\n }\n } else {\n $('#bra-results-from-pdp').hide();\n $('#suggested-sizes-from-pdp').hide();\n $('#box-result-size-from-pdp').hide();\n $('#measure-not-valid-from-pdp').show();\n $('#box-result-size-from-pdp-measure-valid').hide();\n }\n}\n\nfunction calculateTableFromPdp (underbrowSize, cupSize) {\n var suggestedSizes = [];\n var initialCupSize = cupSize;\n var initialUnderBrowSize = underbrowSize;\n var arrSizes = ['A', 'B', 'C', 'D', 'E', 'F'];\n\n for (var i = underbrowSize; i < 6; i++) {\n if (cupSize == 'A') {\n break;\n }\n var PrevUnderbrowSize = i + 1;\n var prevCupSize = arrSizes[arrSizes.indexOf(cupSize) - 1];\n var cupSize = prevCupSize;\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n for (var i = initialUnderBrowSize; i > 1; i--) {\n if (initialCupSize == 'F') {\n break;\n }\n var PrevUnderbrowSize = i - 1;\n var prevCupSize = arrSizes[arrSizes.indexOf(initialCupSize) + 1];\n var initialCupSize = prevCupSize;\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n return suggestedSizes;\n}\n\nfunction calculateTableFromPdpESFRLU (underbrowSize, cupSize) {\n var suggestedSizes = [];\n var initialCupSize = cupSize;\n var initialUnderBrowSize = underbrowSize;\n var arrSizes = ['A', 'B', 'C', 'D', 'E', 'F'];\n\n for (var i = underbrowSize; i < 105; i += 5) {\n if (cupSize == 'A') {\n break;\n }\n var PrevUnderbrowSize = i + 5;\n var prevCupSize = arrSizes[arrSizes.indexOf(cupSize) - 1];\n var cupSize = prevCupSize;\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n for (var i = initialUnderBrowSize; i > 80; i -= 5) {\n if (initialCupSize == 'F') {\n break;\n }\n var PrevUnderbrowSize = i - 5;\n var prevCupSize = arrSizes[arrSizes.indexOf(initialCupSize) + 1];\n var initialCupSize = prevCupSize;\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n return suggestedSizes;\n}\n\nfunction calculateTableFromPdpUS (underbrowSize, cupSize) {\n var suggestedSizes = [];\n var initialCupSize = cupSize;\n var initialUnderBrowSize = underbrowSize;\n var arrSizes = ['A', 'B', 'C', 'D', 'DD', 'DDD'];\n\n if (underbrowSize == 43) {\n underbrowSize = underbrowSize - 1;\n }\n for (var i = underbrowSize; i < 42; i += 2) {\n if (cupSize == 'A') {\n break;\n }\n var PrevUnderbrowSize = i + 2;\n var prevCupSize = arrSizes[arrSizes.indexOf(cupSize) - 1];\n var cupSize = prevCupSize;\n if (PrevUnderbrowSize == 42) {\n PrevUnderbrowSize++;\n }\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n if (initialUnderBrowSize == 43) {\n initialUnderBrowSize = initialUnderBrowSize - 1;\n }\n\n for (var i = initialUnderBrowSize; i > 32; i -= 2) {\n if (initialCupSize == 'F') {\n break;\n }\n var PrevUnderbrowSize = i - 2;\n var prevCupSize = arrSizes[arrSizes.indexOf(initialCupSize) + 1];\n var initialCupSize = prevCupSize;\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n return suggestedSizes;\n}\n\nfunction calculateTableFromPdpEU (underbrowSize, cupSize) {\n var suggestedSizes = [];\n var initialCupSize = cupSize;\n var initialUnderBrowSize = underbrowSize;\n var arrSizes = ['A', 'B', 'C', 'D', 'E', 'F'];\n\n for (var i = underbrowSize; i < 95; i += 5) {\n if (cupSize == 'A') {\n break;\n }\n var PrevUnderbrowSize = i + 5;\n var prevCupSize = arrSizes[arrSizes.indexOf(cupSize) - 1];\n var cupSize = prevCupSize;\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n for (var i = initialUnderBrowSize; i > 70; i -= 5) {\n if (initialCupSize == 'F') {\n break;\n }\n var PrevUnderbrowSize = i - 5;\n var prevCupSize = arrSizes[arrSizes.indexOf(initialCupSize) + 1];\n var initialCupSize = prevCupSize;\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n return suggestedSizes;\n}\n\nfunction calculateTableFromPdpUK (underbrowSize, cupSize) {\n var suggestedSizes = [];\n var initialCupSize = cupSize;\n var initialUnderBrowSize = underbrowSize;\n var arrSizes = ['A', 'B', 'C', 'D', 'DD', 'F'];\n\n if (underbrowSize == 43) {\n underbrowSize = underbrowSize - 1;\n }\n for (var i = underbrowSize; i < 42; i += 2) {\n if (cupSize == 'A') {\n break;\n }\n var PrevUnderbrowSize = i + 2;\n var prevCupSize = arrSizes[arrSizes.indexOf(cupSize) - 1];\n var cupSize = prevCupSize;\n if (PrevUnderbrowSize == 42) {\n PrevUnderbrowSize++;\n }\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n if (initialUnderBrowSize == 43) {\n initialUnderBrowSize = initialUnderBrowSize - 1;\n }\n\n for (var i = initialUnderBrowSize; i > 32; i -= 2) {\n if (initialCupSize == 'F') {\n break;\n }\n var PrevUnderbrowSize = i - 2;\n var prevCupSize = arrSizes[arrSizes.indexOf(initialCupSize) + 1];\n var initialCupSize = prevCupSize;\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n return suggestedSizes;\n}\n\nfunction calculateTableFromPdpPT (underbrowSize, cupSize) {\n var suggestedSizes = [];\n var initialCupSize = cupSize;\n var initialUnderBrowSize = underbrowSize;\n var arrSizes = ['A', 'B', 'C', 'D', 'E', 'F'];\n\n if (underbrowSize == 43) {\n underbrowSize = underbrowSize - 1;\n }\n for (var i = underbrowSize; i < 42; i += 2) {\n if (cupSize == 'A') {\n break;\n }\n var PrevUnderbrowSize = i + 2;\n var prevCupSize = arrSizes[arrSizes.indexOf(cupSize) - 1];\n var cupSize = prevCupSize;\n if (PrevUnderbrowSize == 42) {\n PrevUnderbrowSize++;\n }\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n if (initialUnderBrowSize == 43) {\n initialUnderBrowSize = initialUnderBrowSize - 1;\n }\n\n for (var i = initialUnderBrowSize; i > 32; i -= 2) {\n if (initialCupSize == 'F') {\n break;\n }\n var PrevUnderbrowSize = i - 2;\n var prevCupSize = arrSizes[arrSizes.indexOf(initialCupSize) + 1];\n var initialCupSize = prevCupSize;\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n return suggestedSizes;\n}\n\nfunction calculateTableFromPdpHK (underbrowSize, cupSize) {\n var suggestedSizes = [];\n var initialCupSize = cupSize;\n var initialUnderBrowSize = underbrowSize;\n var arrSizes = ['A', 'B', 'C', 'D', 'E', 'F'];\n\n if (underbrowSize == 43) {\n underbrowSize = underbrowSize - 1;\n }\n for (var i = underbrowSize; i < 42; i += 2) {\n if (cupSize == 'A') {\n break;\n }\n var PrevUnderbrowSize = i + 2;\n var prevCupSize = arrSizes[arrSizes.indexOf(cupSize) - 1];\n var cupSize = prevCupSize;\n if (PrevUnderbrowSize == 42) {\n PrevUnderbrowSize++;\n }\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n if (initialUnderBrowSize == 43) {\n initialUnderBrowSize = initialUnderBrowSize - 1;\n }\n\n for (var i = initialUnderBrowSize; i > 32; i -= 2) {\n if (initialCupSize == 'F') {\n break;\n }\n var PrevUnderbrowSize = i - 2;\n var prevCupSize = arrSizes[arrSizes.indexOf(initialCupSize) + 1];\n var initialCupSize = prevCupSize;\n var id = '' + PrevUnderbrowSize + prevCupSize;\n suggestedSizes.push(id);\n }\n\n return suggestedSizes;\n}\n","'use strict';\n\nconst formatAmount = function (forceChange = false) {\n var oldText = $('span[slot=\"spDisplayAmount\"]').first().text();\n\n // Keep checking until it's updated by the widget's script\n var updatePrice = setInterval(function () {\n var text = $('span[slot=\"spDisplayAmount\"]').first().text();\n\n if (oldText !== text || forceChange) {\n clearInterval(updatePrice);\n // € must be first character\n if (text.indexOf('€') !== 0) {\n return;\n }\n\n var updatedText = '€ ' + text.substring(1);\n $('span[slot=\"spDisplayAmount\"]').text(updatedText);\n }\n }, 500);\n}\n\nclass ScalaPay {\n run () {\n this.currentPage = $('.page').data('action') === 'Product-Show' ? 'product_page' : 'shopping_bag';\n this.availableAPI = $('.scalapay-apis') && $('.scalapay-apis').length > 0;\n this.scalaPayWidget = false;\n this.loadWidget();\n }\n\n // Save ScalaPay widget element, waits for script to be loaded\n loadWidget () {\n if (!this.availableAPI) {\n return;\n }\n\n var _self = this;\n var checkWidget = setInterval(function () {\n let scalaPayWidget = document.querySelector('scalapay-widget');\n\n // Save widget element and launch event observers\n if (!!scalaPayWidget) {\n clearInterval(checkWidget);\n _self.scalaPayWidget = scalaPayWidget;\n _self.prepareObservers();\n formatAmount(true);\n }\n }, 500);\n }\n\n // Observe analytics event\n prepareObservers () {\n var _self = this;\n\n for (let i = 0; i < $('scalapay-widget').length; i++) {\n $($('scalapay-widget')[i].shadowRoot).find('.sp-link, .sp-icon').on('click', function () {\n $('body').trigger('scalaPay:openModal', _self.currentPage);\n });\n }\n\n // When widget changes value, format amount\n $('body').on('product:afterAttributeSelect', formatAmount);\n }\n\n // Run at checkout\n checkout () {\n $('body').on('scalaPay:updateScalaPayPaymentMethod', function (e, order) {\n if (!$('.drawer[data-method-id=\"ScalaPay\"]').length || !order) {\n return;\n }\n\n let scalaPayLabel = false;\n let showPaymentMethod = false;\n if ('scalaPaySettings' in order && order.scalaPaySettings) {\n // For multipayment\n scalaPayLabel = order.scalaPaySettings.widgetText.payment;\n showPaymentMethod = order.scalaPaySettings.isEligible;\n } else if ('scalapayTotals' in order.totals && order.totals.scalapayTotals) {\n scalaPayLabel = order.totals.scalapayTotals.payment.paymentPageWidgetText;\n showPaymentMethod = true;\n }\n\n if (scalaPayLabel) {\n $('.js-billing-scalapay-price').html(scalaPayLabel);\n }\n let isApplicablePaymentMethod = false;\n if (order.billing && order.billing.payment && order.billing.payment.applicablePaymentMethods) {\n for (let i = 0; i < order.billing.payment.applicablePaymentMethods.length; i++) {\n let methodID = order.billing.payment.applicablePaymentMethods[i].ID;\n if (methodID === 'ScalaPay') {\n isApplicablePaymentMethod = true;\n }\n }\n }\n if (!isApplicablePaymentMethod) {\n showPaymentMethod = false;\n }\n $('.drawer[data-method-id=\"ScalaPay\"]').toggle(showPaymentMethod);\n });\n }\n}\n\nconst scalaPay = new ScalaPay();\nexport default scalaPay;","import NotifyHelper from './notify';\nimport SmartGiftHelper from './smartGiftHelper';\nimport { startCarouselTileImageFunction } from './productBox';\nimport { updatePrimaryImagesSlider } from './detail';\nimport sizePanel from './sizePanel';\nimport { addToCartFromListing } from './quickView.js';\nimport { newModalFromString } from '../components/modal';\nimport { runPersonalizationListener } from '../customize';\nimport { updateProductDetailUrl } from 'util/url';\nimport { createCookie } from '../util/common';\nimport { getGtmData } from '../analytics/helpers/helper';\nimport { handleWishlistContainer } from './wishlistHeart.js';\n\nconst isMiniCartOpen = () => {\n return localStorage.getItem('isMiniCartOpen') === 'true';\n};\n\nfunction isChooseBonusProductModalOpen () {\n return ($('.js-chooseBonusProductModal').length > 0);\n}\n\nfunction isQuickUpdateFromModal () {\n return $('.js-quickUpdateModal').length > 0;\n}\n\nconst isMobileDevice = () => {\n return !Foundation.MediaQuery.atLeast('large');\n};\n/**\n * Move close button inside modal content box\n */\nconst moveModalCloseButton = () => {\n var close = document.querySelector('.tingle-modal__close');\n var modalContent = document.querySelector('.tingle-modal-box__content');\n modalContent.appendChild(close);\n};\n\n/**\n * Retrieves the relevant pid value\n * @param {jquery} $el - DOM container for a given add to cart button\n * @return {string} - value to be used when adding product to cart\n */\nconst getPidValue = ($el) => {\n let pid;\n\n if ($('.quickview-modal').hasClass('tingle-modal--visible') && !$('.product-set').length) {\n pid = $('.quickview-modal').find('.product-quickview').data('pid');\n } else if ($('.product-set-detail').length || $('.product-set').length) {\n pid = $($el).closest('.product-detail').find('.product-id').text();\n } else if ($('.modal-size-show').length) {\n pid = $('.modal-size-show').find('.js-add-to-cart').data('pid');\n } else if (isMiniCartOpen()) {\n pid = $($el).data('pid');\n } else {\n pid = $('.product-detail:not(\".bundle-item\")').data('pid');\n }\n\n return pid;\n};\n\n/**\n * updates the product view when a product attribute of quickAdd is selected or deselected or when\n * changing quantity\n * @param {string} selectedValueUrl - the Url for the selected variation value\n * @param {jQuery} $productContainer - DOM element for current product\n * @param {string} type - type of filter selected\n */\nconst attributeSelectQuickAdd = (selectedValueUrl, $productContainer, type = '_', imagesShouldUpdate = true) => {\n if (selectedValueUrl) {\n $('body').trigger('product:beforeAttributeSelect', {\n url: selectedValueUrl,\n container: $productContainer\n });\n\n $.ajax({\n url: selectedValueUrl,\n method: 'GET',\n success: data => {\n handleVariantResponseQuickAdd(data, $productContainer, imagesShouldUpdate);\n updateOptions(data.product.options, $productContainer);\n updateQuantities(data.product.quantities, $productContainer);\n $productContainer.attr('data-pid', data.product.id);\n $productContainer.find('.add-to-cart-quick-add').attr('data-pid', data.product.id);\n $productContainer.find('.add-to-cart-quick-add').attr('data-quantity', data.product.selectedQuantity);\n if ($productContainer.find('.add-to-cart-quick-add').data('mustAdd') === true) {\n $productContainer.find('.add-to-cart-quick-add').trigger('click');\n } else {\n $productContainer.find('.js-panel-opener-size-quick-add').trigger('click');\n $.spinner().stop();\n }\n },\n error: () => {\n $.spinner().stop();\n }\n });\n }\n};\n\nconst activatePromoAnimationMessage = () => {\n $('.js-pdpPromo').removeClass('hide');\n};\n\nconst reactivatePromoAnimationMessage = (promotionId, pdpCalloutMsgText) => {\n $('.js-pdpPromo').attr('data-promotion-id', promotionId);\n $('.js-pdpPromo-message').html(pdpCalloutMsgText);\n activatePromoAnimationMessage();\n};\n\n/**\n * updates the product view when a product attribute is selected or deselected or when changing quantity\n * @param {string} selectedValueUrl - the Url for the selected variation value\n * @param {jQuery} $productContainer - DOM element for current product\n * @param {string} type - type of filter selected\n * @param {boolean} imagesShouldUpdate - update images on attribute selection\n * @param {boolean} ignoreCTA - add immediately to cart without clicking on CTA\n */\nconst attributeSelect = (selectedValueUrl, $productContainer, type = '_', imagesShouldUpdate = true, ignoreCTA = false) => {\n if (selectedValueUrl) {\n // destroyPrimaryImagesSlider();\n $productContainer.prevObject.analyticsPromotion = false;\n\n $('body').trigger('product:beforeAttributeSelect', {\n url: selectedValueUrl,\n container: $productContainer\n });\n\n $.ajax({\n url: selectedValueUrl,\n method: 'GET',\n success: data => {\n var isSize = data.variation.isSize;\n var isQuickViewModal = $productContainer.hasClass('product-quickview');\n\n if (isQuickViewModal && type !== 'color') {\n imagesShouldUpdate = false;\n }\n\n handleVariantResponse(data, $productContainer, imagesShouldUpdate, type);\n\n // Update PDP link if we are in QuickView and a color was selected\n if (type === 'color' && $('.quickview-modal').length) {\n let container = $('.quickview-modal').find('.see-product-details-link');\n container.attr('href', data.product.url);\n }\n\n handleVariationUrlsSelectSizeModal(data.variation.variationUrls);\n handlePromotionTag(data.product ,$productContainer);\n handleVariationUrlsSelectNotifyModal(data.product.variationAttributes[1].values);\n handleVariationComingSoonNotifyModal(data.product.variationAttributes[1].values);\n handleVariationComingSoon(data.product.comingSoon);\n handleVariationWishlistModal(data.product.variationAttributes[1].values);\n\n // here we check if the selected product has the size, if not we put a flag on isToLoad\n if (isSize == false) {\n $('#pidToAdd').attr('isToLoad', 'true');\n } else {\n $('#pidToAdd').attr('isToLoad', 'false');\n }\n $('.persButtonPdpPers').attr('disabled', false);\n $('#custom-page').attr('data-pid', data.product.id);\n $('.js-personalizeButtonCheckout').removeClass('disabled');\n $('.js-personalizeButtonCheckout').attr('disabled', false);\n updateOptions(data.product.options, $productContainer);\n updateQuantities(data.product.quantities, $productContainer);\n updateImageSaveForLater(data.product, $productContainer);\n if ($('.product-detail-keeper').length) {\n var pid = getPID(data.product);\n try {\n $($productContainer).find('.product-set').attr('data-pid', pid);\n } catch (e) {\n }\n $('.product-detail-keeper').attr('data-variant-pid', encodeURIComponent(pid));\n }\n\n if (isSize) {\n $('body').trigger('product:afterAttributeSelect', {\n data: data,\n container: $productContainer,\n type: type\n });\n }\n\n if (type === 'color') {\n if (data.product.promotions && data.product.promotions.length > 0) {\n const promoContainer = $('.js-promo-loyalty-message-pdp-underprice');\n const promoMessage = data.product.promotions[0].promoLoyaltyMessage;\n if (promoContainer && promoMessage && promoMessage.length) {\n promoContainer.html(promoMessage);\n } else {\n promoContainer.html('');\n }\n } else {\n $('.js-promo-loyalty-message-pdp-underprice').html('');\n }\n }\n\n const _updateInformation = (product) => {\n let selectorPrefix = '';\n if (product.variationAttributes[0].onSaleSelected || product.price.saleType) {\n selectorPrefix = '.onSaleContainer';\n } else {\n selectorPrefix = '.notOnSaleContainer';\n }\n\n $productContainer.find(selectorPrefix + ' .js-discount-msg').addClass('hidden');\n $productContainer.find(selectorPrefix + ' .js-promo-msg').addClass('hidden');\n\n if (product.price.discountValue) {\n $productContainer.prevObject.analyticsPromotion = true;\n $productContainer.find(selectorPrefix + ' .js-discount-msg')\n .html(`(${product.price.discountValue}%)`)\n .removeClass('hidden');\n if (product.promotions && product.promotions.length > 0) {\n if (product.promotions[0].calloutMsg) {\n $productContainer.find(selectorPrefix + ' .js-promo-msg')\n .html(product.promotions[0].calloutMsg)\n .removeClass('hidden');\n } else if (product.promotions[1] && product.promotions[1].calloutMsg) {\n $productContainer.find(selectorPrefix + ' .js-promo-msg')\n .html(product.promotions[1].calloutMsg)\n .removeClass('hidden');\n }\n }\n } else if (product.promotions && product.promotions.length > 0) {\n $productContainer.prevObject.analyticsPromotion = true;\n if (product.promotions[0].calloutMsg) {\n $productContainer.find(selectorPrefix + ' .js-promo-msg')\n .html(product.promotions[0].calloutMsg)\n .removeClass('hidden');\n } else if (product.promotions[1] && product.promotions[1].calloutMsg) {\n $productContainer.find(selectorPrefix + ' .js-promo-msg')\n .html(product.promotions[1].calloutMsg)\n .removeClass('hidden');\n }\n }\n };\n\n if (type !== 'size') {\n _updateInformation(data.product);\n }\n\n if ($('.modal-size-show').length) {\n $.spinner().stop();\n if (type === 'size') {\n $('body').trigger('quickBuy:addToCart', data);\n }\n }\n\n if ($('.js-customizePage').length > 0 && data.totalQuantityPrice) {\n $('.js-personalizePrice').text(data.totalQuantityPrice);\n }\n\n handleInexistentSizeQuickView(data);\n handleWishlistContainer(data.product.id);\n },\n error: function (err) {\n if (err.responseJSON.redirectUrl) {\n window.location.href = err.responseJSON.redirectUrl;\n } else {\n let current_url = window.location.pathname.split('/');\n var localized_error_page = window.location.protocol + '://' + window.location.host;\n for (var i = 0; i < current_url.length; i++) {\n if (current_url[i] !== 'product') {\n localized_error_page += '/' + current_url[i];\n } else {\n localized_error_page += '/404/';\n break;\n }\n }\n console.log('localized_error_page = ' + localized_error_page);\n window.location.href = localized_error_page;\n }\n $.spinner().stop();\n }\n }).then(function (data) {\n let stopSpinner = sizePanel.afterSizeSelection(data, type);\n if (stopSpinner) {\n $.spinner().stop();\n }\n if (ignoreCTA) {\n $('.js-prod-select-size-modal').find('button.js-add-to-cart').trigger('click');\n }\n if (type === 'color') {\n if (data.product.promotions.length === 0) {\n $('.js-pdpPromo').addClass('hide');\n } else if (data.product.promotions[0].id && data.product.promotions[0].id != $('.js-pdpPromo').attr('data-promotion-id')) {\n reactivatePromoAnimationMessage(data.product.promotions[0].id, data.product.promotions[0].pdpCalloutMsgText);\n } else {\n $('.js-pdpPromo').removeClass('hide');\n }\n }\n });\n }\n};\n\n/**\n * Retrieve contextual quantity selector\n * @param {jquery} $el - DOM container for the relevant quantity\n * @return {jquery} - quantity selector DOM container\n */\nconst getQuantitySelector = ($el) => {\n return $el && $('.set-items').length ?\n $($el).closest('.product-detail').find('.quantity-select') :\n $('.quantity-select');\n};\n\n/**\n * Retrieves the value associated with the Quantity pull-down menu\n * @param {jquery} $el - DOM container for the relevant quantity\n * @return {string} - value found in the quantity input\n */\nconst getQuantitySelected = ($el) => {\n let quantity = 1;\n if ($el.hasClass('js-add-to-cart-multipack') && $el.data('bundle-quantity')) {\n quantity = $el.data('bundle-quantity');\n } else if ($el.closest('.js-complete-your-promo-quick-view').length > 0) {\n quantity = $el.closest('.wrapper-inner-quick-bottom').find('.js-quick-quantity').val();\n } else if (getQuantitySelector($el).val()) {\n quantity = getQuantitySelector($el).val();\n }\n return quantity;\n};\n\n/**\n * Process the attribute values for an attribute that has image swatches\n *\n * @param {Object} attr - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {Object[]} attr.values - Array of attribute value objects\n * @param {string} attr.values.value - Attribute coded value\n * @param {string} attr.values.url - URL to de/select an attribute value of the product\n * @param {boolean} attr.values.isSelectable - Flag as to whether an attribute value can be\n * selected. If there is no variant that corresponds to a specific combination of attribute\n * values, an attribute may be disabled in the Product Detail Page\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nconst processSwatchValues = (attr, $productContainer) => {\n attr.values.forEach(attrValue => {\n const $attrValue = $productContainer.find(`[data-attr=\"${attr.id}\"] [data-attr-value=\"${attrValue.value}\"]`);\n const $swatchAnchor = $attrValue.parent();\n\n if (attrValue.selected) {\n $productContainer.find('.attribute-label').text(attrValue.id.toLowerCase() + ' - ' + attrValue.displayValue.toLowerCase());\n if ($('.js-pdpStickyBar-colorWrapper').length > 0) {\n $('.js-pdpStickyBar-colorWrapper .label-inside').text(attr.displayName + ': ' + attrValue.displayValue.toLowerCase() + ' - ' + attrValue.id.toLowerCase());\n $('.js-pdpStickyBar-colorWrapper img').attr('src', attrValue.images.swatch[0].url);\n $('.js-pdpStickyBar-colorWrapper img').attr('alt', attrValue.displayValue.toLowerCase() + ' - ' + attrValue.id.toLowerCase());\n }\n if ($attrValue[0]) {\n $productContainer.find(`[data-opener=\"${attr.id}\"] .attribute-selection`).html($attrValue[0].outerHTML);\n $attrValue.addClass('selected');\n }\n } else {\n $attrValue.removeClass('selected');\n }\n\n if (attrValue.url) {\n $swatchAnchor.attr('href', attrValue.url);\n } else {\n $swatchAnchor.removeAttr('href');\n }\n\n // Disable if not selectable\n $attrValue.removeClass('selectable unselectable soldout');\n $attrValue.addClass((attrValue.selectable || attrValue.isSoldout) ? 'selectable' : 'unselectable');\n if (attrValue.isSoldout) {\n $attrValue.addClass('soldout');\n }\n });\n};\n\n/**\n * Process attribute values associated with an attribute that does not have image swatches\n *\n * @param {Object} attr - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {Object[]} attr.values - Array of attribute value objects\n * @param {string} attr.values.value - Attribute coded value\n * @param {string} attr.values.url - URL to de/select an attribute value of the product\n * @param {boolean} attr.values.isSelectable - Flag as to whether an attribute value can be\n * selected. If there is no variant that corresponds to a specific combination of attribute\n * values, an attribute may be disabled in the Product Detail Page\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nconst processNonSwatchValues = (attr, $productContainer, variantType) => {\n const $attr = `[data-attr=\"${attr.id}\"]`;\n const $defaultOption = $productContainer.find(`${$attr} .select-${attr.id} option:first`);\n $defaultOption.attr('value', attr.resetUrl);\n $productContainer.find(`[data-opener=\"${attr.id}\"] .attribute-selection`).html('');\n\n $productContainer.find('.js-intProductDetail-size-item').addClass('hide');\n attr.values.forEach(attrValue => {\n if ($('.page').data('action') && $('.page').data('action').toLowerCase().indexOf('product-show') > -1 && $('#personalize-page') && !$productContainer.hasClass('js-complete-your-promo-quick-view')) {\n $productContainer = $('.js-intProductDetail');\n }\n const $attrValue = $productContainer.find(`${$attr} [data-attr-value=\"${attrValue.value}\"]`);\n const $attrValueMobile = $productContainer.find(`.size-panel-mobile-content [data-attr-value=\"${attrValue.value}_mobile\"]`);\n $attrValue.attr('value', attrValue.url).removeAttr('disabled');\n $attrValueMobile.attr('value', attrValue.variationUrl);\n if (!attrValue.selected) {\n $attrValueMobile.removeAttr('disabled');\n }\n $attrValue.attr('disabled', !attrValue.selectable);\n if (attrValue.isComingSoon && $productContainer.hasClass('product-quickview')) {\n $attrValue.attr('disabled', attrValue.isComingSoon);\n }\n\n if (attrValue.selected && attrValue.selectable && attrValue.id !== 'TU') {\n $productContainer.find(`[data-opener=\"${attr.id}\"] .attribute-selection`).html(attrValue.displayValue);\n $productContainer.find('.product-quickview').data('pid', attrValue.sku);\n }\n\n if (attrValue.selected && attrValue.selectable) {\n const selectedSizeSpan = $productContainer.find('.js-selected-size');\n\n if (selectedSizeSpan.length) {\n selectedSizeSpan.text(attrValue.displayValue);\n }\n }\n\n if ($attrValue.length > 1) {\n $attrValue.each((i, el) => {\n $(el).prop('checked', attrValue.selected && attrValue.selectable);\n });\n } else {\n $attrValue.prop('checked', attrValue.selected && attrValue.selectable);\n }\n\n if (variantType !== 'size') {\n if (!attrValue.selectable || attrValue.isComingSoon) {\n if ($('#isNotifyActive').val() == 'true') {\n $attrValue.siblings().addClass('notifyMe');\n $attrValueMobile.siblings().addClass('notifyMe');\n } else {\n $attrValue.siblings().addClass('wishlistOnly');\n $attrValueMobile.siblings().addClass('wishlistOnly');\n }\n } else {\n $attrValue.siblings().removeClass('notifyMe wishlistOnly');\n $attrValueMobile.siblings().removeClass('notifyMe wishlistOnly');\n }\n if (attrValue.lowAvailability) {\n $attrValue.siblings().addClass('low-stock');\n $attrValueMobile.siblings().addClass('low-stock');\n } else {\n $attrValue.siblings().removeClass('low-stock');\n $attrValueMobile.siblings().removeClass('low-stock');\n }\n }\n\n // Toggle size if disabled or not\n $attrValue.closest('label').toggleClass('hide', attrValue.disabled);\n $attrValueMobile.closest('label').toggleClass('hide', attrValue.disabled);\n\n // Toggle size in stickybar\n $('.js-pdpStickyBar').find('#' + $attrValue[0].id.replace('/', '\\\\/')).closest('label').toggleClass('hide', attrValue.disabled);\n\n // Same check on quick view mobile\n $attrValue.closest('.label-wrapper').toggleClass('hide', attrValue.disabled);\n\n // Toggle selectable size on cart quickview\n if ($('.quickview-modal').length) {\n $attrValue.closest('.boolean-field').toggleClass('cc-cartQuickView_selectedSize', attrValue.selected);\n }\n });\n\n // Update also size selection modal\n const $sizeSelectorContainer = $('#fis-select-size');\n attr.values.forEach(attrValue => {\n const $attrValue = $sizeSelectorContainer.find(`[data-attr-value=\"${attrValue.value}\"]`);\n $attrValue.attr('disabled', !attrValue.selectable);\n if (attrValue.isComingSoon && $productContainer.hasClass('product-quickview')) {\n $attrValue.attr('disabled', attrValue.isComingSoon);\n }\n\n if ($('#isNotifyActive').val() == 'true') {\n if (!attrValue.selectable || attrValue.isComingSoon) {\n $attrValue.addClass('notifyMe notifyPopup');\n $attrValue.find('.notifyIcon').removeClass('hide');\n } else {\n $attrValue.removeClass('notifyMe notifyPopup');\n $attrValue.find('.notifyIcon').addClass('hide');\n }\n } else {\n if (!attrValue.selectable) {\n $attrValue.addClass('wishlistOnly');\n } else {\n $attrValue.removeClass('wishlistOnly');\n }\n }\n\n // Toggle size if disabled or not\n $attrValue.parent('li').toggleClass('hide', attrValue.disabled);\n\n // TODO: improve check. Force size selection of quick add on PDP mobile\n if (!Foundation.MediaQuery.atLeast('large') && $productContainer.closest('.product-quickview').length) {\n $productContainer.find(`.mobile-attributes-container input[id=\"${attrValue.value}\"]`).prop('checked', attrValue.selected && attrValue.selectable);\n }\n });\n};\n\n/**\n * Routes the handling of attribute processing depending on whether the attribute has image\n * swatches or not\n *\n * @param {Object} attrs - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {string} variantType - Size or Color selection\n * @param {jQuery} $productContainer - DOM element for a given product\n */\nconst updateAttrs = (attrs, $productContainer, variantType) => {\n // Currently, the only attribute type that has image swatches is Color.\n const attrsWithSwatches = ['color'];\n\n if ($('.js-personalizeButtonModal').attr('data-personalized') === 'true') {\n $productContainer = $('.fis-select-size');\n }\n\n attrs.forEach(attr => {\n if (attrsWithSwatches.indexOf(attr.attributeId) > -1) {\n processSwatchValues(attr, $productContainer);\n } else {\n processNonSwatchValues(attr, $productContainer, variantType);\n }\n });\n};\n\nconst updateScanTrustLink = (attr, $productContainer) => {\n let $productAuthenticity = $productContainer.find('.cc-details-authenticity-paragraph');\n if ($productAuthenticity.length > 0) {\n $productAuthenticity.find('.js-update-scantrustUrl').attr('href', attr.scanTrustUrlWithParams);\n } \n}\n\n/**\n * Updates the availability status in the Product Detail Page\n *\n * @param {Object} response - Ajax response object after an\n * attribute value has been [de]selected\n * @param {jQuery} $productContainer - DOM element for a given product\n */\nconst updateAvailability = (response, $productContainer) => {\n let availabilityValue = '';\n let availabilityMessages = response.product.availability.messages;\n if (!response.product.readyToOrder) {\n availabilityValue = `
${response.resources.info_selectforstock}
`;\n } else if (response.product.availability.orderable) {\n availabilityMessages.forEach(message => {\n availabilityValue += `
${message}
`;\n });\n }\n\n if ($('.js-personalizeButtonModal').length > 0) {\n $productContainer = $('.tingle-modal-box__content');\n }\n\n $('.js-soldOut-message').addClass('hidden');\n if (!response.product.available || response.product.comingSoon || response.product.isSizeInexistent) {\n $('.js-soldOut-message').removeClass('hidden');\n $('.js-selected-size:not(.js-selected-size-not-available)').text('-');\n }\n\n $($productContainer).trigger('product:updateAvailability', {\n product: response.product,\n $productContainer: $productContainer,\n message: availabilityValue,\n resources: response.resources\n });\n\n if ($productContainer.hasClass('js-intProductDetail')) {\n if (response.product.isSoldout === true) {\n $productContainer.addClass('cc-isSoldOut js-isSoldOut');\n } else {\n $productContainer.removeClass('cc-isSoldOut js-isSoldOut');\n }\n }\n};\n\n/**\n * Generates html for quick add form\n *\n * @param {string} pid - pid used to get variation\n * @param {string} url - url of the Controller\n * @return Compiled HTML\n */\nconst showQuickAddItems = (pid, url) => {\n if ($('.js-modal-quick-add-size-quantity').attr('data-pid') === pid) {\n $('.js-modal-quick-add-size-quantity').removeClass('hidden');\n return;\n }\n $('.select-size-quick-add-container').empty();\n $.spinner().start();\n $.ajax({\n url: url,\n method: 'GET',\n data: {\n pid: pid\n },\n success: function (data) {\n $('.select-size-quick-add-container[data-pid=\"' + pid + '\"]').html(data);\n const $productContainer = $('.select-size-quick-add-container[data-pid=\"' + pid + '\"]').closest('.product-detail-quick-add');\n $productContainer.find('.add-to-cart-quick-add').attr('data-quantity', 1);\n var selectedValue = $productContainer.find('.add-to-cart-quick-add').attr('data-size-selected');\n if (selectedValue) {\n $productContainer.find('[data-attr-id=\"' + selectedValue + '\"]').attr('checked', true);\n $productContainer.find('.add-to-cart-quick-add').attr('data-size-available', true);\n } else {\n $productContainer.find('.add-to-cart-quick-add').attr('data-size-available', false);\n $productContainer.find('.size-selected').empty();\n }\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n};\n\n/**\n * @typedef UpdatedOptionValue\n * @type Object\n * @property {string} id - Option value ID for look up\n * @property {string} url - Updated option value selection URL\n */\n\n/**\n * @typedef OptionSelectionResponse\n * @type Object\n * @property {string} priceHtml - Updated price HTML code\n * @property {Object} options - Updated Options\n * @property {string} options.id - Option ID\n * @property {UpdatedOptionValue[]} options.values - Option values\n */\n\n/**\n * Updates DOM using post-option selection Ajax response\n *\n * @param {OptionSelectionResponse} options - Ajax response options from selecting a product option\n * @param {jQuery} $productContainer - DOM element for current product\n */\nconst updateOptions = (options, $productContainer) => {\n options.forEach(option => {\n const $optionEl = $productContainer.find(`.product-option[data-option-id*=\"${option.id}\"]`);\n option.values.forEach(value => {\n const valueEl = $optionEl.find(`option[data-value-id*=\"${value.id}\"]`);\n valueEl.val(value.url);\n });\n\n option.values.forEach(value => {\n const valueEl = $optionEl.find(`input[id=\"${value.id}\"]`);\n valueEl.data('href', value.url);\n valueEl.attr('href', value.url);\n });\n });\n};\n\nconst updateColorFamily = (product, $productContainer) => {\n $productContainer.find('.family-color').text(product.colorFamily.toLowerCase() + ' - ');\n\n for (let attr of product.variationAttributes) {\n if (attr.attributeId === 'color') {\n if (attr.onSaleSelected) {\n $productContainer.find('.product-color-sales.on-sale').removeClass('hidden');\n $productContainer.find('.product-color-sales.not-on-sale').addClass('hidden');\n } else {\n $productContainer.find('.product-color-sales.on-sale').addClass('hidden');\n $productContainer.find('.product-color-sales.not-on-sale').removeClass('hidden');\n }\n }\n }\n};\n\nconst updatePrices = (product, $productContainer, resources) => {\n if (!product.variationAttributes ||\n !product.variationAttributes[0] ||\n product.variationAttributes[0].attributeId !== 'color') {\n return;\n }\n let selectorPrefix = '';\n if (product.variationAttributes[0].onSaleSelected || product.price.discountValue) {\n selectorPrefix = '.onSaleContainer';\n } else {\n selectorPrefix = '.notOnSaleContainer';\n }\n const priceSelector = selectorPrefix + '.prices .price';\n const priceInfoSelector = ':not(.js-omnibusLabel-wrapper) > .cc-priceOmnibusLabel .price-info';\n const $oldPriceInfoSelector = $(':not(.js-omnibusLabel-wrapper) > .cc-priceOmnibusLabel .js-oldPriceInfo');\n const $regularPriceInfoDiscountSelector = $('.js-priceInfo-discountValue');\n const $oldPriceInfoDiscountSelector = $('.js-oldPriceInfo-discountValue');\n const $pricePercentage = $('.js-pricePercentage');\n const $priceSelector = $(priceSelector, $productContainer).length ?\n $(priceSelector, $productContainer) :\n $(priceSelector);\n const $priceInfoSelector = $(priceInfoSelector, $productContainer).length ?\n $(priceInfoSelector, $productContainer) :\n $(priceInfoSelector);\n const priceInfoInSaleContainerSelector = '.cc-intProductDetail-colors .cc-priceOmnibusLabel .price-info';\n const $priceInfoInSaleContainerSelector = $(priceInfoInSaleContainerSelector, $productContainer);\n const priceInfoInSaleContainerSelector2 = '.cc-intProductDetail-colors .cc-priceOmnibusLabel .js-oldPriceInfo';\n const $priceInfoInSaleContainerSelector2 = $(priceInfoInSaleContainerSelector2, $productContainer);\n const $omnibusPricelForSpecificCountries = $('.js-intProductDetail-attributes-wrapper .js-priceOmnibusLabel .price-info');\n window.onSalesInfoPrice = $priceInfoInSaleContainerSelector.text();\n $priceSelector.replaceWith(product.price.html);\n const currentCountryOmnibus = $oldPriceInfoSelector.closest('.js-omnibusStack').data('currentcountry');\n const isRegularOmnibusCountry = $oldPriceInfoSelector.closest('.js-omnibusStack').data('omnibuscountry');\n if (product.price.sales.formattedPriceInfo) {\n $priceInfoSelector.parent().show();\n $priceInfoSelector.html(product.price.sales.formattedPriceInfo);\n const isCountryWithTooltip = currentCountryOmnibus === 'IT' || currentCountryOmnibus === 'ES' || currentCountryOmnibus === 'SI';\n if (isCountryWithTooltip && resources.tooltip_omnibus && $('i.omnibus-tooltip').length === 0) {\n $('.product-main-price.onSaleContainer .price').append('i

' + resources.tooltip_omnibus + '

');\n }\n if (isRegularOmnibusCountry) {\n $oldPriceInfoSelector.parent().show();\n $oldPriceInfoDiscountSelector.html(product.price.sales.oldPriceOmnibus.priceInfoDiscountValue + '%');\n $oldPriceInfoDiscountSelector.show();\n }\n $oldPriceInfoSelector.html(product.price.list.formatted);\n $regularPriceInfoDiscountSelector.html(product.price.discountValue + '%');\n $priceInfoInSaleContainerSelector.parent().addClass('hidden');\n $priceInfoInSaleContainerSelector2.parent().addClass('hidden');\n $omnibusPricelForSpecificCountries.parent().addClass('hidden');\n window.onSalesInfoPrice = product.price.sales.formattedPriceInfo;\n $priceInfoInSaleContainerSelector2.html(product.price.sales.oldPriceOmnibus.price);\n $pricePercentage.hide();\n } else {\n $priceInfoSelector.parent().hide();\n $priceInfoSelector.html('');\n if (window.onSalesInfoPrice) {\n if (currentCountryOmnibus === 'IT' || currentCountryOmnibus === 'ES' || currentCountryOmnibus === 'SI') {\n $omnibusPricelForSpecificCountries.parent().removeClass('hidden');\n $omnibusPricelForSpecificCountries.html(window.onSalesInfoPrice);\n } else if (isRegularOmnibusCountry) {\n $priceInfoInSaleContainerSelector.parent().removeClass('hidden');\n $priceInfoInSaleContainerSelector.html(window.onSalesInfoPrice);\n $priceInfoInSaleContainerSelector2.parent().removeClass('hidden');\n } else {\n $priceInfoInSaleContainerSelector.parent().removeClass('hidden');\n $priceInfoInSaleContainerSelector.html(window.onSalesInfoPrice);\n }\n }\n $oldPriceInfoSelector.parent().hide();\n $oldPriceInfoSelector.html('');\n if (product.price.discountValue) {\n $pricePercentage.show();\n }\n }\n\n if (product.doubleCurrency && product.doubleCurrency.html) {\n const $doubleCurrencyContainer = $('#descriptionSidebar .js-priceSecondCurrency', $productContainer);\n const innerContent = $(product.doubleCurrency.html).html();\n $doubleCurrencyContainer.html(innerContent);\n }\n\n $productContainer.find(selectorPrefix + ' .js-discount-msg').addClass('hidden');\n $productContainer.find(selectorPrefix + ' .js-promo-msg').addClass('hidden');\n if (product.price.discountValue) {\n $productContainer.find(selectorPrefix + ' .js-discount-msg')\n .html(`(${product.price.discountValue}%)`)\n .removeClass('hidden');\n if (product.promotions && product.promotions.length > 0) {\n if (product.promotions[0].calloutMsg) {\n $productContainer.find(selectorPrefix + ' .js-promo-msg')\n .html(product.promotions[0].calloutMsg)\n .removeClass('hidden');\n } else if (product.promotions[1] && product.promotions[1].calloutMsg) {\n $productContainer.find(selectorPrefix + ' .js-promo-msg')\n .html(product.promotions[1].calloutMsg)\n .removeClass('hidden');\n }\n }\n } else if (product.promotions && product.promotions.length > 0) {\n if (product.promotions[0].calloutMsg) {\n $productContainer.find(selectorPrefix + ' .js-promo-msg')\n .html(product.promotions[0].calloutMsg)\n .removeClass('hidden');\n } else if (product.promotions[1] && product.promotions[1].calloutMsg) {\n $productContainer.find(selectorPrefix + ' .js-promo-msg')\n .html(product.promotions[1].calloutMsg)\n .removeClass('hidden');\n }\n }\n\n $productContainer.find(selectorPrefix + ' .js-loyalty').addClass('hidden');\n $productContainer.find(selectorPrefix + ' .js-loyaltysale').addClass('hidden');\n if (product.price.saleType) {\n let saleType = product.price.saleType;\n if (saleType === 'loyalty1' || saleType === 'loyalty2' || saleType === 'loyalty3' || saleType === 'loyalty4') {\n saleType = 'loyalty';\n } else if (saleType === 'loyaltysale1' || saleType === 'loyaltysale2' || saleType === 'loyaltysale3' || saleType === 'loyaltysale4') {\n saleType = 'loyaltysale';\n }\n $productContainer.find(selectorPrefix + ' .js-' + saleType).removeClass('hidden');\n }\n\n if (product.comingSoon) {\n $productContainer.find('.comingSoonBox').removeClass('hide');\n $productContainer.find('.comingSoonLabel-pdp').removeClass('hidden');\n $productContainer.find(selectorPrefix + ' .js-new-msg').addClass('hidden');\n $productContainer.find(selectorPrefix + ' .js-green-msg').addClass('hidden');\n // $productContainer.find(selectorPrefix + '.js-promo-msg').addClass('hidden');\n } else {\n $productContainer.find('.comingSoonBox').addClass('hide');\n $productContainer.find('.comingSoonLabel-pdp').addClass('hidden');\n $productContainer.find(selectorPrefix + ' .js-new-msg').addClass('hidden');\n $productContainer.find(selectorPrefix + ' .js-green-msg').addClass('hidden');\n if (product.New) {\n $productContainer.find(selectorPrefix + ' .js-new-msg').removeClass('hidden');\n }\n if (product.isGreen) {\n $productContainer.find(selectorPrefix + ' .js-new-msg').addClass('hidden');\n $productContainer.find(selectorPrefix + ' .js-green-msg').removeClass('hidden');\n }\n // $productContainer.find(selectorPrefix + '.js-promo-msg').removeClass('hidden');\n }\n};\n\n/**\n * Parses JSON from Ajax call made whenever an attribute value is [de]selected\n * @param {Object} response - response from Ajax call\n * @param {Object} response.product - Product object\n * @param {string} response.product.id - Product ID\n * @param {Object[]} response.product.variationAttributes - Product attributes\n * @param {Object[]} response.product.images - Product images\n * @param {boolean} response.product.hasRequiredAttrsSelected - Flag as to whether all required\n * attributes have been selected. Used partially to\n * determine whether the Add to Cart button can be enabled\n * @param {jQuery} $productContainer - DOM element for a given product.\n */\nconst handleVariantResponseQuickAdd = (response, $productContainer, imagesShouldUpdate = true) => {\n if (response.product.variationAttributes) {\n updateAttrs(response.product.variationAttributes, $productContainer);\n }\n\n updateAvailability(response, $productContainer);\n\n $('body').trigger('product:updateAddToCartQuickAdd', {\n product: response.product,\n $productContainer: $productContainer\n }).trigger('product:statusUpdate', response.product);\n};\n\nconst updateImageSaveForLater = (product, $productContainer) => {\n $productContainer.find('.js-product-image-saveForLater').attr('src', product.images.small[0].url);\n $productContainer.find('.js-product-image-saveForLater').attr('alt', product.images.small[0].url);\n $productContainer.find('.js-product-image-saveForLater').attr('title', product.images.small[0].title);\n};\n\n/**\n * Parses JSON from Ajax call made whenever an attribute value is [de]selected\n * @param {Object} response - response from Ajax call\n * @param {Object} response.product - Product object\n * @param {string} response.product.id - Product ID\n * @param {Object[]} response.product.variationAttributes - Product attributes\n * @param {Object[]} response.product.images - Product images\n * @param {boolean} response.product.hasRequiredAttrsSelected - Flag as to whether all required\n * attributes have been selected. Used partially to\n * determine whether the Add to Cart button can be enabled\n * @param {jQuery} $productContainer - DOM element for a given product.\n */\nconst handleVariantResponse = (response, $productContainer, imagesShouldUpdate = true, variantType) => {\n if (response.product.variationAttributes) {\n updateAttrs(response.product.variationAttributes, $productContainer, variantType);\n updateColorFamily(response.product, $productContainer);\n updateScanTrustLink(response, $productContainer);\n }\n const $container = $('.js-composition-info');\n\n if (response.product.partTypes) {\n $container.empty();\n const html = `
`;\n $container.append(html);\n\n for (var k = 0; k < response.product.partTypes.length; k++) {\n if (k == 0) {\n var type = `${response.product.partTypes[k].type}: `;\n $container.append(type);\n }\n if (k < response.product.partTypes.length - 1) {\n if (response.product.partTypes[k].type == response.product.partTypes[k + 1].type) {\n var comp = `${response.product.partTypes[k].percentage} % ${response.product.partTypes[k].material}, `;\n $container.append(comp);\n } else {\n var comp = `${response.product.partTypes[k].percentage} % ${response.product.partTypes[k].material}`;\n var type = `
${response.product.partTypes[k + 1].type}: `;\n\n $container.append(comp);\n $container.append(type);\n }\n } else {\n var comp = `${response.product.partTypes[k].percentage} % ${response.product.partTypes[k].material} `;\n $container.append(comp);\n }\n }\n const endTag = `
`;\n $container.append(endTag);\n } else if (response.product.mainComposition) {\n $container.empty();\n const html = `
`;\n $container.append(html);\n\n for (var k = 0; k < response.product.mainComposition.length; k++) {\n if (k == response.product.mainComposition.length - 1) {\n var comp = `${response.product.mainComposition[k].percentage} % ${response.product.mainComposition[k].material} `;\n } else {\n var comp = `${response.product.mainComposition[k].percentage} % ${response.product.mainComposition[k].material}, `;\n }\n\n $container.append(comp);\n }\n const endTag = `
`;\n $container.append(endTag);\n }\n\n // Update primary images\n if (imagesShouldUpdate) {\n const primaryImageUrls = response.product.images;\n if ($productContainer.hasClass('product-quickview:not(.product-quickview--get-product)')) {\n if ($productContainer.find('.carousel-inner').hasClass('slick-initialized')) {\n $productContainer.find('.carousel-inner').slick('destroy');\n }\n $productContainer.find('.carousel-inner').empty();\n $productContainer.find('.product-link-carousel').attr('href', response.product.selectedProductUrl);\n\n primaryImageUrls.large.forEach((imageUrl, idx) => {\n let $carouselInner = $($('#outer').html());\n $productContainer.find('.carousel-inner').append($carouselInner);\n\n let $imgContainer = $carouselInner.find('img');\n $imgContainer.data('index', idx);\n $imgContainer.attr('id', null);\n $imgContainer.attr('src', imageUrl.url).removeClass('hidden');\n });\n\n if (Foundation.MediaQuery.atLeast('large')) {\n $productContainer.find('.carousel-inner').slick({\n slidesToShow: 1,\n slidesToScroll: 1,\n dots: false\n });\n }\n } else if ($productContainer.hasClass('product-quickview--get-product')) {\n if ($productContainer.find('.carousel-inner').hasClass('slick-initialized')) {\n $productContainer.find('.carousel-inner').slick('destroy');\n }\n $productContainer.find('.carousel-inner').empty();\n $productContainer.find('.product-link-carousel').attr('href', response.product.selectedProductUrl);\n\n primaryImageUrls.large.forEach((imageUrl, idx) => {\n let $carouselInner = $($('#outer').html());\n $productContainer.find('.carousel-inner').append($carouselInner);\n\n let $imgContainer = $carouselInner.find('img');\n $imgContainer.data('index', idx);\n $imgContainer.attr('id', null);\n $imgContainer.attr('src', imageUrl.url).removeClass('hidden');\n });\n\n $productContainer.find('.carousel-inner').slick({\n dots: false,\n arrows: false,\n slidesToShow: 2.35,\n infinite: false,\n slidesToScroll: 1,\n responsive: [\n {\n breakpoint: 1023,\n settings: {\n slidesToShow: 2.5\n }\n }]\n });\n } else {\n $('.mobile-gallery').slick('slickUnfilter');\n $productContainer.find('.primary-images .carousel-item').addClass('hidden');\n $productContainer.find('.js-intProductDetail-images-container .desktop-gallery-item').addClass('hidden');\n $productContainer.find('.cc-intProductDetail-images').addClass('hidden');\n $('#zoomModal').data('numberOfImages', primaryImageUrls.large.length);\n // For each image check if tag is generated otherwise generate it and change its src\n primaryImageUrls.large.forEach((imageUrl, idx) => {\n var resizedUrls = '';\n if (imageUrl.resizedUrls) {\n var srcSetArray = imageUrl.resizedUrls.map((element, index) => {\n return element + ' ' + imageUrl.sizes[index].scaleWidth + 'w';\n });\n resizedUrls = srcSetArray.join(',');\n }\n let $imgContainer = $productContainer.find('.primary-images').find(`img[data-index=\"${idx}\"]`);\n let $imgContainerDesktop = $productContainer.find('.js-intProductDetail-images-container').find(`img[data-index=\"${idx}\"]`);\n let $imgZoomModal = $productContainer.find('.js-zoomModal').find(`img[data-index=\"${idx}\"]`);\n let $imgZoomModalMobile = $productContainer.find('.js-zoomModalMobile').find(`img[data-index=\"${idx}\"]`);\n\n if (!$imgContainer.length) {\n let newCarouselSlideHtml = $('#outer').html().replaceAll('{imgIdx}', idx);\n $productContainer.find('.primary-images').slick('slickAdd', newCarouselSlideHtml);\n $imgContainer = $productContainer.find(`.primary-images img[data-index=\"${idx}\"]`);\n }\n if (!$imgContainerDesktop.length) {\n let $galleryItemContainer = $($('#outer-desktop').html().replaceAll('{imgIdx}', idx));\n $productContainer.find('.js-intProductDetail-images-container').append($galleryItemContainer);\n\n $imgContainerDesktop = $galleryItemContainer.find('img');\n $imgContainerDesktop.attr('data-index', idx);\n }\n if (!$imgZoomModal.length) {\n let $zoomTemplate = $($('#zoom-template').html());\n $productContainer.find('.js-zoomModal-content').append($zoomTemplate);\n\n $imgZoomModal = $zoomTemplate.find('img');\n $imgZoomModal.attr('data-index', idx);\n }\n\n if (!$imgZoomModalMobile.length) {\n let $zoomTemplate = $($('#zoom-template').html().replaceAll('{imgIdx}', idx));\n $productContainer.find('.js-zoomModal-content').append($zoomTemplate);\n\n $imgZoomModalMobile = $zoomTemplate.find('img');\n $imgZoomModalMobile.attr('data-index', idx);\n }\n\n if (imageUrl.resizedUrls) {\n $productContainer.find('.primary-images').find(`img[data-index=\"${idx}\"]`).attr('data-srcset', resizedUrls);\n $productContainer.find('.js-intProductDetail-images-container').find(`img[data-index=\"${idx}\"]`).attr('data-srcset', resizedUrls);\n if ($imgZoomModal.length) {\n $imgZoomModal.attr('srcset', resizedUrls).attr('data-srcset', resizedUrls);\n }\n if ($imgZoomModalMobile.length) {\n $imgZoomModalMobile.attr('srcset', resizedUrls).attr('data-srcset', resizedUrls);\n }\n }\n $imgZoomModalMobile.attr('src', imageUrl.url).attr('data-src', imageUrl.url).removeClass('hidden');\n $imgZoomModal.attr('src', imageUrl.url).attr('data-src', imageUrl.url).removeClass('hidden');\n $productContainer.find(`.cc-intProductDetail-images[data-index=\"${idx}\"]`).removeClass('hidden');\n $productContainer.find('.primary-images').find(`img[data-index=\"${idx}\"]`).attr('src', imageUrl.url).attr('data-src', imageUrl.url).removeClass('lazyloaded').addClass('lazyload');\n $productContainer.find('.js-intProductDetail-images-container').find(`img[data-index=\"${idx}\"]`).attr('src', imageUrl.url).attr('data-src', imageUrl.url).removeClass('lazyloaded').addClass('lazyload');\n $productContainer.find('.primary-images').find(`.carousel-item[data-index=${idx}]`).removeClass('hidden');\n $productContainer.find('.js-intProductDetail-images-container').find(`.desktop-gallery-item[data-index=${idx}]`).removeClass('hidden');\n });\n const videoUrl = response.product.videoURL;\n $('.primary-images .js-productVideoContainer').remove();\n $('.js-intProductDetail-images-container .js-productVideoContainer').remove();\n if (videoUrl) {\n // insert primary video in mobile carousel\n let tmpl = $('.js-productVideoContainerOuter').clone()[0];\n tmpl.setAttribute('class', 'carousel-item cc-productVideoContaner js-productVideoContainer');\n $productContainer.find('.primary-images').slick('slickAdd', tmpl, 2, true);\n\n // insert primary video in desktop gallery\n tmpl = $($('#pdp-video-template-desktop').html());\n let $secondItem = $productContainer.find('.js-intProductDetail-images-container .desktop-gallery-item')[1];\n tmpl.insertAfter($secondItem);\n\n $productContainer.find('.js-productVideoContainer source').attr('src', videoUrl);\n\n let videoBlock = $productContainer.find('.js-productVideoContainer video');\n if (videoBlock && videoBlock.length > 0) {\n videoBlock[0].load();\n videoBlock[0].autoplay = true;\n }\n videoListener();\n }\n $('.primary-images').slick('slickGoTo', 0);\n $('.primary-images').slick('slickFilter', ':not(.hidden)');\n if (primaryImageUrls.small.length > 0) {\n $('.still-life-img').data('still-life', primaryImageUrls.small[0].url);\n }\n\n updatePrimaryImagesSlider(primaryImageUrls.large);\n }\n }\n\n // Update pricing\n if (response.product.price) {\n updatePrices(response.product, $productContainer, response.resources);\n }\n\n updateAvailability(response, $productContainer);\n // Enable \"Add to Cart\" button if all required attributes have been selected\n $('button.js-add-to-cart, button.add-to-cart-global, button.update-cart-product-global').trigger('product:updateAddToCart', {\n product: response.product,\n $productContainer: $productContainer\n }).trigger('product:statusUpdate', response.product);\n\n if ($('.js-personalizeButtonModal').length == 0) {\n careAndMaintenance(response.product.id);\n }\n\n var countryEnabled = window.PersonalizationEnabledCountries.PersonalizationEnabledCountries;\n if (response.variation.isPersonalizedVal && response.variation.positions > 0 && countryEnabled) {\n showButton(response);\n } else {\n $('#personalizeButton').addClass('hidden');\n }\n\n updateModelSize(response, $productContainer);\n};\n\nconst updateModelSize = (response, $productContainer) => {\n $('.js-product-model-size').addClass('hide');\n var modelSize = response.product.modelSize;\n if (!modelSize) {\n return;\n }\n\n $('.js-product-model-size').removeClass('hide').find('.js-modelSizeValue').text(modelSize);\n};\n\nconst handleVariationUrlsSelectSizeModal = (variationUrls) => {\n variationUrls.forEach(function (element) {\n $('#whislistSizeSelection-' + element.id).attr('data-attr-info-url', element.variationUrl);\n });\n};\nconst handlePromotionTag = (product, $productContainer) => {\n $productContainer.find('.js-promo-msg').addClass('hidden');\n if (product.promotions && product.promotions.length > 0) {\n for (var i = 0; i < product.promotions.length; i++) {\n if (product.promotions[i].promotionClass === 'PRODUCT' && product.promotions[i].calloutMsg) {\n $productContainer.find('.js-promo-msg').html(product.promotions[i].calloutMsg).removeClass('hidden');\n break;\n }\n }\n }\n};\n\nconst handleVariationUrlsSelectNotifyModal = (variationUrls) => {\n variationUrls.forEach(function (element) {\n if ((element.id).indexOf('/') != -1) {\n let cleanId = (element.id).split('/')[0] + '\\\\/' + (element.id).split('/')[1];\n $('#' + cleanId).attr('data-url', element.variationUrl);\n $('#' + cleanId).parent().attr('sku', element.sku);\n $('.add-size-saveForLater input[data-attr-value=\"' + cleanId + '\"]').parent().removeClass('disabled');\n if (!element.selectable) {\n $('.add-size-saveForLater input[data-attr-value=\"' + cleanId + '\"][data-sku=\"' + element.sku + '\"]').parent().addClass('disabled');\n }\n } else {\n $('#' + element.id).attr('data-url', element.variationUrl);\n $('#' + element.id).parent().attr('data-sku', element.sku);\n $('#' + element.id).attr('data-sku', element.sku);\n $('#' + element.id).attr('data-allocation', element.allocation);\n $('#' + element.id).parent().find('.js-container').removeClass('notifyPopup').removeClass('notifyMe');\n $('#' + element.id + '_mobile').parent().find('.js-container').removeClass('notifyPopup').removeClass('notifyMe');\n $('.js-add-size-saveForLater input[data-attr-value=\"' + element.id + '\"]').parent().removeClass('cc-disabled');\n $('.js-add-size-saveForLater input[data-attr-value=\"' + element.id + '\"]').parent().removeClass('cc-selected');\n if (element.selectable === false) {\n $('.js-add-size-saveForLater input[data-attr-value=\"' + element.id + '\"]').parent().addClass('cc-disabled');\n }\n if (element.selected === true) {\n $('.js-add-size-saveForLater input[data-attr-value=\"' + element.id + '\"]').parent().addClass('cc-selected');\n }\n if (element.allocation === 0 || element.isComingSoon) {\n $('.js-add-size-saveForLater input[data-attr-value=\"' + element.id + '\"]').parent().addClass('cc-disabled');\n $('#' + element.id).parent().find('.js-container').addClass('notifyMe').addClass('notifyPopup');\n $('#' + element.id + '_mobile').parent().find('.js-container').addClass('notifyMe').addClass('notifyPopup');\n }\n }\n });\n};\n\nconst handleVariationComingSoonNotifyModal = (comingSoons) => {\n comingSoons.forEach(function (element) {\n if ((element.id).indexOf('/') != -1) {\n let cleanId = (element.id).split('/')[0] + '\\\\/' + (element.id).split('/')[1];\n $('#' + cleanId).attr('data-isComingSoon', element.isComingSoon);\n } else {\n $('#' + element.id).attr('data-isComingSoon', element.isComingSoon);\n }\n });\n};\nconst handleVariationComingSoon = (comingSoons) => {\n if (!comingSoons) {\n $('.marketing-budge.js-comingSoonBox').addClass('hide');\n $('.js-comingSoonBox.pdp-comingSoonBox').addClass('hide');\n } else {\n $('.marketing-budge.js-comingSoonBox').removeClass('hide');\n $('.js-comingSoonBox.pdp-comingSoonBox').removeClass('hide');\n }\n};\n\nconst handleVariationWishlistModal = (variationUrls) => {\n variationUrls.forEach(function (element) {\n if ((element.id).indexOf('/') != -1) {\n let cleanId = (element.id).split('/')[0] + '\\\\/' + (element.id).split('/')[1];\n $('#fis-select-size-wishlist').find('#whislistSizeSelection').find('button*[data-attr-value=\"' + cleanId + '\"]').attr('data-attr-info-url', element.variationUrl);\n $('#fis-select-size-wishlist').find('#whislistSizeSelection').find('button*[data-attr-value=\"' + cleanId + '\"]').attr('data-attr-selectable', element.selectable ? 'selectable' : 'not-selectable');\n } else {\n $('#fis-select-size-wishlist').find('#whislistSizeSelection').find('button*[data-attr-value=\"' + element.id + '\"]').attr('data-attr-info-url', element.variationUrl);\n $('#fis-select-size-wishlist').find('#whislistSizeSelection').find('button*[data-attr-value=\"' + element.id + '\"]').attr('data-attr-selectable', element.selectable ? 'selectable' : 'not-selectable');\n }\n });\n};\n\n/**\n * This is a workaround for inexisting sizes for the cart's quick view.\n * It should be handled at decorator level but the list of actual variants is incoherent.\n */\nconst handleInexistentSizeQuickView = (data) => {\n if (!data.product.isSizeInexistent || !$('.quickview-modal').length) {\n return;\n }\n\n $('.product-content-size').find('input[data-size-id]').removeClass('hide')\n .closest('.boolean-field').removeClass('hide')\n .closest('.label-wrapper').removeClass('hide');\n};\n\nfunction showButton (response) {\n // $('#iconPersMobile').removeClass('hidden');\n if (response.variation.isPersonalizedVal === true) {\n $('#personalizeButton').removeClass('hidden');\n } else {\n $('#personalizeButton').addClass('hidden');\n }\n $('#personalizeButton')\n .attr('product-id', response.product.id)\n .attr('data-positions', response.variation.positions)\n .attr('data-customizations', response.variation.customizations)\n .attr('data-personalizationImgTop', response.variation.personalizationImgTop)\n .attr('data-personalizationImgDown', response.variation.personalizationImgDown);\n\n var link = $('#personalizeButton').attr('data-url') + '?pid=' + response.product.id +\n '&positions=' + response.variation.positions +\n '&quantity=' + response.product.selectedQuantity;\n $('#personalizeButton a').attr('href', link);\n $('#personalizeButton button').attr('data-url', link);\n\n var linkPlp = $('#personalizeButton').attr('data-url') + '?pid=' + response.product.id +\n '&positions=' + response.variation.positions +\n '&quantity=' + response.product.selectedQuantity +\n '&sizeAttribute=' + $('.persButtonPdpPers').attr('size-attribute');\n\n $('#persButtonPdpPersLink').attr('href', linkPlp);\n}\n\nfunction careAndMaintenance (pid) {\n $('#main-and-care-label-wash-description').removeClass('hidden');\n $('#main-and-care-label').addClass('hidden');\n\n if (!$('#main-and-care').length) {\n return;\n }\n\n $.ajax({\n url: $('#main-and-care').attr('data-url'),\n data: {\n pid: pid\n },\n method: 'GET',\n success: data => {\n $('#cm-container').empty().html(data.html);\n $.spinner().stop();\n },\n error: () => {\n $.spinner().stop();\n }\n });\n}\n\n/**\n * @typespec UpdatedQuantity\n * @type Object\n * @property {boolean} selected - Whether the quantity has been selected\n * @property {string} value - The number of products to purchase\n * @property {string} url - Compiled URL that specifies variation attributes, product ID, options,\n * etc.\n */\n\n/**\n * Updates the quantity DOM elements post Ajax call\n * @param {UpdatedQuantity[]} quantities -\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nconst updateQuantities = (quantities, $productContainer) => {\n if (!($productContainer.parent('.bonus-product-item').length > 0)) {\n const optionsHtml = quantities.map(quantity => {\n const selected = quantity.selected ? 'selected' : '';\n return ``;\n }).join('');\n if ($productContainer.hasClass('product-detail-quick-add')) {\n $('.quantity-select-quick-add').empty().html(optionsHtml);\n } else {\n getQuantitySelector($productContainer).empty().html(optionsHtml);\n }\n }\n};\n\n/**\n * Retrieves url to use when adding a product to the cart\n *\n * @return {string} - The provided URL to use when adding a product to the cart\n */\nconst getAddToCartUrl = () => {\n return $('.add-to-cart-url').val();\n};\n\n/**\n * Parses the html for a modal window\n * @param {string} html - representing the body and footer of the modal window\n *\n * @return {Object} - Object with properties body and footer.\n */\nconst parseHtml = html => {\n var $html = $('
').append($.parseHTML(html));\n\n var body = '';\n let $results = $html.find('.choice-of-bonus-product');\n for (let i = 0; i < $results.length; i++) {\n body += $results[i].outerHTML;\n }\n var footer = $html.find('.modal-footer').children().html();\n\n return {\n body: body,\n footer: footer\n };\n};\n\n// Generates a PID based on the current selected attributes\nconst getPID = (product) => {\n if (typeof product === 'string') {\n return product.trim();\n }\n\n // size and color have already been selected. In this case, the variation\n // group is built with the style of the product, 'color' and the selected\n // color variation\n if (product.productType === 'variant') {\n let sku = product.id;\n return sku;\n } else if (product.productType === 'variationGroup') {\n // in this case the user only chose the color, and not the size\n let pid = product.id.split('_')[0].trim();\n\n let selectedVariation;\n\n for (let k in product.variationAttributes) {\n const variationAttribute = product.variationAttributes[k];\n if (variationAttribute.attributeId === 'color') {\n for (let j in variationAttribute.values) {\n if (variationAttribute.values[j].selected === true) {\n selectedVariation = variationAttribute.values[j].value;\n break;\n }\n }\n }\n if (selectedVariation !== undefined) {\n break;\n }\n }\n\n return pid + '_color_' + selectedVariation;\n }\n\n return '';\n};\n\n/**\n * Updates the Mini-Cart quantity value after the customer has pressed the \"Add to Cart\" button\n * @param {string} response - ajax response from clicking the add to cart button\n */\nconst handlePostCartAdd = (response) => {\n $('.js-mainHeader-minicart').trigger('count:update', response);\n \n const cookies = document.cookie.split(';');\n let cookieSizebaySessionId = null;\n for (let i = 0; i < cookies.length; i++) {\n const cookie = cookies[i].trim();\n if (cookie.startsWith('SIZEBAY_SESSION_ID_V4')) {\n cookieSizebaySessionId = cookie.substring('SIZEBAY_SESSION_ID_V4='.length).replaceAll('\"', '');\n break;\n }\n };\n\n if (cookieSizebaySessionId === null) {\n let urlSessionId = document.querySelector('#sizebayAddProduct').getAttribute('data-sizebaysessionidurl');\n fetch(urlSessionId)\n .then(response => {\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n return response.json();\n })\n .then(data => {\n createCookie('SIZEBAY_SESSION_ID_V4', data);\n callSizebayAPI(data);\n })\n } else {\n callSizebayAPI(cookieSizebaySessionId);\n }\n};\n\nfunction callSizebayAPI(data) {\n let url = document.querySelector('#sizebayAddProduct').getAttribute('data-sizebay-link') + '=' + data;\n let brandURL = document.querySelector('#sizebayAddProduct').getAttribute('data-referrer-sizebay-link');\n let currentCountry = document.querySelector('#sizebayAddProduct').getAttribute('data-sizebay-locale');\n if (!brandURL.includes(currentCountry)) {\n brandURL += '/' + currentCountry + '/';\n }\n let permaURL = brandURL + document.querySelector('.analytics.product.hidden').getAttribute('data-item_id');\n let urlSizebay = new URL(url);\n if (urlSizebay.searchParams.has('sid') && urlSizebay.searchParams.get('sid') === 'null') {\n urlSizebay.searchParams.set('sid', data.trim().replace(/^\"|\"$/g, ''));\n url = urlSizebay.toString();\n }\n let payload = JSON.stringify({\n \"products\": [\n {\n \"permalink\": permaURL\n }\n ],\n \"tenantId\": 2399\n });\n\n let device = $('.cc-intProductDetail-left-content .cell .js-intProductDetail-images-container.cc-intProductDetail-images-container').css('display') === 'block' ? 'mobile' : 'desktop';\n let referrerURL = new URL(window.location.href);\n try {\n fetch(url, {\n method: 'POST',\n body: payload,\n referrerPolicy: \"origin-when-cross-origin\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n tenant_id: '2399',\n device: device,\n referer: referrerURL.hostname\n }\n });\n } catch (error) {\n console.error(\"Error: \", error);\n }\n}\n\nfunction updateQuantityPicker (source) {\n if (source === null || source.closest('.js-pdpStickyBar-btn').length > 0 || source.closest('.js-customizePage').length > 0) {\n source = $('.attribute-container.quantity');\n } else {\n source = source.closest('.attribute-container.quantity');\n }\n\n let value = parseInt(source.find('.js-quantity-value').html());\n if (value === 10) {\n source.find('.js-quantity-button[data-action=\"increase\"]').addClass('disabled');\n source.find('.js-quantity-button[data-action=\"decrease\"]').removeClass('disabled');\n if ($('.js-pdpStickyBar-btn').length > 0) {\n $('.js-pdpStickyBar-btn .js-quantity-button[data-action=\"increase\"]').addClass('disabled');\n $('.js-pdpStickyBar-btn .js-quantity-button[data-action=\"decrease\"]').removeClass('disabled');\n }\n } else if (value === 1) {\n source.find('.js-quantity-button[data-action=\"decrease\"]').addClass('disabled');\n source.find('.js-quantity-button[data-action=\"increase\"]').removeClass('disabled');\n if ($('.js-pdpStickyBar-btn').length > 0) {\n $('.js-pdpStickyBar-btn .js-quantity-button[data-action=\"decrease\"]').addClass('disabled');\n $('.js-pdpStickyBar-btn .js-quantity-button[data-action=\"increase\"]').removeClass('disabled');\n }\n } else {\n source.find('.js-quantity-button[data-action=\"increase\"]').removeClass('disabled');\n source.find('.js-quantity-button[data-action=\"decrease\"]').removeClass('disabled');\n if ($('.js-pdpStickyBar-btn').length > 0) {\n $('.js-pdpStickyBar-btn .js-quantity-button[data-action=\"increase\"]').removeClass('disabled');\n $('.js-pdpStickyBar-btn .js-quantity-button[data-action=\"decrease\"]').removeClass('disabled');\n }\n }\n}\n\nconst calculateWatchedTime = (video) => {\n let percentageWatched = video.currentTime * 100 / video.duration;\n return percentageWatched;\n};\n\nconst triggerVideoInteractionEvent = (action, fullPageLoad) => {\n $('body').trigger('analytics:videoInteraction', {action: action, fullPageLoad: fullPageLoad});\n};\n\nconst videoListener = (fullPageLoad = false) => {\n const $videoBlockContainer = $('.js-productVideoContainer');\n const $videoPlayMiniatureIcon = $('.productVideoMiniatureMobile.js-productVideoMiniatureMobile').find('.videoMiniatureIcon');\n let percentageWatched = 0;\n let firstPlayback = true;\n let watchedFullVideo = false;\n let videoStartInSeconds = 0;\n let videoEndInSeconds = 0;\n if ($videoBlockContainer.length > 0 && !$videoBlockContainer.hasClass('hidden')) {\n var myVideo = $videoBlockContainer.find('video')[0];\n myVideo.onended = function () {\n myVideo.currentTime = 0;\n };\n myVideo.onplaying = function () {\n if (myVideo.autoplay) {\n triggerVideoInteractionEvent('auto_play', fullPageLoad);\n }\n myVideo.autoplay = false;\n };\n myVideo.onpause = function () {\n if (!firstPlayback) {\n watchedFullVideo = videoEndInSeconds - videoStartInSeconds > myVideo.duration;\n triggerVideoInteractionEvent('pause', fullPageLoad);\n if (watchedFullVideo) {\n triggerVideoInteractionEvent('full_view', fullPageLoad);\n } else if (percentageWatched >= 25 && percentageWatched < 50) {\n triggerVideoInteractionEvent('view25', fullPageLoad);\n } else if (percentageWatched >= 50 && percentageWatched < 75) {\n triggerVideoInteractionEvent('view50', fullPageLoad);\n } else if (percentageWatched >= 75 && percentageWatched < 100) {\n triggerVideoInteractionEvent('view75', fullPageLoad);\n } else if (percentageWatched === 100) {\n triggerVideoInteractionEvent('full_view', fullPageLoad);\n }\n }\n firstPlayback = false;\n };\n $('.js-pauseVideoIcon').on('click', function () {\n myVideo.loop = false;\n percentageWatched = calculateWatchedTime(myVideo);\n videoEndInSeconds = new Date().getTime() / 1000;\n myVideo.pause();\n myVideo.currentTime = 0;\n $videoBlockContainer.find('.js-pauseVideoIcon').addClass('hide');\n $videoBlockContainer.find('.js-playVideoIcon').removeClass('hide');\n $videoPlayMiniatureIcon.removeClass('black-border');\n });\n $('.js-playVideoIcon').on('click', function () {\n myVideo.loop = true;\n $videoBlockContainer.find('.js-pauseVideoIcon').removeClass('hide');\n $videoBlockContainer.find('.js-playVideoIcon').addClass('hide');\n $videoPlayMiniatureIcon.addClass('black-border');\n if (myVideo.paused && !myVideo.autoplay) {\n triggerVideoInteractionEvent('play', fullPageLoad);\n }\n videoStartInSeconds = new Date().getTime() / 1000;\n myVideo.play();\n });\n }\n};\n\n/**\n * reorder the swatches in $swatchContainer in order to push the soldout ones at the end\n */\nconst reorderSwatches = ($swatchContainer) => {\n if ($swatchContainer.find('span.swatch-value.soldout').length === 0) {\n return;\n }\n var $soldoutColorsContainers = $swatchContainer.find('span.swatch-value.soldout').closest('div');\n var $lastNonSoldoutColorContainer = $swatchContainer.find('span.swatch-value').closest('div').not($soldoutColorsContainers).last();\n $soldoutColorsContainers.insertAfter($lastNonSoldoutColorContainer);\n};\n\nclass ProductHelpers {\n constructor () {\n this.freeGiftDetailsModal = 'freeGiftDetailsModal';\n this.bonusProductModal = null;\n this.methods = {\n getPidValue: function ($el) {\n return getPidValue($el);\n }\n };\n }\n\n run () {\n this.colorAttribute();\n this.colorAttributeQuickAddListing();\n this.sizeAttribute();\n this.sizeAttributeQuickAddListing();\n this.sizeAttributeQuickAddPDP();\n this.sizeAttributeSet();\n this.quantity();\n this.availability();\n this.addToCart();\n // this.selectBonusProduct();\n // this.removeBonusProduct();\n // this.enableBonusProductSelection();\n // this.showMoreBonusProducts();\n // this.closeBonusProductModal();\n // this.enableAddAfterBonusColorSelection();\n // this.removeSizePickerPopup();\n // this.addBonusProductsToCart();\n // this.handleBonusSize();\n // this.handleBonusColor();\n // this.removeColorPickerPopup();\n this.careAndMaintenanceClick();\n this.personalizationButton();\n this.sizeTU();\n this.quickAddListener();\n videoListener(true);\n NotifyHelper.notifyMeModal();\n this.checkSoldoutAvailability();\n SmartGiftHelper.run();\n sizePanel.init();\n this.registerAttributionTokenSending();\n this.loadGoogleRecommendations();\n this.createNextPageToken();\n }\n\n personalizationButton () {\n $('body').on('click', '.persButt', (e) => {\n e.preventDefault();\n // Simulate disabled button with class to allow click and event\n if ($(e.currentTarget).data('disabled') || !this.isSizeSelected()) {\n // If no size is selected, open modal to choose one\n\n if ($(e.currentTarget).closest('.quickview-modal').length) {\n // QuickView (Open the other modal type)\n\n let modal = $('.js-modal-quick-size-quantity');\n // First check if it is open\n if (modal.hasClass('open')) {\n // Check if size is selected, then add to cart\n } else {\n // Show it\n modal.removeClass('hidden').addClass('open');\n modal.find('.slick-slider.slick-initialized').slick('refresh');\n\n modal.find('.js-close-select-size').on('click', function (e) {\n modal.addClass('hidden').removeClass('open');\n });\n }\n } else if (!($(e.currentTarget).hasClass('persButtMobile') && !$('.pdp-buy-look-container').hasClass('hidden'))) {\n sizePanel.openSizePanel(sizePanel.Types.PERSONALIZE);\n }\n\n // Prevent further progress until a size is selected\n e.preventDefault();\n } else {\n if ($('.jsPersonalizationToolModal').length === 0) {\n let url = $(e.currentTarget).attr('data-url') || $(e.currentTarget).data('url');\n $.get(url, function (data) {\n if (data && data !== '') {\n let modal = newModalFromString(data, true, ['jsPersonalizationToolModal'], () => {\n // TODO: On Open Actions\n $('.tingle-modal .close').on('click touchstart', function (e) {\n e.preventDefault();\n modal.close();\n modal.destroy();\n });\n }, () => {\n // TODO: On Close Actions\n $('[data-attr=\"size\"] input.js-mobile-size-selected').prop('checked', true);\n });\n $(modal.modalBox).addClass('rightModalAttribute cc-detailsPopup-modalBox rightModalAttribute_sizeXtraLarge');\n modal.open();\n runPersonalizationListener();\n }\n });\n }\n }\n });\n }\n\n careAndMaintenanceClick () {\n $(document).on('click', '.js-caremaintenance-container ul.tabs li', function () {\n $('.js-caremaintenance-container ul.tabs li').removeClass('current');\n $('.tab-content').removeClass('current');\n $(this).addClass('current');\n const description = $(this).data('tab');\n $(`#${description}`).addClass('current');\n });\n }\n\n colorAttribute () {\n $('body').on('click', '[data-attr=\"color\"] a', e => {\n e.preventDefault();\n if ($(e.currentTarget).attr('disabled') || $(e.currentTarget).find('.swatch-value').hasClass('selected')) {\n return;\n }\n var $productContainer = $(e.currentTarget).closest('.set-item');\n if (!$productContainer.length) {\n $productContainer = $(e.currentTarget).closest('.product-detail');\n }\n\n if (!$productContainer.length && $(e.currentTarget).hasClass('saveToLater')) {\n $productContainer = $('.wishlist-product-card').closest('.product-detail');\n }\n\n let imagesShouldUpdate = true;\n if ($productContainer.hasClass('cart-line-item')) {\n imagesShouldUpdate = false;\n }\n attributeSelect(e.currentTarget.href, $productContainer, 'color', imagesShouldUpdate);\n let color = $productContainer.prevObject.children('span').data('attr-value');\n var firstPart = $productContainer.attr('data-pid');\n var firstPartSplit = firstPart.split('_');\n var firstPartSKU = '';\n if (firstPartSplit.length > 1) {\n firstPartSKU = firstPartSplit[0];\n } else {\n firstPartSKU = firstPart;\n }\n\n var sku = null;\n let splitSku = firstPartSKU ? firstPartSKU.replace(/\\s+/g, '_').split('_') : [];\n let productId = splitSku[0];\n\n if ($('.page[data-action=\"Product-Show\"]').length > 0) {\n let size = $('.selected-size-value').first().text().trim();\n $('#analyticsSelectedColor').val(color);\n\n sku = size && size !== 'false' ? productId + '_' + color + '_' + size : productId + '_' + color;\n $('body').trigger('product:didChangeColor', {sku: sku});\n } else if ($('.page[data-action=\"Cart-Show\"]').length > 0) {\n let selectedSize = $('.cc-cartQuickView_selectedSize').attr('for');\n let colorValue = $(e.currentTarget).data('color-value');\n $('#analyticsSelectedColor').val(colorValue);\n\n sku = selectedSize ? productId + '_' + colorValue + '_' + selectedSize : productId + '_' + colorValue;\n $('body').trigger('product:didChangeColor', {sku: sku});\n }\n });\n\n $('body').on('click', '.product-detail [data-attr=\"color\"] a', e => {\n if ($(e.currentTarget).parents('.quickview-modal').length !== 0) {\n return;\n }\n // Get new color to push to query string\n var selectedColor = $(e.currentTarget).data('color-value');\n if (!selectedColor) {\n return;\n }\n // Perform URL query string update\n updateProductDetailUrl('_col_', selectedColor);\n });\n }\n\n colorAttributeQuickAddListing () {\n $('body').on('click', '[data-attr=\"color-listing\"] a', e => {\n e.preventDefault();\n if ($(e.currentTarget).attr('disabled') || $(e.currentTarget).find('.swatch-value').hasClass('selected')) {\n return;\n }\n\n var url = $(e.currentTarget).attr('href');\n $.spinner().start();\n $.ajax({\n url: url,\n type: 'GET',\n success: function (data) {\n const $productTile = $(e.target).closest('.product-tile-cell');\n $productTile.html(data);\n startCarouselTileImageFunction($productTile.find('.js-tileImageCarousel'));\n $('body').trigger('product:didChangeColor');\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n });\n }\n\n sizeAttribute () {\n $('body').on('change', '[data-attr=\"size\"] input', e => {\n e.preventDefault();\n $('.size-available').attr('available', true);\n const selectedValue = $(e.currentTarget).attr('value');\n $('#size').attr('size-attribute', $(e.currentTarget).attr('data-attr-value'));\n $('.persButtonPdpPers').attr('size-attribute', $(e.currentTarget).attr('data-attr-value'));\n if (selectedValue === 'null') {\n return;\n }\n\n let $productContainer = $(e.currentTarget).closest('.set-item');\n if (!$productContainer.length) {\n if ($(e.currentTarget).hasClass('js-add-size-saveForLater')) {\n var sku = $(e.currentTarget).data('sku');\n $productContainer = $(e.currentTarget).closest('.cart-line-item-sku-' + sku);\n } else {\n $productContainer = $(e.currentTarget).closest('.product-detail');\n }\n }\n if ($(e.currentTarget).closest('.product-quickview') && $(e.currentTarget).closest('.product-quickview').length) {\n $('.selectSizeQuickView').removeClass('toSelect');\n }\n if ($(e.currentTarget).closest('.js-complete-your-promo-quick-view')) {\n $(e.currentTarget).closest('.js-complete-your-promo-quick-view').find('.add-to-cart-global').data('disabled', false);\n }\n\n let ignoreCTA = $('.js-prod-select-size-modal').length && !Foundation.MediaQuery.atLeast('large');\n let isPdp = $('.page').data('action') && $('.page').data('action').toLowerCase().indexOf('product-show') > -1;\n let isPeronalizePage = $('#personalize-page');\n if (isPdp && isPeronalizePage) {\n $productContainer = $('.js-intProductDetail');\n }\n if ($('.js-complete-your-promo-quick-view').length > 0) {\n $productContainer = $('.js-complete-your-promo-quick-view');\n }\n if (isPdp && $('.js-prod-select-size-modal').length || isPeronalizePage && $('.js-prod-select-size-modal').length) {\n ignoreCTA = false;\n }\n\n let imagesShouldUpdate = true;\n if ($productContainer.hasClass('cart-line-item') || $productContainer.hasClass('js-complete-your-promo-quick-view') ) {\n imagesShouldUpdate = false;\n }\n attributeSelect(selectedValue, $productContainer, 'size', imagesShouldUpdate, ignoreCTA);\n var sizeData = $(e.currentTarget).data('attr-value');\n var skuData = $productContainer.data('variant-pid');\n skuData = skuData ? decodeURI(skuData).replace(/\\s+/g, '_') : '';\n\n let color = $('#analyticsSelectedColor').val();\n let splitSkuData = skuData ? skuData.split('_') : [];\n\n skuData = splitSkuData.length >= 2 && color.trim().length > 0 ? splitSkuData[0] + '_' + color : skuData;\n\n if ($('.page[data-action=\"Product-Show\"]').length > 0) {\n $('body').trigger('product:didChangeSize', { size: sizeData, sku: skuData });\n } else if ($('.page[data-action=\"Cart-Show\"]').length > 0) {\n $('body').trigger('product:didChangeSize', { size: sizeData, sku: skuData });\n }\n });\n $('.js-container').on('keydown', function (e) {\n if (e.type === 'keydown' && e.originalEvent.code === 'Enter') {\n $(e.currentTarget).trigger('click');\n }\n });\n $('body').on('change', '[data-attr=\"size-mobile\"] input', e => {\n e.preventDefault();\n $(\"[data-attr='size-mobile'] input\")\n .removeClass('js-mobile-size-selected')\n .closest('.js-intProductDetail-size-item')\n .removeClass('cc-intProductDetail-size-item_selected');\n $(e.currentTarget)\n .addClass('js-mobile-size-selected')\n .closest('.js-intProductDetail-size-item')\n .addClass('cc-intProductDetail-size-item_selected');\n let selectedSize = $(e.currentTarget).data('size-id');\n let $sizeSelectedeElem = $(`[data-size-id=\"${selectedSize}\"]`);\n $sizeSelectedeElem.each(function (element) {\n $(this).closest('.js-intProductDetail-size-item').addClass('cc-intProductDetail-size-item_selected');\n });\n $('js-sizeBox-openPanel').attr('');\n $('.js-selectedSizeMobile').text($(e.currentTarget).data('size-value'));\n $('#product-error-msg-mobile').addClass('invisible');\n $('#product-error-msg').hide();\n });\n $('body').on('click', '.js-linkMobileModalConfirmSize', e => {\n let $sizeSelected = $(\"[data-attr='size-mobile'] input.js-mobile-size-selected\");\n $('.size-available').attr('available', true);\n const selectedValue = $sizeSelected.attr('value');\n $('#size').attr('size-attribute', $sizeSelected.attr('data-attr-value'));\n $('.persButtonPdpPers').attr('size-attribute', $sizeSelected.attr('data-attr-value'));\n if (selectedValue === undefined || selectedValue === null || selectedValue === 'null') {\n $('#product-error-msg-mobile').removeClass('invisible');\n return;\n }\n $('#product-error-msg-mobile').addClass('invisible');\n\n let $productContainer = $sizeSelected.closest('.set-item');\n if (!$productContainer.length) {\n $productContainer = $sizeSelected.closest('.product-detail');\n }\n if ($sizeSelected.closest('.product-quickview') && $sizeSelected.closest('.product-quickview').length) {\n $('.selectSizeQuickView').removeClass('toSelect');\n }\n\n let ignoreCTA = $('.js-prod-select-size-modal').length && !Foundation.MediaQuery.atLeast('large');\n let isPdp = $('.page').data('action') && $('.page').data('action').toLowerCase().indexOf('product-show') > -1;\n let isPeronalizePage = $('#personalize-page');\n if (isPdp && $('.js-prod-select-size-modal').length || isPeronalizePage && $('.js-prod-select-size-modal').length) {\n ignoreCTA = false;\n }\n\n let imagesShouldUpdate = true;\n if ($productContainer.hasClass('cart-line-item')) {\n imagesShouldUpdate = false;\n }\n attributeSelect(selectedValue, $productContainer, 'size', imagesShouldUpdate, ignoreCTA);\n var sizeData = null;\n var skuData = null;\n if ($('.page[data-action=\"Product-Show\"]').length > 0) {\n sizeData = $sizeSelected.attr('data-attr-value');\n skuData = $productContainer.data('master-pid');\n }\n $('body').trigger('product:didChangeSize', { size: sizeData, sku: skuData });\n });\n $('body').on('change', '[data-attr=\"size\"] input', e => {\n e.preventDefault();\n $(\"[data-attr='size'] input\")\n .removeClass('js-mobile-size-selected')\n .closest('.js-intProductDetail-size-item')\n .removeClass('cc-intProductDetail-size-item_selected');\n $(e.currentTarget)\n .addClass('js-mobile-size-selected');\n let selectedSize = $(e.currentTarget).data('size-id');\n let $sizeSelectedeElem = $(`[data-size-id=\"${selectedSize}\"]`);\n $sizeSelectedeElem.each(function (element) {\n $(this).closest('.js-intProductDetail-size-item').addClass('cc-intProductDetail-size-item_selected');\n });\n $('#product-error-msg').hide();\n });\n }\n\n sizeAttributeQuickAddListing () {\n $('body').on('click', '.quick-buy-sizes-item', function (e) {\n e.preventDefault();\n\n const selectedValue = $(e.currentTarget).data('url');\n if (selectedValue === 'null') {\n return;\n }\n\n let $productContainer = $(e.currentTarget).closest('.product-tile');\n let imagesShouldUpdate = true;\n if ($productContainer.hasClass('cart-line-item')) {\n imagesShouldUpdate = false;\n }\n attributeSelect(selectedValue, $productContainer, 'size', imagesShouldUpdate, true);\n $('body').trigger('product:didChangeSize');\n });\n\n $('body').on('quickBuy:addToCart', function (e, data) {\n if (!$('.modal-size-show').length) {\n return;\n }\n\n $('.modal-size-show').find('.js-add-to-cart').data('pid', data.product.id).trigger('click');\n $('body').trigger('quickBuy:afterAddToCart');\n });\n }\n\n sizeAttributeQuickAddPDP () {\n if ($('.page').data('action') !== 'Product-Show') {\n return;\n }\n $('body').on('click', '.js-quick-buy-sizes-item-pdp', function (e) {\n e.preventDefault();\n if ($(this).hasClass('disable') || !$(this).data('variant')) {\n return false;\n }\n\n var url = $(this).data('variant');\n $.spinner().start();\n $.ajax({\n url: url,\n type: 'GET',\n dataType: 'json',\n success: function (response) {\n $.spinner().stop();\n const $productContainer = $(e.target);\n\n // For minicart promo carousel\n var promotionId = $productContainer.closest('.product').find('.promotion-info-plp').data('promo-id') || false;\n\n if (response.product.available && !response.product.comingSoon) {\n addToCartFromListing(response.product.id, promotionId, $productContainer);\n } else {\n $('body').trigger('product:afterAddToCartFailed', {\n ...response,\n $productContainer\n });\n }\n },\n error: function (err) {\n console.error('ErrorCase: ' + err.message);\n $.spinner().stop();\n }\n });\n });\n }\n\n sizeAttributeSet () {\n $('.set-size').on('click', function (e) {\n $($(e.currentTarget).closest('.product-content-size')[0]).children('.set-size').children('.radio-label-set').removeClass('setsize-selected');\n $(e.currentTarget).children('.radio-label-set').addClass('setsize-selected');\n const selectedValue = e.currentTarget.children[0].value;\n if (selectedValue === 'null') {\n return;\n }\n\n var $productContainer = $(e.currentTarget).closest('.product-detail');\n attributeSelect(selectedValue, $productContainer, 'size', false);\n\n $('body').trigger('product:didChangeSize');\n });\n }\n\n isSizeSelected () {\n if ($('.page-checkout').length > 0 || $('.cart-page').length > 0 || $('.modal-size-show').length > 0 || isMiniCartOpen()) {\n return true;\n }\n return $('[data-attr=\"size\"] input:checked').length > 0;\n };\n\n quantity () {\n updateQuantityPicker(null);\n\n $('body').on('click', '.js-quantity-button', function (e) {\n const $button = $(this);\n var $target = $button.closest('.quantity').find('.js-quantity-value');\n var $input = $button.closest('.quantity').find('.quantity-select');\n if ($button.hasClass('js-quantity-button-quick-add')) {\n $target = $button.closest('.quantity').find('.js-quantity-value-quick-add');\n $input = $button.closest('.quantity').find('.quantity-select-quick-add');\n }\n const value = parseInt($target.text());\n if ($button.data('action') === 'increase' && value < 10 && !$button.hasClass('disabled')) {\n let newValue = value + 1;\n $('.js-quantity-value').text(newValue);\n $input.val(newValue);\n\n $('.update-cart-url').data('selected-quantity', newValue);\n $(`[data-opener=\"QNT\"] .attribute-selection`).html(newValue);\n\n updateQuantityPicker($button);\n $input.trigger('change');\n } else if ($button.data('action') === 'decrease' && value > 1 && !$button.hasClass('disabled')) {\n let newValue = value - 1;\n $('.js-quantity-value').text(newValue);\n $input.val(newValue);\n $('.update-cart-url').data('selected-quantity', newValue);\n $(`[data-opener=\"QNT\"] .attribute-selection`).html(newValue);\n\n updateQuantityPicker($button);\n $input.trigger('change');\n }\n });\n }\n\n availability () {\n $('body').on('change', '.quantity-select', e => {\n e.preventDefault();\n\n var $productContainer = $(e.currentTarget).closest('.product-detail');\n if (!$productContainer.length) {\n $productContainer = $(e.currentTarget).closest('.modal-content').find('.product-quickview');\n }\n if (!$productContainer.length) {\n $productContainer = $(e.currentTarget).closest('.product-tile-modal');\n }\n\n if ($('.bundle-items', $productContainer).length === 0) {\n attributeSelect($(e.currentTarget).find('option:selected').data('url'),\n $productContainer, '_', false);\n }\n });\n $('body').on('change', '.quantity-select-quick-add', e => {\n e.preventDefault();\n\n var $productContainer = $(e.currentTarget).closest('.product-detail-quick-add');\n if ($('.bundle-items', $productContainer).length === 0) {\n attributeSelectQuickAdd($(e.currentTarget).find('option:selected').data('url'),\n $productContainer, '_', false);\n }\n });\n }\n\n addToCart () {\n $('body').on('click', 'button.js-add-to-cart, button.add-to-cart-global, button.js-add-to-cart-multipack', (e) => {\n const _openStickySizeSelectorModal = (target) => {\n if ($(e.currentTarget).hasClass('add-to-cart-multipack')) {\n sizePanel.openSizePanel(sizePanel.Types.ADDTOCART_BUNDLE);\n } else if ($(e.currentTarget).closest('.js-pdpStickyBar-btn').length > 0) {\n $('.js-pdpStickyBar-select').addClass('cc-sizeBox-isOpen');\n } else {\n if ($('.cc-intProductDetail-size-item_selected').length === 0) {\n $('#product-error-msg-mobile').removeClass('invisible');\n }\n sizePanel.openSizePanel(sizePanel.Types.ADDTOCART);\n }\n $('.pdp-size-box .js-sizeBox-openPanel').addClass('cc-sizeBox-openPanel_error');\n $('#product-error-msg').show();\n $('.pdp-size-box .js-sizeBox-openPanel').attr('aria-invalid', 'true');\n };\n\n let addToCartUrl;\n let pid;\n let pidsObj;\n let setPids;\n let isPersonalizedProduct = $('.js-personalizeButtonCheckout').length > 0;\n\n let target = e.currentTarget;\n if ($(target).closest('.js-addToCartStickyBar').length > 0) {\n // open the size modal\n _openStickySizeSelectorModal(target);\n return;\n }\n if ($(target).closest('.js-addToCartStickyBar').length > 0) {\n // close quickview modal\n _openStickySizeSelectorModal(target);\n }\n\n var $productContainer = $(e.currentTarget).closest('.product-detail');\n\n if (!$productContainer.length) {\n $productContainer = $(e.currentTarget).closest('.quickview-modal').find('.product-detail');\n }\n\n if (!$productContainer.length) {\n $productContainer = $('.quickview-modal').find('.product-detail');\n }\n\n if (!$productContainer.length) {\n $productContainer = $('.product-detail');\n }\n\n const GTMItem = getGtmData({\n item_id: $('.analytics.product').attr('data-item_id'),\n item_variant: $('.analytics.product').attr('data-item_variant')\n });\n\n // here we add the personalized product - if there is the personalizeButtonCheckout button, we are adding a pers product\n if (isPersonalizedProduct) {\n var text = $('.form-text').val();\n\n // here we check the symbolType - in personalization we store the symbols with a number. Here we substitute them with character\n /*\n if ($('.form-symbolType').val() != '') {\n var symbol = $('.form-symbol').val();\n\n switch (symbol) {\n case '1':\n symbol = '/_%*_';\n break;\n case '2':\n symbol = '-_%*_';\n break;\n case '3':\n symbol = '__%*_';\n break;\n case '4':\n symbol = '*_%*_';\n break;\n }\n\n switch ($('.form-symbolType').val()) {\n case 'letters':\n switch ($('.form-text').val().length) {\n case 1:\n text = $('.form-text').val()[0] + symbol;\n break;\n case 2:\n text = $('.form-text').val()[0] + symbol + $('.form-text').val()[1];\n break;\n case 3:\n text = $('.form-text').val()[0] + $('.form-text').val()[1] + symbol + $('.form-text').val()[2];\n break;\n case 4:\n text = $('.form-text').val()[0] + $('.form-text').val()[1] + symbol + $('.form-text').val()[2] + $('.form-text').val()[3];\n break;\n }\n\n break;\n case 'nameSymbol':\n text = $('.form-text').val() + symbol;\n break;\n case 'symbolName':\n text = symbol + $('.form-text').val();\n break;\n default:\n text = $('.form-text').val();\n }\n }\n */\n var personalizationText = text;\n var personalizationTextFont;\n personalizationTextFont = $('.form-font').val().indexOf('GillSansNova') > -1\n ? 'Avant'\n : ($('.form-font').val().indexOf('Didot') > -1\n ? 'Didot'\n : $('.form-font').val().indexOf('Altastgreeting') > -1\n ? 'Altastgreeting'\n : '');\n\n var personalizationColorPref = window.PersonalizationColor.personalizationColor;\n var personalizationColorJson = JSON.parse(personalizationColorPref);\n\n var personalizationTextColor;\n for (var i = 0; i < personalizationColorJson.length; i++) {\n if (personalizationColorJson[i].alt === $('.form-color').val()) {\n var src = personalizationColorJson[i].src;\n src = src.substring(0, src.lastIndexOf('.'));\n personalizationTextColor = src;\n }\n }\n\n var personalizationPositionKey = $('.form-position').val();\n\n // ----\n\n var customizationClassPref = window.CustomizationClass.customizationClass;\n var customizationClassJson = JSON.parse(customizationClassPref);\n var category = $('#category').attr('category-attribute');\n personalizationPositionKey = (customizationClassJson[category]['customizationPositions'] === 1)\n ? customizationClassJson[category]['0']\n : customizationClassJson[category][($('.form-position').val()).toString()];\n\n // ----\n\n var personalizationTextSVG = $('#base64').attr('data-fullTextSVG');\n var personalizationFullSVG = $('#base64').attr('data-fullSVG');\n var personalizationSmallSVG = $('#base64').attr('data-smallSVG');\n\n $.spinner().start();\n\n addToCartUrl = $('#custom-page').attr('data-url');\n var quantity = $('.js-quantity-value').html();\n var uniqueIdentifiers = {};\n for (var i = 0; i < quantity; i++) {\n var random = Math.random();\n var id = 'uniqueIdentifier' + i;\n uniqueIdentifiers[id] = random;\n }\n uniqueIdentifiers = JSON.stringify(uniqueIdentifiers);\n\n if ($('#pidToAdd').attr('pidRecentlyAdded') == undefined) {\n // $('#custom-page').attr('data-pid', $('#pidToAdd').attr('data-pid'));\n $('#pidToAdd').attr('isToLoad', 'false');\n }\n\n if ($('#pidToAdd').attr('isToLoad') == 'true') {\n $('#custom-page').attr('data-pid', $('#pidToAdd').attr('pidRecentlyAdded'));\n }\n\n $('#pidToAdd').attr('pidRecentlyAdded', $('.personalizeButtonBtn').attr('product-id'));\n\n if (quantity > 1) {\n var form = {\n pid: $('.personalizeButtonBtn').attr('product-id'),\n quantity: quantity,\n personalizedObj: true,\n uniqueIdentifiers: uniqueIdentifiers, // Random value\n personalizationText: personalizationText,\n personalizationTextFont: personalizationTextFont,\n personalizationTextColor: personalizationTextColor,\n personalizationPositionKey: personalizationPositionKey,\n personalizationTextSVG: personalizationTextSVG,\n personalizationFullSVG: personalizationFullSVG,\n personalizationSmallSVG: personalizationSmallSVG,\n isDate: $('.choice-item.choice-item-3').hasClass('active'),\n isLove: $('#love').hasClass('active'),\n GTMItemListName: GTMItem.item_list_name,\n GTMItemListId: GTMItem.item_list_id,\n GTMIndex: GTMItem.index\n };\n } else {\n var form = {\n pid: $('.personalizeButtonBtn').attr('product-id'),\n quantity: quantity,\n personalizedObj: true,\n uniqueIdentifier: Math.random(), // Random value\n personalizationText: personalizationText,\n personalizationTextFont: personalizationTextFont,\n personalizationTextColor: personalizationTextColor,\n personalizationPositionKey: personalizationPositionKey,\n personalizationTextSVG: personalizationTextSVG,\n personalizationFullSVG: personalizationFullSVG,\n personalizationSmallSVG: personalizationSmallSVG,\n isDate: $('.choice-item.choice-item-3').hasClass('active'),\n isLove: $('#love').hasClass('active'),\n GTMItemListName: GTMItem.item_list_name,\n GTMItemListId: GTMItem.item_list_id,\n GTMIndex: GTMItem.index\n };\n }\n $('.js-customizePage .js-customizePage-icon_pageClose').trigger('click');\n } else {\n // ------\n if (!$(e.currentTarget).hasClass('product-set')) {\n // Simulate disabled button with class to allow click and event\n if ($(e.currentTarget).data('disabled') || !this.isSizeSelected()) {\n $('.persButtonPdpAdd').show();\n $('.persButtonPdpPers').hide();\n // If no size is selected, open modal to choose one\n if (!$('.cc-text.selected-size-msg.show-when-size-selected')) {\n $('#newsletter-error-msg').toggle();\n }\n if ($(e.currentTarget).closest('.quickview-modal').length) {\n // QuickView (Open the other modal type)\n\n let modal = $('.js-modal-quick-size-quantity');\n // First check if it is open\n if (modal.hasClass('open')) {\n // Check if size is selected, then add to cart\n } else {\n // Show it\n modal.removeClass('hidden').addClass('open');\n modal.find('.slick-slider.slick-initialized').slick('refresh');\n\n modal.find('.js-close-select-size').on('click', function (e) {\n modal.addClass('hidden').removeClass('open');\n });\n if ($('.js-modal-quick-size-quantity [data-attr=\"size\"] input#TU:checked').length > 0\n && $('.quickview-modal .global-availability').data('ready-to-order')) {\n $('.quickview-modal').find('button.add-to-cart-global').data('disabled', false);\n }\n if (Foundation.MediaQuery.is('small')) {\n $('.quickview-modal .wrapper-details').animate({\n scrollTop: $('.wrapper-inner-quick-bottom').eq(0).offset().top\n }, 500);\n }\n }\n } else {\n _openStickySizeSelectorModal(e.currentTarget);\n }\n\n // Prevent further progress until a size is selected\n return;\n }\n }\n\n $('body').trigger('product:beforeAddToCart', e.currentTarget);\n\n if ($('.set-items').length && $(e.currentTarget).hasClass('add-to-cart-global')) {\n setPids = [];\n\n $('.product-detail').each(function () {\n if (!$(e.currentTarget).hasClass('product-set-detail')) {\n setPids.push({\n pid: $(e.currentTarget).find('.product-id').text(),\n qty: $(e.currentTarget).find('.quantity-select').val(),\n options: []\n });\n }\n });\n pidsObj = JSON.stringify(setPids);\n }\n\n pid = getPidValue($(e.currentTarget));\n // console.log(pid);\n\n if ($(target).closest('div.js-pdpStickyBar-btn').length > 0) {\n $productContainer.addClass('analytics-addToCart-sticky');\n }\n\n addToCartUrl = getAddToCartUrl();\n\n let uid = $(e.currentTarget).data('uid');\n\n var pidSet;\n var buttonAdd = $('button.js-add-to-cart, button.add-to-cart-global, button.update-cart-product-global');\n\n for (var j = 0; j < buttonAdd.length; j++) {\n if (uid === $(buttonAdd[i]).data('uid')) {\n pidSet = $(buttonAdd[i]).attr('data-pid');\n }\n }\n\n var promoId = $('.js-promo-msg.marketing-budge', $productContainer).first().data('promotion-id') || false;\n\n // ------\n var form = {\n pid: pid || pidSet,\n pidsObj: pidsObj,\n childProducts: [],\n quantity: getQuantitySelected($(e.currentTarget)),\n uuid: uid,\n promoId: promoId,\n GTMItemListName: GTMItem.item_list_name,\n GTMItemListId: GTMItem.item_list_id,\n GTMIndex: GTMItem.index\n };\n\n if (!$('.bundle-item').length) {\n form.options = [];\n }\n\n if ($('.js-complete-your-promo').length > 0) {\n $('.js-complete-the-promo-status').val($('.js-complete-the-promo-status').val() - form.quantity);\n form.completePromoItems = $('.js-complete-the-promo-status').val();\n $productContainer.addClass('analytics-completeYourPromo');\n }\n }\n\n $(e.currentTarget).trigger('updateAddToCartFormData', form);\n $('body').trigger('updateQuickAddToCartModal', form);\n if (addToCartUrl) {\n $.ajax({\n url: addToCartUrl,\n method: 'POST',\n data: form,\n success: data => {\n $.spinner().stop();\n if (data.error && isPersonalizedProduct) {\n $('.content-input-err').removeClass('hidden');\n } else {\n if (data.completePromoItemsLabel && data.completePromoItemsLabel !== '' && $('.js-completeYourPromo-header_remaining').length > 0) {\n $('.js-completeYourPromo-header_remaining').html(data.completePromoItemsLabel);\n if (form.completePromoItems === '0') {\n $('.js-completeYourPromo-header_remaining').addClass('cc-cartPromotionModal-footer_completed');\n }\n }\n $('body').trigger('product:afterAddToCart', {\n ...data,\n form,\n $productContainer\n });\n data.quantityTotal = data.cart ? data.cart.numItems : data.cartModel.numItems;\n handlePostCartAdd(data);\n }\n },\n error: () => {\n $.spinner().stop();\n }\n });\n }\n });\n }\n\n /*\n selectBonusProduct () {\n $('body').on('click', '.select-bonus-product', function () {\n var $choiceOfBonusProduct = $(this).parents('.choice-of-bonus-product');\n var pid = $(this).data('pid');\n var maxPids = $('.choose-bonus-product-dialog').data('total-qty');\n var submittedQty = parseInt($(this).parents('.choice-of-bonus-product').find('.bonus-quantity-select').val(), 10);\n var totalQty = 0;\n $.each($('#chooseBonusProductModal .selected-bonus-products .selected-pid'), function () {\n totalQty += $(this).data('qty');\n });\n totalQty += submittedQty;\n var optionID = $(this).parents('.choice-of-bonus-product').find('.product-option').data('option-id');\n var valueId = $(this).parents('.choice-of-bonus-product').find('.options-select option:selected').data('valueId');\n if (totalQty <= maxPids) {\n const selectedBonusProductHtml = `\n
\n\n
${$choiceOfBonusProduct.find('.product-name').html()}
'\n
\n \n
\n
`;\n\n $('#chooseBonusProductModal .selected-bonus-products').append(selectedBonusProductHtml);\n $('.pre-cart-products').html(totalQty);\n $('.selected-bonus-products .bonus-summary').removeClass('alert-danger');\n } else {\n $('.selected-bonus-products .bonus-summary').addClass('alert-danger');\n }\n });\n }\n */\n\n sizeTU () {\n if (document.getElementById('TU')) {\n document.getElementById('TU').click();\n }\n }\n\n quickAddListener () {\n $('body').on('click', '.js-panel-opener-size-quick-add', function (e, data) {\n /** open/close quickAdd modal**/\n e.preventDefault();\n if ($(this).find('.icon-toggle-top.triangle-dropdown-pdp').hasClass('icon-toggle-opened')) {\n $('.js-modal-quick-add-size-quantity').addClass('hidden');\n $('.product-detail-quick-add .icon-toggle-top.triangle-dropdown-pdp').removeClass('icon-toggle-opened');\n $('.product-detail-quick-add .size-opener-opened').addClass('hidden');\n $('.product-detail-quick-add .size-opener-closed').removeClass('hidden');\n } else {\n $('.product-detail-quick-add .icon-toggle-top.triangle-dropdown-pdp').removeClass('icon-toggle-opened');\n $(this).find('.icon-toggle-top.triangle-dropdown-pdp').addClass('icon-toggle-opened');\n var mustAdd = (data && data.mustAdd === true) || false;\n $(this).closest('.product-detail-quick-add').find('.add-to-cart-quick-add').data('mustAdd', mustAdd);\n const pid = $(this).attr('data-pid');\n const url = $(this).attr('data-get-url');\n $(this).find('.size-opener-opened').removeClass('hidden');\n $(this).find('.size-opener-closed').addClass('hidden');\n showQuickAddItems(pid, url);\n }\n });\n\n $('body').on('click', '.js-close-select-size-quick-add', function (e) {\n /** close quickAdd modal**/\n e.preventDefault();\n $('.js-modal-quick-add-size-quantity').addClass('hidden');\n $('.product-detail-quick-add .icon-toggle-top.triangle-dropdown-pdp').removeClass('icon-toggle-opened');\n $('.product-detail-quick-add .size-opener-opened').addClass('hidden');\n $('.product-detail-quick-add .size-opener-closed').removeClass('hidden');\n });\n\n $('body').on('change', '[data-attr=\"size_qa\"] input ', e => {\n /** change size and update attribute for the cart**/\n e.preventDefault();\n const selectedValue = $(e.currentTarget).attr('value');\n if (selectedValue === 'null') {\n return;\n }\n\n let $productContainer = $(e.currentTarget).closest('.product-detail-quick-add');\n if ($productContainer && $productContainer.length > 0) {\n attributeSelectQuickAdd(selectedValue, $productContainer, '_', false);\n $productContainer.find('.add-to-cart-quick-add').attr('data-size-available', true);\n $productContainer.find('.add-to-cart-quick-add').attr('data-size-selected', $(e.currentTarget).data('attr-id'));\n $productContainer.find('.add-to-cart-quick-add').removeClass('item-added-quick');\n }\n $('body').trigger('product:didChangeSize');\n });\n\n $('body').on('product:updateAddToCartQuickAdd', (e, response) => {\n /** manage response variation after size selection **/\n let availabilityValue = '';\n let availabilityMessages = response.product.availability.messages;\n var $productContainer = response.$productContainer;\n $productContainer.find('.response-message-quick-add').empty();\n if ($productContainer.find('[data-attr=\"size_qa\"] input:checked') && $productContainer.find('[data-attr=\"size_qa\"] input:checked').length > 0) {\n var sizeChecked = $productContainer.find('[data-attr=\"size_qa\"] input:checked').attr('data-display-value');\n $productContainer.find('.size-selected').text(sizeChecked);\n $productContainer.find('.response-message-quick-add').addClass('hidden');\n $productContainer.find('.add-to-cart-quick-add').attr('data-size-available', true);\n $productContainer.find('.add-to-cart-quick-add').attr('data-pid', response.product.id);\n $productContainer.find('.response-error-quick-add').addClass('hidden');\n }\n if (!response.product.readyToOrder) {\n $productContainer.find('.add-to-cart-quick-add').attr('data-disabled', true);\n $productContainer.find('.add-to-cart-quick-add').attr('disabled', true);\n } else if (!response.product.available || response.product.comingSoon) {\n $productContainer.find('.add-to-cart-quick-add').attr('data-disabled', true);\n $productContainer.find('.add-to-cart-quick-add').attr('disabled', true);\n availabilityMessages.forEach(message => {\n availabilityValue += `
${message}
`;\n });\n $productContainer.find('.response-message-quick-add').html(availabilityValue);\n } else {\n $productContainer.find('.add-to-cart-quick-add').attr('data-disabled', false);\n $productContainer.find('.add-to-cart-quick-add').attr('disabled', false);\n }\n });\n\n $('body').on('click', 'button.add-to-cart-quick-add', (e) => {\n if ($(e.currentTarget).closest('.completeYourLookContainer').length > 0) {\n localStorage.setItem('prevlisttypeforcart', localStorage.getItem('listtypeforcart'));\n localStorage.setItem('listtypeforcart', 'complete_your_look');\n }\n\n let addToCartUrl;\n let pidsObj;\n const $productContainer = $(e.currentTarget).closest('.product-detail-quick-add');\n // Simulate disabled button with class to allow click and event\n if ($(e.currentTarget).attr('data-size-available') !== 'true') {\n $productContainer.find('.response-message-quick-add').removeClass('hidden');\n return;\n } else if ($(e.currentTarget).attr('data-disabled') === 'true' || $(e.currentTarget).attr('data-disabled') === 'NaN') {\n return;\n }\n $productContainer.find('.response-message-quick-add').addClass('hidden');\n $productContainer.find('.response-error-quick-add').addClass('hidden');\n\n $('body').trigger('product:beforeAddToCart', e.currentTarget);\n\n let pid = $(e.currentTarget).attr('data-pid');\n let uid = $(e.currentTarget).attr('data-uid');\n let quantitySelected = parseInt($(e.currentTarget).attr('data-quantity')) || 1;\n\n addToCartUrl = getAddToCartUrl();\n\n let promoId = false;\n if ($('.promoCrossSellEnabled').length > 0) {\n promoId = $('.js-promo-msg.marketing-budge').first().data('promotion-id') || false;\n }\n\n const GTMItem = getGtmData({\n item_id: $('.analytics.product').attr('data-item_id'),\n item_variant: $('.analytics.product').attr('data-item_variant')\n });\n\n var form = {\n pid: pid,\n pidsObj: pidsObj,\n childProducts: [],\n quantity: quantitySelected,\n uuid: uid,\n promoId: promoId,\n GTMItemListName: GTMItem.item_list_name,\n GTMItemListId: GTMItem.item_list_id,\n GTMIndex: GTMItem.index\n };\n\n $(e.currentTarget).trigger('updateAddToCartFormData', form);\n if (addToCartUrl) {\n $.ajax({\n url: addToCartUrl,\n method: 'POST',\n data: form,\n success: data => {\n $.spinner().stop();\n if (data.error) {\n $productContainer.find('.response-error-quick-add').removeClass('hidden');\n } else {\n $('body').trigger('product:afterAddToCart', {\n ...data,\n form,\n $productContainer\n });\n data.quantityTotal = data.cart.numItems;\n handlePostCartAdd(data);\n $productContainer.find('.add-to-cart-quick-add').addClass('item-added-quick');\n $('.js-modal-quick-add-size-quantity').addClass('hidden');\n $('.product-detail-quick-add .icon-toggle-top.triangle-dropdown-pdp').removeClass('icon-toggle-opened');\n $('.product-detail-quick-add .size-opener-opened').addClass('hidden');\n $('.product-detail-quick-add .size-opener-closed').removeClass('hidden');\n }\n },\n error: () => {\n $.spinner().stop();\n }\n });\n }\n });\n }\n\n checkSoldoutAvailability () {\n if ($('.page').data('action') !== 'Product-Show') {\n return;\n }\n var $productContainer = $('div.product-detail.container').first();\n var attributesUpdateUrl = $productContainer.data('variationAttrUpdate');\n if (!attributesUpdateUrl) {\n return;\n }\n $.ajax({\n url: attributesUpdateUrl,\n method: 'GET',\n dataType: 'json',\n success: data => {\n if (data.product && data.product.variationAttributes) {\n updateAttrs(data.product.variationAttributes, $productContainer);\n updateAvailability(data, $productContainer);\n $('body').trigger('product:updateAddToCart', {\n product: data.product,\n $productContainer: $productContainer\n });\n // reorder swatches in order to push soldout colors in the laste positions\n reorderSwatches($('.js-carousel-select-color.not-sale-container'));\n reorderSwatches($('.js-carousel-select-color.on-sale-container'));\n }\n }\n });\n }\n registerAttributionTokenSending () {\n $('body').on('click', '.js-google-recommendations-container .js-prodTile', function () {\n const attributionToken = $(this).closest('.js-google-recommendations-container').data('attributionToken');\n createCookie('attribution_token', attributionToken);\n });\n }\n loadGoogleRecommendations () {\n const $googleConfig = $('.js-googleRecommendationConfig');\n if ($googleConfig.length) {\n const url = $('#googleRecommendationsUrl').val();\n const servingConfig = $googleConfig.data('servingConfig');\n const nodeToAppendTo = $googleConfig.data('nodeToAppendTo');\n const cgid = $('#primaryCategoryId').val();\n const sku = $('#variationGroupSku').val();\n const route = $('.page').data('action');\n\n $.ajax({\n type: 'GET',\n url: url,\n data: {\n cgid: cgid,\n sku: sku,\n route: route,\n servingConfig: servingConfig\n },\n success: function (html) {\n const $outputContainer = $(nodeToAppendTo).find('.google-recommendation-results');\n if (!$outputContainer.length) {\n $('
').appendTo(nodeToAppendTo);\n }\n $(nodeToAppendTo).find('.google-recommendation-results').empty().append(html);\n },\n error: function () {\n $('#youMayAlsoLikeContainer').addClass('hidden');\n }\n });\n }\n }\n\n createNextPageToken () {\n const $googleAttributionToken = $('.js-google-search-token');\n if ($googleAttributionToken.length) {\n const attributionToken = $googleAttributionToken.data('attributiontoken');\n const previousPageToken = $googleAttributionToken.data('nextpagetoken');\n const url = new URL(window.location.href);\n const searchTerm = url.searchParams.get('q');\n createCookie('prev_search_query', searchTerm);\n createCookie('search_attribution_token', attributionToken);\n if (previousPageToken !== null) {\n createCookie('previousPageToken', previousPageToken);\n }\n }\n }\n}\n\nconst productHelpers = new ProductHelpers();\nexport default productHelpers;\nexport {\n moveModalCloseButton,\n parseHtml,\n activatePromoAnimationMessage,\n updateColorFamily,\n updatePrices,\n updateAvailability,\n updateOptions,\n updateQuantities,\n isMiniCartOpen,\n isChooseBonusProductModalOpen,\n isQuickUpdateFromModal,\n isMobileDevice\n};\n","'use strict';\n\nclass Klarna {\n // Save ScalaPay widget element, waits for script to be loaded\n loadWidget () {\n if (document.getElementsByTagName('klarna-placement') && document.getElementsByTagName('klarna-placement')[0]) {\n $('body').on('product:afterAttributeSelect', function (e, response) {\n if (response.data.product.price.sales) {\n document.getElementsByTagName('klarna-placement')[0].setAttribute('data-purchase-amount', Math.round(response.data.product.price.sales.value * 100));\n window.KlarnaOnsiteService.push({ eventName: 'refresh-placements' });\n }\n });\n }\n }\n\n // Load Klarna widget and analytics observer\n loadKlarnaWidgetAndObservers () {\n if ($('.page').data('action') === 'Product-Show' || $('.page').data('action') === 'Cart-Show') {\n var _self = this;\n _self.loadWidget();\n\n var checkWidget = setInterval(function () {\n let klarnaPayWidget = $('klarna-placement');\n\n if (klarnaPayWidget.length) {\n clearInterval(checkWidget);\n _self.prepareObservers();\n }\n }, 2000);\n }\n }\n\n // Observe analytics event\n prepareObservers () {\n if (!$('klarna-placement div').length) {\n return;\n }\n $($('klarna-placement div')[0].shadowRoot).find('button.link').on('click', function () {\n $('body').trigger('klarnaPay:openModal');\n });\n }\n}\n\nconst klarna = new Klarna();\nexport default klarna;\n","'use strict';\n\nimport {\n newModalFromSelector\n} from '../components/modal';\n\nimport sizePanel from './sizePanel';\n\n// Checks if size is selected before adding to wishlist\nfunction isSizeSelected () {\n if ($('.page-checkout').length > 0 || $('.cart-page').length > 0) {\n return true;\n }\n if ($('.form-control.pdp-size-box.checkbox-size').length > 0 || $('.form-control.pdp-size-box.checkbox-quickview-mobile').length > 0) {\n return ($('.form-control.pdp-size-box.checkbox-size input:checked').length > 0 || $('.form-control.pdp-size-box.checkbox-quickview-mobile input:checked').length > 0);\n } else {\n return $('[data-attr=\"size\"] input:checked').length > 0;\n }\n};\n\n\n/**\n * Adapts FE to the current state of the wishlist:\n * - Add / Remove the `added` class to the correct target (either button or icon)\n * - Shows the \"correctly added\" / \"correctly removed\" notification\n * - Triggers ADD event for analytics\n * - Add/remove the PID from the ID in page to always have the correct state\n * (updateWishlistInternalState)\n * @param {string} data - data returned from the server's ajax call\n * @param {Object} icon - icon that was clicked to toggle a product to the wishlist\n * @param {boolean} isAddAction - if the te action was add or remove\n */\nfunction displayMessageAndChangeIcon (data, icon, isAddAction) {\n if (data.success) {\n $('body').trigger('wishlist:update', data.wishlistTotal);\n\n if (icon) {\n if (isAddAction) {\n if ($('.page').data('action') === 'Product-Show' && $('.js-pdpStickyBar').length > 0) {\n $('.wishlist-icon').addClass('added');\n $('.wishlist-icon').find('use').attr('href', icon.data('full-heart'));\n } else {\n icon.addClass('added');\n icon.find('use').attr('href', icon.data('full-heart'));\n }\n let sender = icon.data('analytics-sender') ? icon.data('analytics-sender') : '';\n $('body').trigger('wishlist:add', { sku: data.pid, sender: sender });\n } else {\n if ($('.page').data('action') === 'Product-Show' && $('.js-pdpStickyBar').length > 0) {\n $('.wishlist-icon').removeClass('added');\n $('.wishlist-icon').find('use').attr('href', icon.data('empty-heart'));\n } else {\n icon.removeClass('added');\n icon.find('use').attr('href', icon.data('empty-heart'));\n }\n }\n updateAriaLabelForWishlistLink($('.wishlist-icon'));\n icon.blur();\n }\n\n showWishlistNotification(data.renderedTemplate);\n\n updateWishlistInternalState(data.pid, isAddAction);\n }\n}\n\nfunction showWishlistNotification (html) {\n $('body').append(html);\n let offsetTop = 12;\n if (Foundation.MediaQuery.atLeast('large')) {\n offsetTop = $('.js-mainHeader').outerHeight() + 10;\n }\n $('.js-add-to-wishlist-notification').css({\n top: offsetTop\n });\n\n function closeNotification () {\n $('.js-add-to-wishlist-notification').off('click', '.js-close-notification');\n $('.js-add-to-wishlist-notification').remove();\n }\n\n $('.js-add-to-wishlist-notification').on('click', '.js-close-notification', closeNotification);\n\n setTimeout(closeNotification, 5000);\n}\n\n/**\n * Updates the internal state of the wishlist with the new item:\n * - adds the item in the state if the item was added\n * - removes the item if the item was removed\n * @param {string} pid - The PID of the product changed in the wishlist\n * @param {boolean} isAddAction - true if the item has been added, false is it has been removed\n */\nfunction updateWishlistInternalState (pid, isAddAction) {\n /** @type {Array.} */\n let oldItems = $('#wishlistItems').val().split(',');\n let newItems;\n if (isAddAction) {\n oldItems.push(pid);\n newItems = oldItems.join(',');\n } else {\n let oldIdx = oldItems.indexOf(pid);\n if (oldIdx > -1) {\n oldItems.splice(oldIdx, 1);\n newItems = oldItems.join(',');\n }\n }\n $('#wishlistItems').val(newItems);\n};\n\nfunction addDefinitelyToWishlist (sender, productID, e) {\n // If productID is set then it means that it belongs to an unavailable size\n // Add or remove from wishlist now!\n\n var btn = sender;\n var addURL = btn.data('href');\n var removeURL = btn.data('remove');\n\n let pid = '';\n if (productID === null) {\n pid = $('.product-detail-keeper').attr('data-variant-pid');\n } else {\n pid = productID;\n }\n var optionId = btn.closest('.product-detail-keeper').find('.product-option').attr('data-option-id');\n var optionVal = btn.closest('.product-detail-keeper').find('.options-select option:selected').attr('data-value-id');\n optionId = optionId || null;\n optionVal = optionVal || null;\n\n var shouldAdd = !btn.hasClass('added');\n\n if (!(addURL && removeURL) || !pid) {\n return;\n }\n\n $.spinner().start();\n $.ajax({\n url: shouldAdd ? addURL : removeURL,\n type: shouldAdd ? 'post' : 'get',\n dataType: 'json',\n data: {\n pid: pid,\n optionId: optionId,\n optionVal: optionVal\n },\n success: function (data) {\n // if (productID === null) {\n // displayMessageAndChangeIcon(data, btn, shouldAdd);\n // }\n if ($('.size-available').attr('available') != 'false') {\n displayMessageAndChangeIcon(data, btn, shouldAdd);\n }\n\n $('body').trigger('wishlist:changedSuccessfully', {\n data: data,\n isAdding: shouldAdd,\n pid: pid\n });\n var $productContainer = $(e.currentTarget).closest('.product-detail');\n\n if (!$productContainer.length) {\n $productContainer = $(e.currentTarget).closest('.quickview-modal').find('.product-detail');\n }\n\n if (!$productContainer.length) {\n $productContainer = $('.quickview-modal').find('.product-detail');\n }\n\n if (!$productContainer.length) {\n $productContainer = $('.product-detail');\n }\n if (shouldAdd) {\n $('body').trigger('product:afterAddToWishlist', { ...data, $productContainer });\n } else {\n $('body').trigger('product:afterRemoveFromWishlist');\n }\n $('body').trigger('wishlist:update', data.wishlistTotal);\n\n $.spinner().stop();\n },\n error: function (err) {\n $.spinner().stop();\n $('body').trigger('product:failedAddToWishlist');\n displayMessageAndChangeIcon(err, btn, shouldAdd);\n }\n });\n}\n\nfunction updateAriaLabelForWishlistLink (product) {\n var added = $(product).hasClass('added');\n var labelAddWishlist = product.data('label-add-wishlist');\n var labelRemoveWishlist = product.data('label-remove-wishlist');\n if (added) {\n product.attr('aria-label', labelRemoveWishlist);\n } else {\n product.attr('aria-label', labelAddWishlist);\n }\n}\n\nmodule.exports = {\n handleWishlistContainer: function (item) {\n if (module.exports.checkItemInWishlist(item)) {\n $('.wishlist-icon').addClass('added');\n $('.wishlist-icon').find('use').attr('href', $('.wishlist-icon').data('full-heart'));\n } else {\n $('.wishlist-icon').removeClass('added');\n $('.wishlist-icon').find('use').attr('href', $('.wishlist-icon').data('empty-heart'));\n }\n updateAriaLabelForWishlistLink($('.wishlist-icon'));\n },\n\n checkItemInWishlist: function (itemCode) {\n return $('#wishlistItems').length > 0 && $('#wishlistItems').val().split(',').indexOf(itemCode) > -1;\n },\n\n /**\n * Add the `added' class to the wishlist icon if the item is available in the wishlist.\n * It is not possible to do it in ISML because both the PDP and the PLP are cached\n *\n * Read the DOM element `#wishlistItems` and adds the `added` class to all the\n * `plp-wishlist` or `add-to-wish-list` items available in>\n * - quickview\n * - PDP\n * - PLP\n */\n highlightIconsForAllItemsInWishlist: function () {\n if (!$('#wishlistItems').length) {\n return;\n }\n\n var itemsInWishlist = $('#wishlistItems').val().split(',');\n for (var i = 0; i < itemsInWishlist.length; i++) {\n var itemCode = itemsInWishlist[i];\n\n let plpWishlist = $(`.product[data-pid=\"${itemCode}\"] .plp-wishlist`);\n let productDetailWishlist = $(`.product-detail[data-pid=\"${itemCode}\"] .add-to-wish-list`);\n\n plpWishlist.addClass('added');\n updateAriaLabelForWishlistLink(plpWishlist);\n plpWishlist.find('use').attr('xlink:href', plpWishlist.data('full-heart'));\n plpWishlist.blur();\n\n productDetailWishlist.addClass('added');\n updateAriaLabelForWishlistLink(productDetailWishlist);\n productDetailWishlist.find('use').attr('xlink:href', productDetailWishlist.data('full-heart'));\n productDetailWishlist.blur();\n }\n },\n\n moveToWishlistHelper: function (e) {\n if (!e) {\n return;\n }\n e.preventDefault();\n\n var $btn = $(e.currentTarget);\n var url = $btn.data('href');\n var pid = $btn.data('pid');\n\n $.spinner().start();\n return $.ajax({\n url: url,\n type: 'post',\n dataType: 'json',\n data: {\n pid: pid,\n optionId: null,\n optionVal: null\n },\n success: function (data) {\n displayMessageAndChangeIcon(data, null);\n },\n error: function (err) {\n displayMessageAndChangeIcon(err, null);\n }\n });\n },\n\n\n moveToWishlistHelperSaveForLater: function (e) {\n if (!e) {\n return;\n }\n e.preventDefault();\n\n var $btn = $(e.currentTarget);\n var url = $btn.data('href');\n var pid = $btn.data('pid');\n\n $.spinner().start();\n return $.ajax({\n url: url,\n type: 'post',\n dataType: 'json',\n data: {\n pid: pid,\n optionId: null,\n optionVal: null\n },\n success: function (data) {\n //displayMessageAndChangeIcon(data, null);\n },\n error: function (err) {\n displayMessageAndChangeIcon(err, null);\n }\n });\n },\n\n /**\n * Adds the current item referenced by the current target to the wishlist\n * and updates the front-end\n */\n addToWishlist () {\n $('body').on('click', '.add-to-wish-list', (e) => {\n e.preventDefault();\n let target = $(e.currentTarget);\n // Simulate disabled button with class to allow click and event\n if (($(e.currentTarget).hasClass('add-to-wish-list-quickview-mobile') && !isSizeSelected()) || ($(e.currentTarget).hasClass('wishlistButtMobile') && !$('.pdp-buy-look-container').hasClass('hidden'))) {\n return;\n } else if (!isSizeSelected()) {\n // If no size is selected, open modal to choose one\n if (target.closest('.product-quickview').length) {\n this.sizeModal = newModalFromSelector('fis-select-size-wishlist', false, ['js-prod-select-size-modal']);\n this.sizeModal.open();\n\n $(this.sizeModal.modalBox).find('.add-to-wish-list-confirm').attr('disabled', true);\n\n $(this.sizeModal.modalBox)\n .on('click', '.modal__closeIcon', (e) => {\n this.sizeModal.close();\n this.sizeModal.destroy();\n })\n .on('click', '.size-selector', (e) => {\n const $clickedButton = $(e.currentTarget);\n const sizeValue = $clickedButton.data('size-fixed');\n $clickedButton.closest('ul').find('button').not(e.currentTarget).removeClass('selected');\n $clickedButton.addClass('selected');\n\n const $inputToClick = $('[data-attr=\"size\"] input').filter(`[data-size-fixed=\"${sizeValue}\"]`);\n\n if ($clickedButton.data('attr-selectable') === 'selectable' && $inputToClick.prop('disabled') === false) {\n // Select size in PDP by passing click to attribute selector click only if selectable\n $inputToClick.trigger('click');\n $(this.sizeModal.modalBox).find('.add-to-wish-list-confirm').prop('disabled', false);\n $('.size-available').attr('available', true);\n } else {\n // Only if the size is not available\n let infoURL = $clickedButton.data('attr-info-url');\n if ($('.product-quickview').length > 0) {\n $('.product-quickview').find('.wishlist-icon').removeClass('added');\n $('.product-quickview').find('.wishlist-icon').find('use').attr('xlink:href', $('.wishlist-icon').data('empty-heart'));\n }\n var _self = this;\n $.spinner().start();\n $.ajax({\n url: infoURL,\n type: 'get',\n dataType: 'json',\n success: function (data) {\n $(_self.sizeModal.modalBox)\n .find('.add-to-wish-list-confirm')\n .prop('disabled', !data.product.readyToOrder);\n $('.product-detail-keeper').attr('data-variant-pid', encodeURIComponent(data.product.id));\n $('.product-detail').data('pid', data.product.id);\n $('.size-available').attr('available', false);\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n });\n\n $(this.sizeModal.modalBox).on('click', '.add-to-wish-list-confirm', (e) => {\n // Add to wishlist definitely\n let pid = null;\n if ($('.product-detail')) {\n pid = $('.product-detail').data('pid');\n } else if ($('.product-quickview')) {\n pid = $('.product-quickview').data('pid');\n }\n addDefinitelyToWishlist(target, pid, e);\n });\n\n $('body').on('product:afterAddToWishlist', (e) => {\n if (this.sizeModal.modal) {\n this.sizeModal.close();\n this.sizeModal.destroy();\n }\n });\n\n $('body').on('product:failedAddToWishlist', (e) => {\n if (this.sizeModal.modal) {\n this.sizeModal.close();\n this.sizeModal.destroy();\n }\n });\n } else {\n sizePanel.openSizePanel(sizePanel.Types.WISHILIST);\n $('.pdp-size-box .js-sizeBox-openPanel').addClass('cc-sizeBox-openPanel_error');\n }\n return;\n }\n addDefinitelyToWishlist(target, null, e);\n });\n\n $('body').on('wishlist:add-pid', (_, d) => {\n const target = $('.add-to-wish-list').eq(0);\n addDefinitelyToWishlist(target, d.pid, {currentTarget: target});\n });\n }\n};\n","/* build: `node build.js modules=ALL exclude=gestures,accessors requirejs minifier=uglifyjs` */\n/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */\n\nvar fabric = fabric || { version: '3.6.6' };\nif (typeof exports !== 'undefined') {\n exports.fabric = fabric;\n}\n/* _AMD_START_ */\nelse if (typeof define === 'function' && define.amd) {\n define([], function() { return fabric; });\n}\n/* _AMD_END_ */\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n if (document instanceof (typeof HTMLDocument !== 'undefined' ? HTMLDocument : Document)) {\n fabric.document = document;\n }\n else {\n fabric.document = document.implementation.createHTMLDocument('');\n }\n fabric.window = window;\n}\nelse {\n // assume we're running under node.js when document/window are not present\n var jsdom = require('jsdom');\n var virtualWindow = new jsdom.JSDOM(\n decodeURIComponent('%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E'),\n {\n features: {\n FetchExternalResources: ['img']\n },\n resources: 'usable'\n }).window;\n fabric.document = virtualWindow.document;\n fabric.jsdomImplForWrapper = require('jsdom/lib/jsdom/living/generated/utils').implForWrapper;\n fabric.nodeCanvas = require('jsdom/lib/jsdom/utils').Canvas;\n fabric.window = virtualWindow;\n DOMParser = fabric.window.DOMParser;\n}\n\n/**\n * True when in environment that supports touch events\n * @type boolean\n */\nfabric.isTouchSupported = 'ontouchstart' in fabric.window || 'ontouchstart' in fabric.document ||\n (fabric.window && fabric.window.navigator && fabric.window.navigator.maxTouchPoints > 0);\n\n/**\n * True when in environment that's probably Node.js\n * @type boolean\n */\nfabric.isLikelyNode = typeof Buffer !== 'undefined' &&\n typeof window === 'undefined';\n\n/* _FROM_SVG_START_ */\n/**\n * Attributes parsed from all SVG elements\n * @type array\n */\nfabric.SHARED_ATTRIBUTES = [\n 'display',\n 'transform',\n 'fill', 'fill-opacity', 'fill-rule',\n 'opacity',\n 'stroke', 'stroke-dasharray', 'stroke-linecap', 'stroke-dashoffset',\n 'stroke-linejoin', 'stroke-miterlimit',\n 'stroke-opacity', 'stroke-width',\n 'id', 'paint-order', 'vector-effect',\n 'instantiated_by_use', 'clip-path'\n];\n/* _FROM_SVG_END_ */\n\n/**\n * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion.\n */\nfabric.DPI = 96;\nfabric.reNum = '(?:[-+]?(?:\\\\d+|\\\\d*\\\\.\\\\d+)(?:[eE][-+]?\\\\d+)?)';\nfabric.rePathCommand = /([-+]?((\\d+\\.\\d+)|((\\d+)|(\\.\\d+)))(?:[eE][-+]?\\d+)?)/ig;\nfabric.reNonWord = /[ \\n\\.,;!\\?\\-]/;\nfabric.fontPaths = { };\nfabric.iMatrix = [1, 0, 0, 1, 0, 0];\nfabric.svgNS = 'http://www.w3.org/2000/svg';\n\n/**\n * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.perfLimitSizeTotal = 2097152;\n\n/**\n * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.maxCacheSideLimit = 4096;\n\n/**\n * Lowest pixel limit for cache canvases, set at 256PX\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.minCacheSideLimit = 256;\n\n/**\n * Cache Object for widths of chars in text rendering.\n */\nfabric.charWidthsCache = { };\n\n/**\n * if webgl is enabled and available, textureSize will determine the size\n * of the canvas backend\n * @since 2.0.0\n * @type Number\n * @default\n */\nfabric.textureSize = 2048;\n\n/**\n * When 'true', style information is not retained when copy/pasting text, making\n * pasted text use destination style.\n * Defaults to 'false'.\n * @type Boolean\n * @default\n */\nfabric.disableStyleCopyPaste = false;\n\n/**\n * Enable webgl for filtering picture is available\n * A filtering backend will be initialized, this will both take memory and\n * time since a default 2048x2048 canvas will be created for the gl context\n * @since 2.0.0\n * @type Boolean\n * @default\n */\nfabric.enableGLFiltering = true;\n\n/**\n * Device Pixel Ratio\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n */\nfabric.devicePixelRatio = fabric.window.devicePixelRatio ||\n fabric.window.webkitDevicePixelRatio ||\n fabric.window.mozDevicePixelRatio ||\n 1;\n/**\n * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value,\n * which is unitless and not rendered equally across browsers.\n *\n * Values that work quite well (as of October 2017) are:\n * - Chrome: 1.5\n * - Edge: 1.75\n * - Firefox: 0.9\n * - Safari: 0.95\n *\n * @since 2.0.0\n * @type Number\n * @default 1\n */\nfabric.browserShadowBlurConstant = 1;\n\n/**\n * This object contains the result of arc to beizer conversion for faster retrieving if the same arc needs to be converted again.\n * It was an internal variable, is accessible since version 2.3.4\n */\nfabric.arcToSegmentsCache = { };\n\n/**\n * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.\n * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing\n * you do not get any speed benefit and you get a big object in memory.\n * The object was a private variable before, while now is appended to the lib so that you have access to it and you\n * can eventually clear it.\n * It was an internal variable, is accessible since version 2.3.4\n */\nfabric.boundsOfCurveCache = { };\n\n/**\n * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better\n * @default true\n */\nfabric.cachesBoundsOfCurve = true;\n\n/**\n * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on\n * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true\n * this has to be set before instantiating the filtering backend ( before filtering the first image )\n * @type Boolean\n * @default false\n */\nfabric.forceGLPutImageData = false;\n\nfabric.initFilterBackend = function() {\n if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) {\n console.log('max texture size: ' + fabric.maxTextureSize);\n return (new fabric.WebglFilterBackend({ tileSize: fabric.textureSize }));\n }\n else if (fabric.Canvas2dFilterBackend) {\n return (new fabric.Canvas2dFilterBackend());\n }\n};\n\n\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n // ensure globality even if entire library were function wrapped (as in Meteor.js packaging system)\n window.fabric = fabric;\n}\n\n\n(function() {\n\n /**\n * @private\n * @param {String} eventName\n * @param {Function} handler\n */\n function _removeEventListener(eventName, handler) {\n if (!this.__eventListeners[eventName]) {\n return;\n }\n var eventListener = this.__eventListeners[eventName];\n if (handler) {\n eventListener[eventListener.indexOf(handler)] = false;\n }\n else {\n fabric.util.array.fill(eventListener, false);\n }\n }\n\n /**\n * Observes specified event\n * @deprecated `observe` deprecated since 0.8.34 (use `on` instead)\n * @memberOf fabric.Observable\n * @alias on\n * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Self} thisArg\n * @chainable\n */\n function observe(eventName, handler) {\n if (!this.__eventListeners) {\n this.__eventListeners = { };\n }\n // one object with key/value pairs was passed\n if (arguments.length === 1) {\n for (var prop in eventName) {\n this.on(prop, eventName[prop]);\n }\n }\n else {\n if (!this.__eventListeners[eventName]) {\n this.__eventListeners[eventName] = [];\n }\n this.__eventListeners[eventName].push(handler);\n }\n return this;\n }\n\n /**\n * Stops event observing for a particular event handler. Calling this method\n * without arguments removes all handlers for all events\n * @deprecated `stopObserving` deprecated since 0.8.34 (use `off` instead)\n * @memberOf fabric.Observable\n * @alias off\n * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function to be deleted from EventListeners\n * @return {Self} thisArg\n * @chainable\n */\n function stopObserving(eventName, handler) {\n if (!this.__eventListeners) {\n return this;\n }\n\n // remove all key/value pairs (event name -> event handler)\n if (arguments.length === 0) {\n for (eventName in this.__eventListeners) {\n _removeEventListener.call(this, eventName);\n }\n }\n // one object with key/value pairs was passed\n else if (arguments.length === 1 && typeof arguments[0] === 'object') {\n for (var prop in eventName) {\n _removeEventListener.call(this, prop, eventName[prop]);\n }\n }\n else {\n _removeEventListener.call(this, eventName, handler);\n }\n return this;\n }\n\n /**\n * Fires event with an optional options object\n * @deprecated `fire` deprecated since 1.0.7 (use `trigger` instead)\n * @memberOf fabric.Observable\n * @alias trigger\n * @param {String} eventName Event name to fire\n * @param {Object} [options] Options object\n * @return {Self} thisArg\n * @chainable\n */\n function fire(eventName, options) {\n if (!this.__eventListeners) {\n return this;\n }\n\n var listenersForEvent = this.__eventListeners[eventName];\n if (!listenersForEvent) {\n return this;\n }\n\n for (var i = 0, len = listenersForEvent.length; i < len; i++) {\n listenersForEvent[i] && listenersForEvent[i].call(this, options || { });\n }\n this.__eventListeners[eventName] = listenersForEvent.filter(function(value) {\n return value !== false;\n });\n return this;\n }\n\n /**\n * @namespace fabric.Observable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}\n * @see {@link http://fabricjs.com/events|Events demo}\n */\n fabric.Observable = {\n observe: observe,\n stopObserving: stopObserving,\n fire: fire,\n\n on: observe,\n off: stopObserving,\n trigger: fire\n };\n})();\n\n\n/**\n * @namespace fabric.Collection\n */\nfabric.Collection = {\n\n _objects: [],\n\n /**\n * Adds objects to collection, Canvas or Group, then renders canvas\n * (if `renderOnAddRemove` is not `false`).\n * in case of Group no changes to bounding box are made.\n * Objects should be instances of (or inherit from) fabric.Object\n * Use of this function is highly discouraged for groups.\n * you can add a bunch of objects with the add method but then you NEED\n * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n * @param {...fabric.Object} object Zero or more fabric instances\n * @return {Self} thisArg\n * @chainable\n */\n add: function () {\n this._objects.push.apply(this._objects, arguments);\n if (this._onObjectAdded) {\n for (var i = 0, length = arguments.length; i < length; i++) {\n this._onObjectAdded(arguments[i]);\n }\n }\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`)\n * An object should be an instance of (or inherit from) fabric.Object\n * Use of this function is highly discouraged for groups.\n * you can add a bunch of objects with the insertAt method but then you NEED\n * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n * @param {Object} object Object to insert\n * @param {Number} index Index to insert object at\n * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs\n * @return {Self} thisArg\n * @chainable\n */\n insertAt: function (object, index, nonSplicing) {\n var objects = this._objects;\n if (nonSplicing) {\n objects[index] = object;\n }\n else {\n objects.splice(index, 0, object);\n }\n this._onObjectAdded && this._onObjectAdded(object);\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)\n * @param {...fabric.Object} object Zero or more fabric instances\n * @return {Self} thisArg\n * @chainable\n */\n remove: function() {\n var objects = this._objects,\n index, somethingRemoved = false;\n\n for (var i = 0, length = arguments.length; i < length; i++) {\n index = objects.indexOf(arguments[i]);\n\n // only call onObjectRemoved if an object was actually removed\n if (index !== -1) {\n somethingRemoved = true;\n objects.splice(index, 1);\n this._onObjectRemoved && this._onObjectRemoved(arguments[i]);\n }\n }\n\n this.renderOnAddRemove && somethingRemoved && this.requestRenderAll();\n return this;\n },\n\n /**\n * Executes given function for each object in this group\n * @param {Function} callback\n * Callback invoked with current object as first argument,\n * index - as second and an array of all objects - as third.\n * Callback is invoked in a context of Global Object (e.g. `window`)\n * when no `context` argument is given\n *\n * @param {Object} context Context (aka thisObject)\n * @return {Self} thisArg\n * @chainable\n */\n forEachObject: function(callback, context) {\n var objects = this.getObjects();\n for (var i = 0, len = objects.length; i < len; i++) {\n callback.call(context, objects[i], i, objects);\n }\n return this;\n },\n\n /**\n * Returns an array of children objects of this instance\n * Type parameter introduced in 1.3.10\n * since 2.3.5 this method return always a COPY of the array;\n * @param {String} [type] When specified, only objects of this type are returned\n * @return {Array}\n */\n getObjects: function(type) {\n if (typeof type === 'undefined') {\n return this._objects.concat();\n }\n return this._objects.filter(function(o) {\n return o.type === type;\n });\n },\n\n /**\n * Returns object at specified index\n * @param {Number} index\n * @return {Self} thisArg\n */\n item: function (index) {\n return this._objects[index];\n },\n\n /**\n * Returns true if collection contains no objects\n * @return {Boolean} true if collection is empty\n */\n isEmpty: function () {\n return this._objects.length === 0;\n },\n\n /**\n * Returns a size of a collection (i.e: length of an array containing its objects)\n * @return {Number} Collection size\n */\n size: function() {\n return this._objects.length;\n },\n\n /**\n * Returns true if collection contains an object\n * @param {Object} object Object to check against\n * @return {Boolean} `true` if collection contains an object\n */\n contains: function(object) {\n return this._objects.indexOf(object) > -1;\n },\n\n /**\n * Returns number representation of a collection complexity\n * @return {Number} complexity\n */\n complexity: function () {\n return this._objects.reduce(function (memo, current) {\n memo += current.complexity ? current.complexity() : 0;\n return memo;\n }, 0);\n }\n};\n\n\n/**\n * @namespace fabric.CommonMethods\n */\nfabric.CommonMethods = {\n\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n _setOptions: function(options) {\n for (var prop in options) {\n this.set(prop, options[prop]);\n }\n },\n\n /**\n * @private\n * @param {Object} [filler] Options object\n * @param {String} [property] property to set the Gradient to\n */\n _initGradient: function(filler, property) {\n if (filler && filler.colorStops && !(filler instanceof fabric.Gradient)) {\n this.set(property, new fabric.Gradient(filler));\n }\n },\n\n /**\n * @private\n * @param {Object} [filler] Options object\n * @param {String} [property] property to set the Pattern to\n * @param {Function} [callback] callback to invoke after pattern load\n */\n _initPattern: function(filler, property, callback) {\n if (filler && filler.source && !(filler instanceof fabric.Pattern)) {\n this.set(property, new fabric.Pattern(filler, callback));\n }\n else {\n callback && callback();\n }\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initClipping: function(options) {\n if (!options.clipTo || typeof options.clipTo !== 'string') {\n return;\n }\n\n var functionBody = fabric.util.getFunctionBody(options.clipTo);\n if (typeof functionBody !== 'undefined') {\n this.clipTo = new Function('ctx', functionBody);\n }\n },\n\n /**\n * @private\n */\n _setObject: function(obj) {\n for (var prop in obj) {\n this._set(prop, obj[prop]);\n }\n },\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n set: function(key, value) {\n if (typeof key === 'object') {\n this._setObject(key);\n }\n else {\n if (typeof value === 'function' && key !== 'clipTo') {\n this._set(key, value(this.get(key)));\n }\n else {\n this._set(key, value);\n }\n }\n return this;\n },\n\n _set: function(key, value) {\n this[key] = value;\n },\n\n /**\n * Toggles specified property from `true` to `false` or from `false` to `true`\n * @param {String} property Property to toggle\n * @return {fabric.Object} thisArg\n * @chainable\n */\n toggle: function(property) {\n var value = this.get(property);\n if (typeof value === 'boolean') {\n this.set(property, !value);\n }\n return this;\n },\n\n /**\n * Basic getter\n * @param {String} property Property name\n * @return {*} value of a property\n */\n get: function(property) {\n return this[property];\n }\n};\n\n\n(function(global) {\n\n var sqrt = Math.sqrt,\n atan2 = Math.atan2,\n pow = Math.pow,\n PiBy180 = Math.PI / 180,\n PiBy2 = Math.PI / 2;\n\n /**\n * @namespace fabric.util\n */\n fabric.util = {\n\n /**\n * Calculate the cos of an angle, avoiding returning floats for known results\n * @static\n * @memberOf fabric.util\n * @param {Number} angle the angle in radians or in degree\n * @return {Number}\n */\n cos: function(angle) {\n if (angle === 0) { return 1; }\n if (angle < 0) {\n // cos(a) = cos(-a)\n angle = -angle;\n }\n var angleSlice = angle / PiBy2;\n switch (angleSlice) {\n case 1: case 3: return 0;\n case 2: return -1;\n }\n return Math.cos(angle);\n },\n\n /**\n * Calculate the sin of an angle, avoiding returning floats for known results\n * @static\n * @memberOf fabric.util\n * @param {Number} angle the angle in radians or in degree\n * @return {Number}\n */\n sin: function(angle) {\n if (angle === 0) { return 0; }\n var angleSlice = angle / PiBy2, sign = 1;\n if (angle < 0) {\n // sin(-a) = -sin(a)\n sign = -1;\n }\n switch (angleSlice) {\n case 1: return sign;\n case 2: return 0;\n case 3: return -sign;\n }\n return Math.sin(angle);\n },\n\n /**\n * Removes value from an array.\n * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`\n * @static\n * @memberOf fabric.util\n * @param {Array} array\n * @param {*} value\n * @return {Array} original array\n */\n removeFromArray: function(array, value) {\n var idx = array.indexOf(value);\n if (idx !== -1) {\n array.splice(idx, 1);\n }\n return array;\n },\n\n /**\n * Returns random number between 2 specified ones.\n * @static\n * @memberOf fabric.util\n * @param {Number} min lower limit\n * @param {Number} max upper limit\n * @return {Number} random value (between min and max)\n */\n getRandomInt: function(min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n },\n\n /**\n * Transforms degrees to radians.\n * @static\n * @memberOf fabric.util\n * @param {Number} degrees value in degrees\n * @return {Number} value in radians\n */\n degreesToRadians: function(degrees) {\n return degrees * PiBy180;\n },\n\n /**\n * Transforms radians to degrees.\n * @static\n * @memberOf fabric.util\n * @param {Number} radians value in radians\n * @return {Number} value in degrees\n */\n radiansToDegrees: function(radians) {\n return radians / PiBy180;\n },\n\n /**\n * Rotates `point` around `origin` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {fabric.Point} point The point to rotate\n * @param {fabric.Point} origin The origin of the rotation\n * @param {Number} radians The radians of the angle for the rotation\n * @return {fabric.Point} The new rotated point\n */\n rotatePoint: function(point, origin, radians) {\n point.subtractEquals(origin);\n var v = fabric.util.rotateVector(point, radians);\n return new fabric.Point(v.x, v.y).addEquals(origin);\n },\n\n /**\n * Rotates `vector` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {Object} vector The vector to rotate (x and y)\n * @param {Number} radians The radians of the angle for the rotation\n * @return {Object} The new rotated point\n */\n rotateVector: function(vector, radians) {\n var sin = fabric.util.sin(radians),\n cos = fabric.util.cos(radians),\n rx = vector.x * cos - vector.y * sin,\n ry = vector.x * sin + vector.y * cos;\n return {\n x: rx,\n y: ry\n };\n },\n\n /**\n * Apply transform t to point p\n * @static\n * @memberOf fabric.util\n * @param {fabric.Point} p The point to transform\n * @param {Array} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {fabric.Point} The transformed point\n */\n transformPoint: function(p, t, ignoreOffset) {\n if (ignoreOffset) {\n return new fabric.Point(\n t[0] * p.x + t[2] * p.y,\n t[1] * p.x + t[3] * p.y\n );\n }\n return new fabric.Point(\n t[0] * p.x + t[2] * p.y + t[4],\n t[1] * p.x + t[3] * p.y + t[5]\n );\n },\n\n /**\n * Returns coordinates of points's bounding rectangle (left, top, width, height)\n * @param {Array} points 4 points array\n * @param {Array} [transform] an array of 6 numbers representing a 2x3 transform matrix\n * @return {Object} Object with left, top, width, height properties\n */\n makeBoundingBoxFromPoints: function(points, transform) {\n if (transform) {\n for (var i = 0; i < points.length; i++) {\n points[i] = fabric.util.transformPoint(points[i], transform);\n }\n }\n var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x],\n minX = fabric.util.array.min(xPoints),\n maxX = fabric.util.array.max(xPoints),\n width = maxX - minX,\n yPoints = [points[0].y, points[1].y, points[2].y, points[3].y],\n minY = fabric.util.array.min(yPoints),\n maxY = fabric.util.array.max(yPoints),\n height = maxY - minY;\n\n return {\n left: minX,\n top: minY,\n width: width,\n height: height\n };\n },\n\n /**\n * Invert transformation t\n * @static\n * @memberOf fabric.util\n * @param {Array} t The transform\n * @return {Array} The inverted transform\n */\n invertTransform: function(t) {\n var a = 1 / (t[0] * t[3] - t[1] * t[2]),\n r = [a * t[3], -a * t[1], -a * t[2], a * t[0]],\n o = fabric.util.transformPoint({ x: t[4], y: t[5] }, r, true);\n r[4] = -o.x;\n r[5] = -o.y;\n return r;\n },\n\n /**\n * A wrapper around Number#toFixed, which contrary to native method returns number, not string.\n * @static\n * @memberOf fabric.util\n * @param {Number|String} number number to operate on\n * @param {Number} fractionDigits number of fraction digits to \"leave\"\n * @return {Number}\n */\n toFixed: function(number, fractionDigits) {\n return parseFloat(Number(number).toFixed(fractionDigits));\n },\n\n /**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {Number|String} value number to operate on\n * @param {Number} fontSize\n * @return {Number|String}\n */\n parseUnit: function(value, fontSize) {\n var unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n if (!fontSize) {\n fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\n switch (unit[0]) {\n case 'mm':\n return number * fabric.DPI / 25.4;\n\n case 'cm':\n return number * fabric.DPI / 2.54;\n\n case 'in':\n return number * fabric.DPI;\n\n case 'pt':\n return number * fabric.DPI / 72; // or * 4 / 3\n\n case 'pc':\n return number * fabric.DPI / 72 * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n },\n\n /**\n * Function which always returns `false`.\n * @static\n * @memberOf fabric.util\n * @return {Boolean}\n */\n falseFunction: function() {\n return false;\n },\n\n /**\n * Returns klass \"Class\" object of given namespace\n * @memberOf fabric.util\n * @param {String} type Type of object (eg. 'circle')\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @return {Object} klass \"Class\"\n */\n getKlass: function(type, namespace) {\n // capitalize first letter only\n type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1));\n return fabric.util.resolveNamespace(namespace)[type];\n },\n\n /**\n * Returns array of attributes for given svg that fabric parses\n * @memberOf fabric.util\n * @param {String} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\n getSvgAttributes: function(type) {\n var attributes = [\n 'instantiated_by_use',\n 'style',\n 'id',\n 'class'\n ];\n switch (type) {\n case 'linearGradient':\n attributes = attributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']);\n break;\n case 'radialGradient':\n attributes = attributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']);\n break;\n case 'stop':\n attributes = attributes.concat(['offset', 'stop-color', 'stop-opacity']);\n break;\n }\n return attributes;\n },\n\n /**\n * Returns object of given namespace\n * @memberOf fabric.util\n * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric'\n * @return {Object} Object for given namespace (default fabric)\n */\n resolveNamespace: function(namespace) {\n if (!namespace) {\n return fabric;\n }\n\n var parts = namespace.split('.'),\n len = parts.length, i,\n obj = global || fabric.window;\n\n for (i = 0; i < len; ++i) {\n obj = obj[parts[i]];\n }\n\n return obj;\n },\n\n /**\n * Loads image element from given url and passes it to a callback\n * @memberOf fabric.util\n * @param {String} url URL representing an image\n * @param {Function} callback Callback; invoked with loaded image\n * @param {*} [context] Context to invoke callback in\n * @param {Object} [crossOrigin] crossOrigin value to set image element to\n */\n loadImage: function(url, callback, context, crossOrigin) {\n if (!url) {\n callback && callback.call(context, url);\n return;\n }\n\n var img = fabric.util.createImage();\n\n /** @ignore */\n var onLoadCallback = function () {\n callback && callback.call(context, img);\n img = img.onload = img.onerror = null;\n };\n\n img.onload = onLoadCallback;\n /** @ignore */\n img.onerror = function() {\n fabric.log('Error loading ' + img.src);\n callback && callback.call(context, null, true);\n img = img.onload = img.onerror = null;\n };\n\n // data-urls appear to be buggy with crossOrigin\n // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767\n // see https://code.google.com/p/chromium/issues/detail?id=315152\n // https://bugzilla.mozilla.org/show_bug.cgi?id=935069\n if (url.indexOf('data') !== 0 && crossOrigin) {\n img.crossOrigin = crossOrigin;\n }\n\n // IE10 / IE11-Fix: SVG contents from data: URI\n // will only be available if the IMG is present\n // in the DOM (and visible)\n if (url.substring(0,14) === 'data:image/svg') {\n img.onload = null;\n fabric.util.loadImageInDom(img, onLoadCallback);\n }\n\n img.src = url;\n },\n\n /**\n * Attaches SVG image with data: URL to the dom\n * @memberOf fabric.util\n * @param {Object} img Image object with data:image/svg src\n * @param {Function} callback Callback; invoked with loaded image\n * @return {Object} DOM element (div containing the SVG image)\n */\n loadImageInDom: function(img, onLoadCallback) {\n var div = fabric.document.createElement('div');\n div.style.width = div.style.height = '1px';\n div.style.left = div.style.top = '-100%';\n div.style.position = 'absolute';\n div.appendChild(img);\n fabric.document.querySelector('body').appendChild(div);\n /**\n * Wrap in function to:\n * 1. Call existing callback\n * 2. Cleanup DOM\n */\n img.onload = function () {\n onLoadCallback();\n div.parentNode.removeChild(div);\n div = null;\n };\n },\n\n /**\n * Creates corresponding fabric instances from their object representations\n * @static\n * @memberOf fabric.util\n * @param {Array} objects Objects to enliven\n * @param {Function} callback Callback to invoke when all objects are created\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @param {Function} reviver Method for further parsing of object elements,\n * called after each fabric object created.\n */\n enlivenObjects: function(objects, callback, namespace, reviver) {\n objects = objects || [];\n\n var enlivenedObjects = [],\n numLoadedObjects = 0,\n numTotalObjects = objects.length;\n\n function onLoaded() {\n if (++numLoadedObjects === numTotalObjects) {\n callback && callback(enlivenedObjects.filter(function(obj) {\n // filter out undefined objects (objects that gave error)\n return obj;\n }));\n }\n }\n\n if (!numTotalObjects) {\n callback && callback(enlivenedObjects);\n return;\n }\n\n objects.forEach(function (o, index) {\n // if sparse array\n if (!o || !o.type) {\n onLoaded();\n return;\n }\n var klass = fabric.util.getKlass(o.type, namespace);\n klass.fromObject(o, function (obj, error) {\n error || (enlivenedObjects[index] = obj);\n reviver && reviver(o, obj, error);\n onLoaded();\n });\n });\n },\n\n /**\n * Create and wait for loading of patterns\n * @static\n * @memberOf fabric.util\n * @param {Array} patterns Objects to enliven\n * @param {Function} callback Callback to invoke when all objects are created\n * called after each fabric object created.\n */\n enlivenPatterns: function(patterns, callback) {\n patterns = patterns || [];\n\n function onLoaded() {\n if (++numLoadedPatterns === numPatterns) {\n callback && callback(enlivenedPatterns);\n }\n }\n\n var enlivenedPatterns = [],\n numLoadedPatterns = 0,\n numPatterns = patterns.length;\n\n if (!numPatterns) {\n callback && callback(enlivenedPatterns);\n return;\n }\n\n patterns.forEach(function (p, index) {\n if (p && p.source) {\n new fabric.Pattern(p, function(pattern) {\n enlivenedPatterns[index] = pattern;\n onLoaded();\n });\n }\n else {\n enlivenedPatterns[index] = p;\n onLoaded();\n }\n });\n },\n\n /**\n * Groups SVG elements (usually those retrieved from SVG document)\n * @static\n * @memberOf fabric.util\n * @param {Array} elements SVG elements to group\n * @param {Object} [options] Options object\n * @param {String} path Value to set sourcePath to\n * @return {fabric.Object|fabric.Group}\n */\n groupSVGElements: function(elements, options, path) {\n var object;\n if (elements && elements.length === 1) {\n return elements[0];\n }\n if (options) {\n if (options.width && options.height) {\n options.centerPoint = {\n x: options.width / 2,\n y: options.height / 2\n };\n }\n else {\n delete options.width;\n delete options.height;\n }\n }\n object = new fabric.Group(elements, options);\n if (typeof path !== 'undefined') {\n object.sourcePath = path;\n }\n return object;\n },\n\n /**\n * Populates an object with properties of another object\n * @static\n * @memberOf fabric.util\n * @param {Object} source Source object\n * @param {Object} destination Destination object\n * @return {Array} properties Properties names to include\n */\n populateWithProperties: function(source, destination, properties) {\n if (properties && Object.prototype.toString.call(properties) === '[object Array]') {\n for (var i = 0, len = properties.length; i < len; i++) {\n if (properties[i] in source) {\n destination[properties[i]] = source[properties[i]];\n }\n }\n }\n },\n\n /**\n * Draws a dashed line between two points\n *\n * This method is used to draw dashed line around selection area.\n * See dotted stroke in canvas\n *\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x start x coordinate\n * @param {Number} y start y coordinate\n * @param {Number} x2 end x coordinate\n * @param {Number} y2 end y coordinate\n * @param {Array} da dash array pattern\n */\n drawDashedLine: function(ctx, x, y, x2, y2, da) {\n var dx = x2 - x,\n dy = y2 - y,\n len = sqrt(dx * dx + dy * dy),\n rot = atan2(dy, dx),\n dc = da.length,\n di = 0,\n draw = true;\n\n ctx.save();\n ctx.translate(x, y);\n ctx.moveTo(0, 0);\n ctx.rotate(rot);\n\n x = 0;\n while (len > x) {\n x += da[di++ % dc];\n if (x > len) {\n x = len;\n }\n ctx[draw ? 'lineTo' : 'moveTo'](x, 0);\n draw = !draw;\n }\n\n ctx.restore();\n },\n\n /**\n * Creates canvas element\n * @static\n * @memberOf fabric.util\n * @return {CanvasElement} initialized canvas element\n */\n createCanvasElement: function() {\n return fabric.document.createElement('canvas');\n },\n\n /**\n * Creates a canvas element that is a copy of another and is also painted\n * @param {CanvasElement} canvas to copy size and content of\n * @static\n * @memberOf fabric.util\n * @return {CanvasElement} initialized canvas element\n */\n copyCanvasElement: function(canvas) {\n var newCanvas = fabric.util.createCanvasElement();\n newCanvas.width = canvas.width;\n newCanvas.height = canvas.height;\n newCanvas.getContext('2d').drawImage(canvas, 0, 0);\n return newCanvas;\n },\n\n /**\n * since 2.6.0 moved from canvas instance to utility.\n * @param {CanvasElement} canvasEl to copy size and content of\n * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too\n * @param {Number} quality <= 1 and > 0\n * @static\n * @memberOf fabric.util\n * @return {String} data url\n */\n toDataURL: function(canvasEl, format, quality) {\n return canvasEl.toDataURL('image/' + format, quality);\n },\n\n /**\n * Creates image element (works on client and node)\n * @static\n * @memberOf fabric.util\n * @return {HTMLImageElement} HTML image element\n */\n createImage: function() {\n return fabric.document.createElement('img');\n },\n\n /**\n * @static\n * @memberOf fabric.util\n * @deprecated since 2.0.0\n * @param {fabric.Object} receiver Object implementing `clipTo` method\n * @param {CanvasRenderingContext2D} ctx Context to clip\n */\n clipContext: function(receiver, ctx) {\n ctx.save();\n ctx.beginPath();\n receiver.clipTo(ctx);\n ctx.clip();\n },\n\n /**\n * Multiply matrix A by matrix B to nest transformations\n * @static\n * @memberOf fabric.util\n * @param {Array} a First transformMatrix\n * @param {Array} b Second transformMatrix\n * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices\n * @return {Array} The product of the two transform matrices\n */\n multiplyTransformMatrices: function(a, b, is2x2) {\n // Matrix multiply a * b\n return [\n a[0] * b[0] + a[2] * b[1],\n a[1] * b[0] + a[3] * b[1],\n a[0] * b[2] + a[2] * b[3],\n a[1] * b[2] + a[3] * b[3],\n is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4],\n is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5]\n ];\n },\n\n /**\n * Decomposes standard 2x3 matrix into transform components\n * @static\n * @memberOf fabric.util\n * @param {Array} a transformMatrix\n * @return {Object} Components of transform\n */\n qrDecompose: function(a) {\n var angle = atan2(a[1], a[0]),\n denom = pow(a[0], 2) + pow(a[1], 2),\n scaleX = sqrt(denom),\n scaleY = (a[0] * a[3] - a[2] * a [1]) / scaleX,\n skewX = atan2(a[0] * a[2] + a[1] * a [3], denom);\n return {\n angle: angle / PiBy180,\n scaleX: scaleX,\n scaleY: scaleY,\n skewX: skewX / PiBy180,\n skewY: 0,\n translateX: a[4],\n translateY: a[5]\n };\n },\n\n /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.angle] angle in degrees\n * @return {Number[]} transform matrix\n */\n calcRotateMatrix: function(options) {\n if (!options.angle) {\n return fabric.iMatrix.concat();\n }\n var theta = fabric.util.degreesToRadians(options.angle),\n cos = fabric.util.cos(theta),\n sin = fabric.util.sin(theta);\n return [cos, sin, -sin, cos, 0, 0];\n },\n\n /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet.\n * is called DimensionsTransformMatrix because those properties are the one that influence\n * the size of the resulting box of the object.\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewX]\n * @return {Number[]} transform matrix\n */\n calcDimensionsMatrix: function(options) {\n var scaleX = typeof options.scaleX === 'undefined' ? 1 : options.scaleX,\n scaleY = typeof options.scaleY === 'undefined' ? 1 : options.scaleY,\n scaleMatrix = [\n options.flipX ? -scaleX : scaleX,\n 0,\n 0,\n options.flipY ? -scaleY : scaleY,\n 0,\n 0],\n multiply = fabric.util.multiplyTransformMatrices,\n degreesToRadians = fabric.util.degreesToRadians;\n if (options.skewX) {\n scaleMatrix = multiply(\n scaleMatrix,\n [1, 0, Math.tan(degreesToRadians(options.skewX)), 1],\n true);\n }\n if (options.skewY) {\n scaleMatrix = multiply(\n scaleMatrix,\n [1, Math.tan(degreesToRadians(options.skewY)), 0, 1],\n true);\n }\n return scaleMatrix;\n },\n\n /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.angle]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewX]\n * @param {Number} [options.translateX]\n * @param {Number} [options.translateY]\n * @return {Number[]} transform matrix\n */\n composeMatrix: function(options) {\n var matrix = [1, 0, 0, 1, options.translateX || 0, options.translateY || 0],\n multiply = fabric.util.multiplyTransformMatrices;\n if (options.angle) {\n matrix = multiply(matrix, fabric.util.calcRotateMatrix(options));\n }\n if (options.scaleX || options.scaleY || options.skewX || options.skewY || options.flipX || options.flipY) {\n matrix = multiply(matrix, fabric.util.calcDimensionsMatrix(options));\n }\n return matrix;\n },\n\n /**\n * Returns a transform matrix that has the same effect of scaleX, scaleY and skewX.\n * Is deprecated for composeMatrix. Please do not use it.\n * @static\n * @deprecated since 3.4.0\n * @memberOf fabric.util\n * @param {Number} scaleX\n * @param {Number} scaleY\n * @param {Number} skewX\n * @return {Number[]} transform matrix\n */\n customTransformMatrix: function(scaleX, scaleY, skewX) {\n return fabric.util.composeMatrix({ scaleX: scaleX, scaleY: scaleY, skewX: skewX });\n },\n\n /**\n * reset an object transform state to neutral. Top and left are not accounted for\n * @static\n * @memberOf fabric.util\n * @param {fabric.Object} target object to transform\n */\n resetObjectTransform: function (target) {\n target.scaleX = 1;\n target.scaleY = 1;\n target.skewX = 0;\n target.skewY = 0;\n target.flipX = false;\n target.flipY = false;\n target.rotate(0);\n },\n\n /**\n * Extract Object transform values\n * @static\n * @memberOf fabric.util\n * @param {fabric.Object} target object to read from\n * @return {Object} Components of transform\n */\n saveObjectTransform: function (target) {\n return {\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n angle: target.angle,\n left: target.left,\n flipX: target.flipX,\n flipY: target.flipY,\n top: target.top\n };\n },\n\n /**\n * Returns string representation of function body\n * @param {Function} fn Function to get body of\n * @return {String} Function body\n */\n getFunctionBody: function(fn) {\n return (String(fn).match(/function[^{]*\\{([\\s\\S]*)\\}/) || {})[1];\n },\n\n /**\n * Returns true if context has transparent pixel\n * at specified location (taking tolerance into account)\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x x coordinate\n * @param {Number} y y coordinate\n * @param {Number} tolerance Tolerance\n */\n isTransparent: function(ctx, x, y, tolerance) {\n\n // If tolerance is > 0 adjust start coords to take into account.\n // If moves off Canvas fix to 0\n if (tolerance > 0) {\n if (x > tolerance) {\n x -= tolerance;\n }\n else {\n x = 0;\n }\n if (y > tolerance) {\n y -= tolerance;\n }\n else {\n y = 0;\n }\n }\n\n var _isTransparent = true, i, temp,\n imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1),\n l = imageData.data.length;\n\n // Split image data - for tolerance > 1, pixelDataSize = 4;\n for (i = 3; i < l; i += 4) {\n temp = imageData.data[i];\n _isTransparent = temp <= 0;\n if (_isTransparent === false) {\n break; // Stop if colour found\n }\n }\n\n imageData = null;\n\n return _isTransparent;\n },\n\n /**\n * Parse preserveAspectRatio attribute from element\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\n parsePreserveAspectRatioAttribute: function(attribute) {\n var meetOrSlice = 'meet', alignX = 'Mid', alignY = 'Mid',\n aspectRatioAttrs = attribute.split(' '), align;\n\n if (aspectRatioAttrs && aspectRatioAttrs.length) {\n meetOrSlice = aspectRatioAttrs.pop();\n if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') {\n align = meetOrSlice;\n meetOrSlice = 'meet';\n }\n else if (aspectRatioAttrs.length) {\n align = aspectRatioAttrs.pop();\n }\n }\n //divide align in alignX and alignY\n alignX = align !== 'none' ? align.slice(1, 4) : 'none';\n alignY = align !== 'none' ? align.slice(5, 8) : 'none';\n return {\n meetOrSlice: meetOrSlice,\n alignX: alignX,\n alignY: alignY\n };\n },\n\n /**\n * Clear char widths cache for the given font family or all the cache if no\n * fontFamily is specified.\n * Use it if you know you are loading fonts in a lazy way and you are not waiting\n * for custom fonts to load properly when adding text objects to the canvas.\n * If a text object is added when its own font is not loaded yet, you will get wrong\n * measurement and so wrong bounding boxes.\n * After the font cache is cleared, either change the textObject text content or call\n * initDimensions() to trigger a recalculation\n * @memberOf fabric.util\n * @param {String} [fontFamily] font family to clear\n */\n clearFabricFontCache: function(fontFamily) {\n fontFamily = (fontFamily || '').toLowerCase();\n if (!fontFamily) {\n fabric.charWidthsCache = { };\n }\n else if (fabric.charWidthsCache[fontFamily]) {\n delete fabric.charWidthsCache[fontFamily];\n }\n },\n\n /**\n * Given current aspect ratio, determines the max width and height that can\n * respect the total allowed area for the cache.\n * @memberOf fabric.util\n * @param {Number} ar aspect ratio\n * @param {Number} maximumArea Maximum area you want to achieve\n * @return {Object.x} Limited dimensions by X\n * @return {Object.y} Limited dimensions by Y\n */\n limitDimsByArea: function(ar, maximumArea) {\n var roughWidth = Math.sqrt(maximumArea * ar),\n perfLimitSizeY = Math.floor(maximumArea / roughWidth);\n return { x: Math.floor(roughWidth), y: perfLimitSizeY };\n },\n\n capValue: function(min, value, max) {\n return Math.max(min, Math.min(value, max));\n },\n\n /**\n * Finds the scale for the object source to fit inside the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @memberOf fabric.util\n * @param {Object | fabric.Object} source\n * @param {Number} source.height natural unscaled height of the object\n * @param {Number} source.width natural unscaled width of the object\n * @param {Object | fabric.Object} destination\n * @param {Number} destination.height natural unscaled height of the object\n * @param {Number} destination.width natural unscaled width of the object\n * @return {Number} scale factor to apply to source to fit into destination\n */\n findScaleToFit: function(source, destination) {\n return Math.min(destination.width / source.width, destination.height / source.height);\n },\n\n /**\n * Finds the scale for the object source to cover entirely the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @memberOf fabric.util\n * @param {Object | fabric.Object} source\n * @param {Number} source.height natural unscaled height of the object\n * @param {Number} source.width natural unscaled width of the object\n * @param {Object | fabric.Object} destination\n * @param {Number} destination.height natural unscaled height of the object\n * @param {Number} destination.width natural unscaled width of the object\n * @return {Number} scale factor to apply to source to cover destination\n */\n findScaleToCover: function(source, destination) {\n return Math.max(destination.width / source.width, destination.height / source.height);\n },\n\n /**\n * given an array of 6 number returns something like `\"matrix(...numbers)\"`\n * @memberOf fabric.util\n * @param {Array} trasnform an array with 6 numbers\n * @return {String} transform matrix for svg\n * @return {Object.y} Limited dimensions by Y\n */\n matrixToSVG: function(transform) {\n return 'matrix(' + transform.map(function(value) {\n return fabric.util.toFixed(value, fabric.Object.NUM_FRACTION_DIGITS);\n }).join(' ') + ')';\n }\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n var _join = Array.prototype.join;\n\n /* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n */\n function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {\n var argsString = _join.call(arguments);\n if (fabric.arcToSegmentsCache[argsString]) {\n return fabric.arcToSegmentsCache[argsString];\n }\n\n var PI = Math.PI, th = rotateX * PI / 180,\n sinTh = fabric.util.sin(th),\n cosTh = fabric.util.cos(th),\n fromX = 0, fromY = 0;\n\n rx = Math.abs(rx);\n ry = Math.abs(ry);\n\n var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5,\n py = -cosTh * toY * 0.5 + sinTh * toX * 0.5,\n rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px,\n pl = rx2 * ry2 - rx2 * py2 - ry2 * px2,\n root = 0;\n\n if (pl < 0) {\n var s = Math.sqrt(1 - pl / (rx2 * ry2));\n rx *= s;\n ry *= s;\n }\n else {\n root = (large === sweep ? -1.0 : 1.0) *\n Math.sqrt( pl / (rx2 * py2 + ry2 * px2));\n }\n\n var cx = root * rx * py / ry,\n cy = -root * ry * px / rx,\n cx1 = cosTh * cx - sinTh * cy + toX * 0.5,\n cy1 = sinTh * cx + cosTh * cy + toY * 0.5,\n mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry),\n dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry);\n\n if (sweep === 0 && dtheta > 0) {\n dtheta -= 2 * PI;\n }\n else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n }\n\n // Convert into cubic bezier segments <= 90deg\n var segments = Math.ceil(Math.abs(dtheta / PI * 2)),\n result = [], mDelta = dtheta / segments,\n mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2),\n th3 = mTheta + mDelta;\n\n for (var i = 0; i < segments; i++) {\n result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY);\n fromX = result[i][4];\n fromY = result[i][5];\n mTheta = th3;\n th3 += mDelta;\n }\n fabric.arcToSegmentsCache[argsString] = result;\n return result;\n }\n\n function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {\n var costh2 = fabric.util.cos(th2),\n sinth2 = fabric.util.sin(th2),\n costh3 = fabric.util.cos(th3),\n sinth3 = fabric.util.sin(th3),\n toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1,\n toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1,\n cp1X = fromX + mT * ( -cosTh * rx * sinth2 - sinTh * ry * costh2),\n cp1Y = fromY + mT * ( -sinTh * rx * sinth2 + cosTh * ry * costh2),\n cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3),\n cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3);\n\n return [\n cp1X, cp1Y,\n cp2X, cp2Y,\n toX, toY\n ];\n }\n\n /*\n * Private\n */\n function calcVectorAngle(ux, uy, vx, vy) {\n var ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n if (tb >= ta) {\n return tb - ta;\n }\n else {\n return 2 * Math.PI - (ta - tb);\n }\n }\n\n /**\n * Draws arc\n * @param {CanvasRenderingContext2D} ctx\n * @param {Number} fx\n * @param {Number} fy\n * @param {Array} coords\n */\n fabric.util.drawArc = function(ctx, fx, fy, coords) {\n var rx = coords[0],\n ry = coords[1],\n rot = coords[2],\n large = coords[3],\n sweep = coords[4],\n tx = coords[5],\n ty = coords[6],\n segs = [[], [], [], []],\n segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (var i = 0, len = segsNorm.length; i < len; i++) {\n segs[i][0] = segsNorm[i][0] + fx;\n segs[i][1] = segsNorm[i][1] + fy;\n segs[i][2] = segsNorm[i][2] + fx;\n segs[i][3] = segsNorm[i][3] + fy;\n segs[i][4] = segsNorm[i][4] + fx;\n segs[i][5] = segsNorm[i][5] + fy;\n ctx.bezierCurveTo.apply(ctx, segs[i]);\n }\n };\n\n /**\n * Calculate bounding box of a elliptic-arc\n * @param {Number} fx start point of arc\n * @param {Number} fy\n * @param {Number} rx horizontal radius\n * @param {Number} ry vertical radius\n * @param {Number} rot angle of horizontal axe\n * @param {Number} large 1 or 0, whatever the arc is the big or the small on the 2 points\n * @param {Number} sweep 1 or 0, 1 clockwise or counterclockwise direction\n * @param {Number} tx end point of arc\n * @param {Number} ty\n */\n fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) {\n\n var fromX = 0, fromY = 0, bound, bounds = [],\n segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (var i = 0, len = segs.length; i < len; i++) {\n bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]);\n bounds.push({ x: bound[0].x + fx, y: bound[0].y + fy });\n bounds.push({ x: bound[1].x + fx, y: bound[1].y + fy });\n fromX = segs[i][4];\n fromY = segs[i][5];\n }\n return bounds;\n };\n\n /**\n * Calculate bounding box of a beziercurve\n * @param {Number} x0 starting point\n * @param {Number} y0\n * @param {Number} x1 first control point\n * @param {Number} y1\n * @param {Number} x2 secondo control point\n * @param {Number} y2\n * @param {Number} x3 end of beizer\n * @param {Number} y3\n */\n // taken from http://jsbin.com/ivomiq/56/edit no credits available for that.\n function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) {\n var argsString;\n if (fabric.cachesBoundsOfCurve) {\n argsString = _join.call(arguments);\n if (fabric.boundsOfCurveCache[argsString]) {\n return fabric.boundsOfCurveCache[argsString];\n }\n }\n\n var sqrt = Math.sqrt,\n min = Math.min, max = Math.max,\n abs = Math.abs, tvalues = [],\n bounds = [[], []],\n a, b, c, t, t1, t2, b2ac, sqrtb2ac;\n\n b = 6 * x0 - 12 * x1 + 6 * x2;\n a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;\n c = 3 * x1 - 3 * x0;\n\n for (var i = 0; i < 2; ++i) {\n if (i > 0) {\n b = 6 * y0 - 12 * y1 + 6 * y2;\n a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;\n c = 3 * y1 - 3 * y0;\n }\n\n if (abs(a) < 1e-12) {\n if (abs(b) < 1e-12) {\n continue;\n }\n t = -c / b;\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n continue;\n }\n b2ac = b * b - 4 * c * a;\n if (b2ac < 0) {\n continue;\n }\n sqrtb2ac = sqrt(b2ac);\n t1 = (-b + sqrtb2ac) / (2 * a);\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n t2 = (-b - sqrtb2ac) / (2 * a);\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n var x, y, j = tvalues.length, jlen = j, mt;\n while (j--) {\n t = tvalues[j];\n mt = 1 - t;\n x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);\n bounds[0][j] = x;\n\n y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);\n bounds[1][j] = y;\n }\n\n bounds[0][jlen] = x0;\n bounds[1][jlen] = y0;\n bounds[0][jlen + 1] = x3;\n bounds[1][jlen + 1] = y3;\n var result = [\n {\n x: min.apply(null, bounds[0]),\n y: min.apply(null, bounds[1])\n },\n {\n x: max.apply(null, bounds[0]),\n y: max.apply(null, bounds[1])\n }\n ];\n if (fabric.cachesBoundsOfCurve) {\n fabric.boundsOfCurveCache[argsString] = result;\n }\n return result;\n }\n\n fabric.util.getBoundsOfCurve = getBoundsOfCurve;\n\n})();\n\n\n(function() {\n\n var slice = Array.prototype.slice;\n\n /**\n * Invokes method on all items in a given array\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} method Name of a method to invoke\n * @return {Array}\n */\n function invoke(array, method) {\n var args = slice.call(arguments, 2), result = [];\n for (var i = 0, len = array.length; i < len; i++) {\n result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]);\n }\n return result;\n }\n\n /**\n * Finds maximum value in array (not necessarily \"first\" one)\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} byProperty\n * @return {*}\n */\n function max(array, byProperty) {\n return find(array, byProperty, function(value1, value2) {\n return value1 >= value2;\n });\n }\n\n /**\n * Finds minimum value in array (not necessarily \"first\" one)\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} byProperty\n * @return {*}\n */\n function min(array, byProperty) {\n return find(array, byProperty, function(value1, value2) {\n return value1 < value2;\n });\n }\n\n /**\n * @private\n */\n function fill(array, value) {\n var k = array.length;\n while (k--) {\n array[k] = value;\n }\n return array;\n }\n\n /**\n * @private\n */\n function find(array, byProperty, condition) {\n if (!array || array.length === 0) {\n return;\n }\n\n var i = array.length - 1,\n result = byProperty ? array[i][byProperty] : array[i];\n if (byProperty) {\n while (i--) {\n if (condition(array[i][byProperty], result)) {\n result = array[i][byProperty];\n }\n }\n }\n else {\n while (i--) {\n if (condition(array[i], result)) {\n result = array[i];\n }\n }\n }\n return result;\n }\n\n /**\n * @namespace fabric.util.array\n */\n fabric.util.array = {\n fill: fill,\n invoke: invoke,\n min: min,\n max: max\n };\n\n})();\n\n\n(function() {\n /**\n * Copies all enumerable properties of one js object to another\n * this does not and cannot compete with generic utils.\n * Does not clone or extend fabric.Object subclasses.\n * This is mostly for internal use and has extra handling for fabricJS objects\n * it skips the canvas property in deep cloning.\n * @memberOf fabric.util.object\n * @param {Object} destination Where to copy to\n * @param {Object} source Where to copy from\n * @return {Object}\n */\n\n function extend(destination, source, deep) {\n // JScript DontEnum bug is not taken care of\n // the deep clone is for internal use, is not meant to avoid\n // javascript traps or cloning html element or self referenced objects.\n if (deep) {\n if (!fabric.isLikelyNode && source instanceof Element) {\n // avoid cloning deep images, canvases,\n destination = source;\n }\n else if (source instanceof Array) {\n destination = [];\n for (var i = 0, len = source.length; i < len; i++) {\n destination[i] = extend({ }, source[i], deep);\n }\n }\n else if (source && typeof source === 'object') {\n for (var property in source) {\n if (property === 'canvas') {\n destination[property] = extend({ }, source[property]);\n }\n else if (source.hasOwnProperty(property)) {\n destination[property] = extend({ }, source[property], deep);\n }\n }\n }\n else {\n // this sounds odd for an extend but is ok for recursive use\n destination = source;\n }\n }\n else {\n for (var property in source) {\n destination[property] = source[property];\n }\n }\n return destination;\n }\n\n /**\n * Creates an empty object and copies all enumerable properties of another object to it\n * @memberOf fabric.util.object\n * TODO: this function return an empty object if you try to clone null\n * @param {Object} object Object to clone\n * @return {Object}\n */\n function clone(object, deep) {\n return extend({ }, object, deep);\n }\n\n /** @namespace fabric.util.object */\n fabric.util.object = {\n extend: extend,\n clone: clone\n };\n fabric.util.object.extend(fabric.util, fabric.Observable);\n})();\n\n\n(function() {\n\n /**\n * Camelizes a string\n * @memberOf fabric.util.string\n * @param {String} string String to camelize\n * @return {String} Camelized version of a string\n */\n function camelize(string) {\n return string.replace(/-+(.)?/g, function(match, character) {\n return character ? character.toUpperCase() : '';\n });\n }\n\n /**\n * Capitalizes a string\n * @memberOf fabric.util.string\n * @param {String} string String to capitalize\n * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized\n * and other letters stay untouched, if false first letter is capitalized\n * and other letters are converted to lowercase.\n * @return {String} Capitalized version of a string\n */\n function capitalize(string, firstLetterOnly) {\n return string.charAt(0).toUpperCase() +\n (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());\n }\n\n /**\n * Escapes XML in a string\n * @memberOf fabric.util.string\n * @param {String} string String to escape\n * @return {String} Escaped version of a string\n */\n function escapeXml(string) {\n return string.replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(//g, '>');\n }\n\n /**\n * Divide a string in the user perceived single units\n * @memberOf fabric.util.string\n * @param {String} textstring String to escape\n * @return {Array} array containing the graphemes\n */\n function graphemeSplit(textstring) {\n var i = 0, chr, graphemes = [];\n for (i = 0, chr; i < textstring.length; i++) {\n if ((chr = getWholeChar(textstring, i)) === false) {\n continue;\n }\n graphemes.push(chr);\n }\n return graphemes;\n }\n\n // taken from mdn in the charAt doc page.\n function getWholeChar(str, i) {\n var code = str.charCodeAt(i);\n\n if (isNaN(code)) {\n return ''; // Position not found\n }\n if (code < 0xD800 || code > 0xDFFF) {\n return str.charAt(i);\n }\n\n // High surrogate (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xD800 <= code && code <= 0xDBFF) {\n if (str.length <= (i + 1)) {\n throw 'High surrogate without following low surrogate';\n }\n var next = str.charCodeAt(i + 1);\n if (0xDC00 > next || next > 0xDFFF) {\n throw 'High surrogate without following low surrogate';\n }\n return str.charAt(i) + str.charAt(i + 1);\n }\n // Low surrogate (0xDC00 <= code && code <= 0xDFFF)\n if (i === 0) {\n throw 'Low surrogate without preceding high surrogate';\n }\n var prev = str.charCodeAt(i - 1);\n\n // (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xD800 > prev || prev > 0xDBFF) {\n throw 'Low surrogate without preceding high surrogate';\n }\n // We can pass over low surrogates now as the second component\n // in a pair which we have already processed\n return false;\n }\n\n\n /**\n * String utilities\n * @namespace fabric.util.string\n */\n fabric.util.string = {\n camelize: camelize,\n capitalize: capitalize,\n escapeXml: escapeXml,\n graphemeSplit: graphemeSplit\n };\n})();\n\n\n(function() {\n\n var slice = Array.prototype.slice, emptyFunction = function() { },\n\n IS_DONTENUM_BUGGY = (function() {\n for (var p in { toString: 1 }) {\n if (p === 'toString') {\n return false;\n }\n }\n return true;\n })(),\n\n /** @ignore */\n addMethods = function(klass, source, parent) {\n for (var property in source) {\n\n if (property in klass.prototype &&\n typeof klass.prototype[property] === 'function' &&\n (source[property] + '').indexOf('callSuper') > -1) {\n\n klass.prototype[property] = (function(property) {\n return function() {\n\n var superclass = this.constructor.superclass;\n this.constructor.superclass = parent;\n var returnValue = source[property].apply(this, arguments);\n this.constructor.superclass = superclass;\n\n if (property !== 'initialize') {\n return returnValue;\n }\n };\n })(property);\n }\n else {\n klass.prototype[property] = source[property];\n }\n\n if (IS_DONTENUM_BUGGY) {\n if (source.toString !== Object.prototype.toString) {\n klass.prototype.toString = source.toString;\n }\n if (source.valueOf !== Object.prototype.valueOf) {\n klass.prototype.valueOf = source.valueOf;\n }\n }\n }\n };\n\n function Subclass() { }\n\n function callSuper(methodName) {\n var parentMethod = null,\n _this = this;\n\n // climb prototype chain to find method not equal to callee's method\n while (_this.constructor.superclass) {\n var superClassMethod = _this.constructor.superclass.prototype[methodName];\n if (_this[methodName] !== superClassMethod) {\n parentMethod = superClassMethod;\n break;\n }\n // eslint-disable-next-line\n _this = _this.constructor.superclass.prototype;\n }\n\n if (!parentMethod) {\n return console.log('tried to callSuper ' + methodName + ', method not found in prototype chain', this);\n }\n\n return (arguments.length > 1)\n ? parentMethod.apply(this, slice.call(arguments, 1))\n : parentMethod.call(this);\n }\n\n /**\n * Helper for creation of \"classes\".\n * @memberOf fabric.util\n * @param {Function} [parent] optional \"Class\" to inherit from\n * @param {Object} [properties] Properties shared by all instances of this class\n * (be careful modifying objects defined here as this would affect all instances)\n */\n function createClass() {\n var parent = null,\n properties = slice.call(arguments, 0);\n\n if (typeof properties[0] === 'function') {\n parent = properties.shift();\n }\n function klass() {\n this.initialize.apply(this, arguments);\n }\n\n klass.superclass = parent;\n klass.subclasses = [];\n\n if (parent) {\n Subclass.prototype = parent.prototype;\n klass.prototype = new Subclass();\n parent.subclasses.push(klass);\n }\n for (var i = 0, length = properties.length; i < length; i++) {\n addMethods(klass, properties[i], parent);\n }\n if (!klass.prototype.initialize) {\n klass.prototype.initialize = emptyFunction;\n }\n klass.prototype.constructor = klass;\n klass.prototype.callSuper = callSuper;\n return klass;\n }\n\n fabric.util.createClass = createClass;\n})();\n\n\n(function () {\n // since ie10 or ie9 can use addEventListener but they do not support options, i need to check\n var couldUseAttachEvent = !!fabric.document.createElement('div').attachEvent;\n /**\n * Adds an event listener to an element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {String} eventName\n * @param {Function} handler\n */\n fabric.util.addListener = function(element, eventName, handler, options) {\n element && element.addEventListener(eventName, handler, couldUseAttachEvent ? false : options);\n };\n\n /**\n * Removes an event listener from an element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {String} eventName\n * @param {Function} handler\n */\n fabric.util.removeListener = function(element, eventName, handler, options) {\n element && element.removeEventListener(eventName, handler, couldUseAttachEvent ? false : options);\n };\n\n function getTouchInfo(event) {\n var touchProp = event.changedTouches;\n if (touchProp && touchProp[0]) {\n return touchProp[0];\n }\n return event;\n }\n\n fabric.util.getPointer = function(event) {\n var element = event.target,\n scroll = fabric.util.getScrollLeftTop(element),\n _evt = getTouchInfo(event);\n return {\n x: _evt.clientX + scroll.left,\n y: _evt.clientY + scroll.top\n };\n };\n})();\n\n\n(function () {\n\n /**\n * Cross-browser wrapper for setting element's style\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {Object} styles\n * @return {HTMLElement} Element that was passed as a first argument\n */\n function setStyle(element, styles) {\n var elementStyle = element.style;\n if (!elementStyle) {\n return element;\n }\n if (typeof styles === 'string') {\n element.style.cssText += ';' + styles;\n return styles.indexOf('opacity') > -1\n ? setOpacity(element, styles.match(/opacity:\\s*(\\d?\\.?\\d*)/)[1])\n : element;\n }\n for (var property in styles) {\n if (property === 'opacity') {\n setOpacity(element, styles[property]);\n }\n else {\n var normalizedProperty = (property === 'float' || property === 'cssFloat')\n ? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat')\n : property;\n elementStyle[normalizedProperty] = styles[property];\n }\n }\n return element;\n }\n\n var parseEl = fabric.document.createElement('div'),\n supportsOpacity = typeof parseEl.style.opacity === 'string',\n supportsFilters = typeof parseEl.style.filter === 'string',\n reOpacity = /alpha\\s*\\(\\s*opacity\\s*=\\s*([^\\)]+)\\)/,\n\n /** @ignore */\n setOpacity = function (element) { return element; };\n\n if (supportsOpacity) {\n /** @ignore */\n setOpacity = function(element, value) {\n element.style.opacity = value;\n return element;\n };\n }\n else if (supportsFilters) {\n /** @ignore */\n setOpacity = function(element, value) {\n var es = element.style;\n if (element.currentStyle && !element.currentStyle.hasLayout) {\n es.zoom = 1;\n }\n if (reOpacity.test(es.filter)) {\n value = value >= 0.9999 ? '' : ('alpha(opacity=' + (value * 100) + ')');\n es.filter = es.filter.replace(reOpacity, value);\n }\n else {\n es.filter += ' alpha(opacity=' + (value * 100) + ')';\n }\n return element;\n };\n }\n\n fabric.util.setStyle = setStyle;\n\n})();\n\n\n(function() {\n\n var _slice = Array.prototype.slice;\n\n /**\n * Takes id and returns an element with that id (if one exists in a document)\n * @memberOf fabric.util\n * @param {String|HTMLElement} id\n * @return {HTMLElement|null}\n */\n function getById(id) {\n return typeof id === 'string' ? fabric.document.getElementById(id) : id;\n }\n\n var sliceCanConvertNodelists,\n /**\n * Converts an array-like object (e.g. arguments or NodeList) to an array\n * @memberOf fabric.util\n * @param {Object} arrayLike\n * @return {Array}\n */\n toArray = function(arrayLike) {\n return _slice.call(arrayLike, 0);\n };\n\n try {\n sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;\n }\n catch (err) { }\n\n if (!sliceCanConvertNodelists) {\n toArray = function(arrayLike) {\n var arr = new Array(arrayLike.length), i = arrayLike.length;\n while (i--) {\n arr[i] = arrayLike[i];\n }\n return arr;\n };\n }\n\n /**\n * Creates specified element with specified attributes\n * @memberOf fabric.util\n * @param {String} tagName Type of an element to create\n * @param {Object} [attributes] Attributes to set on an element\n * @return {HTMLElement} Newly created element\n */\n function makeElement(tagName, attributes) {\n var el = fabric.document.createElement(tagName);\n for (var prop in attributes) {\n if (prop === 'class') {\n el.className = attributes[prop];\n }\n else if (prop === 'for') {\n el.htmlFor = attributes[prop];\n }\n else {\n el.setAttribute(prop, attributes[prop]);\n }\n }\n return el;\n }\n\n /**\n * Adds class to an element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to add class to\n * @param {String} className Class to add to an element\n */\n function addClass(element, className) {\n if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) {\n element.className += (element.className ? ' ' : '') + className;\n }\n }\n\n /**\n * Wraps element with another element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to wrap\n * @param {HTMLElement|String} wrapper Element to wrap with\n * @param {Object} [attributes] Attributes to set on a wrapper\n * @return {HTMLElement} wrapper\n */\n function wrapElement(element, wrapper, attributes) {\n if (typeof wrapper === 'string') {\n wrapper = makeElement(wrapper, attributes);\n }\n if (element.parentNode) {\n element.parentNode.replaceChild(wrapper, element);\n }\n wrapper.appendChild(element);\n return wrapper;\n }\n\n /**\n * Returns element scroll offsets\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to operate on\n * @return {Object} Object with left/top values\n */\n function getScrollLeftTop(element) {\n\n var left = 0,\n top = 0,\n docElement = fabric.document.documentElement,\n body = fabric.document.body || {\n scrollLeft: 0, scrollTop: 0\n };\n\n // While loop checks (and then sets element to) .parentNode OR .host\n // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,\n // but the .parentNode of a root ShadowDOM node will always be null, instead\n // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938\n while (element && (element.parentNode || element.host)) {\n\n // Set element to element parent, or 'host' in case of ShadowDOM\n element = element.parentNode || element.host;\n\n if (element === fabric.document) {\n left = body.scrollLeft || docElement.scrollLeft || 0;\n top = body.scrollTop || docElement.scrollTop || 0;\n }\n else {\n left += element.scrollLeft || 0;\n top += element.scrollTop || 0;\n }\n\n if (element.nodeType === 1 && element.style.position === 'fixed') {\n break;\n }\n }\n\n return { left: left, top: top };\n }\n\n /**\n * Returns offset for a given element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to get offset for\n * @return {Object} Object with \"left\" and \"top\" properties\n */\n function getElementOffset(element) {\n var docElem,\n doc = element && element.ownerDocument,\n box = { left: 0, top: 0 },\n offset = { left: 0, top: 0 },\n scrollLeftTop,\n offsetAttributes = {\n borderLeftWidth: 'left',\n borderTopWidth: 'top',\n paddingLeft: 'left',\n paddingTop: 'top'\n };\n\n if (!doc) {\n return offset;\n }\n\n for (var attr in offsetAttributes) {\n offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0;\n }\n\n docElem = doc.documentElement;\n if ( typeof element.getBoundingClientRect !== 'undefined' ) {\n box = element.getBoundingClientRect();\n }\n\n scrollLeftTop = getScrollLeftTop(element);\n\n return {\n left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,\n top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top\n };\n }\n\n /**\n * Returns style attribute value of a given element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to get style attribute for\n * @param {String} attr Style attribute to get for element\n * @return {String} Style attribute value of the given element.\n */\n var getElementStyle;\n if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) {\n getElementStyle = function(element, attr) {\n var style = fabric.document.defaultView.getComputedStyle(element, null);\n return style ? style[attr] : undefined;\n };\n }\n else {\n getElementStyle = function(element, attr) {\n var value = element.style[attr];\n if (!value && element.currentStyle) {\n value = element.currentStyle[attr];\n }\n return value;\n };\n }\n\n (function () {\n var style = fabric.document.documentElement.style,\n selectProp = 'userSelect' in style\n ? 'userSelect'\n : 'MozUserSelect' in style\n ? 'MozUserSelect'\n : 'WebkitUserSelect' in style\n ? 'WebkitUserSelect'\n : 'KhtmlUserSelect' in style\n ? 'KhtmlUserSelect'\n : '';\n\n /**\n * Makes element unselectable\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to make unselectable\n * @return {HTMLElement} Element that was passed in\n */\n function makeElementUnselectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = fabric.util.falseFunction;\n }\n if (selectProp) {\n element.style[selectProp] = 'none';\n }\n else if (typeof element.unselectable === 'string') {\n element.unselectable = 'on';\n }\n return element;\n }\n\n /**\n * Makes element selectable\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to make selectable\n * @return {HTMLElement} Element that was passed in\n */\n function makeElementSelectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = null;\n }\n if (selectProp) {\n element.style[selectProp] = '';\n }\n else if (typeof element.unselectable === 'string') {\n element.unselectable = '';\n }\n return element;\n }\n\n fabric.util.makeElementUnselectable = makeElementUnselectable;\n fabric.util.makeElementSelectable = makeElementSelectable;\n })();\n\n (function() {\n\n /**\n * Inserts a script element with a given url into a document; invokes callback, when that script is finished loading\n * @memberOf fabric.util\n * @param {String} url URL of a script to load\n * @param {Function} callback Callback to execute when script is finished loading\n */\n function getScript(url, callback) {\n var headEl = fabric.document.getElementsByTagName('head')[0],\n scriptEl = fabric.document.createElement('script'),\n loading = true;\n\n /** @ignore */\n scriptEl.onload = /** @ignore */ scriptEl.onreadystatechange = function(e) {\n if (loading) {\n if (typeof this.readyState === 'string' &&\n this.readyState !== 'loaded' &&\n this.readyState !== 'complete') {\n return;\n }\n loading = false;\n callback(e || fabric.window.event);\n scriptEl = scriptEl.onload = scriptEl.onreadystatechange = null;\n }\n };\n scriptEl.src = url;\n headEl.appendChild(scriptEl);\n // causes issue in Opera\n // headEl.removeChild(scriptEl);\n }\n\n fabric.util.getScript = getScript;\n })();\n\n function getNodeCanvas(element) {\n var impl = fabric.jsdomImplForWrapper(element);\n return impl._canvas || impl._image;\n };\n\n function cleanUpJsdomNode(element) {\n if (!fabric.isLikelyNode) {\n return;\n }\n var impl = fabric.jsdomImplForWrapper(element);\n if (impl) {\n impl._image = null;\n impl._canvas = null;\n // unsure if necessary\n impl._currentSrc = null;\n impl._attributes = null;\n impl._classList = null;\n }\n }\n\n fabric.util.getById = getById;\n fabric.util.toArray = toArray;\n fabric.util.makeElement = makeElement;\n fabric.util.addClass = addClass;\n fabric.util.wrapElement = wrapElement;\n fabric.util.getScrollLeftTop = getScrollLeftTop;\n fabric.util.getElementOffset = getElementOffset;\n fabric.util.getElementStyle = getElementStyle;\n fabric.util.getNodeCanvas = getNodeCanvas;\n fabric.util.cleanUpJsdomNode = cleanUpJsdomNode;\n\n})();\n\n\n(function() {\n\n function addParamToUrl(url, param) {\n return url + (/\\?/.test(url) ? '&' : '?') + param;\n }\n\n function emptyFn() { }\n\n /**\n * Cross-browser abstraction for sending XMLHttpRequest\n * @memberOf fabric.util\n * @param {String} url URL to send XMLHttpRequest to\n * @param {Object} [options] Options object\n * @param {String} [options.method=\"GET\"]\n * @param {String} [options.parameters] parameters to append to url in GET or in body\n * @param {String} [options.body] body to send with POST or PUT request\n * @param {Function} options.onComplete Callback to invoke when request is completed\n * @return {XMLHttpRequest} request\n */\n function request(url, options) {\n options || (options = { });\n\n var method = options.method ? options.method.toUpperCase() : 'GET',\n onComplete = options.onComplete || function() { },\n xhr = new fabric.window.XMLHttpRequest(),\n body = options.body || options.parameters;\n\n /** @ignore */\n xhr.onreadystatechange = function() {\n if (xhr.readyState === 4) {\n onComplete(xhr);\n xhr.onreadystatechange = emptyFn;\n }\n };\n\n if (method === 'GET') {\n body = null;\n if (typeof options.parameters === 'string') {\n url = addParamToUrl(url, options.parameters);\n }\n }\n\n xhr.open(method, url, true);\n\n if (method === 'POST' || method === 'PUT') {\n xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n }\n\n xhr.send(body);\n return xhr;\n }\n\n fabric.util.request = request;\n})();\n\n\n/**\n * Wrapper around `console.log` (when available)\n * @param {*} [values] Values to log\n */\nfabric.log = console.log;\n\n/**\n * Wrapper around `console.warn` (when available)\n * @param {*} [values] Values to log as a warning\n */\nfabric.warn = console.warn;\n\n\n(function() {\n\n function noop() {\n return false;\n }\n\n function defaultEasing(t, b, c, d) {\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n }\n\n /**\n * Changes value from one to another within certain period of time, invoking callbacks as value is being changed.\n * @memberOf fabric.util\n * @param {Object} [options] Animation options\n * @param {Function} [options.onChange] Callback; invoked on every value change\n * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n * @param {Number} [options.startValue=0] Starting value\n * @param {Number} [options.endValue=100] Ending value\n * @param {Number} [options.byValue=100] Value to modify the property by\n * @param {Function} [options.easing] Easing function\n * @param {Number} [options.duration=500] Duration of change (in ms)\n * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called.\n */\n function animate(options) {\n\n requestAnimFrame(function(timestamp) {\n options || (options = { });\n\n var start = timestamp || +new Date(),\n duration = options.duration || 500,\n finish = start + duration, time,\n onChange = options.onChange || noop,\n abort = options.abort || noop,\n onComplete = options.onComplete || noop,\n easing = options.easing || defaultEasing,\n startValue = 'startValue' in options ? options.startValue : 0,\n endValue = 'endValue' in options ? options.endValue : 100,\n byValue = options.byValue || endValue - startValue;\n\n options.onStart && options.onStart();\n\n (function tick(ticktime) {\n // TODO: move abort call after calculation\n // and pass (current,valuePerc, timePerc) as arguments\n time = ticktime || +new Date();\n var currentTime = time > finish ? duration : (time - start),\n timePerc = currentTime / duration,\n current = easing(currentTime, startValue, byValue, duration),\n valuePerc = Math.abs((current - startValue) / byValue);\n if (abort()) {\n onComplete(endValue, 1, 1);\n return;\n }\n if (time > finish) {\n onChange(endValue, 1, 1);\n onComplete(endValue, 1, 1);\n return;\n }\n else {\n onChange(current, valuePerc, timePerc);\n requestAnimFrame(tick);\n }\n })(start);\n });\n }\n\n var _requestAnimFrame = fabric.window.requestAnimationFrame ||\n fabric.window.webkitRequestAnimationFrame ||\n fabric.window.mozRequestAnimationFrame ||\n fabric.window.oRequestAnimationFrame ||\n fabric.window.msRequestAnimationFrame ||\n function(callback) {\n return fabric.window.setTimeout(callback, 1000 / 60);\n };\n\n var _cancelAnimFrame = fabric.window.cancelAnimationFrame || fabric.window.clearTimeout;\n\n /**\n * requestAnimationFrame polyfill based on http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n * In order to get a precise start time, `requestAnimFrame` should be called as an entry into the method\n * @memberOf fabric.util\n * @param {Function} callback Callback to invoke\n * @param {DOMElement} element optional Element to associate with animation\n */\n function requestAnimFrame() {\n return _requestAnimFrame.apply(fabric.window, arguments);\n }\n\n function cancelAnimFrame() {\n return _cancelAnimFrame.apply(fabric.window, arguments);\n }\n\n fabric.util.animate = animate;\n fabric.util.requestAnimFrame = requestAnimFrame;\n fabric.util.cancelAnimFrame = cancelAnimFrame;\n})();\n\n\n(function() {\n // Calculate an in-between color. Returns a \"rgba()\" string.\n // Credit: Edwin Martin \n // http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors.js\n function calculateColor(begin, end, pos) {\n var color = 'rgba('\n + parseInt((begin[0] + pos * (end[0] - begin[0])), 10) + ','\n + parseInt((begin[1] + pos * (end[1] - begin[1])), 10) + ','\n + parseInt((begin[2] + pos * (end[2] - begin[2])), 10);\n\n color += ',' + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1);\n color += ')';\n return color;\n }\n\n /**\n * Changes the color from one to another within certain period of time, invoking callbacks as value is being changed.\n * @memberOf fabric.util\n * @param {String} fromColor The starting color in hex or rgb(a) format.\n * @param {String} toColor The starting color in hex or rgb(a) format.\n * @param {Number} [duration] Duration of change (in ms).\n * @param {Object} [options] Animation options\n * @param {Function} [options.onChange] Callback; invoked on every value change\n * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n * @param {Function} [options.colorEasing] Easing function. Note that this function only take two arguments (currentTime, duration). Thus the regular animation easing functions cannot be used.\n * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called.\n */\n function animateColor(fromColor, toColor, duration, options) {\n var startColor = new fabric.Color(fromColor).getSource(),\n endColor = new fabric.Color(toColor).getSource();\n\n options = options || {};\n\n fabric.util.animate(fabric.util.object.extend(options, {\n duration: duration || 500,\n startValue: startColor,\n endValue: endColor,\n byValue: endColor,\n easing: function (currentTime, startValue, byValue, duration) {\n var posValue = options.colorEasing\n ? options.colorEasing(currentTime, duration)\n : 1 - Math.cos(currentTime / duration * (Math.PI / 2));\n return calculateColor(startValue, byValue, posValue);\n }\n }));\n }\n\n fabric.util.animateColor = animateColor;\n\n})();\n\n\n(function() {\n\n function normalize(a, c, p, s) {\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n }\n else {\n //handle the 0/0 case:\n if (c === 0 && a === 0) {\n s = p / (2 * Math.PI) * Math.asin(1);\n }\n else {\n s = p / (2 * Math.PI) * Math.asin(c / a);\n }\n }\n return { a: a, c: c, p: p, s: s };\n }\n\n function elastic(opts, t, d) {\n return opts.a *\n Math.pow(2, 10 * (t -= 1)) *\n Math.sin( (t * d - opts.s) * (2 * Math.PI) / opts.p );\n }\n\n /**\n * Cubic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutCubic(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t + 1) + b;\n }\n\n /**\n * Cubic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutCubic(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t + b;\n }\n return c / 2 * ((t -= 2) * t * t + 2) + b;\n }\n\n /**\n * Quartic easing in\n * @memberOf fabric.util.ease\n */\n function easeInQuart(t, b, c, d) {\n return c * (t /= d) * t * t * t + b;\n }\n\n /**\n * Quartic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutQuart(t, b, c, d) {\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\n }\n\n /**\n * Quartic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutQuart(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t * t + b;\n }\n return -c / 2 * ((t -= 2) * t * t * t - 2) + b;\n }\n\n /**\n * Quintic easing in\n * @memberOf fabric.util.ease\n */\n function easeInQuint(t, b, c, d) {\n return c * (t /= d) * t * t * t * t + b;\n }\n\n /**\n * Quintic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutQuint(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\n }\n\n /**\n * Quintic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutQuint(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t * t * t + b;\n }\n return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\n }\n\n /**\n * Sinusoidal easing in\n * @memberOf fabric.util.ease\n */\n function easeInSine(t, b, c, d) {\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n }\n\n /**\n * Sinusoidal easing out\n * @memberOf fabric.util.ease\n */\n function easeOutSine(t, b, c, d) {\n return c * Math.sin(t / d * (Math.PI / 2)) + b;\n }\n\n /**\n * Sinusoidal easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutSine(t, b, c, d) {\n return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n }\n\n /**\n * Exponential easing in\n * @memberOf fabric.util.ease\n */\n function easeInExpo(t, b, c, d) {\n return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;\n }\n\n /**\n * Exponential easing out\n * @memberOf fabric.util.ease\n */\n function easeOutExpo(t, b, c, d) {\n return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;\n }\n\n /**\n * Exponential easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutExpo(t, b, c, d) {\n if (t === 0) {\n return b;\n }\n if (t === d) {\n return b + c;\n }\n t /= d / 2;\n if (t < 1) {\n return c / 2 * Math.pow(2, 10 * (t - 1)) + b;\n }\n return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;\n }\n\n /**\n * Circular easing in\n * @memberOf fabric.util.ease\n */\n function easeInCirc(t, b, c, d) {\n return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n }\n\n /**\n * Circular easing out\n * @memberOf fabric.util.ease\n */\n function easeOutCirc(t, b, c, d) {\n return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n }\n\n /**\n * Circular easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutCirc(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;\n }\n return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n }\n\n /**\n * Elastic easing in\n * @memberOf fabric.util.ease\n */\n function easeInElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n var opts = normalize(a, c, p, s);\n return -elastic(opts, t, d) + b;\n }\n\n /**\n * Elastic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n var opts = normalize(a, c, p, s);\n return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) + opts.c + b;\n }\n\n /**\n * Elastic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d / 2;\n if (t === 2) {\n return b + c;\n }\n if (!p) {\n p = d * (0.3 * 1.5);\n }\n var opts = normalize(a, c, p, s);\n if (t < 1) {\n return -0.5 * elastic(opts, t, d) + b;\n }\n return opts.a * Math.pow(2, -10 * (t -= 1)) *\n Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) * 0.5 + opts.c + b;\n }\n\n /**\n * Backwards easing in\n * @memberOf fabric.util.ease\n */\n function easeInBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n return c * (t /= d) * t * ((s + 1) * t - s) + b;\n }\n\n /**\n * Backwards easing out\n * @memberOf fabric.util.ease\n */\n function easeOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n }\n\n /**\n * Backwards easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n t /= d / 2;\n if (t < 1) {\n return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;\n }\n return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;\n }\n\n /**\n * Bouncing easing in\n * @memberOf fabric.util.ease\n */\n function easeInBounce(t, b, c, d) {\n return c - easeOutBounce (d - t, 0, c, d) + b;\n }\n\n /**\n * Bouncing easing out\n * @memberOf fabric.util.ease\n */\n function easeOutBounce(t, b, c, d) {\n if ((t /= d) < (1 / 2.75)) {\n return c * (7.5625 * t * t) + b;\n }\n else if (t < (2 / 2.75)) {\n return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;\n }\n else if (t < (2.5 / 2.75)) {\n return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;\n }\n else {\n return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;\n }\n }\n\n /**\n * Bouncing easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutBounce(t, b, c, d) {\n if (t < d / 2) {\n return easeInBounce (t * 2, 0, c, d) * 0.5 + b;\n }\n return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n }\n\n /**\n * Easing functions\n * See Easing Equations by Robert Penner\n * @namespace fabric.util.ease\n */\n fabric.util.ease = {\n\n /**\n * Quadratic easing in\n * @memberOf fabric.util.ease\n */\n easeInQuad: function(t, b, c, d) {\n return c * (t /= d) * t + b;\n },\n\n /**\n * Quadratic easing out\n * @memberOf fabric.util.ease\n */\n easeOutQuad: function(t, b, c, d) {\n return -c * (t /= d) * (t - 2) + b;\n },\n\n /**\n * Quadratic easing in and out\n * @memberOf fabric.util.ease\n */\n easeInOutQuad: function(t, b, c, d) {\n t /= (d / 2);\n if (t < 1) {\n return c / 2 * t * t + b;\n }\n return -c / 2 * ((--t) * (t - 2) - 1) + b;\n },\n\n /**\n * Cubic easing in\n * @memberOf fabric.util.ease\n */\n easeInCubic: function(t, b, c, d) {\n return c * (t /= d) * t * t + b;\n },\n\n easeOutCubic: easeOutCubic,\n easeInOutCubic: easeInOutCubic,\n easeInQuart: easeInQuart,\n easeOutQuart: easeOutQuart,\n easeInOutQuart: easeInOutQuart,\n easeInQuint: easeInQuint,\n easeOutQuint: easeOutQuint,\n easeInOutQuint: easeInOutQuint,\n easeInSine: easeInSine,\n easeOutSine: easeOutSine,\n easeInOutSine: easeInOutSine,\n easeInExpo: easeInExpo,\n easeOutExpo: easeOutExpo,\n easeInOutExpo: easeInOutExpo,\n easeInCirc: easeInCirc,\n easeOutCirc: easeOutCirc,\n easeInOutCirc: easeInOutCirc,\n easeInElastic: easeInElastic,\n easeOutElastic: easeOutElastic,\n easeInOutElastic: easeInOutElastic,\n easeInBack: easeInBack,\n easeOutBack: easeOutBack,\n easeInOutBack: easeInOutBack,\n easeInBounce: easeInBounce,\n easeOutBounce: easeOutBounce,\n easeInOutBounce: easeInOutBounce\n };\n\n})();\n\n\n(function(global) {\n\n 'use strict';\n\n /**\n * @name fabric\n * @namespace\n */\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n toFixed = fabric.util.toFixed,\n parseUnit = fabric.util.parseUnit,\n multiplyTransformMatrices = fabric.util.multiplyTransformMatrices,\n\n svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line',\n 'image', 'text'],\n svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],\n svgInvalidAncestors = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'],\n svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'],\n\n attributesMap = {\n cx: 'left',\n x: 'left',\n r: 'radius',\n cy: 'top',\n y: 'top',\n display: 'visible',\n visibility: 'visible',\n transform: 'transformMatrix',\n 'fill-opacity': 'fillOpacity',\n 'fill-rule': 'fillRule',\n 'font-family': 'fontFamily',\n 'font-size': 'fontSize',\n 'font-style': 'fontStyle',\n 'font-weight': 'fontWeight',\n 'letter-spacing': 'charSpacing',\n 'paint-order': 'paintFirst',\n 'stroke-dasharray': 'strokeDashArray',\n 'stroke-dashoffset': 'strokeDashOffset',\n 'stroke-linecap': 'strokeLineCap',\n 'stroke-linejoin': 'strokeLineJoin',\n 'stroke-miterlimit': 'strokeMiterLimit',\n 'stroke-opacity': 'strokeOpacity',\n 'stroke-width': 'strokeWidth',\n 'text-decoration': 'textDecoration',\n 'text-anchor': 'textAnchor',\n opacity: 'opacity',\n 'clip-path': 'clipPath',\n 'clip-rule': 'clipRule',\n 'vector-effect': 'strokeUniform'\n },\n\n colorAttributes = {\n stroke: 'strokeOpacity',\n fill: 'fillOpacity'\n },\n\n fSize = 'font-size', cPath = 'clip-path';\n\n fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);\n fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);\n fabric.svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);\n fabric.svgValidParentsRegEx = getSvgRegex(svgValidParents);\n\n fabric.cssRules = { };\n fabric.gradientDefs = { };\n fabric.clipPaths = { };\n\n function normalizeAttr(attr) {\n // transform attribute names\n if (attr in attributesMap) {\n return attributesMap[attr];\n }\n return attr;\n }\n\n function normalizeValue(attr, value, parentAttributes, fontSize) {\n var isArray = Object.prototype.toString.call(value) === '[object Array]',\n parsed;\n\n if ((attr === 'fill' || attr === 'stroke') && value === 'none') {\n value = '';\n }\n else if (attr === 'vector-effect') {\n value = value === 'non-scaling-stroke';\n }\n else if (attr === 'strokeDashArray') {\n if (value === 'none') {\n value = null;\n }\n else {\n value = value.replace(/,/g, ' ').split(/\\s+/).map(parseFloat);\n }\n }\n else if (attr === 'transformMatrix') {\n if (parentAttributes && parentAttributes.transformMatrix) {\n value = multiplyTransformMatrices(\n parentAttributes.transformMatrix, fabric.parseTransformAttribute(value));\n }\n else {\n value = fabric.parseTransformAttribute(value);\n }\n }\n else if (attr === 'visible') {\n value = value !== 'none' && value !== 'hidden';\n // display=none on parent element always takes precedence over child element\n if (parentAttributes && parentAttributes.visible === false) {\n value = false;\n }\n }\n else if (attr === 'opacity') {\n value = parseFloat(value);\n if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n value *= parentAttributes.opacity;\n }\n }\n else if (attr === 'textAnchor' /* text-anchor */) {\n value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center';\n }\n else if (attr === 'charSpacing') {\n // parseUnit returns px and we convert it to em\n parsed = parseUnit(value, fontSize) / fontSize * 1000;\n }\n else if (attr === 'paintFirst') {\n var fillIndex = value.indexOf('fill');\n var strokeIndex = value.indexOf('stroke');\n var value = 'fill';\n if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) {\n value = 'stroke';\n }\n else if (fillIndex === -1 && strokeIndex > -1) {\n value = 'stroke';\n }\n }\n else if (attr === 'href' || attr === 'xlink:href') {\n return value;\n }\n else {\n parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize);\n }\n\n return (!isArray && isNaN(parsed) ? value : parsed);\n }\n\n /**\n * @private\n */\n function getSvgRegex(arr) {\n return new RegExp('^(' + arr.join('|') + ')\\\\b', 'i');\n }\n\n /**\n * @private\n * @param {Object} attributes Array of attributes to parse\n */\n function _setStrokeFillOpacity(attributes) {\n for (var attr in colorAttributes) {\n\n if (typeof attributes[colorAttributes[attr]] === 'undefined' || attributes[attr] === '') {\n continue;\n }\n\n if (typeof attributes[attr] === 'undefined') {\n if (!fabric.Object.prototype[attr]) {\n continue;\n }\n attributes[attr] = fabric.Object.prototype[attr];\n }\n\n if (attributes[attr].indexOf('url(') === 0) {\n continue;\n }\n\n var color = new fabric.Color(attributes[attr]);\n attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba();\n }\n return attributes;\n }\n\n /**\n * @private\n */\n function _getMultipleNodes(doc, nodeNames) {\n var nodeName, nodeArray = [], nodeList, i, len;\n for (i = 0, len = nodeNames.length; i < len; i++) {\n nodeName = nodeNames[i];\n nodeList = doc.getElementsByTagName(nodeName);\n nodeArray = nodeArray.concat(Array.prototype.slice.call(nodeList));\n }\n return nodeArray;\n }\n\n /**\n * Parses \"transform\" attribute, returning an array of values\n * @static\n * @function\n * @memberOf fabric\n * @param {String} attributeValue String containing attribute value\n * @return {Array} Array of 6 elements representing transformation matrix\n */\n fabric.parseTransformAttribute = (function() {\n function rotateMatrix(matrix, args) {\n var cos = fabric.util.cos(args[0]), sin = fabric.util.sin(args[0]),\n x = 0, y = 0;\n if (args.length === 3) {\n x = args[1];\n y = args[2];\n }\n\n matrix[0] = cos;\n matrix[1] = sin;\n matrix[2] = -sin;\n matrix[3] = cos;\n matrix[4] = x - (cos * x - sin * y);\n matrix[5] = y - (sin * x + cos * y);\n }\n\n function scaleMatrix(matrix, args) {\n var multiplierX = args[0],\n multiplierY = (args.length === 2) ? args[1] : args[0];\n\n matrix[0] = multiplierX;\n matrix[3] = multiplierY;\n }\n\n function skewMatrix(matrix, args, pos) {\n matrix[pos] = Math.tan(fabric.util.degreesToRadians(args[0]));\n }\n\n function translateMatrix(matrix, args) {\n matrix[4] = args[0];\n if (args.length === 2) {\n matrix[5] = args[1];\n }\n }\n\n // identity matrix\n var iMatrix = fabric.iMatrix,\n\n // == begin transform regexp\n number = fabric.reNum,\n\n commaWsp = '(?:\\\\s+,?\\\\s*|,\\\\s*)',\n\n skewX = '(?:(skewX)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n skewY = '(?:(skewY)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n rotate = '(?:(rotate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + ')' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n scale = '(?:(scale)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n translate = '(?:(translate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n matrix = '(?:(matrix)\\\\s*\\\\(\\\\s*' +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' +\n '\\\\s*\\\\))',\n\n transform = '(?:' +\n matrix + '|' +\n translate + '|' +\n scale + '|' +\n rotate + '|' +\n skewX + '|' +\n skewY +\n ')',\n\n transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')',\n\n transformList = '^\\\\s*(?:' + transforms + '?)\\\\s*$',\n\n // http://www.w3.org/TR/SVG/coords.html#TransformAttribute\n reTransformList = new RegExp(transformList),\n // == end transform regexp\n\n reTransform = new RegExp(transform, 'g');\n\n return function(attributeValue) {\n\n // start with identity matrix\n var matrix = iMatrix.concat(),\n matrices = [];\n\n // return if no argument was given or\n // an argument does not match transform attribute regexp\n if (!attributeValue || (attributeValue && !reTransformList.test(attributeValue))) {\n return matrix;\n }\n\n attributeValue.replace(reTransform, function(match) {\n\n var m = new RegExp(transform).exec(match).filter(function (match) {\n // match !== '' && match != null\n return (!!match);\n }),\n operation = m[1],\n args = m.slice(2).map(parseFloat);\n\n switch (operation) {\n case 'translate':\n translateMatrix(matrix, args);\n break;\n case 'rotate':\n args[0] = fabric.util.degreesToRadians(args[0]);\n rotateMatrix(matrix, args);\n break;\n case 'scale':\n scaleMatrix(matrix, args);\n break;\n case 'skewX':\n skewMatrix(matrix, args, 2);\n break;\n case 'skewY':\n skewMatrix(matrix, args, 1);\n break;\n case 'matrix':\n matrix = args;\n break;\n }\n\n // snapshot current matrix into matrices array\n matrices.push(matrix.concat());\n // reset\n matrix = iMatrix.concat();\n });\n\n var combinedMatrix = matrices[0];\n while (matrices.length > 1) {\n matrices.shift();\n combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]);\n }\n return combinedMatrix;\n };\n })();\n\n /**\n * @private\n */\n function parseStyleString(style, oStyle) {\n var attr, value;\n style.replace(/;\\s*$/, '').split(';').forEach(function (chunk) {\n var pair = chunk.split(':');\n\n attr = pair[0].trim().toLowerCase();\n value = pair[1].trim();\n\n oStyle[attr] = value;\n });\n }\n\n /**\n * @private\n */\n function parseStyleObject(style, oStyle) {\n var attr, value;\n for (var prop in style) {\n if (typeof style[prop] === 'undefined') {\n continue;\n }\n\n attr = prop.toLowerCase();\n value = style[prop];\n\n oStyle[attr] = value;\n }\n }\n\n /**\n * @private\n */\n function getGlobalStylesForElement(element, svgUid) {\n var styles = { };\n for (var rule in fabric.cssRules[svgUid]) {\n if (elementMatchesRule(element, rule.split(' '))) {\n for (var property in fabric.cssRules[svgUid][rule]) {\n styles[property] = fabric.cssRules[svgUid][rule][property];\n }\n }\n }\n return styles;\n }\n\n /**\n * @private\n */\n function elementMatchesRule(element, selectors) {\n var firstMatching, parentMatching = true;\n //start from rightmost selector.\n firstMatching = selectorMatches(element, selectors.pop());\n if (firstMatching && selectors.length) {\n parentMatching = doesSomeParentMatch(element, selectors);\n }\n return firstMatching && parentMatching && (selectors.length === 0);\n }\n\n function doesSomeParentMatch(element, selectors) {\n var selector, parentMatching = true;\n while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) {\n if (parentMatching) {\n selector = selectors.pop();\n }\n element = element.parentNode;\n parentMatching = selectorMatches(element, selector);\n }\n return selectors.length === 0;\n }\n\n /**\n * @private\n */\n function selectorMatches(element, selector) {\n var nodeName = element.nodeName,\n classNames = element.getAttribute('class'),\n id = element.getAttribute('id'), matcher, i;\n // i check if a selector matches slicing away part from it.\n // if i get empty string i should match\n matcher = new RegExp('^' + nodeName, 'i');\n selector = selector.replace(matcher, '');\n if (id && selector.length) {\n matcher = new RegExp('#' + id + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n if (classNames && selector.length) {\n classNames = classNames.split(' ');\n for (i = classNames.length; i--;) {\n matcher = new RegExp('\\\\.' + classNames[i] + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n }\n return selector.length === 0;\n }\n\n /**\n * @private\n * to support IE8 missing getElementById on SVGdocument and on node xmlDOM\n */\n function elementById(doc, id) {\n var el;\n doc.getElementById && (el = doc.getElementById(id));\n if (el) {\n return el;\n }\n var node, i, len, nodelist = doc.getElementsByTagName('*');\n for (i = 0, len = nodelist.length; i < len; i++) {\n node = nodelist[i];\n if (id === node.getAttribute('id')) {\n return node;\n }\n }\n }\n\n /**\n * @private\n */\n function parseUseDirectives(doc) {\n var nodelist = _getMultipleNodes(doc, ['use', 'svg:use']), i = 0;\n while (nodelist.length && i < nodelist.length) {\n var el = nodelist[i],\n xlink = (el.getAttribute('xlink:href') || el.getAttribute('href')).substr(1),\n x = el.getAttribute('x') || 0,\n y = el.getAttribute('y') || 0,\n el2 = elementById(doc, xlink).cloneNode(true),\n currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')',\n parentNode, oldLength = nodelist.length, attr, j, attrs, len, namespace = fabric.svgNS;\n\n applyViewboxTransform(el2);\n if (/^svg$/i.test(el2.nodeName)) {\n var el3 = el2.ownerDocument.createElementNS(namespace, 'g');\n for (j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) {\n attr = attrs.item(j);\n el3.setAttributeNS(namespace, attr.nodeName, attr.nodeValue);\n }\n // el2.firstChild != null\n while (el2.firstChild) {\n el3.appendChild(el2.firstChild);\n }\n el2 = el3;\n }\n\n for (j = 0, attrs = el.attributes, len = attrs.length; j < len; j++) {\n attr = attrs.item(j);\n if (attr.nodeName === 'x' || attr.nodeName === 'y' ||\n attr.nodeName === 'xlink:href' || attr.nodeName === 'href') {\n continue;\n }\n\n if (attr.nodeName === 'transform') {\n currentTrans = attr.nodeValue + ' ' + currentTrans;\n }\n else {\n el2.setAttribute(attr.nodeName, attr.nodeValue);\n }\n }\n\n el2.setAttribute('transform', currentTrans);\n el2.setAttribute('instantiated_by_use', '1');\n el2.removeAttribute('id');\n parentNode = el.parentNode;\n parentNode.replaceChild(el2, el);\n // some browsers do not shorten nodelist after replaceChild (IE8)\n if (nodelist.length === oldLength) {\n i++;\n }\n }\n }\n\n // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n // matches, e.g.: +14.56e-12, etc.\n var reViewBoxAttrValue = new RegExp(\n '^' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*' +\n '$'\n );\n\n /**\n * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n */\n function applyViewboxTransform(element) {\n\n var viewBoxAttr = element.getAttribute('viewBox'),\n scaleX = 1,\n scaleY = 1,\n minX = 0,\n minY = 0,\n viewBoxWidth, viewBoxHeight, matrix, el,\n widthAttr = element.getAttribute('width'),\n heightAttr = element.getAttribute('height'),\n x = element.getAttribute('x') || 0,\n y = element.getAttribute('y') || 0,\n preserveAspectRatio = element.getAttribute('preserveAspectRatio') || '',\n missingViewBox = (!viewBoxAttr || !fabric.svgViewBoxElementsRegEx.test(element.nodeName)\n || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))),\n missingDimAttr = (!widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'),\n toBeParsed = missingViewBox && missingDimAttr,\n parsedDim = { }, translateMatrix = '', widthDiff = 0, heightDiff = 0;\n\n parsedDim.width = 0;\n parsedDim.height = 0;\n parsedDim.toBeParsed = toBeParsed;\n\n if (toBeParsed) {\n return parsedDim;\n }\n\n if (missingViewBox) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n return parsedDim;\n }\n minX = -parseFloat(viewBoxAttr[1]);\n minY = -parseFloat(viewBoxAttr[2]);\n viewBoxWidth = parseFloat(viewBoxAttr[3]);\n viewBoxHeight = parseFloat(viewBoxAttr[4]);\n parsedDim.minX = minX;\n parsedDim.minY = minY;\n parsedDim.viewBoxWidth = viewBoxWidth;\n parsedDim.viewBoxHeight = viewBoxHeight;\n if (!missingDimAttr) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n scaleX = parsedDim.width / viewBoxWidth;\n scaleY = parsedDim.height / viewBoxHeight;\n }\n else {\n parsedDim.width = viewBoxWidth;\n parsedDim.height = viewBoxHeight;\n }\n\n // default is to preserve aspect ratio\n preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio);\n if (preserveAspectRatio.alignX !== 'none') {\n //translate all container for the effect of Mid, Min, Max\n if (preserveAspectRatio.meetOrSlice === 'meet') {\n scaleY = scaleX = (scaleX > scaleY ? scaleY : scaleX);\n // calculate additional translation to move the viewbox\n }\n if (preserveAspectRatio.meetOrSlice === 'slice') {\n scaleY = scaleX = (scaleX > scaleY ? scaleX : scaleY);\n // calculate additional translation to move the viewbox\n }\n widthDiff = parsedDim.width - viewBoxWidth * scaleX;\n heightDiff = parsedDim.height - viewBoxHeight * scaleX;\n if (preserveAspectRatio.alignX === 'Mid') {\n widthDiff /= 2;\n }\n if (preserveAspectRatio.alignY === 'Mid') {\n heightDiff /= 2;\n }\n if (preserveAspectRatio.alignX === 'Min') {\n widthDiff = 0;\n }\n if (preserveAspectRatio.alignY === 'Min') {\n heightDiff = 0;\n }\n }\n\n if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) {\n return parsedDim;\n }\n\n if (x || y) {\n translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';\n }\n\n matrix = translateMatrix + ' matrix(' + scaleX +\n ' 0' +\n ' 0 ' +\n scaleY + ' ' +\n (minX * scaleX + widthDiff) + ' ' +\n (minY * scaleY + heightDiff) + ') ';\n parsedDim.viewboxTransform = fabric.parseTransformAttribute(matrix);\n if (element.nodeName === 'svg') {\n el = element.ownerDocument.createElementNS(fabric.svgNS, 'g');\n // element.firstChild != null\n while (element.firstChild) {\n el.appendChild(element.firstChild);\n }\n element.appendChild(el);\n }\n else {\n el = element;\n matrix = el.getAttribute('transform') + matrix;\n }\n el.setAttribute('transform', matrix);\n return parsedDim;\n }\n\n function hasAncestorWithNodeName(element, nodeName) {\n while (element && (element = element.parentNode)) {\n if (element.nodeName && nodeName.test(element.nodeName.replace('svg:', ''))\n && !element.getAttribute('instantiated_by_use')) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @param {Function} callback Callback to call when parsing is finished;\n * It's being passed an array of elements (parsed from a document).\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [parsingOptions] options for parsing document\n * @param {String} [parsingOptions.crossOrigin] crossOrigin settings\n */\n fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) {\n if (!doc) {\n return;\n }\n\n parseUseDirectives(doc);\n\n var svgUid = fabric.Object.__uid++, i, len,\n options = applyViewboxTransform(doc),\n descendants = fabric.util.toArray(doc.getElementsByTagName('*'));\n options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;\n options.svgUid = svgUid;\n\n if (descendants.length === 0 && fabric.isLikelyNode) {\n // we're likely in node, where \"o3-xml\" library fails to gEBTN(\"*\")\n // https://github.com/ajaxorg/node-o3-xml/issues/21\n descendants = doc.selectNodes('//*[name(.)!=\"svg\"]');\n var arr = [];\n for (i = 0, len = descendants.length; i < len; i++) {\n arr[i] = descendants[i];\n }\n descendants = arr;\n }\n\n var elements = descendants.filter(function(el) {\n applyViewboxTransform(el);\n return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')) &&\n !hasAncestorWithNodeName(el, fabric.svgInvalidAncestorsRegEx); // http://www.w3.org/TR/SVG/struct.html#DefsElement\n });\n\n if (!elements || (elements && !elements.length)) {\n callback && callback([], {});\n return;\n }\n var clipPaths = { };\n descendants.filter(function(el) {\n return el.nodeName.replace('svg:', '') === 'clipPath';\n }).forEach(function(el) {\n var id = el.getAttribute('id');\n clipPaths[id] = fabric.util.toArray(el.getElementsByTagName('*')).filter(function(el) {\n return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', ''));\n });\n });\n fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc);\n fabric.cssRules[svgUid] = fabric.getCSSRules(doc);\n fabric.clipPaths[svgUid] = clipPaths;\n // Precedence of rules: style > class > attribute\n fabric.parseElements(elements, function(instances, elements) {\n if (callback) {\n callback(instances, options, elements, descendants);\n delete fabric.gradientDefs[svgUid];\n delete fabric.cssRules[svgUid];\n delete fabric.clipPaths[svgUid];\n }\n }, clone(options), reviver, parsingOptions);\n };\n\n function recursivelyParseGradientsXlink(doc, gradient) {\n var gradientsAttrs = ['gradientTransform', 'x1', 'x2', 'y1', 'y2', 'gradientUnits', 'cx', 'cy', 'r', 'fx', 'fy'],\n xlinkAttr = 'xlink:href',\n xLink = gradient.getAttribute(xlinkAttr).substr(1),\n referencedGradient = elementById(doc, xLink);\n if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) {\n recursivelyParseGradientsXlink(doc, referencedGradient);\n }\n gradientsAttrs.forEach(function(attr) {\n if (referencedGradient && !gradient.hasAttribute(attr) && referencedGradient.hasAttribute(attr)) {\n gradient.setAttribute(attr, referencedGradient.getAttribute(attr));\n }\n });\n if (!gradient.children.length) {\n var referenceClone = referencedGradient.cloneNode(true);\n while (referenceClone.firstChild) {\n gradient.appendChild(referenceClone.firstChild);\n }\n }\n gradient.removeAttribute(xlinkAttr);\n }\n\n var reFontDeclaration = new RegExp(\n '(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' +\n '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' +\n fabric.reNum +\n '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' + fabric.reNum + '))?\\\\s+(.*)');\n\n extend(fabric, {\n /**\n * Parses a short font declaration, building adding its properties to a style object\n * @static\n * @function\n * @memberOf fabric\n * @param {String} value font declaration\n * @param {Object} oStyle definition\n */\n parseFontDeclaration: function(value, oStyle) {\n var match = value.match(reFontDeclaration);\n\n if (!match) {\n return;\n }\n var fontStyle = match[1],\n // font variant is not used\n // fontVariant = match[2],\n fontWeight = match[3],\n fontSize = match[4],\n lineHeight = match[5],\n fontFamily = match[6];\n\n if (fontStyle) {\n oStyle.fontStyle = fontStyle;\n }\n if (fontWeight) {\n oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);\n }\n if (fontSize) {\n oStyle.fontSize = parseUnit(fontSize);\n }\n if (fontFamily) {\n oStyle.fontFamily = fontFamily;\n }\n if (lineHeight) {\n oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;\n }\n },\n\n /**\n * Parses an SVG document, returning all of the gradient declarations found in it\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element\n */\n getGradientDefs: function(doc) {\n var tagArray = [\n 'linearGradient',\n 'radialGradient',\n 'svg:linearGradient',\n 'svg:radialGradient'],\n elList = _getMultipleNodes(doc, tagArray),\n el, j = 0, gradientDefs = { };\n j = elList.length;\n while (j--) {\n el = elList[j];\n if (el.getAttribute('xlink:href')) {\n recursivelyParseGradientsXlink(doc, el);\n }\n gradientDefs[el.getAttribute('id')] = el;\n }\n return gradientDefs;\n },\n\n /**\n * Returns an object of attributes' name/value, given element and an array of attribute names;\n * Parses parent \"g\" nodes recursively upwards.\n * @static\n * @memberOf fabric\n * @param {DOMElement} element Element to parse\n * @param {Array} attributes Array of attributes to parse\n * @return {Object} object containing parsed attributes' names/values\n */\n parseAttributes: function(element, attributes, svgUid) {\n\n if (!element) {\n return;\n }\n\n var value,\n parentAttributes = { },\n fontSize, parentFontSize;\n\n if (typeof svgUid === 'undefined') {\n svgUid = element.getAttribute('svgUid');\n }\n // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n if (element.parentNode && fabric.svgValidParentsRegEx.test(element.parentNode.nodeName)) {\n parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid);\n }\n\n var ownAttributes = attributes.reduce(function(memo, attr) {\n value = element.getAttribute(attr);\n if (value) { // eslint-disable-line\n memo[attr] = value;\n }\n return memo;\n }, { });\n // add values parsed from style, which take precedence over attributes\n // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n var cssAttrs = extend(\n getGlobalStylesForElement(element, svgUid),\n fabric.parseStyleAttribute(element)\n );\n ownAttributes = extend(\n ownAttributes,\n cssAttrs\n );\n if (cssAttrs[cPath]) {\n element.setAttribute(cPath, cssAttrs[cPath]);\n }\n fontSize = parentFontSize = parentAttributes.fontSize || fabric.Text.DEFAULT_SVG_FONT_SIZE;\n if (ownAttributes[fSize]) {\n // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers.\n ownAttributes[fSize] = fontSize = parseUnit(ownAttributes[fSize], parentFontSize);\n }\n\n var normalizedAttr, normalizedValue, normalizedStyle = {};\n for (var attr in ownAttributes) {\n normalizedAttr = normalizeAttr(attr);\n normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);\n normalizedStyle[normalizedAttr] = normalizedValue;\n }\n if (normalizedStyle && normalizedStyle.font) {\n fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);\n }\n var mergedAttrs = extend(parentAttributes, normalizedStyle);\n return fabric.svgValidParentsRegEx.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);\n },\n\n /**\n * Transforms an array of svg elements to corresponding fabric.* instances\n * @static\n * @memberOf fabric\n * @param {Array} elements Array of elements to parse\n * @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements)\n * @param {Object} [options] Options object\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n */\n parseElements: function(elements, callback, options, reviver, parsingOptions) {\n new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();\n },\n\n /**\n * Parses \"style\" attribute, retuning an object with values\n * @static\n * @memberOf fabric\n * @param {SVGElement} element Element to parse\n * @return {Object} Objects with values parsed from style attribute of an element\n */\n parseStyleAttribute: function(element) {\n var oStyle = { },\n style = element.getAttribute('style');\n\n if (!style) {\n return oStyle;\n }\n\n if (typeof style === 'string') {\n parseStyleString(style, oStyle);\n }\n else {\n parseStyleObject(style, oStyle);\n }\n\n return oStyle;\n },\n\n /**\n * Parses \"points\" attribute, returning an array of values\n * @static\n * @memberOf fabric\n * @param {String} points points attribute string\n * @return {Array} array of points\n */\n parsePointsAttribute: function(points) {\n\n // points attribute is required and must not be empty\n if (!points) {\n return null;\n }\n\n // replace commas with whitespace and remove bookending whitespace\n points = points.replace(/,/g, ' ').trim();\n\n points = points.split(/\\s+/);\n var parsedPoints = [], i, len;\n\n for (i = 0, len = points.length; i < len; i += 2) {\n parsedPoints.push({\n x: parseFloat(points[i]),\n y: parseFloat(points[i + 1])\n });\n }\n\n // odd number of points is an error\n // if (parsedPoints.length % 2 !== 0) {\n // return null;\n // }\n\n return parsedPoints;\n },\n\n /**\n * Returns CSS rules for a given SVG document\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} CSS rules of this document\n */\n getCSSRules: function(doc) {\n var styles = doc.getElementsByTagName('style'), i, len,\n allRules = { }, rules;\n\n // very crude parsing of style contents\n for (i = 0, len = styles.length; i < len; i++) {\n // \\n'\n ].join('');\n }\n\n return markup;\n },\n\n /**\n * @private\n */\n _setSVGObjects: function(markup, reviver) {\n var instance, i, len, objects = this._objects;\n for (i = 0, len = objects.length; i < len; i++) {\n instance = objects[i];\n if (instance.excludeFromExport) {\n continue;\n }\n this._setSVGObject(markup, instance, reviver);\n }\n },\n\n /**\n * @private\n */\n _setSVGObject: function(markup, instance, reviver) {\n markup.push(instance.toSVG(reviver));\n },\n\n /**\n * @private\n */\n _setSVGBgOverlayImage: function(markup, property, reviver) {\n if (this[property] && !this[property].excludeFromExport && this[property].toSVG) {\n markup.push(this[property].toSVG(reviver));\n }\n },\n\n /**\n * @private\n */\n _setSVGBgOverlayColor: function(markup, property) {\n var filler = this[property + 'Color'], vpt = this.viewportTransform, finalWidth = this.width,\n finalHeight = this.height;\n if (!filler) {\n return;\n }\n if (filler.toLive) {\n var repeat = filler.repeat, iVpt = fabric.util.invertTransform(vpt), shouldInvert = this[property + 'Vpt'],\n additionalTransform = shouldInvert ? fabric.util.matrixToSVG(iVpt) : '';\n markup.push(\n '\\n'\n );\n }\n else {\n markup.push(\n '\\n'\n );\n }\n },\n /* _TO_SVG_END_ */\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the bottom of the stack of drawn objects\n * @param {fabric.Object} object Object to send to back\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n sendToBack: function (object) {\n if (!object) {\n return this;\n }\n var activeSelection = this._activeObject,\n i, obj, objs;\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n for (i = objs.length; i--;) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n this._objects.unshift(obj);\n }\n }\n else {\n removeFromArray(this._objects, object);\n this._objects.unshift(object);\n }\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the top of the stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n bringToFront: function (object) {\n if (!object) {\n return this;\n }\n var activeSelection = this._activeObject,\n i, obj, objs;\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n this._objects.push(obj);\n }\n }\n else {\n removeFromArray(this._objects, object);\n this._objects.push(object);\n }\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Moves an object or a selection down in stack of drawn objects\n * An optional paramter, intersecting allowes to move the object in behind\n * the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n sendBackwards: function (object, intersecting) {\n if (!object) {\n return this;\n }\n var activeSelection = this._activeObject,\n i, obj, idx, newIdx, objs, objsMoved = 0;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n if (idx > 0 + objsMoved) {\n newIdx = idx - 1;\n removeFromArray(this._objects, obj);\n this._objects.splice(newIdx, 0, obj);\n }\n objsMoved++;\n }\n }\n else {\n idx = this._objects.indexOf(object);\n if (idx !== 0) {\n // if object is not on the bottom of stack\n newIdx = this._findNewLowerIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n }\n }\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewLowerIndex: function(object, idx, intersecting) {\n var newIdx, i;\n\n if (intersecting) {\n newIdx = idx;\n\n // traverse down the stack looking for the nearest intersecting object\n for (i = idx - 1; i >= 0; --i) {\n\n var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n object.isContainedWithinObject(this._objects[i]) ||\n this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\n }\n }\n }\n else {\n newIdx = idx - 1;\n }\n\n return newIdx;\n },\n\n /**\n * Moves an object or a selection up in stack of drawn objects\n * An optional paramter, intersecting allowes to move the object in front\n * of the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n bringForward: function (object, intersecting) {\n if (!object) {\n return this;\n }\n var activeSelection = this._activeObject,\n i, obj, idx, newIdx, objs, objsMoved = 0;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n for (i = objs.length; i--;) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n if (idx < this._objects.length - 1 - objsMoved) {\n newIdx = idx + 1;\n removeFromArray(this._objects, obj);\n this._objects.splice(newIdx, 0, obj);\n }\n objsMoved++;\n }\n }\n else {\n idx = this._objects.indexOf(object);\n if (idx !== this._objects.length - 1) {\n // if object is not on top of stack (last item in an array)\n newIdx = this._findNewUpperIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n }\n }\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewUpperIndex: function(object, idx, intersecting) {\n var newIdx, i, len;\n\n if (intersecting) {\n newIdx = idx;\n\n // traverse up the stack looking for the nearest intersecting object\n for (i = idx + 1, len = this._objects.length; i < len; ++i) {\n\n var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n object.isContainedWithinObject(this._objects[i]) ||\n this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\n }\n }\n }\n else {\n newIdx = idx + 1;\n }\n\n return newIdx;\n },\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {Number} index Position to move to\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n moveTo: function (object, index) {\n removeFromArray(this._objects, object);\n this._objects.splice(index, 0, object);\n return this.renderOnAddRemove && this.requestRenderAll();\n },\n\n /**\n * Clears a canvas element and dispose objects\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n dispose: function () {\n // cancel eventually ongoing renders\n if (this.isRendering) {\n fabric.util.cancelAnimFrame(this.isRendering);\n this.isRendering = 0;\n }\n this.forEachObject(function(object) {\n object.dispose && object.dispose();\n });\n this._objects = [];\n if (this.backgroundImage && this.backgroundImage.dispose) {\n this.backgroundImage.dispose();\n }\n this.backgroundImage = null;\n if (this.overlayImage && this.overlayImage.dispose) {\n this.overlayImage.dispose();\n }\n this.overlayImage = null;\n this._iTextInstances = null;\n this.contextContainer = null;\n fabric.util.cleanUpJsdomNode(this.lowerCanvasEl);\n this.lowerCanvasEl = undefined;\n return this;\n },\n\n /**\n * Returns a string representation of an instance\n * @return {String} string representation of an instance\n */\n toString: function () {\n return '#';\n }\n });\n\n extend(fabric.StaticCanvas.prototype, fabric.Observable);\n extend(fabric.StaticCanvas.prototype, fabric.Collection);\n extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);\n\n extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ {\n\n /**\n * @static\n * @type String\n * @default\n */\n EMPTY_JSON: '{\"objects\": [], \"background\": \"white\"}',\n\n /**\n * Provides a way to check support of some of the canvas methods\n * (either those of HTMLCanvasElement itself, or rendering context)\n *\n * @param {String} methodName Method to check support for;\n * Could be one of \"setLineDash\"\n * @return {Boolean | null} `true` if method is supported (or at least exists),\n * `null` if canvas element or context can not be initialized\n */\n supports: function (methodName) {\n var el = createCanvasElement();\n\n if (!el || !el.getContext) {\n return null;\n }\n\n var ctx = el.getContext('2d');\n if (!ctx) {\n return null;\n }\n\n switch (methodName) {\n\n case 'setLineDash':\n return typeof ctx.setLineDash !== 'undefined';\n\n default:\n return null;\n }\n }\n });\n\n /**\n * Returns JSON representation of canvas\n * @function\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} JSON string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}\n * @example JSON without additional properties\n * var json = canvas.toJSON();\n * @example JSON with additional properties included\n * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY', 'lockUniScaling']);\n * @example JSON without default values\n * canvas.includeDefaultValues = false;\n * var json = canvas.toJSON();\n */\n fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;\n\n if (fabric.isLikelyNode) {\n fabric.StaticCanvas.prototype.createPNGStream = function() {\n var impl = getNodeCanvas(this.lowerCanvasEl);\n return impl && impl.createPNGStream();\n };\n fabric.StaticCanvas.prototype.createJPEGStream = function(opts) {\n var impl = getNodeCanvas(this.lowerCanvasEl);\n return impl && impl.createJPEGStream(opts);\n };\n }\n})();\n\n\n/**\n * BaseBrush class\n * @class fabric.BaseBrush\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\nfabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ {\n\n /**\n * Color of a brush\n * @type String\n * @default\n */\n color: 'rgb(0, 0, 0)',\n\n /**\n * Width of a brush, has to be a Number, no string literals\n * @type Number\n * @default\n */\n width: 1,\n\n /**\n * Shadow object representing shadow of this shape.\n * Backwards incompatibility note: This property replaces \"shadowColor\" (String), \"shadowOffsetX\" (Number),\n * \"shadowOffsetY\" (Number) and \"shadowBlur\" (Number) since v1.2.12\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * Line endings style of a brush (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: 'round',\n\n /**\n * Corner style of a brush (one of \"bevel\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: 'round',\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of a brush's\n * @type Number\n * @default\n */\n strokeMiterLimit: 10,\n\n /**\n * Stroke Dash Array.\n * @type Array\n * @default\n */\n strokeDashArray: null,\n\n /**\n * Sets shadow of an object\n * @param {Object|String} [options] Options object or string (e.g. \"2px 2px 10px rgba(0,0,0,0.2)\")\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setShadow: function(options) {\n this.shadow = new fabric.Shadow(options);\n return this;\n },\n\n /**\n * Sets brush styles\n * @private\n */\n _setBrushStyles: function() {\n var ctx = this.canvas.contextTop;\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.width;\n ctx.lineCap = this.strokeLineCap;\n ctx.miterLimit = this.strokeMiterLimit;\n ctx.lineJoin = this.strokeLineJoin;\n if (fabric.StaticCanvas.supports('setLineDash')) {\n ctx.setLineDash(this.strokeDashArray || []);\n }\n },\n\n /**\n * Sets the transformation on given context\n * @param {RenderingContext2d} ctx context to render on\n * @private\n */\n _saveAndTransform: function(ctx) {\n var v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n },\n\n /**\n * Sets brush shadow styles\n * @private\n */\n _setShadow: function() {\n if (!this.shadow) {\n return;\n }\n\n var canvas = this.canvas,\n shadow = this.shadow,\n ctx = canvas.contextTop,\n zoom = canvas.getZoom();\n if (canvas && canvas._isRetinaScaling()) {\n zoom *= fabric.devicePixelRatio;\n }\n\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * zoom;\n ctx.shadowOffsetX = shadow.offsetX * zoom;\n ctx.shadowOffsetY = shadow.offsetY * zoom;\n },\n\n needsFullRender: function() {\n var color = new fabric.Color(this.color);\n return color.getAlpha() < 1 || !!this.shadow;\n },\n\n /**\n * Removes brush shadow styles\n * @private\n */\n _resetShadow: function() {\n var ctx = this.canvas.contextTop;\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n});\n\n\n(function() {\n /**\n * PencilBrush class\n * @class fabric.PencilBrush\n * @extends fabric.BaseBrush\n */\n fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.PencilBrush.prototype */ {\n\n /**\n * Discard points that are less than `decimate` pixel distant from each other\n * @type Number\n * @default 0.4\n */\n decimate: 0.4,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.PencilBrush} Instance of a pencil brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this._points = [];\n },\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Object} pointer\n */\n _drawSegment: function (ctx, p1, p2) {\n var midPoint = p1.midPointFrom(p2);\n ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);\n return midPoint;\n },\n\n /**\n * Inovoked on mouse down\n * @param {Object} pointer\n */\n onMouseDown: function(pointer, options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return;\n }\n this._prepareForDrawing(pointer);\n // capture coordinates immediately\n // this allows to draw dots (when movement never occurs)\n this._captureDrawingPath(pointer);\n this._render();\n },\n\n /**\n * Inovoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer, options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return;\n }\n if (this._captureDrawingPath(pointer) && this._points.length > 1) {\n if (this.needsFullRender()) {\n // redraw curve\n // clear top canvas\n this.canvas.clearContext(this.canvas.contextTop);\n this._render();\n }\n else {\n var points = this._points, length = points.length, ctx = this.canvas.contextTop;\n // draw the curve update\n this._saveAndTransform(ctx);\n if (this.oldEnd) {\n ctx.beginPath();\n ctx.moveTo(this.oldEnd.x, this.oldEnd.y);\n }\n this.oldEnd = this._drawSegment(ctx, points[length - 2], points[length - 1], true);\n ctx.stroke();\n ctx.restore();\n }\n }\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function(options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return true;\n }\n this.oldEnd = undefined;\n this._finalizeAndAddPath();\n return false;\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _prepareForDrawing: function(pointer) {\n\n var p = new fabric.Point(pointer.x, pointer.y);\n\n this._reset();\n this._addPoint(p);\n this.canvas.contextTop.moveTo(p.x, p.y);\n },\n\n /**\n * @private\n * @param {fabric.Point} point Point to be added to points array\n */\n _addPoint: function(point) {\n if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) {\n return false;\n }\n this._points.push(point);\n return true;\n },\n\n /**\n * Clear points array and set contextTop canvas style.\n * @private\n */\n _reset: function() {\n this._points = [];\n this._setBrushStyles();\n this._setShadow();\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _captureDrawingPath: function(pointer) {\n var pointerPoint = new fabric.Point(pointer.x, pointer.y);\n return this._addPoint(pointerPoint);\n },\n\n /**\n * Draw a smooth path on the topCanvas using quadraticCurveTo\n * @private\n */\n _render: function() {\n var ctx = this.canvas.contextTop, i, len,\n p1 = this._points[0],\n p2 = this._points[1];\n\n this._saveAndTransform(ctx);\n ctx.beginPath();\n //if we only have 2 points in the path and they are the same\n //it means that the user only clicked the canvas without moving the mouse\n //then we should be drawing a dot. A path isn't drawn between two identical dots\n //that's why we set them apart a bit\n if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {\n var width = this.width / 1000;\n p1 = new fabric.Point(p1.x, p1.y);\n p2 = new fabric.Point(p2.x, p2.y);\n p1.x -= width;\n p2.x += width;\n }\n ctx.moveTo(p1.x, p1.y);\n\n for (i = 1, len = this._points.length; i < len; i++) {\n // we pick the point between pi + 1 & pi + 2 as the\n // end point and p1 as our control point.\n this._drawSegment(ctx, p1, p2);\n p1 = this._points[i];\n p2 = this._points[i + 1];\n }\n // Draw last line as a straight line while\n // we wait for the next point to be able to calculate\n // the bezier control point\n ctx.lineTo(p1.x, p1.y);\n ctx.stroke();\n ctx.restore();\n },\n\n /**\n * Converts points to SVG path\n * @param {Array} points Array of points\n * @return {String} SVG path\n */\n convertPointsToSVGPath: function(points) {\n var path = [], i, width = this.width / 1000,\n p1 = new fabric.Point(points[0].x, points[0].y),\n p2 = new fabric.Point(points[1].x, points[1].y),\n len = points.length, multSignX = 1, multSignY = 0, manyPoints = len > 2;\n\n if (manyPoints) {\n multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n }\n path.push('M ', p1.x - multSignX * width, ' ', p1.y - multSignY * width, ' ');\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n var midPoint = p1.midPointFrom(p2);\n // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' ');\n }\n p1 = points[i];\n if ((i + 1) < points.length) {\n p2 = points[i + 1];\n }\n }\n if (manyPoints) {\n multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n }\n path.push('L ', p1.x + multSignX * width, ' ', p1.y + multSignY * width);\n return path;\n },\n\n /**\n * Creates fabric.Path object to add on canvas\n * @param {String} pathData Path data\n * @return {fabric.Path} Path to add on canvas\n */\n createPath: function(pathData) {\n var path = new fabric.Path(pathData, {\n fill: null,\n stroke: this.color,\n strokeWidth: this.width,\n strokeLineCap: this.strokeLineCap,\n strokeMiterLimit: this.strokeMiterLimit,\n strokeLineJoin: this.strokeLineJoin,\n strokeDashArray: this.strokeDashArray,\n });\n if (this.shadow) {\n this.shadow.affectStroke = true;\n path.setShadow(this.shadow);\n }\n\n return path;\n },\n\n /**\n * Decimate poins array with the decimate value\n */\n decimatePoints: function(points, distance) {\n if (points.length <= 2) {\n return points;\n }\n var zoom = this.canvas.getZoom(), adjustedDistance = Math.pow(distance / zoom, 2),\n i, l = points.length - 1, lastPoint = points[0], newPoints = [lastPoint],\n cDistance;\n for (i = 1; i < l; i++) {\n cDistance = Math.pow(lastPoint.x - points[i].x, 2) + Math.pow(lastPoint.y - points[i].y, 2);\n if (cDistance >= adjustedDistance) {\n lastPoint = points[i];\n newPoints.push(lastPoint);\n }\n }\n if (newPoints.length === 1) {\n newPoints.push(new fabric.Point(newPoints[0].x, newPoints[0].y));\n }\n return newPoints;\n },\n\n /**\n * On mouseup after drawing the path on contextTop canvas\n * we use the points captured to create an new fabric path object\n * and add it to the fabric canvas.\n */\n _finalizeAndAddPath: function() {\n var ctx = this.canvas.contextTop;\n ctx.closePath();\n if (this.decimate) {\n this._points = this.decimatePoints(this._points, this.decimate);\n }\n var pathData = this.convertPointsToSVGPath(this._points).join('');\n if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') {\n // do not create 0 width/height paths, as they are\n // rendered inconsistently across browsers\n // Firefox 4, for example, renders a dot,\n // whereas Chrome 10 renders nothing\n this.canvas.requestRenderAll();\n return;\n }\n\n var path = this.createPath(pathData);\n this.canvas.clearContext(this.canvas.contextTop);\n this.canvas.add(path);\n this.canvas.requestRenderAll();\n path.setCoords();\n this._resetShadow();\n\n\n // fire event 'path' created\n this.canvas.fire('path:created', { path: path });\n }\n });\n})();\n\n\n/**\n * CircleBrush class\n * @class fabric.CircleBrush\n */\nfabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.CircleBrush.prototype */ {\n\n /**\n * Width of a brush\n * @type Number\n * @default\n */\n width: 10,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.CircleBrush} Instance of a circle brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this.points = [];\n },\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Object} pointer\n */\n drawDot: function(pointer) {\n var point = this.addPoint(pointer),\n ctx = this.canvas.contextTop;\n this._saveAndTransform(ctx);\n this.dot(ctx, point);\n ctx.restore();\n },\n\n dot: function(ctx, point) {\n ctx.fillStyle = point.fill;\n ctx.beginPath();\n ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);\n ctx.closePath();\n ctx.fill();\n },\n\n /**\n * Invoked on mouse down\n */\n onMouseDown: function(pointer) {\n this.points.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n this.drawDot(pointer);\n },\n\n /**\n * Render the full state of the brush\n * @private\n */\n _render: function() {\n var ctx = this.canvas.contextTop, i, len,\n points = this.points;\n this._saveAndTransform(ctx);\n for (i = 0, len = points.length; i < len; i++) {\n this.dot(ctx, points[i]);\n }\n ctx.restore();\n },\n\n /**\n * Invoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer) {\n if (this.needsFullRender()) {\n this.canvas.clearContext(this.canvas.contextTop);\n this.addPoint(pointer);\n this._render();\n }\n else {\n this.drawDot(pointer);\n }\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function() {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove, i, len;\n this.canvas.renderOnAddRemove = false;\n\n var circles = [];\n\n for (i = 0, len = this.points.length; i < len; i++) {\n var point = this.points[i],\n circle = new fabric.Circle({\n radius: point.radius,\n left: point.x,\n top: point.y,\n originX: 'center',\n originY: 'center',\n fill: point.fill\n });\n\n this.shadow && circle.setShadow(this.shadow);\n\n circles.push(circle);\n }\n var group = new fabric.Group(circles);\n group.canvas = this.canvas;\n\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n },\n\n /**\n * @param {Object} pointer\n * @return {fabric.Point} Just added pointer point\n */\n addPoint: function(pointer) {\n var pointerPoint = new fabric.Point(pointer.x, pointer.y),\n\n circleRadius = fabric.util.getRandomInt(\n Math.max(0, this.width - 20), this.width + 20) / 2,\n\n circleColor = new fabric.Color(this.color)\n .setAlpha(fabric.util.getRandomInt(0, 100) / 100)\n .toRgba();\n\n pointerPoint.radius = circleRadius;\n pointerPoint.fill = circleColor;\n\n this.points.push(pointerPoint);\n\n return pointerPoint;\n }\n});\n\n\n/**\n * SprayBrush class\n * @class fabric.SprayBrush\n */\nfabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric.SprayBrush.prototype */ {\n\n /**\n * Width of a spray\n * @type Number\n * @default\n */\n width: 10,\n\n /**\n * Density of a spray (number of dots per chunk)\n * @type Number\n * @default\n */\n density: 20,\n\n /**\n * Width of spray dots\n * @type Number\n * @default\n */\n dotWidth: 1,\n\n /**\n * Width variance of spray dots\n * @type Number\n * @default\n */\n dotWidthVariance: 1,\n\n /**\n * Whether opacity of a dot should be random\n * @type Boolean\n * @default\n */\n randomOpacity: false,\n\n /**\n * Whether overlapping dots (rectangles) should be removed (for performance reasons)\n * @type Boolean\n * @default\n */\n optimizeOverlapping: true,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.SprayBrush} Instance of a spray brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this.sprayChunks = [];\n },\n\n /**\n * Invoked on mouse down\n * @param {Object} pointer\n */\n onMouseDown: function(pointer) {\n this.sprayChunks.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n\n this.addSprayChunk(pointer);\n this.render(this.sprayChunkPoints);\n },\n\n /**\n * Invoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer) {\n this.addSprayChunk(pointer);\n this.render(this.sprayChunkPoints);\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function() {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n var rects = [];\n\n for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n var sprayChunk = this.sprayChunks[i];\n\n for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) {\n\n var rect = new fabric.Rect({\n width: sprayChunk[j].width,\n height: sprayChunk[j].width,\n left: sprayChunk[j].x + 1,\n top: sprayChunk[j].y + 1,\n originX: 'center',\n originY: 'center',\n fill: this.color\n });\n rects.push(rect);\n }\n }\n\n if (this.optimizeOverlapping) {\n rects = this._getOptimizedRects(rects);\n }\n\n var group = new fabric.Group(rects);\n this.shadow && group.setShadow(this.shadow);\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n },\n\n /**\n * @private\n * @param {Array} rects\n */\n _getOptimizedRects: function(rects) {\n\n // avoid creating duplicate rects at the same coordinates\n var uniqueRects = { }, key, i, len;\n\n for (i = 0, len = rects.length; i < len; i++) {\n key = rects[i].left + '' + rects[i].top;\n if (!uniqueRects[key]) {\n uniqueRects[key] = rects[i];\n }\n }\n var uniqueRectsArray = [];\n for (key in uniqueRects) {\n uniqueRectsArray.push(uniqueRects[key]);\n }\n\n return uniqueRectsArray;\n },\n\n /**\n * Render new chunk of spray brush\n */\n render: function(sprayChunk) {\n var ctx = this.canvas.contextTop, i, len;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (i = 0, len = sprayChunk.length; i < len; i++) {\n var point = sprayChunk[i];\n if (typeof point.opacity !== 'undefined') {\n ctx.globalAlpha = point.opacity;\n }\n ctx.fillRect(point.x, point.y, point.width, point.width);\n }\n ctx.restore();\n },\n\n /**\n * Render all spray chunks\n */\n _render: function() {\n var ctx = this.canvas.contextTop, i, ilen;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n this.render(this.sprayChunks[i]);\n }\n ctx.restore();\n },\n\n /**\n * @param {Object} pointer\n */\n addSprayChunk: function(pointer) {\n this.sprayChunkPoints = [];\n\n var x, y, width, radius = this.width / 2, i;\n\n for (i = 0; i < this.density; i++) {\n\n x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius);\n y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius);\n\n if (this.dotWidthVariance) {\n width = fabric.util.getRandomInt(\n // bottom clamp width to 1\n Math.max(1, this.dotWidth - this.dotWidthVariance),\n this.dotWidth + this.dotWidthVariance);\n }\n else {\n width = this.dotWidth;\n }\n\n var point = new fabric.Point(x, y);\n point.width = width;\n\n if (this.randomOpacity) {\n point.opacity = fabric.util.getRandomInt(0, 100) / 100;\n }\n\n this.sprayChunkPoints.push(point);\n }\n\n this.sprayChunks.push(this.sprayChunkPoints);\n }\n});\n\n\n/**\n * PatternBrush class\n * @class fabric.PatternBrush\n * @extends fabric.BaseBrush\n */\nfabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.PatternBrush.prototype */ {\n\n getPatternSrc: function() {\n\n var dotWidth = 20,\n dotDistance = 5,\n patternCanvas = fabric.util.createCanvasElement(),\n patternCtx = patternCanvas.getContext('2d');\n\n patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\n\n patternCtx.fillStyle = this.color;\n patternCtx.beginPath();\n patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false);\n patternCtx.closePath();\n patternCtx.fill();\n\n return patternCanvas;\n },\n\n getPatternSrcFunction: function() {\n return String(this.getPatternSrc).replace('this.color', '\"' + this.color + '\"');\n },\n\n /**\n * Creates \"pattern\" instance property\n */\n getPattern: function() {\n return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat');\n },\n\n /**\n * Sets brush styles\n */\n _setBrushStyles: function() {\n this.callSuper('_setBrushStyles');\n this.canvas.contextTop.strokeStyle = this.getPattern();\n },\n\n /**\n * Creates path\n */\n createPath: function(pathData) {\n var path = this.callSuper('createPath', pathData),\n topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);\n\n path.stroke = new fabric.Pattern({\n source: this.source || this.getPatternSrcFunction(),\n offsetX: -topLeft.x,\n offsetY: -topLeft.y\n });\n return path;\n }\n});\n\n\n(function() {\n\n var getPointer = fabric.util.getPointer,\n degreesToRadians = fabric.util.degreesToRadians,\n radiansToDegrees = fabric.util.radiansToDegrees,\n atan2 = Math.atan2,\n abs = Math.abs,\n supportLineDash = fabric.StaticCanvas.supports('setLineDash'),\n\n STROKE_OFFSET = 0.5;\n\n /**\n * Canvas class\n * @class fabric.Canvas\n * @extends fabric.StaticCanvas\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}\n * @see {@link fabric.Canvas#initialize} for constructor definition\n *\n * @fires object:modified at the end of a transform or any change when statefull is true\n * @fires object:rotated at the end of a rotation transform\n * @fires object:scaled at the end of a scale transform\n * @fires object:moved at the end of translation transform\n * @fires object:skewed at the end of a skew transform\n * @fires object:rotating while an object is being rotated from the control\n * @fires object:scaling while an object is being scaled by controls\n * @fires object:moving while an object is being dragged\n * @fires object:skewing while an object is being skewed from the controls\n * @fires object:selected this event is deprecated. use selection:created\n *\n * @fires before:transform before a transform is is started\n * @fires before:selection:cleared\n * @fires selection:cleared\n * @fires selection:updated\n * @fires selection:created\n *\n * @fires path:created after a drawing operation ends and the path is added\n * @fires mouse:down\n * @fires mouse:move\n * @fires mouse:up\n * @fires mouse:down:before on mouse down, before the inner fabric logic runs\n * @fires mouse:move:before on mouse move, before the inner fabric logic runs\n * @fires mouse:up:before on mouse up, before the inner fabric logic runs\n * @fires mouse:over\n * @fires mouse:out\n * @fires mouse:dblclick whenever a native dbl click event fires on the canvas.\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drop\n * @fires after:render at the end of the render process, receives the context in the callback\n * @fires before:render at start the render process, receives the context in the callback\n *\n */\n fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * Constructor\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(el, options) {\n options || (options = { });\n this.renderAndResetBound = this.renderAndReset.bind(this);\n this.requestRenderAllBound = this.requestRenderAll.bind(this);\n this._initStatic(el, options);\n this._initInteractive();\n this._createCacheCanvas();\n },\n\n /**\n * When true, objects can be transformed by one side (unproportionally)\n * @type Boolean\n * @default\n */\n uniScaleTransform: false,\n\n /**\n * Indicates which key enable unproportional scaling\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n uniScaleKey: 'shiftKey',\n\n /**\n * When true, objects use center point as the origin of scale transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: false,\n\n /**\n * When true, objects use center point as the origin of rotate transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: false,\n\n /**\n * Indicates which key enable centered Transform\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n centeredKey: 'altKey',\n\n /**\n * Indicates which key enable alternate action on corner\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n altActionKey: 'shiftKey',\n\n /**\n * Indicates that canvas is interactive. This property should not be changed.\n * @type Boolean\n * @default\n */\n interactive: true,\n\n /**\n * Indicates whether group selection should be enabled\n * @type Boolean\n * @default\n */\n selection: true,\n\n /**\n * Indicates which key or keys enable multiple click selection\n * Pass value as a string or array of strings\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or empty or containing any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.2\n * @type String|Array\n * @default\n */\n selectionKey: 'shiftKey',\n\n /**\n * Indicates which key enable alternative selection\n * in case of target overlapping with active object\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * For a series of reason that come from the general expectations on how\n * things should work, this feature works only for preserveObjectStacking true.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.5\n * @type null|String\n * @default\n */\n altSelectionKey: null,\n\n /**\n * Color of selection\n * @type String\n * @default\n */\n selectionColor: 'rgba(100, 100, 255, 0.3)', // blue\n\n /**\n * Default dash array pattern\n * If not empty the selection border is dashed\n * @type Array\n */\n selectionDashArray: [],\n\n /**\n * Color of the border of selection (usually slightly darker than color of selection itself)\n * @type String\n * @default\n */\n selectionBorderColor: 'rgba(255, 255, 255, 0.3)',\n\n /**\n * Width of a line used in object/group selection\n * @type Number\n * @default\n */\n selectionLineWidth: 1,\n\n /**\n * Select only shapes that are fully contained in the dragged selection rectangle.\n * @type Boolean\n * @default\n */\n selectionFullyContained: false,\n\n /**\n * Default cursor value used when hovering over an object on canvas\n * @type String\n * @default\n */\n hoverCursor: 'move',\n\n /**\n * Default cursor value used when moving an object on canvas\n * @type String\n * @default\n */\n moveCursor: 'move',\n\n /**\n * Default cursor value used for the entire canvas\n * @type String\n * @default\n */\n defaultCursor: 'default',\n\n /**\n * Cursor value used during free drawing\n * @type String\n * @default\n */\n freeDrawingCursor: 'crosshair',\n\n /**\n * Cursor value used for rotation point\n * @type String\n * @default\n */\n rotationCursor: 'crosshair',\n\n /**\n * Cursor value used for disabled elements ( corners with disabled action )\n * @type String\n * @since 2.0.0\n * @default\n */\n notAllowedCursor: 'not-allowed',\n\n /**\n * Default element class that's given to wrapper (div) element of canvas\n * @type String\n * @default\n */\n containerClass: 'canvas-container',\n\n /**\n * When true, object detection happens on per-pixel basis rather than on per-bounding-box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: false,\n\n /**\n * Number of pixels around target pixel to tolerate (consider active) during object detection\n * @type Number\n * @default\n */\n targetFindTolerance: 0,\n\n /**\n * When true, target detection is skipped when hovering over canvas. This can be used to improve performance.\n * @type Boolean\n * @default\n */\n skipTargetFind: false,\n\n /**\n * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.\n * After mousedown, mousemove creates a shape,\n * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}\n * @type Boolean\n * @default\n */\n isDrawingMode: false,\n\n /**\n * Indicates whether objects should remain in current stack position when selected.\n * When false objects are brought to top and rendered as part of the selection group\n * @type Boolean\n * @default\n */\n preserveObjectStacking: false,\n\n /**\n * Indicates the angle that an object will lock to while rotating.\n * @type Number\n * @since 1.6.7\n * @default\n */\n snapAngle: 0,\n\n /**\n * Indicates the distance from the snapAngle the rotation will lock to the snapAngle.\n * When `null`, the snapThreshold will default to the snapAngle.\n * @type null|Number\n * @since 1.6.7\n * @default\n */\n snapThreshold: null,\n\n /**\n * Indicates if the right click on canvas can output the context menu or not\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n stopContextMenu: false,\n\n /**\n * Indicates if the canvas can fire right click events\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n fireRightClick: false,\n\n /**\n * Indicates if the canvas can fire middle click events\n * @type Boolean\n * @since 1.7.8\n * @default\n */\n fireMiddleClick: false,\n\n /**\n * Keep track of the subTargets for Mouse Events\n * @type fabric.Object[]\n */\n targets: [],\n\n /**\n * Keep track of the hovered target\n * @type fabric.Object\n * @private\n */\n _hoveredTarget: null,\n\n /**\n * hold the list of nested targets hovered\n * @type fabric.Object[]\n * @private\n */\n _hoveredTargets: [],\n\n /**\n * @private\n */\n _initInteractive: function() {\n this._currentTransform = null;\n this._groupSelector = null;\n this._initWrapperElement();\n this._createUpperCanvas();\n this._initEventListeners();\n\n this._initRetinaScaling();\n\n this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this);\n\n this.calcOffset();\n },\n\n /**\n * Divides objects in two groups, one to render immediately\n * and one to render as activeGroup.\n * @return {Array} objects to render immediately and pushes the other in the activeGroup.\n */\n _chooseObjectsToRender: function() {\n var activeObjects = this.getActiveObjects(),\n object, objsToRender, activeGroupObjects;\n\n if (activeObjects.length > 0 && !this.preserveObjectStacking) {\n objsToRender = [];\n activeGroupObjects = [];\n for (var i = 0, length = this._objects.length; i < length; i++) {\n object = this._objects[i];\n if (activeObjects.indexOf(object) === -1 ) {\n objsToRender.push(object);\n }\n else {\n activeGroupObjects.push(object);\n }\n }\n if (activeObjects.length > 1) {\n this._activeObject._objects = activeGroupObjects;\n }\n objsToRender.push.apply(objsToRender, activeGroupObjects);\n }\n else {\n objsToRender = this._objects;\n }\n return objsToRender;\n },\n\n /**\n * Renders both the top canvas and the secondary container canvas.\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderAll: function () {\n if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n this.clearContext(this.contextTop);\n this.contextTopDirty = false;\n }\n if (this.hasLostContext) {\n this.renderTopLayer(this.contextTop);\n }\n var canvasToDrawOn = this.contextContainer;\n this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());\n return this;\n },\n\n renderTopLayer: function(ctx) {\n ctx.save();\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this.freeDrawingBrush && this.freeDrawingBrush._render();\n this.contextTopDirty = true;\n }\n // we render the top context - last object\n if (this.selection && this._groupSelector) {\n this._drawSelection(ctx);\n this.contextTopDirty = true;\n }\n ctx.restore();\n },\n\n /**\n * Method to render only the top canvas.\n * Also used to render the group selection box.\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n renderTop: function () {\n var ctx = this.contextTop;\n this.clearContext(ctx);\n this.renderTopLayer(ctx);\n this.fire('after:render');\n return this;\n },\n\n /**\n * Resets the current transform to its original values and chooses the type of resizing based on the event\n * @private\n */\n _resetCurrentTransform: function() {\n var t = this._currentTransform;\n\n t.target.set({\n scaleX: t.original.scaleX,\n scaleY: t.original.scaleY,\n skewX: t.original.skewX,\n skewY: t.original.skewY,\n left: t.original.left,\n top: t.original.top\n });\n\n if (this._shouldCenterTransform(t.target)) {\n if (t.originX !== 'center') {\n if (t.originX === 'right') {\n t.mouseXSign = -1;\n }\n else {\n t.mouseXSign = 1;\n }\n }\n if (t.originY !== 'center') {\n if (t.originY === 'bottom') {\n t.mouseYSign = -1;\n }\n else {\n t.mouseYSign = 1;\n }\n }\n\n t.originX = 'center';\n t.originY = 'center';\n }\n else {\n t.originX = t.original.originX;\n t.originY = t.original.originY;\n }\n },\n\n /**\n * Checks if point is contained within an area of given object\n * @param {Event} e Event object\n * @param {fabric.Object} target Object to test against\n * @param {Object} [point] x,y object of point coordinates we want to check.\n * @return {Boolean} true if point is contained within an area of given object\n */\n containsPoint: function (e, target, point) {\n var ignoreZoom = true,\n pointer = point || this.getPointer(e, ignoreZoom),\n xy;\n\n if (target.group && target.group === this._activeObject && target.group.type === 'activeSelection') {\n xy = this._normalizePointer(target.group, pointer);\n }\n else {\n xy = { x: pointer.x, y: pointer.y };\n }\n // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html\n // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html\n return (target.containsPoint(xy) || target._findTargetCorner(pointer));\n },\n\n /**\n * @private\n */\n _normalizePointer: function (object, pointer) {\n var m = object.calcTransformMatrix(),\n invertedM = fabric.util.invertTransform(m),\n vptPointer = this.restorePointerVpt(pointer);\n return fabric.util.transformPoint(vptPointer, invertedM);\n },\n\n /**\n * Returns true if object is transparent at a certain location\n * @param {fabric.Object} target Object to check\n * @param {Number} x Left coordinate\n * @param {Number} y Top coordinate\n * @return {Boolean}\n */\n isTargetTransparent: function (target, x, y) {\n // in case the target is the activeObject, we cannot execute this optimization\n // because we need to draw controls too.\n if (target.shouldCache() && target._cacheCanvas && target !== this._activeObject) {\n var normalizedPointer = this._normalizePointer(target, {x: x, y: y}),\n targetRelativeX = Math.max(target.cacheTranslationX + (normalizedPointer.x * target.zoomX), 0),\n targetRelativeY = Math.max(target.cacheTranslationY + (normalizedPointer.y * target.zoomY), 0);\n\n var isTransparent = fabric.util.isTransparent(\n target._cacheContext, Math.round(targetRelativeX), Math.round(targetRelativeY), this.targetFindTolerance);\n\n return isTransparent;\n }\n\n var ctx = this.contextCache,\n originalColor = target.selectionBackgroundColor, v = this.viewportTransform;\n\n target.selectionBackgroundColor = '';\n\n this.clearContext(ctx);\n\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n target.render(ctx);\n ctx.restore();\n\n target === this._activeObject && target._renderControls(ctx, {\n hasBorders: false,\n transparentCorners: false\n }, {\n hasBorders: false,\n });\n\n target.selectionBackgroundColor = originalColor;\n\n var isTransparent = fabric.util.isTransparent(\n ctx, x, y, this.targetFindTolerance);\n\n return isTransparent;\n },\n\n /**\n * takes an event and determins if selection key has been pressed\n * @private\n * @param {Event} e Event object\n */\n _isSelectionKeyPressed: function(e) {\n var selectionKeyPressed = false;\n\n if (Object.prototype.toString.call(this.selectionKey) === '[object Array]') {\n selectionKeyPressed = !!this.selectionKey.find(function(key) { return e[key] === true; });\n }\n else {\n selectionKeyPressed = e[this.selectionKey];\n }\n\n return selectionKeyPressed;\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _shouldClearSelection: function (e, target) {\n var activeObjects = this.getActiveObjects(),\n activeObject = this._activeObject;\n\n return (\n !target\n ||\n (target &&\n activeObject &&\n activeObjects.length > 1 &&\n activeObjects.indexOf(target) === -1 &&\n activeObject !== target &&\n !this._isSelectionKeyPressed(e))\n ||\n (target && !target.evented)\n ||\n (target &&\n !target.selectable &&\n activeObject &&\n activeObject !== target)\n );\n },\n\n /**\n * centeredScaling from object can't override centeredScaling from canvas.\n * this should be fixed, since object setting should take precedence over canvas.\n * @private\n * @param {fabric.Object} target\n */\n _shouldCenterTransform: function (target) {\n if (!target) {\n return;\n }\n\n var t = this._currentTransform,\n centerTransform;\n\n if (t.action === 'scale' || t.action === 'scaleX' || t.action === 'scaleY') {\n centerTransform = this.centeredScaling || target.centeredScaling;\n }\n else if (t.action === 'rotate') {\n centerTransform = this.centeredRotation || target.centeredRotation;\n }\n\n return centerTransform ? !t.altKey : t.altKey;\n },\n\n /**\n * @private\n */\n _getOriginFromCorner: function(target, corner) {\n var origin = {\n x: target.originX,\n y: target.originY\n };\n\n if (corner === 'ml' || corner === 'tl' || corner === 'bl') {\n origin.x = 'right';\n }\n else if (corner === 'mr' || corner === 'tr' || corner === 'br') {\n origin.x = 'left';\n }\n\n if (corner === 'tl' || corner === 'mt' || corner === 'tr') {\n origin.y = 'bottom';\n }\n else if (corner === 'bl' || corner === 'mb' || corner === 'br') {\n origin.y = 'top';\n }\n\n return origin;\n },\n\n /**\n * @private\n * @param {Boolean} alreadySelected true if target is already selected\n * @param {String} corner a string representing the corner ml, mr, tl ...\n * @param {Event} e Event object\n * @param {fabric.Object} [target] inserted back to help overriding. Unused\n */\n _getActionFromCorner: function(alreadySelected, corner, e /* target */) {\n if (!corner || !alreadySelected) {\n return 'drag';\n }\n\n switch (corner) {\n case 'mtr':\n return 'rotate';\n case 'ml':\n case 'mr':\n return e[this.altActionKey] ? 'skewY' : 'scaleX';\n case 'mt':\n case 'mb':\n return e[this.altActionKey] ? 'skewX' : 'scaleY';\n default:\n return 'scale';\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _setupCurrentTransform: function (e, target, alreadySelected) {\n if (!target) {\n return;\n }\n\n var pointer = this.getPointer(e),\n corner = target._findTargetCorner(this.getPointer(e, true)),\n action = this._getActionFromCorner(alreadySelected, corner, e, target),\n origin = this._getOriginFromCorner(target, corner);\n\n this._currentTransform = {\n target: target,\n action: action,\n corner: corner,\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n // used by transation\n offsetX: pointer.x - target.left,\n offsetY: pointer.y - target.top,\n originX: origin.x,\n originY: origin.y,\n ex: pointer.x,\n ey: pointer.y,\n lastX: pointer.x,\n lastY: pointer.y,\n // unsure they are usefull anymore.\n // left: target.left,\n // top: target.top,\n theta: degreesToRadians(target.angle),\n // end of unsure\n width: target.width * target.scaleX,\n mouseXSign: 1,\n mouseYSign: 1,\n shiftKey: e.shiftKey,\n altKey: e[this.centeredKey],\n original: fabric.util.saveObjectTransform(target),\n };\n\n this._currentTransform.original.originX = origin.x;\n this._currentTransform.original.originY = origin.y;\n\n this._resetCurrentTransform();\n this._beforeTransform(e);\n },\n\n /**\n * Translates object by \"setting\" its left/top\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @return {Boolean} true if the translation occurred\n */\n _translateObject: function (x, y) {\n var transform = this._currentTransform,\n target = transform.target,\n newLeft = x - transform.offsetX,\n newTop = y - transform.offsetY,\n moveX = !target.get('lockMovementX') && target.left !== newLeft,\n moveY = !target.get('lockMovementY') && target.top !== newTop;\n\n moveX && target.set('left', newLeft);\n moveY && target.set('top', newTop);\n return moveX || moveY;\n },\n\n /**\n * Check if we are increasing a positive skew or lower it,\n * checking mouse direction and pressed corner.\n * @private\n */\n _changeSkewTransformOrigin: function(mouseMove, t, by) {\n var property = 'originX', origins = { 0: 'center' },\n skew = t.target.skewX, originA = 'left', originB = 'right',\n corner = t.corner === 'mt' || t.corner === 'ml' ? 1 : -1,\n flipSign = 1;\n\n mouseMove = mouseMove > 0 ? 1 : -1;\n if (by === 'y') {\n skew = t.target.skewY;\n originA = 'top';\n originB = 'bottom';\n property = 'originY';\n }\n origins[-1] = originA;\n origins[1] = originB;\n\n t.target.flipX && (flipSign *= -1);\n t.target.flipY && (flipSign *= -1);\n\n if (skew === 0) {\n t.skewSign = -corner * mouseMove * flipSign;\n t[property] = origins[-mouseMove];\n }\n else {\n skew = skew > 0 ? 1 : -1;\n t.skewSign = skew;\n t[property] = origins[skew * corner * flipSign];\n }\n },\n\n /**\n * Skew object by mouse events\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @param {String} by Either 'x' or 'y'\n * @return {Boolean} true if the skewing occurred\n */\n _skewObject: function (x, y, by) {\n var t = this._currentTransform,\n target = t.target, skewed = false,\n lockSkewingX = target.get('lockSkewingX'),\n lockSkewingY = target.get('lockSkewingY');\n\n if ((lockSkewingX && by === 'x') || (lockSkewingY && by === 'y')) {\n return false;\n }\n\n // Get the constraint point\n var center = target.getCenterPoint(),\n actualMouseByCenter = target.toLocalPoint(new fabric.Point(x, y), 'center', 'center')[by],\n lastMouseByCenter = target.toLocalPoint(new fabric.Point(t.lastX, t.lastY), 'center', 'center')[by],\n actualMouseByOrigin, constraintPosition, dim = target._getTransformedDimensions();\n\n this._changeSkewTransformOrigin(actualMouseByCenter - lastMouseByCenter, t, by);\n actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by];\n constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY);\n // Actually skew the object\n skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim);\n t.lastX = x;\n t.lastY = y;\n // Make sure the constraints apply\n target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n return skewed;\n },\n\n /**\n * Set object skew\n * @private\n * @return {Boolean} true if the skewing occurred\n */\n _setObjectSkew: function(localMouse, transform, by, _dim) {\n var target = transform.target, newValue, skewed = false,\n skewSign = transform.skewSign, newDim, dimNoSkew,\n otherBy, _otherBy, _by, newDimMouse, skewX, skewY;\n\n if (by === 'x') {\n otherBy = 'y';\n _otherBy = 'Y';\n _by = 'X';\n skewX = 0;\n skewY = target.skewY;\n }\n else {\n otherBy = 'x';\n _otherBy = 'X';\n _by = 'Y';\n skewX = target.skewX;\n skewY = 0;\n }\n\n dimNoSkew = target._getTransformedDimensions(skewX, skewY);\n newDimMouse = 2 * Math.abs(localMouse) - dimNoSkew[by];\n if (newDimMouse <= 2) {\n newValue = 0;\n }\n else {\n newValue = skewSign * Math.atan((newDimMouse / target['scale' + _by]) /\n (dimNoSkew[otherBy] / target['scale' + _otherBy]));\n newValue = fabric.util.radiansToDegrees(newValue);\n }\n skewed = target['skew' + _by] !== newValue;\n target.set('skew' + _by, newValue);\n if (target['skew' + _otherBy] !== 0) {\n newDim = target._getTransformedDimensions();\n newValue = (_dim[otherBy] / newDim[otherBy]) * target['scale' + _otherBy];\n target.set('scale' + _otherBy, newValue);\n }\n return skewed;\n },\n\n /**\n * Scales object by invoking its scaleX/scaleY methods\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @param {String} by Either 'x' or 'y' - specifies dimension constraint by which to scale an object.\n * When not provided, an object is scaled by both dimensions equally\n * @return {Boolean} true if the scaling occurred\n */\n _scaleObject: function (x, y, by) {\n var t = this._currentTransform,\n target = t.target,\n lockScalingX = target.lockScalingX,\n lockScalingY = target.lockScalingY,\n lockScalingFlip = target.lockScalingFlip;\n\n if (lockScalingX && lockScalingY) {\n return false;\n }\n\n // Get the constraint point\n var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY),\n localMouse = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY),\n dim = target._getTransformedDimensions(), scaled = false;\n\n this._setLocalMouse(localMouse, t);\n\n // Actually scale the object\n scaled = this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip, dim);\n\n // Make sure the constraints apply\n target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n return scaled;\n },\n\n /**\n * @private\n * @return {Boolean} true if the scaling occurred\n */\n _setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {\n var target = transform.target, forbidScalingX = false, forbidScalingY = false, scaled = false,\n scaleX = localMouse.x * target.scaleX / _dim.x,\n scaleY = localMouse.y * target.scaleY / _dim.y,\n changeX = target.scaleX !== scaleX,\n changeY = target.scaleY !== scaleY;\n\n transform.newScaleX = scaleX;\n transform.newScaleY = scaleY;\n if (fabric.Textbox && by === 'x' && target instanceof fabric.Textbox) {\n var w = target.width * (localMouse.x / _dim.x);\n if (w >= target.getMinWidth()) {\n scaled = w !== target.width;\n target.set('width', w);\n return scaled;\n }\n return false;\n }\n\n if (lockScalingFlip && scaleX <= 0 && scaleX < target.scaleX) {\n forbidScalingX = true;\n localMouse.x = 0;\n }\n\n if (lockScalingFlip && scaleY <= 0 && scaleY < target.scaleY) {\n forbidScalingY = true;\n localMouse.y = 0;\n }\n\n if (by === 'equally' && !lockScalingX && !lockScalingY) {\n scaled = this._scaleObjectEqually(localMouse, target, transform, _dim);\n }\n else if (!by) {\n forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = scaled || changeX));\n forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));\n }\n else if (by === 'x' && !target.get('lockUniScaling')) {\n forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = changeX));\n }\n else if (by === 'y' && !target.get('lockUniScaling')) {\n forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = changeY));\n }\n forbidScalingX || forbidScalingY || this._flipObject(transform, by);\n return scaled;\n },\n\n /**\n * @private\n * @return {Boolean} true if the scaling occurred\n */\n _scaleObjectEqually: function(localMouse, target, transform, _dim) {\n\n var dist = localMouse.y + localMouse.x,\n lastDist = _dim.y * transform.original.scaleY / target.scaleY +\n _dim.x * transform.original.scaleX / target.scaleX,\n scaled, signX = localMouse.x < 0 ? -1 : 1,\n signY = localMouse.y < 0 ? -1 : 1, newScaleX, newScaleY;\n\n // We use transform.scaleX/Y instead of target.scaleX/Y\n // because the object may have a min scale and we'll loose the proportions\n newScaleX = signX * Math.abs(transform.original.scaleX * dist / lastDist);\n newScaleY = signY * Math.abs(transform.original.scaleY * dist / lastDist);\n scaled = newScaleX !== target.scaleX || newScaleY !== target.scaleY;\n target.set('scaleX', newScaleX);\n target.set('scaleY', newScaleY);\n return scaled;\n },\n\n /**\n * @private\n */\n _flipObject: function(transform, by) {\n if (transform.newScaleX < 0 && by !== 'y') {\n if (transform.originX === 'left') {\n transform.originX = 'right';\n }\n else if (transform.originX === 'right') {\n transform.originX = 'left';\n }\n }\n\n if (transform.newScaleY < 0 && by !== 'x') {\n if (transform.originY === 'top') {\n transform.originY = 'bottom';\n }\n else if (transform.originY === 'bottom') {\n transform.originY = 'top';\n }\n }\n },\n\n /**\n * @private\n */\n _setLocalMouse: function(localMouse, t) {\n var target = t.target, zoom = this.getZoom(),\n padding = target.padding / zoom;\n\n if (t.originX === 'right') {\n localMouse.x *= -1;\n }\n else if (t.originX === 'center') {\n localMouse.x *= t.mouseXSign * 2;\n if (localMouse.x < 0) {\n t.mouseXSign = -t.mouseXSign;\n }\n }\n\n if (t.originY === 'bottom') {\n localMouse.y *= -1;\n }\n else if (t.originY === 'center') {\n localMouse.y *= t.mouseYSign * 2;\n if (localMouse.y < 0) {\n t.mouseYSign = -t.mouseYSign;\n }\n }\n\n // adjust the mouse coordinates when dealing with padding\n if (abs(localMouse.x) > padding) {\n if (localMouse.x < 0) {\n localMouse.x += padding;\n }\n else {\n localMouse.x -= padding;\n }\n }\n else { // mouse is within the padding, set to 0\n localMouse.x = 0;\n }\n\n if (abs(localMouse.y) > padding) {\n if (localMouse.y < 0) {\n localMouse.y += padding;\n }\n else {\n localMouse.y -= padding;\n }\n }\n else {\n localMouse.y = 0;\n }\n },\n\n /**\n * Rotates object by invoking its rotate method\n * @private\n * @param {Number} x pointer's x coordinate\n * @param {Number} y pointer's y coordinate\n * @return {Boolean} true if the rotation occurred\n */\n _rotateObject: function (x, y) {\n\n var t = this._currentTransform,\n target = t.target, constraintPosition,\n constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY);\n\n if (target.lockRotation) {\n return false;\n }\n\n var lastAngle = atan2(t.ey - constraintPosition.y, t.ex - constraintPosition.x),\n curAngle = atan2(y - constraintPosition.y, x - constraintPosition.x),\n angle = radiansToDegrees(curAngle - lastAngle + t.theta),\n hasRotated = true;\n\n if (target.snapAngle > 0) {\n var snapAngle = target.snapAngle,\n snapThreshold = target.snapThreshold || snapAngle,\n rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n angle = leftAngleLocked;\n }\n else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n angle = rightAngleLocked;\n }\n }\n\n // normalize angle to positive value\n if (angle < 0) {\n angle = 360 + angle;\n }\n angle %= 360;\n\n if (target.angle === angle) {\n hasRotated = false;\n }\n else {\n // rotation only happen here\n target.angle = angle;\n // Make sure the constraints apply\n target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n }\n\n return hasRotated;\n },\n\n /**\n * Set the cursor type of the canvas element\n * @param {String} value Cursor type of the canvas element.\n * @see http://www.w3.org/TR/css3-ui/#cursor\n */\n setCursor: function (value) {\n this.upperCanvasEl.style.cursor = value;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx to draw the selection on\n */\n _drawSelection: function (ctx) {\n var groupSelector = this._groupSelector,\n left = groupSelector.left,\n top = groupSelector.top,\n aleft = abs(left),\n atop = abs(top);\n\n if (this.selectionColor) {\n ctx.fillStyle = this.selectionColor;\n\n ctx.fillRect(\n groupSelector.ex - ((left > 0) ? 0 : -left),\n groupSelector.ey - ((top > 0) ? 0 : -top),\n aleft,\n atop\n );\n }\n\n if (!this.selectionLineWidth || !this.selectionBorderColor) {\n return;\n }\n ctx.lineWidth = this.selectionLineWidth;\n ctx.strokeStyle = this.selectionBorderColor;\n\n // selection border\n if (this.selectionDashArray.length > 1 && !supportLineDash) {\n\n var px = groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n py = groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop);\n\n ctx.beginPath();\n\n fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray);\n\n ctx.closePath();\n ctx.stroke();\n }\n else {\n fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray);\n ctx.strokeRect(\n groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop),\n aleft,\n atop\n );\n }\n },\n\n /**\n * Method that determines what object we are clicking on\n * the skipGroup parameter is for internal use, is needed for shift+click action\n * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target\n * or the outside part of the corner.\n * @param {Event} e mouse event\n * @param {Boolean} skipGroup when true, activeGroup is skipped and only objects are traversed through\n * @return {fabric.Object} the target found\n */\n findTarget: function (e, skipGroup) {\n if (this.skipTargetFind) {\n return;\n }\n\n var ignoreZoom = true,\n pointer = this.getPointer(e, ignoreZoom),\n activeObject = this._activeObject,\n aObjects = this.getActiveObjects(),\n activeTarget, activeTargetSubs;\n\n // first check current group (if one exists)\n // active group does not check sub targets like normal groups.\n // if active group just exits.\n this.targets = [];\n\n if (aObjects.length > 1 && !skipGroup && activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n return activeObject;\n }\n // if we hit the corner of an activeObject, let's return that.\n if (aObjects.length === 1 && activeObject._findTargetCorner(pointer)) {\n return activeObject;\n }\n if (aObjects.length === 1 &&\n activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n if (!this.preserveObjectStacking) {\n return activeObject;\n }\n else {\n activeTarget = activeObject;\n activeTargetSubs = this.targets;\n this.targets = [];\n }\n }\n var target = this._searchPossibleTargets(this._objects, pointer);\n if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) {\n target = activeTarget;\n this.targets = activeTargetSubs;\n }\n return target;\n },\n\n /**\n * Checks point is inside the object.\n * @param {Object} [pointer] x,y object of point coordinates we want to check.\n * @param {fabric.Object} obj Object to test against\n * @param {Object} [globalPointer] x,y object of point coordinates relative to canvas used to search per pixel target.\n * @return {Boolean} true if point is contained within an area of given object\n * @private\n */\n _checkTarget: function(pointer, obj, globalPointer) {\n if (obj &&\n obj.visible &&\n obj.evented &&\n this.containsPoint(null, obj, pointer)){\n if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {\n var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y);\n if (!isTransparent) {\n return true;\n }\n }\n else {\n return true;\n }\n }\n },\n\n /**\n * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n * @param {Array} [objects] objects array to look into\n * @param {Object} [pointer] x,y object of point coordinates we want to check.\n * @return {fabric.Object} object that contains pointer\n * @private\n */\n _searchPossibleTargets: function(objects, pointer) {\n // Cache all targets where their bounding box contains point.\n var target, i = objects.length, subTarget;\n // Do not check for currently grouped objects, since we check the parent group itself.\n // until we call this function specifically to search inside the activeGroup\n while (i--) {\n var objToCheck = objects[i];\n var pointerToUse = objToCheck.group && objToCheck.group.type !== 'activeSelection' ?\n this._normalizePointer(objToCheck.group, pointer) : pointer;\n if (this._checkTarget(pointerToUse, objToCheck, pointer)) {\n target = objects[i];\n if (target.subTargetCheck && target instanceof fabric.Group) {\n subTarget = this._searchPossibleTargets(target._objects, pointer);\n subTarget && this.targets.push(subTarget);\n }\n break;\n }\n }\n return target;\n },\n\n /**\n * Returns pointer coordinates without the effect of the viewport\n * @param {Object} pointer with \"x\" and \"y\" number values\n * @return {Object} object with \"x\" and \"y\" number values\n */\n restorePointerVpt: function(pointer) {\n return fabric.util.transformPoint(\n pointer,\n fabric.util.invertTransform(this.viewportTransform)\n );\n },\n\n /**\n * Returns pointer coordinates relative to canvas.\n * Can return coordinates with or without viewportTransform.\n * ignoreZoom false gives back coordinates that represent\n * the point clicked on canvas element.\n * ignoreZoom true gives back coordinates after being processed\n * by the viewportTransform ( sort of coordinates of what is displayed\n * on the canvas where you are clicking.\n * ignoreZoom true = HTMLElement coordinates relative to top,left\n * ignoreZoom false, default = fabric space coordinates, the same used for shape position\n * To interact with your shapes top and left you want to use ignoreZoom true\n * most of the time, while ignoreZoom false will give you coordinates\n * compatible with the object.oCoords system.\n * of the time.\n * @param {Event} e\n * @param {Boolean} ignoreZoom\n * @return {Object} object with \"x\" and \"y\" number values\n */\n getPointer: function (e, ignoreZoom) {\n // return cached values if we are in the event processing chain\n if (this._absolutePointer && !ignoreZoom) {\n return this._absolutePointer;\n }\n if (this._pointer && ignoreZoom) {\n return this._pointer;\n }\n\n var pointer = getPointer(e),\n upperCanvasEl = this.upperCanvasEl,\n bounds = upperCanvasEl.getBoundingClientRect(),\n boundsWidth = bounds.width || 0,\n boundsHeight = bounds.height || 0,\n cssScale;\n\n if (!boundsWidth || !boundsHeight ) {\n if ('top' in bounds && 'bottom' in bounds) {\n boundsHeight = Math.abs( bounds.top - bounds.bottom );\n }\n if ('right' in bounds && 'left' in bounds) {\n boundsWidth = Math.abs( bounds.right - bounds.left );\n }\n }\n\n this.calcOffset();\n pointer.x = pointer.x - this._offset.left;\n pointer.y = pointer.y - this._offset.top;\n if (!ignoreZoom) {\n pointer = this.restorePointerVpt(pointer);\n }\n\n var retinaScaling = this.getRetinaScaling();\n if (retinaScaling !== 1) {\n pointer.x /= retinaScaling;\n pointer.y /= retinaScaling;\n }\n\n if (boundsWidth === 0 || boundsHeight === 0) {\n // If bounds are not available (i.e. not visible), do not apply scale.\n cssScale = { width: 1, height: 1 };\n }\n else {\n cssScale = {\n width: upperCanvasEl.width / boundsWidth,\n height: upperCanvasEl.height / boundsHeight\n };\n }\n\n return {\n x: pointer.x * cssScale.width,\n y: pointer.y * cssScale.height\n };\n },\n\n /**\n * @private\n * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized\n */\n _createUpperCanvas: function () {\n var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\\s*lower-canvas\\s*/, ''),\n lowerCanvasEl = this.lowerCanvasEl, upperCanvasEl = this.upperCanvasEl;\n\n // there is no need to create a new upperCanvas element if we have already one.\n if (upperCanvasEl) {\n upperCanvasEl.className = '';\n }\n else {\n upperCanvasEl = this._createCanvasElement();\n this.upperCanvasEl = upperCanvasEl;\n }\n fabric.util.addClass(upperCanvasEl, 'upper-canvas ' + lowerCanvasClass);\n\n this.wrapperEl.appendChild(upperCanvasEl);\n\n this._copyCanvasStyle(lowerCanvasEl, upperCanvasEl);\n this._applyCanvasStyle(upperCanvasEl);\n this.contextTop = upperCanvasEl.getContext('2d');\n },\n\n /**\n * @private\n */\n _createCacheCanvas: function () {\n this.cacheCanvasEl = this._createCanvasElement();\n this.cacheCanvasEl.setAttribute('width', this.width);\n this.cacheCanvasEl.setAttribute('height', this.height);\n this.contextCache = this.cacheCanvasEl.getContext('2d');\n },\n\n /**\n * @private\n */\n _initWrapperElement: function () {\n this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', {\n 'class': this.containerClass\n });\n fabric.util.setStyle(this.wrapperEl, {\n width: this.width + 'px',\n height: this.height + 'px',\n position: 'relative'\n });\n fabric.util.makeElementUnselectable(this.wrapperEl);\n },\n\n /**\n * @private\n * @param {HTMLElement} element canvas element to apply styles on\n */\n _applyCanvasStyle: function (element) {\n var width = this.width || element.width,\n height = this.height || element.height;\n\n fabric.util.setStyle(element, {\n position: 'absolute',\n width: width + 'px',\n height: height + 'px',\n left: 0,\n top: 0,\n 'touch-action': this.allowTouchScrolling ? 'manipulation' : 'none',\n '-ms-touch-action': this.allowTouchScrolling ? 'manipulation' : 'none'\n });\n element.width = width;\n element.height = height;\n fabric.util.makeElementUnselectable(element);\n },\n\n /**\n * Copy the entire inline style from one element (fromEl) to another (toEl)\n * @private\n * @param {Element} fromEl Element style is copied from\n * @param {Element} toEl Element copied style is applied to\n */\n _copyCanvasStyle: function (fromEl, toEl) {\n toEl.style.cssText = fromEl.style.cssText;\n },\n\n /**\n * Returns context of canvas where object selection is drawn\n * @return {CanvasRenderingContext2D}\n */\n getSelectionContext: function() {\n return this.contextTop;\n },\n\n /**\n * Returns <canvas> element on which object selection is drawn\n * @return {HTMLCanvasElement}\n */\n getSelectionElement: function () {\n return this.upperCanvasEl;\n },\n\n /**\n * Returns currently active object\n * @return {fabric.Object} active object\n */\n getActiveObject: function () {\n return this._activeObject;\n },\n\n /**\n * Returns an array with the current selected objects\n * @return {fabric.Object} active object\n */\n getActiveObjects: function () {\n var active = this._activeObject;\n if (active) {\n if (active.type === 'activeSelection' && active._objects) {\n return active._objects.slice(0);\n }\n else {\n return [active];\n }\n }\n return [];\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was removed\n */\n _onObjectRemoved: function(obj) {\n // removing active object should fire \"selection:cleared\" events\n if (obj === this._activeObject) {\n this.fire('before:selection:cleared', { target: obj });\n this._discardActiveObject();\n this.fire('selection:cleared', { target: obj });\n obj.fire('deselected');\n }\n if (obj === this._hoveredTarget){\n this._hoveredTarget = null;\n this._hoveredTargets = [];\n }\n this.callSuper('_onObjectRemoved', obj);\n },\n\n /**\n * @private\n * Compares the old activeObject with the current one and fires correct events\n * @param {fabric.Object} obj old activeObject\n */\n _fireSelectionEvents: function(oldObjects, e) {\n var somethingChanged = false, objects = this.getActiveObjects(),\n added = [], removed = [], opt = { e: e };\n oldObjects.forEach(function(oldObject) {\n if (objects.indexOf(oldObject) === -1) {\n somethingChanged = true;\n oldObject.fire('deselected', opt);\n removed.push(oldObject);\n }\n });\n objects.forEach(function(object) {\n if (oldObjects.indexOf(object) === -1) {\n somethingChanged = true;\n object.fire('selected', opt);\n added.push(object);\n }\n });\n if (oldObjects.length > 0 && objects.length > 0) {\n opt.selected = added;\n opt.deselected = removed;\n // added for backward compatibility\n opt.updated = added[0] || removed[0];\n opt.target = this._activeObject;\n somethingChanged && this.fire('selection:updated', opt);\n }\n else if (objects.length > 0) {\n // deprecated event\n if (objects.length === 1) {\n opt.target = added[0];\n this.fire('object:selected', opt);\n }\n opt.selected = added;\n // added for backward compatibility\n opt.target = this._activeObject;\n this.fire('selection:created', opt);\n }\n else if (oldObjects.length > 0) {\n opt.deselected = removed;\n this.fire('selection:cleared', opt);\n }\n },\n\n /**\n * Sets given object as the only active object on canvas\n * @param {fabric.Object} object Object to set as an active one\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n setActiveObject: function (object, e) {\n var currentActives = this.getActiveObjects();\n this._setActiveObject(object, e);\n this._fireSelectionEvents(currentActives, e);\n return this;\n },\n\n /**\n * @private\n * @param {Object} object to set as active\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {Boolean} true if the selection happened\n */\n _setActiveObject: function(object, e) {\n if (this._activeObject === object) {\n return false;\n }\n if (!this._discardActiveObject(e, object)) {\n return false;\n }\n if (object.onSelect({ e: e })) {\n return false;\n }\n this._activeObject = object;\n return true;\n },\n\n /**\n * @private\n */\n _discardActiveObject: function(e, object) {\n var obj = this._activeObject;\n if (obj) {\n // onDeselect return TRUE to cancel selection;\n if (obj.onDeselect({ e: e, object: object })) {\n return false;\n }\n this._activeObject = null;\n }\n return true;\n },\n\n /**\n * Discards currently active object and fire events. If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parameter and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @param {event} e\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n discardActiveObject: function (e) {\n var currentActives = this.getActiveObjects(), activeObject = this.getActiveObject();\n if (currentActives.length) {\n this.fire('before:selection:cleared', { target: activeObject, e: e });\n }\n this._discardActiveObject(e);\n this._fireSelectionEvents(currentActives, e);\n return this;\n },\n\n /**\n * Clears a canvas element and removes all event listeners\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n dispose: function () {\n var wrapper = this.wrapperEl;\n this.removeListeners();\n wrapper.removeChild(this.upperCanvasEl);\n wrapper.removeChild(this.lowerCanvasEl);\n this.contextCache = null;\n this.contextTop = null;\n ['upperCanvasEl', 'cacheCanvasEl'].forEach((function(element) {\n fabric.util.cleanUpJsdomNode(this[element]);\n this[element] = undefined;\n }).bind(this));\n if (wrapper.parentNode) {\n wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl);\n }\n delete this.wrapperEl;\n fabric.StaticCanvas.prototype.dispose.call(this);\n return this;\n },\n\n /**\n * Clears all contexts (background, main, top) of an instance\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clear: function () {\n // this.discardActiveGroup();\n this.discardActiveObject();\n this.clearContext(this.contextTop);\n return this.callSuper('clear');\n },\n\n /**\n * Draws objects' controls (borders/controls)\n * @param {CanvasRenderingContext2D} ctx Context to render controls on\n */\n drawControls: function(ctx) {\n var activeObject = this._activeObject;\n\n if (activeObject) {\n activeObject._renderControls(ctx);\n }\n },\n\n /**\n * @private\n */\n _toObject: function(instance, methodName, propertiesToInclude) {\n //If the object is part of the current selection group, it should\n //be transformed appropriately\n //i.e. it should be serialised as it would appear if the selection group\n //were to be destroyed.\n var originalProperties = this._realizeGroupTransformOnObject(instance),\n object = this.callSuper('_toObject', instance, methodName, propertiesToInclude);\n //Undo the damage we did by changing all of its properties\n this._unwindGroupTransformOnObject(instance, originalProperties);\n return object;\n },\n\n /**\n * Realises an object's group transformation on it\n * @private\n * @param {fabric.Object} [instance] the object to transform (gets mutated)\n * @returns the original values of instance which were changed\n */\n _realizeGroupTransformOnObject: function(instance) {\n if (instance.group && instance.group.type === 'activeSelection' && this._activeObject === instance.group) {\n var layoutProps = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top'];\n //Copy all the positionally relevant properties across now\n var originalValues = {};\n layoutProps.forEach(function(prop) {\n originalValues[prop] = instance[prop];\n });\n this._activeObject.realizeTransform(instance);\n return originalValues;\n }\n else {\n return null;\n }\n },\n\n /**\n * Restores the changed properties of instance\n * @private\n * @param {fabric.Object} [instance] the object to un-transform (gets mutated)\n * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject\n */\n _unwindGroupTransformOnObject: function(instance, originalValues) {\n if (originalValues) {\n instance.set(originalValues);\n }\n },\n\n /**\n * @private\n */\n _setSVGObject: function(markup, instance, reviver) {\n //If the object is in a selection group, simulate what would happen to that\n //object when the group is deselected\n var originalProperties = this._realizeGroupTransformOnObject(instance);\n this.callSuper('_setSVGObject', markup, instance, reviver);\n this._unwindGroupTransformOnObject(instance, originalProperties);\n },\n\n setViewportTransform: function (vpt) {\n if (this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing) {\n this._activeObject.clearContextTop();\n }\n fabric.StaticCanvas.prototype.setViewportTransform.call(this, vpt);\n }\n });\n\n // copying static properties manually to work around Opera's bug,\n // where \"prototype\" property is enumerable and overrides existing prototype\n for (var prop in fabric.StaticCanvas) {\n if (prop !== 'prototype') {\n fabric.Canvas[prop] = fabric.StaticCanvas[prop];\n }\n }\n})();\n\n\n(function() {\n\n var cursorOffset = {\n mt: 0, // n\n tr: 1, // ne\n mr: 2, // e\n br: 3, // se\n mb: 4, // s\n bl: 5, // sw\n ml: 6, // w\n tl: 7 // nw\n },\n addListener = fabric.util.addListener,\n removeListener = fabric.util.removeListener,\n RIGHT_CLICK = 3, MIDDLE_CLICK = 2, LEFT_CLICK = 1,\n addEventOptions = { passive: false };\n\n function checkClick(e, value) {\n return e.button && (e.button === value - 1);\n }\n\n fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * Map of cursor style values for each of the object controls\n * @private\n */\n cursorMap: [\n 'n-resize',\n 'ne-resize',\n 'e-resize',\n 'se-resize',\n 's-resize',\n 'sw-resize',\n 'w-resize',\n 'nw-resize'\n ],\n\n /**\n * Contains the id of the touch event that owns the fabric transform\n * @type Number\n * @private\n */\n mainTouchId: null,\n\n /**\n * Adds mouse listeners to canvas\n * @private\n */\n _initEventListeners: function () {\n // in case we initialized the class twice. This should not happen normally\n // but in some kind of applications where the canvas element may be changed\n // this is a workaround to having double listeners.\n this.removeListeners();\n this._bindEvents();\n this.addOrRemove(addListener, 'add');\n },\n\n /**\n * return an event prefix pointer or mouse.\n * @private\n */\n _getEventPrefix: function () {\n return this.enablePointerEvents ? 'pointer' : 'mouse';\n },\n\n addOrRemove: function(functor, eventjsFunctor) {\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n functor(fabric.window, 'resize', this._onResize);\n functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n functor(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n functor(canvasElement, eventTypePrefix + 'out', this._onMouseOut);\n functor(canvasElement, eventTypePrefix + 'enter', this._onMouseEnter);\n functor(canvasElement, 'wheel', this._onMouseWheel);\n functor(canvasElement, 'contextmenu', this._onContextMenu);\n functor(canvasElement, 'dblclick', this._onDoubleClick);\n functor(canvasElement, 'dragover', this._onDragOver);\n functor(canvasElement, 'dragenter', this._onDragEnter);\n functor(canvasElement, 'dragleave', this._onDragLeave);\n functor(canvasElement, 'drop', this._onDrop);\n if (!this.enablePointerEvents) {\n functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);\n }\n if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {\n eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture);\n eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag);\n eventjs[eventjsFunctor](canvasElement, 'orientation', this._onOrientationChange);\n eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake);\n eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress);\n }\n },\n\n /**\n * Removes all event listeners\n */\n removeListeners: function() {\n this.addOrRemove(removeListener, 'remove');\n // if you dispose on a mouseDown, before mouse up, you need to clean document to...\n var eventTypePrefix = this._getEventPrefix();\n removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n },\n\n /**\n * @private\n */\n _bindEvents: function() {\n if (this.eventsBound) {\n // for any reason we pass here twice we do not want to bind events twice.\n return;\n }\n this._onMouseDown = this._onMouseDown.bind(this);\n this._onTouchStart = this._onTouchStart.bind(this);\n this._onMouseMove = this._onMouseMove.bind(this);\n this._onMouseUp = this._onMouseUp.bind(this);\n this._onTouchEnd = this._onTouchEnd.bind(this);\n this._onResize = this._onResize.bind(this);\n this._onGesture = this._onGesture.bind(this);\n this._onDrag = this._onDrag.bind(this);\n this._onShake = this._onShake.bind(this);\n this._onLongPress = this._onLongPress.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n this._onMouseWheel = this._onMouseWheel.bind(this);\n this._onMouseOut = this._onMouseOut.bind(this);\n this._onMouseEnter = this._onMouseEnter.bind(this);\n this._onContextMenu = this._onContextMenu.bind(this);\n this._onDoubleClick = this._onDoubleClick.bind(this);\n this._onDragOver = this._onDragOver.bind(this);\n this._onDragEnter = this._simpleEventHandler.bind(this, 'dragenter');\n this._onDragLeave = this._simpleEventHandler.bind(this, 'dragleave');\n this._onDrop = this._simpleEventHandler.bind(this, 'drop');\n this.eventsBound = true;\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js gesture\n * @param {Event} [self] Inner Event object\n */\n _onGesture: function(e, self) {\n this.__onTransformGesture && this.__onTransformGesture(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js drag\n * @param {Event} [self] Inner Event object\n */\n _onDrag: function(e, self) {\n this.__onDrag && this.__onDrag(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on wheel event\n */\n _onMouseWheel: function(e) {\n this.__onMouseWheel(e);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseOut: function(e) {\n var target = this._hoveredTarget;\n this.fire('mouse:out', { target: target, e: e });\n this._hoveredTarget = null;\n target && target.fire('mouseout', { e: e });\n\n var _this = this;\n this._hoveredTargets.forEach(function(_target){\n _this.fire('mouse:out', { target: target, e: e });\n _target && target.fire('mouseout', { e: e });\n });\n this._hoveredTargets = [];\n\n if (this._iTextInstances) {\n this._iTextInstances.forEach(function(obj) {\n if (obj.isEditing) {\n obj.hiddenTextarea.focus();\n }\n });\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseenter\n */\n _onMouseEnter: function(e) {\n // This find target and consequent 'mouse:over' is used to\n // clear old instances on hovered target.\n // calling findTarget has the side effect of killing target.__corner.\n // as a short term fix we are not firing this if we are currently transforming.\n // as a long term fix we need to separate the action of finding a target with the\n // side effects we added to it.\n if (!this.currentTransform && !this.findTarget(e)) {\n this.fire('mouse:over', { target: null, e: e });\n this._hoveredTarget = null;\n this._hoveredTargets = [];\n }\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js orientation change\n * @param {Event} [self] Inner Event object\n */\n _onOrientationChange: function(e, self) {\n this.__onOrientationChange && this.__onOrientationChange(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n * @param {Event} [self] Inner Event object\n */\n _onShake: function(e, self) {\n this.__onShake && this.__onShake(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n * @param {Event} [self] Inner Event object\n */\n _onLongPress: function(e, self) {\n this.__onLongPress && this.__onLongPress(e, self);\n },\n\n /**\n * prevent default to allow drop event to be fired\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n */\n _onDragOver: function(e) {\n e.preventDefault();\n var target = this._simpleEventHandler('dragover', e);\n this._fireEnterLeaveEvents(target, e);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onContextMenu: function (e) {\n if (this.stopContextMenu) {\n e.stopPropagation();\n e.preventDefault();\n }\n return false;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onDoubleClick: function (e) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'dblclick');\n this._resetTransformEventData(e);\n },\n\n /**\n * Return a the id of an event.\n * returns either the pointerId or the identifier or 0 for the mouse event\n * @private\n * @param {Event} evt Event object\n */\n getPointerId: function(evt) {\n var changedTouches = evt.changedTouches;\n\n if (changedTouches) {\n return changedTouches[0] && changedTouches[0].identifier;\n }\n\n if (this.enablePointerEvents) {\n return evt.pointerId;\n }\n\n return -1;\n },\n\n /**\n * Determines if an event has the id of the event that is considered main\n * @private\n * @param {evt} event Event object\n */\n _isMainEvent: function(evt) {\n if (evt.isPrimary === true) {\n return true;\n }\n if (evt.isPrimary === false) {\n return false;\n }\n if (evt.type === 'touchend' && evt.touches.length === 0) {\n return true;\n }\n if (evt.changedTouches) {\n return evt.changedTouches[0].identifier === this.mainTouchId;\n }\n return true;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchStart: function(e) {\n e.preventDefault();\n if (this.mainTouchId === null) {\n this.mainTouchId = this.getPointerId(e);\n }\n this.__onMouseDown(e);\n this._resetTransformEventData();\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n addListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n addListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n // Unbind mousedown to prevent double triggers from touch devices\n removeListener(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDown: function (e) {\n this.__onMouseDown(e);\n this._resetTransformEventData();\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n removeListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n addListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n addListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchEnd: function(e) {\n if (e.touches.length > 0) {\n // if there are still touches stop here\n return;\n }\n this.__onMouseUp(e);\n this._resetTransformEventData();\n this.mainTouchId = null;\n var eventTypePrefix = this._getEventPrefix();\n removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n var _this = this;\n if (this._willAddMouseDown) {\n clearTimeout(this._willAddMouseDown);\n }\n this._willAddMouseDown = setTimeout(function() {\n // Wait 400ms before rebinding mousedown to prevent double triggers\n // from touch devices\n addListener(_this.upperCanvasEl, eventTypePrefix + 'down', _this._onMouseDown);\n _this._willAddMouseDown = 0;\n }, 400);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUp: function (e) {\n this.__onMouseUp(e);\n this._resetTransformEventData();\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n if (this._isMainEvent(e)) {\n removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n addListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMove: function (e) {\n !this.allowTouchScrolling && e.preventDefault && e.preventDefault();\n this.__onMouseMove(e);\n },\n\n /**\n * @private\n */\n _onResize: function () {\n this.calcOffset();\n },\n\n /**\n * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n * @private\n * @param {Object} target\n */\n _shouldRender: function(target) {\n var activeObject = this._activeObject;\n\n if (\n !!activeObject !== !!target ||\n (activeObject && target && (activeObject !== target))\n ) {\n // this covers: switch of target, from target to no target, selection of target\n // multiSelection with key and mouse\n return true;\n }\n else if (activeObject && activeObject.isEditing) {\n // if we mouse up/down over a editing textbox a cursor change,\n // there is no need to re render\n return false;\n }\n return false;\n },\n\n /**\n * Method that defines the actions when mouse is released on canvas.\n * The method resets the currentTransform parameters, store the image corner\n * position in the image object and render the canvas on top.\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseUp: function (e) {\n var target, transform = this._currentTransform,\n groupSelector = this._groupSelector, shouldRender = false,\n isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0));\n this._cacheTransformEventData(e);\n target = this._target;\n this._handleEvent(e, 'up:before');\n // if right/middle click just fire events and return\n // target undefined will make the _handleEvent search the target\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'up', RIGHT_CLICK, isClick);\n }\n return;\n }\n\n if (checkClick(e, MIDDLE_CLICK)) {\n if (this.fireMiddleClick) {\n this._handleEvent(e, 'up', MIDDLE_CLICK, isClick);\n }\n this._resetTransformEventData();\n return;\n }\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this._onMouseUpInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n if (transform) {\n this._finalizeCurrentTransform(e);\n shouldRender = transform.actionPerformed;\n }\n\n if (!isClick) {\n this._maybeGroupObjects(e);\n shouldRender || (shouldRender = this._shouldRender(target));\n }\n if (target) {\n target.isMoving = false;\n }\n this._setCursorFromEvent(e, target);\n this._handleEvent(e, 'up', LEFT_CLICK, isClick);\n this._groupSelector = null;\n this._currentTransform = null;\n // reset the target information about which corner is selected\n target && (target.__corner = 0);\n if (shouldRender) {\n this.requestRenderAll();\n }\n else if (!isClick) {\n this.renderTop();\n }\n },\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {Event} e event from mouse\n * @param {String} eventType event to fire (up, down or move)\n * @return {Fabric.Object} target return the the target found, for internal reasons.\n */\n _simpleEventHandler: function(eventType, e) {\n var target = this.findTarget(e),\n targets = this.targets,\n options = {\n e: e,\n target: target,\n subTargets: targets,\n };\n this.fire(eventType, options);\n target && target.fire(eventType, options);\n if (!targets) {\n return target;\n }\n for (var i = 0; i < targets.length; i++) {\n targets[i].fire(eventType, options);\n }\n return target;\n },\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {Event} e event from mouse\n * @param {String} eventType event to fire (up, down or move)\n * @param {fabric.Object} targetObj receiving event\n * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right\n * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move.\n */\n _handleEvent: function(e, eventType, button, isClick) {\n var target = this._target,\n targets = this.targets || [],\n options = {\n e: e,\n target: target,\n subTargets: targets,\n button: button || LEFT_CLICK,\n isClick: isClick || false,\n pointer: this._pointer,\n absolutePointer: this._absolutePointer,\n transform: this._currentTransform\n };\n this.fire('mouse:' + eventType, options);\n target && target.fire('mouse' + eventType, options);\n for (var i = 0; i < targets.length; i++) {\n targets[i].fire('mouse' + eventType, options);\n }\n },\n\n /**\n * @private\n * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event\n */\n _finalizeCurrentTransform: function(e) {\n\n var transform = this._currentTransform,\n target = transform.target,\n eventName,\n options = {\n e: e,\n target: target,\n transform: transform,\n };\n\n if (target._scaling) {\n target._scaling = false;\n }\n\n target.setCoords();\n\n if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) {\n if (transform.actionPerformed) {\n eventName = this._addEventOptions(options, transform);\n this._fire(eventName, options);\n }\n this._fire('modified', options);\n }\n },\n\n /**\n * Mutate option object in order to add by property and give back the event name.\n * @private\n * @param {Object} options to mutate\n * @param {Object} transform to inspect action from\n */\n _addEventOptions: function(options, transform) {\n // we can probably add more details at low cost\n // scale change, rotation changes, translation changes\n var eventName, by;\n switch (transform.action) {\n case 'scaleX':\n eventName = 'scaled';\n by = 'x';\n break;\n case 'scaleY':\n eventName = 'scaled';\n by = 'y';\n break;\n case 'skewX':\n eventName = 'skewed';\n by = 'x';\n break;\n case 'skewY':\n eventName = 'skewed';\n by = 'y';\n break;\n case 'scale':\n eventName = 'scaled';\n by = 'equally';\n break;\n case 'rotate':\n eventName = 'rotated';\n break;\n case 'drag':\n eventName = 'moved';\n break;\n }\n options.by = by;\n return eventName;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDownInDrawingMode: function(e) {\n this._isCurrentlyDrawing = true;\n if (this.getActiveObject()) {\n this.discardActiveObject(e).requestRenderAll();\n }\n if (this.clipTo) {\n fabric.util.clipContext(this, this.contextTop);\n }\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseDown(pointer, { e: e, pointer: pointer });\n this._handleEvent(e, 'down');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMoveInDrawingMode: function(e) {\n if (this._isCurrentlyDrawing) {\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseMove(pointer, { e: e, pointer: pointer });\n }\n this.setCursor(this.freeDrawingCursor);\n this._handleEvent(e, 'move');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUpInDrawingMode: function(e) {\n if (this.clipTo) {\n this.contextTop.restore();\n }\n var pointer = this.getPointer(e);\n this._isCurrentlyDrawing = this.freeDrawingBrush.onMouseUp({ e: e, pointer: pointer });\n this._handleEvent(e, 'up');\n },\n\n /**\n * Method that defines the actions when mouse is clicked on canvas.\n * The method inits the currentTransform parameters and renders all the\n * canvas so the current image can be placed on the top canvas and the rest\n * in on the container one.\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n __onMouseDown: function (e) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'down:before');\n var target = this._target;\n // if right click just fire events\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'down', RIGHT_CLICK);\n }\n return;\n }\n\n if (checkClick(e, MIDDLE_CLICK)) {\n if (this.fireMiddleClick) {\n this._handleEvent(e, 'down', MIDDLE_CLICK);\n }\n return;\n }\n\n if (this.isDrawingMode) {\n this._onMouseDownInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n // ignore if some object is being transformed at this moment\n if (this._currentTransform) {\n return;\n }\n\n var pointer = this._pointer;\n // save pointer for check in __onMouseUp event\n this._previousPointer = pointer;\n var shouldRender = this._shouldRender(target),\n shouldGroup = this._shouldGroup(e, target);\n if (this._shouldClearSelection(e, target)) {\n this.discardActiveObject(e);\n }\n else if (shouldGroup) {\n this._handleGrouping(e, target);\n target = this._activeObject;\n }\n\n if (this.selection && (!target ||\n (!target.selectable && !target.isEditing && target !== this._activeObject))) {\n this._groupSelector = {\n ex: pointer.x,\n ey: pointer.y,\n top: 0,\n left: 0\n };\n }\n\n if (target) {\n var alreadySelected = target === this._activeObject;\n if (target.selectable) {\n this.setActiveObject(target, e);\n }\n if (target === this._activeObject && (target.__corner || !shouldGroup)) {\n this._setupCurrentTransform(e, target, alreadySelected);\n }\n }\n this._handleEvent(e, 'down');\n // we must renderAll so that we update the visuals\n (shouldRender || shouldGroup) && this.requestRenderAll();\n },\n\n /**\n * reset cache form common information needed during event processing\n * @private\n */\n _resetTransformEventData: function() {\n this._target = null;\n this._pointer = null;\n this._absolutePointer = null;\n },\n\n /**\n * Cache common information needed during event processing\n * @private\n * @param {Event} e Event object fired on event\n */\n _cacheTransformEventData: function(e) {\n // reset in order to avoid stale caching\n this._resetTransformEventData();\n this._pointer = this.getPointer(e, true);\n this._absolutePointer = this.restorePointerVpt(this._pointer);\n this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(e) || null;\n },\n\n /**\n * @private\n */\n _beforeTransform: function(e) {\n var t = this._currentTransform;\n this.stateful && t.target.saveState();\n this.fire('before:transform', {\n e: e,\n transform: t,\n });\n // determine if it's a drag or rotate case\n if (t.corner) {\n this.onBeforeScaleRotate(t.target);\n }\n },\n\n /**\n * Method that defines the actions when mouse is hovering the canvas.\n * The currentTransform parameter will define whether the user is rotating/scaling/translating\n * an image or neither of them (only hovering). A group selection is also possible and would cancel\n * all any other type of action.\n * In case of an image transformation only the top canvas will be rendered.\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n __onMouseMove: function (e) {\n this._handleEvent(e, 'move:before');\n this._cacheTransformEventData(e);\n var target, pointer;\n\n if (this.isDrawingMode) {\n this._onMouseMoveInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n var groupSelector = this._groupSelector;\n\n // We initially clicked in an empty area, so we draw a box for multiple selection\n if (groupSelector) {\n pointer = this._pointer;\n\n groupSelector.left = pointer.x - groupSelector.ex;\n groupSelector.top = pointer.y - groupSelector.ey;\n\n this.renderTop();\n }\n else if (!this._currentTransform) {\n target = this.findTarget(e) || null;\n this._setCursorFromEvent(e, target);\n this._fireOverOutEvents(target, e);\n }\n else {\n this._transformObject(e);\n }\n this._handleEvent(e, 'move');\n this._resetTransformEventData();\n },\n\n /**\n * Manage the mouseout, mouseover events for the fabric object on the canvas\n * @param {Fabric.Object} target the target where the target from the mousemove event\n * @param {Event} e Event object fired on mousemove\n * @private\n */\n _fireOverOutEvents: function(target, e) {\n var _hoveredTarget = this._hoveredTarget,\n _hoveredTargets = this._hoveredTargets, targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents(target, e, {\n oldTarget: _hoveredTarget,\n evtOut: 'mouseout',\n canvasEvtOut: 'mouse:out',\n evtIn: 'mouseover',\n canvasEvtIn: 'mouse:over',\n });\n for (var i = 0; i < length; i++){\n this.fireSyntheticInOutEvents(targets[i], e, {\n oldTarget: _hoveredTargets[i],\n evtOut: 'mouseout',\n evtIn: 'mouseover',\n });\n }\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\n },\n\n /**\n * Manage the dragEnter, dragLeave events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the onDrag event\n * @param {Event} e Event object fired on ondrag\n * @private\n */\n _fireEnterLeaveEvents: function(target, e) {\n var _draggedoverTarget = this._draggedoverTarget,\n _hoveredTargets = this._hoveredTargets, targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents(target, e, {\n oldTarget: _draggedoverTarget,\n evtOut: 'dragleave',\n evtIn: 'dragenter',\n });\n for (var i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents(targets[i], e, {\n oldTarget: _hoveredTargets[i],\n evtOut: 'dragleave',\n evtIn: 'dragenter',\n });\n }\n this._draggedoverTarget = target;\n },\n\n /**\n * Manage the synthetic in/out events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the supported events\n * @param {Event} e Event object fired\n * @param {Object} config configuration for the function to work\n * @param {String} config.targetName property on the canvas where the old target is stored\n * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out\n * @param {String} config.evtOut name of the event to fire for out\n * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in\n * @param {String} config.evtIn name of the event to fire for in\n * @private\n */\n fireSyntheticInOutEvents: function(target, e, config) {\n var inOpt, outOpt, oldTarget = config.oldTarget, outFires, inFires,\n targetChanged = oldTarget !== target, canvasEvtIn = config.canvasEvtIn, canvasEvtOut = config.canvasEvtOut;\n if (targetChanged) {\n inOpt = { e: e, target: target, previousTarget: oldTarget };\n outOpt = { e: e, target: oldTarget, nextTarget: target };\n }\n inFires = target && targetChanged;\n outFires = oldTarget && targetChanged;\n if (outFires) {\n canvasEvtOut && this.fire(canvasEvtOut, outOpt);\n oldTarget.fire(config.evtOut, outOpt);\n }\n if (inFires) {\n canvasEvtIn && this.fire(canvasEvtIn, inOpt);\n target.fire(config.evtIn, inOpt);\n }\n },\n\n /**\n * Method that defines actions when an Event Mouse Wheel\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseWheel: function(e) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'wheel');\n this._resetTransformEventData();\n },\n\n /**\n * @private\n * @param {Event} e Event fired on mousemove\n */\n _transformObject: function(e) {\n var pointer = this.getPointer(e),\n transform = this._currentTransform;\n\n transform.reset = false;\n transform.target.isMoving = true;\n transform.shiftKey = e.shiftKey;\n transform.altKey = e[this.centeredKey];\n\n this._beforeScaleTransform(e, transform);\n this._performTransformAction(e, transform, pointer);\n\n transform.actionPerformed && this.requestRenderAll();\n },\n\n /**\n * @private\n */\n _performTransformAction: function(e, transform, pointer) {\n var x = pointer.x,\n y = pointer.y,\n action = transform.action,\n actionPerformed = false,\n options = {\n target: transform.target,\n e: e,\n transform: transform,\n pointer: pointer\n };\n\n if (action === 'rotate') {\n (actionPerformed = this._rotateObject(x, y)) && this._fire('rotating', options);\n }\n else if (action === 'scale') {\n (actionPerformed = this._onScale(e, transform, x, y)) && this._fire('scaling', options);\n }\n else if (action === 'scaleX') {\n (actionPerformed = this._scaleObject(x, y, 'x')) && this._fire('scaling', options);\n }\n else if (action === 'scaleY') {\n (actionPerformed = this._scaleObject(x, y, 'y')) && this._fire('scaling', options);\n }\n else if (action === 'skewX') {\n (actionPerformed = this._skewObject(x, y, 'x')) && this._fire('skewing', options);\n }\n else if (action === 'skewY') {\n (actionPerformed = this._skewObject(x, y, 'y')) && this._fire('skewing', options);\n }\n else {\n actionPerformed = this._translateObject(x, y);\n if (actionPerformed) {\n this._fire('moving', options);\n this.setCursor(options.target.moveCursor || this.moveCursor);\n }\n }\n transform.actionPerformed = transform.actionPerformed || actionPerformed;\n },\n\n /**\n * @private\n */\n _fire: function(eventName, options) {\n this.fire('object:' + eventName, options);\n options.target.fire(eventName, options);\n },\n\n /**\n * @private\n */\n _beforeScaleTransform: function(e, transform) {\n if (transform.action === 'scale' || transform.action === 'scaleX' || transform.action === 'scaleY') {\n var centerTransform = this._shouldCenterTransform(transform.target);\n\n // Switch from a normal resize to center-based\n if ((centerTransform && (transform.originX !== 'center' || transform.originY !== 'center')) ||\n // Switch from center-based resize to normal one\n (!centerTransform && transform.originX === 'center' && transform.originY === 'center')\n ) {\n this._resetCurrentTransform();\n transform.reset = true;\n }\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {Object} transform current transform\n * @param {Number} x mouse position x from origin\n * @param {Number} y mouse position y from origin\n * @return {Boolean} true if the scaling occurred\n */\n _onScale: function(e, transform, x, y) {\n if (this._isUniscalePossible(e, transform.target)) {\n transform.currentAction = 'scale';\n return this._scaleObject(x, y);\n }\n else {\n // Switch from a normal resize to proportional\n if (!transform.reset && transform.currentAction === 'scale') {\n this._resetCurrentTransform();\n }\n\n transform.currentAction = 'scaleEqually';\n return this._scaleObject(x, y, 'equally');\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target current target\n * @return {Boolean} true if unproportional scaling is possible\n */\n _isUniscalePossible: function(e, target) {\n return (e[this.uniScaleKey] || this.uniScaleTransform) && !target.get('lockUniScaling');\n },\n\n /**\n * Sets the cursor depending on where the canvas is being hovered.\n * Note: very buggy in Opera\n * @param {Event} e Event object\n * @param {Object} target Object that the mouse is hovering, if so.\n */\n _setCursorFromEvent: function (e, target) {\n if (!target) {\n this.setCursor(this.defaultCursor);\n return false;\n }\n var hoverCursor = target.hoverCursor || this.hoverCursor,\n activeSelection = this._activeObject && this._activeObject.type === 'activeSelection' ?\n this._activeObject : null,\n // only show proper corner when group selection is not active\n corner = (!activeSelection || !activeSelection.contains(target))\n && target._findTargetCorner(this.getPointer(e, true));\n\n if (!corner) {\n if (target.subTargetCheck){\n // hoverCursor should come from top-most subTarget,\n // so we walk the array backwards\n this.targets.concat().reverse().map(function(_target){\n hoverCursor = _target.hoverCursor || hoverCursor;\n });\n }\n this.setCursor(hoverCursor);\n }\n else {\n this.setCursor(this.getCornerCursor(corner, target, e));\n }\n },\n\n /**\n * @private\n */\n getCornerCursor: function(corner, target, e) {\n if (this.actionIsDisabled(corner, target, e)) {\n return this.notAllowedCursor;\n }\n else if (corner in cursorOffset) {\n return this._getRotatedCornerCursor(corner, target, e);\n }\n else if (corner === 'mtr' && target.hasRotatingPoint) {\n return this.rotationCursor;\n }\n else {\n return this.defaultCursor;\n }\n },\n\n actionIsDisabled: function(corner, target, e) {\n if (corner === 'mt' || corner === 'mb') {\n return e[this.altActionKey] ? target.lockSkewingX : target.lockScalingY;\n }\n else if (corner === 'ml' || corner === 'mr') {\n return e[this.altActionKey] ? target.lockSkewingY : target.lockScalingX;\n }\n else if (corner === 'mtr') {\n return target.lockRotation;\n }\n else {\n return this._isUniscalePossible(e, target) ?\n target.lockScalingX && target.lockScalingY : target.lockScalingX || target.lockScalingY;\n }\n },\n\n /**\n * @private\n */\n _getRotatedCornerCursor: function(corner, target, e) {\n var n = Math.round((target.angle % 360) / 45);\n\n if (n < 0) {\n n += 8; // full circle ahead\n }\n n += cursorOffset[corner];\n if (e[this.altActionKey] && cursorOffset[corner] % 2 === 0) {\n //if we are holding shift and we are on a mx corner...\n n += 2;\n }\n // normalize n to be from 0 to 7\n n %= 8;\n\n return this.cursorMap[n];\n }\n });\n})();\n\n\n(function() {\n\n var min = Math.min,\n max = Math.max;\n\n fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n * @return {Boolean}\n */\n _shouldGroup: function(e, target) {\n var activeObject = this._activeObject;\n return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection &&\n (activeObject !== target || activeObject.type === 'activeSelection') && !target.onSelect({ e: e });\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _handleGrouping: function (e, target) {\n var activeObject = this._activeObject;\n // avoid multi select when shift click on a corner\n if (activeObject.__corner) {\n return;\n }\n if (target === activeObject) {\n // if it's a group, find target again, using activeGroup objects\n target = this.findTarget(e, true);\n // if even object is not found or we are on activeObjectCorner, bail out\n if (!target || !target.selectable) {\n return;\n }\n }\n if (activeObject && activeObject.type === 'activeSelection') {\n this._updateActiveSelection(target, e);\n }\n else {\n this._createActiveSelection(target, e);\n }\n },\n\n /**\n * @private\n */\n _updateActiveSelection: function(target, e) {\n var activeSelection = this._activeObject,\n currentActiveObjects = activeSelection._objects.slice(0);\n if (activeSelection.contains(target)) {\n activeSelection.removeWithUpdate(target);\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\n if (activeSelection.size() === 1) {\n // activate last remaining object\n this._setActiveObject(activeSelection.item(0), e);\n }\n }\n else {\n activeSelection.addWithUpdate(target);\n this._hoveredTarget = activeSelection;\n this._hoveredTargets = this.targets.concat();\n }\n this._fireSelectionEvents(currentActiveObjects, e);\n },\n\n /**\n * @private\n */\n _createActiveSelection: function(target, e) {\n var currentActives = this.getActiveObjects(), group = this._createGroup(target);\n this._hoveredTarget = group;\n // ISSUE 4115: should we consider subTargets here?\n // this._hoveredTargets = [];\n // this._hoveredTargets = this.targets.concat();\n this._setActiveObject(group, e);\n this._fireSelectionEvents(currentActives, e);\n },\n\n /**\n * @private\n * @param {Object} target\n */\n _createGroup: function(target) {\n var objects = this._objects,\n isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target),\n groupObjects = isActiveLower\n ? [this._activeObject, target]\n : [target, this._activeObject];\n this._activeObject.isEditing && this._activeObject.exitEditing();\n return new fabric.ActiveSelection(groupObjects, {\n canvas: this\n });\n },\n\n /**\n * @private\n * @param {Event} e mouse event\n */\n _groupSelectedObjects: function (e) {\n\n var group = this._collectObjects(e),\n aGroup;\n\n // do not create group for 1 element only\n if (group.length === 1) {\n this.setActiveObject(group[0], e);\n }\n else if (group.length > 1) {\n aGroup = new fabric.ActiveSelection(group.reverse(), {\n canvas: this\n });\n this.setActiveObject(aGroup, e);\n }\n },\n\n /**\n * @private\n */\n _collectObjects: function(e) {\n var group = [],\n currentObject,\n x1 = this._groupSelector.ex,\n y1 = this._groupSelector.ey,\n x2 = x1 + this._groupSelector.left,\n y2 = y1 + this._groupSelector.top,\n selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),\n selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),\n allowIntersect = !this.selectionFullyContained,\n isClick = x1 === x2 && y1 === y2;\n // we iterate reverse order to collect top first in case of click.\n for (var i = this._objects.length; i--; ) {\n currentObject = this._objects[i];\n\n if (!currentObject || !currentObject.selectable || !currentObject.visible) {\n continue;\n }\n\n if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2)) ||\n currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) ||\n (allowIntersect && currentObject.containsPoint(selectionX1Y1)) ||\n (allowIntersect && currentObject.containsPoint(selectionX2Y2))\n ) {\n group.push(currentObject);\n // only add one object if it's a click\n if (isClick) {\n break;\n }\n }\n }\n\n if (group.length > 1) {\n group = group.filter(function(object) {\n return !object.onSelect({ e: e });\n });\n }\n\n return group;\n },\n\n /**\n * @private\n */\n _maybeGroupObjects: function(e) {\n if (this.selection && this._groupSelector) {\n this._groupSelectedObjects(e);\n }\n this.setCursor(this.defaultCursor);\n // clear selection and current transformation\n this._groupSelector = null;\n }\n });\n\n})();\n\n\n(function () {\n fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately\n * @param {Object} [options] Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo}\n * @example Generate jpeg dataURL with lower quality\n * var dataURL = canvas.toDataURL({\n * format: 'jpeg',\n * quality: 0.8\n * });\n * @example Generate cropped png dataURL (clipping of canvas)\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * left: 100,\n * top: 100,\n * width: 200,\n * height: 200\n * });\n * @example Generate double scaled png dataURL\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * multiplier: 2\n * });\n */\n toDataURL: function (options) {\n options || (options = { });\n\n var format = options.format || 'png',\n quality = options.quality || 1,\n multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? this.getRetinaScaling() : 1),\n canvasEl = this.toCanvasElement(multiplier, options);\n return fabric.util.toDataURL(canvasEl, format, quality);\n },\n\n /**\n * Create a new HTMLCanvas element painted with the current canvas content.\n * No need to resize the actual one or repaint it.\n * Will transfer object ownership to a new canvas, paint it, and set everything back.\n * This is an intermediary step used to get to a dataUrl but also it is useful to\n * create quick image copies of a canvas without passing for the dataUrl string\n * @param {Number} [multiplier] a zoom factor.\n * @param {Object} [cropping] Cropping informations\n * @param {Number} [cropping.left] Cropping left offset.\n * @param {Number} [cropping.top] Cropping top offset.\n * @param {Number} [cropping.width] Cropping width.\n * @param {Number} [cropping.height] Cropping height.\n */\n toCanvasElement: function(multiplier, cropping) {\n multiplier = multiplier || 1;\n cropping = cropping || { };\n var scaledWidth = (cropping.width || this.width) * multiplier,\n scaledHeight = (cropping.height || this.height) * multiplier,\n zoom = this.getZoom(),\n originalWidth = this.width,\n originalHeight = this.height,\n newZoom = zoom * multiplier,\n vp = this.viewportTransform,\n translateX = (vp[4] - (cropping.left || 0)) * multiplier,\n translateY = (vp[5] - (cropping.top || 0)) * multiplier,\n originalInteractive = this.interactive,\n newVp = [newZoom, 0, 0, newZoom, translateX, translateY],\n originalRetina = this.enableRetinaScaling,\n canvasEl = fabric.util.createCanvasElement(),\n originalContextTop = this.contextTop;\n canvasEl.width = scaledWidth;\n canvasEl.height = scaledHeight;\n this.contextTop = null;\n this.enableRetinaScaling = false;\n this.interactive = false;\n this.viewportTransform = newVp;\n this.width = scaledWidth;\n this.height = scaledHeight;\n this.calcViewportBoundaries();\n this.renderCanvas(canvasEl.getContext('2d'), this._objects);\n this.viewportTransform = vp;\n this.width = originalWidth;\n this.height = originalHeight;\n this.calcViewportBoundaries();\n this.interactive = originalInteractive;\n this.enableRetinaScaling = originalRetina;\n this.contextTop = originalContextTop;\n return canvasEl;\n },\n });\n\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Populates canvas with data from the specified dataless JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toDatalessJSON}\n * @deprecated since 1.2.2\n * @param {String|Object} json JSON string or object\n * @param {Function} callback Callback, invoked when json is parsed\n * and corresponding objects (e.g: {@link fabric.Image})\n * are initialized\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @return {fabric.Canvas} instance\n * @chainable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n */\n loadFromDatalessJSON: function (json, callback, reviver) {\n return this.loadFromJSON(json, callback, reviver);\n },\n\n /**\n * Populates canvas with data from the specified JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toJSON}\n * @param {String|Object} json JSON string or object\n * @param {Function} callback Callback, invoked when json is parsed\n * and corresponding objects (e.g: {@link fabric.Image})\n * are initialized\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @return {fabric.Canvas} instance\n * @chainable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}\n * @example loadFromJSON\n * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));\n * @example loadFromJSON with reviver\n * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) {\n * // `o` = json object\n * // `object` = fabric.Object instance\n * // ... do some stuff ...\n * });\n */\n loadFromJSON: function (json, callback, reviver) {\n if (!json) {\n return;\n }\n\n // serialize if it wasn't already\n var serialized = (typeof json === 'string')\n ? JSON.parse(json)\n : fabric.util.object.clone(json);\n\n var _this = this,\n clipPath = serialized.clipPath,\n renderOnAddRemove = this.renderOnAddRemove;\n\n this.renderOnAddRemove = false;\n\n delete serialized.clipPath;\n\n this._enlivenObjects(serialized.objects, function (enlivenedObjects) {\n _this.clear();\n _this._setBgOverlay(serialized, function () {\n if (clipPath) {\n _this._enlivenObjects([clipPath], function (enlivenedCanvasClip) {\n _this.clipPath = enlivenedCanvasClip[0];\n _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);\n });\n }\n else {\n _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);\n }\n });\n }, reviver);\n return this;\n },\n\n /**\n * @private\n * @param {Object} serialized Object with background and overlay information\n * @param {Array} restored canvas objects\n * @param {Function} cached renderOnAddRemove callback\n * @param {Function} callback Invoked after all background and overlay images/patterns loaded\n */\n __setupCanvas: function(serialized, enlivenedObjects, renderOnAddRemove, callback) {\n var _this = this;\n enlivenedObjects.forEach(function(obj, index) {\n // we splice the array just in case some custom classes restored from JSON\n // will add more object to canvas at canvas init.\n _this.insertAt(obj, index);\n });\n this.renderOnAddRemove = renderOnAddRemove;\n // remove parts i cannot set as options\n delete serialized.objects;\n delete serialized.backgroundImage;\n delete serialized.overlayImage;\n delete serialized.background;\n delete serialized.overlay;\n // this._initOptions does too many things to just\n // call it. Normally loading an Object from JSON\n // create the Object instance. Here the Canvas is\n // already an instance and we are just loading things over it\n this._setOptions(serialized);\n this.renderAll();\n callback && callback();\n },\n\n /**\n * @private\n * @param {Object} serialized Object with background and overlay information\n * @param {Function} callback Invoked after all background and overlay images/patterns loaded\n */\n _setBgOverlay: function(serialized, callback) {\n var loaded = {\n backgroundColor: false,\n overlayColor: false,\n backgroundImage: false,\n overlayImage: false\n };\n\n if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) {\n callback && callback();\n return;\n }\n\n var cbIfLoaded = function () {\n if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) {\n callback && callback();\n }\n };\n\n this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded);\n this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded);\n this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded);\n this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded);\n },\n\n /**\n * @private\n * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor)\n * @param {(Object|String)} value Value to set\n * @param {Object} loaded Set loaded property to true if property is set\n * @param {Object} callback Callback function to invoke after property is set\n */\n __setBgOverlay: function(property, value, loaded, callback) {\n var _this = this;\n\n if (!value) {\n loaded[property] = true;\n callback && callback();\n return;\n }\n\n if (property === 'backgroundImage' || property === 'overlayImage') {\n fabric.util.enlivenObjects([value], function(enlivedObject){\n _this[property] = enlivedObject[0];\n loaded[property] = true;\n callback && callback();\n });\n }\n else {\n this['set' + fabric.util.string.capitalize(property, true)](value, function() {\n loaded[property] = true;\n callback && callback();\n });\n }\n },\n\n /**\n * @private\n * @param {Array} objects\n * @param {Function} callback\n * @param {Function} [reviver]\n */\n _enlivenObjects: function (objects, callback, reviver) {\n if (!objects || objects.length === 0) {\n callback && callback([]);\n return;\n }\n\n fabric.util.enlivenObjects(objects, function(enlivenedObjects) {\n callback && callback(enlivenedObjects);\n }, null, reviver);\n },\n\n /**\n * @private\n * @param {String} format\n * @param {Function} callback\n */\n _toDataURL: function (format, callback) {\n this.clone(function (clone) {\n callback(clone.toDataURL(format));\n });\n },\n\n /**\n * @private\n * @param {String} format\n * @param {Number} multiplier\n * @param {Function} callback\n */\n _toDataURLWithMultiplier: function (format, multiplier, callback) {\n this.clone(function (clone) {\n callback(clone.toDataURLWithMultiplier(format, multiplier));\n });\n },\n\n /**\n * Clones canvas instance\n * @param {Object} [callback] Receives cloned instance as a first argument\n * @param {Array} [properties] Array of properties to include in the cloned canvas and children\n */\n clone: function (callback, properties) {\n var data = JSON.stringify(this.toJSON(properties));\n this.cloneWithoutData(function(clone) {\n clone.loadFromJSON(data, function() {\n callback && callback(clone);\n });\n });\n },\n\n /**\n * Clones canvas instance without cloning existing data.\n * This essentially copies canvas dimensions, clipping properties, etc.\n * but leaves data empty (so that you can populate it with your own)\n * @param {Object} [callback] Receives cloned instance as a first argument\n */\n cloneWithoutData: function(callback) {\n var el = fabric.util.createCanvasElement();\n\n el.width = this.width;\n el.height = this.height;\n\n var clone = new fabric.Canvas(el);\n clone.clipTo = this.clipTo;\n if (this.backgroundImage) {\n clone.setBackgroundImage(this.backgroundImage.src, function() {\n clone.renderAll();\n callback && callback(clone);\n });\n clone.backgroundImageOpacity = this.backgroundImageOpacity;\n clone.backgroundImageStretch = this.backgroundImageStretch;\n }\n else {\n callback && callback(clone);\n }\n }\n});\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n toFixed = fabric.util.toFixed,\n capitalize = fabric.util.string.capitalize,\n degreesToRadians = fabric.util.degreesToRadians,\n supportsLineDash = fabric.StaticCanvas.supports('setLineDash'),\n objectCaching = !fabric.isLikelyNode,\n ALIASING_LIMIT = 2;\n\n if (fabric.Object) {\n return;\n }\n\n /**\n * Root object class from which all 2d shape classes inherit from\n * @class fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}\n * @see {@link fabric.Object#initialize} for constructor definition\n *\n * @fires added\n * @fires removed\n *\n * @fires selected\n * @fires deselected\n * @fires modified\n * @fires modified\n * @fires moved\n * @fires scaled\n * @fires rotated\n * @fires skewed\n *\n * @fires rotating\n * @fires scaling\n * @fires moving\n * @fires skewing\n *\n * @fires mousedown\n * @fires mouseup\n * @fires mouseover\n * @fires mouseout\n * @fires mousewheel\n * @fires mousedblclick\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drop\n */\n fabric.Object = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.Object.prototype */ {\n\n /**\n * Type of an object (rect, circle, path, etc.).\n * Note that this property is meant to be read-only and not meant to be modified.\n * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly.\n * @type String\n * @default\n */\n type: 'object',\n\n /**\n * Horizontal origin of transformation of an object (one of \"left\", \"right\", \"center\")\n * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups\n * @type String\n * @default\n */\n originX: 'left',\n\n /**\n * Vertical origin of transformation of an object (one of \"top\", \"bottom\", \"center\")\n * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups\n * @type String\n * @default\n */\n originY: 'top',\n\n /**\n * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom}\n * @type Number\n * @default\n */\n top: 0,\n\n /**\n * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right}\n * @type Number\n * @default\n */\n left: 0,\n\n /**\n * Object width\n * @type Number\n * @default\n */\n width: 0,\n\n /**\n * Object height\n * @type Number\n * @default\n */\n height: 0,\n\n /**\n * Object scale factor (horizontal)\n * @type Number\n * @default\n */\n scaleX: 1,\n\n /**\n * Object scale factor (vertical)\n * @type Number\n * @default\n */\n scaleY: 1,\n\n /**\n * When true, an object is rendered as flipped horizontally\n * @type Boolean\n * @default\n */\n flipX: false,\n\n /**\n * When true, an object is rendered as flipped vertically\n * @type Boolean\n * @default\n */\n flipY: false,\n\n /**\n * Opacity of an object\n * @type Number\n * @default\n */\n opacity: 1,\n\n /**\n * Angle of rotation of an object (in degrees)\n * @type Number\n * @default\n */\n angle: 0,\n\n /**\n * Angle of skew on x axes of an object (in degrees)\n * @type Number\n * @default\n */\n skewX: 0,\n\n /**\n * Angle of skew on y axes of an object (in degrees)\n * @type Number\n * @default\n */\n skewY: 0,\n\n /**\n * Size of object's controlling corners (in pixels)\n * @type Number\n * @default\n */\n cornerSize: 13,\n\n /**\n * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill)\n * @type Boolean\n * @default\n */\n transparentCorners: true,\n\n /**\n * Default cursor value used when hovering over this object on canvas\n * @type String\n * @default\n */\n hoverCursor: null,\n\n /**\n * Default cursor value used when moving this object on canvas\n * @type String\n * @default\n */\n moveCursor: null,\n\n /**\n * Padding between object and its controlling borders (in pixels)\n * @type Number\n * @default\n */\n padding: 0,\n\n /**\n * Color of controlling borders of an object (when it's active)\n * @type String\n * @default\n */\n borderColor: 'rgba(102,153,255,0.75)',\n\n /**\n * Array specifying dash pattern of an object's borders (hasBorder must be true)\n * @since 1.6.2\n * @type Array\n */\n borderDashArray: null,\n\n /**\n * Color of controlling corners of an object (when it's active)\n * @type String\n * @default\n */\n cornerColor: 'rgba(102,153,255,0.5)',\n\n /**\n * Color of controlling corners of an object (when it's active and transparentCorners false)\n * @since 1.6.2\n * @type String\n * @default\n */\n cornerStrokeColor: null,\n\n /**\n * Specify style of control, 'rect' or 'circle'\n * @since 1.6.2\n * @type String\n */\n cornerStyle: 'rect',\n\n /**\n * Array specifying dash pattern of an object's control (hasBorder must be true)\n * @since 1.6.2\n * @type Array\n */\n cornerDashArray: null,\n\n /**\n * When true, this object will use center point as the origin of transformation\n * when being scaled via the controls.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: false,\n\n /**\n * When true, this object will use center point as the origin of transformation\n * when being rotated via the controls.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: true,\n\n /**\n * Color of object's fill\n * takes css colors https://www.w3.org/TR/css-color-3/\n * @type String\n * @default\n */\n fill: 'rgb(0,0,0)',\n\n /**\n * Fill rule used to fill an object\n * accepted values are nonzero, evenodd\n * Backwards incompatibility note: This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead)\n * @type String\n * @default\n */\n fillRule: 'nonzero',\n\n /**\n * Composite rule used for canvas globalCompositeOperation\n * @type String\n * @default\n */\n globalCompositeOperation: 'source-over',\n\n /**\n * Background color of an object.\n * takes css colors https://www.w3.org/TR/css-color-3/\n * @type String\n * @default\n */\n backgroundColor: '',\n\n /**\n * Selection Background color of an object. colored layer behind the object when it is active.\n * does not mix good with globalCompositeOperation methods.\n * @type String\n * @default\n */\n selectionBackgroundColor: '',\n\n /**\n * When defined, an object is rendered via stroke and this property specifies its color\n * takes css colors https://www.w3.org/TR/css-color-3/\n * @type String\n * @default\n */\n stroke: null,\n\n /**\n * Width of a stroke used to render this object\n * @type Number\n * @default\n */\n strokeWidth: 1,\n\n /**\n * Array specifying dash pattern of an object's stroke (stroke must be defined)\n * @type Array\n */\n strokeDashArray: null,\n\n /**\n * Line offset of an object's stroke\n * @type Number\n * @default\n */\n strokeDashOffset: 0,\n\n /**\n * Line endings style of an object's stroke (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: 'butt',\n\n /**\n * Corner style of an object's stroke (one of \"bevil\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: 'miter',\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of an object's stroke\n * @type Number\n * @default\n */\n strokeMiterLimit: 4,\n\n /**\n * Shadow object representing shadow of this shape\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * Opacity of object's controlling borders when object is active and moving\n * @type Number\n * @default\n */\n borderOpacityWhenMoving: 0.4,\n\n /**\n * Scale factor of object's controlling borders\n * bigger number will make a thicker border\n * border is 1, so this is basically a border tickness\n * since there is no way to change the border itself.\n * @type Number\n * @default\n */\n borderScaleFactor: 1,\n\n /**\n * Transform matrix (similar to SVG's transform matrix)\n * This property has been depreacted. Since caching and and qrDecompose this\n * property can be handled with the standard top,left,scaleX,scaleY,angle and skewX.\n * A documentation example on how to parse and merge a transformMatrix will be provided before\n * completely removing it in fabric 4.0\n * If you are starting a project now, DO NOT use it.\n * @deprecated since 3.2.0\n * @type Array\n */\n transformMatrix: null,\n\n /**\n * Minimum allowed scale value of an object\n * @type Number\n * @default\n */\n minScaleLimit: 0,\n\n /**\n * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection).\n * But events still fire on it.\n * @type Boolean\n * @default\n */\n selectable: true,\n\n /**\n * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4\n * @type Boolean\n * @default\n */\n evented: true,\n\n /**\n * When set to `false`, an object is not rendered on canvas\n * @type Boolean\n * @default\n */\n visible: true,\n\n /**\n * When set to `false`, object's controls are not displayed and can not be used to manipulate object\n * @type Boolean\n * @default\n */\n hasControls: true,\n\n /**\n * When set to `false`, object's controlling borders are not rendered\n * @type Boolean\n * @default\n */\n hasBorders: true,\n\n /**\n * When set to `false`, object's controlling rotating point will not be visible or selectable\n * @type Boolean\n * @default\n */\n hasRotatingPoint: true,\n\n /**\n * Offset for object's controlling rotating point (when enabled via `hasRotatingPoint`)\n * @type Number\n * @default\n */\n rotatingPointOffset: 40,\n\n /**\n * When set to `true`, objects are \"found\" on canvas on per-pixel basis rather than according to bounding box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: false,\n\n /**\n * When `false`, default object's values are not included in its serialization\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * Function that determines clipping of an object (context is passed as a first argument).\n * If you are using code minification, ctx argument can be minified/manglied you should use\n * as a workaround `var ctx = arguments[0];` in the function;\n * Note that context origin is at the object's center point (not left/top corner)\n * @deprecated since 2.0.0\n * @type Function\n */\n clipTo: null,\n\n /**\n * When `true`, object horizontal movement is locked\n * @type Boolean\n * @default\n */\n lockMovementX: false,\n\n /**\n * When `true`, object vertical movement is locked\n * @type Boolean\n * @default\n */\n lockMovementY: false,\n\n /**\n * When `true`, object rotation is locked\n * @type Boolean\n * @default\n */\n lockRotation: false,\n\n /**\n * When `true`, object horizontal scaling is locked\n * @type Boolean\n * @default\n */\n lockScalingX: false,\n\n /**\n * When `true`, object vertical scaling is locked\n * @type Boolean\n * @default\n */\n lockScalingY: false,\n\n /**\n * When `true`, object non-uniform scaling is locked\n * @type Boolean\n * @default\n */\n lockUniScaling: false,\n\n /**\n * When `true`, object horizontal skewing is locked\n * @type Boolean\n * @default\n */\n lockSkewingX: false,\n\n /**\n * When `true`, object vertical skewing is locked\n * @type Boolean\n * @default\n */\n lockSkewingY: false,\n\n /**\n * When `true`, object cannot be flipped by scaling into negative values\n * @type Boolean\n * @default\n */\n lockScalingFlip: false,\n\n /**\n * When `true`, object is not exported in OBJECT/JSON\n * @since 1.6.3\n * @type Boolean\n * @default\n */\n excludeFromExport: false,\n\n /**\n * When `true`, object is cached on an additional canvas.\n * When `false`, object is not cached unless necessary ( clipPath )\n * default to true\n * @since 1.7.0\n * @type Boolean\n * @default true\n */\n objectCaching: objectCaching,\n\n /**\n * When `true`, object properties are checked for cache invalidation. In some particular\n * situation you may want this to be disabled ( spray brush, very big, groups)\n * or if your application does not allow you to modify properties for groups child you want\n * to disable it for groups.\n * default to false\n * since 1.7.0\n * @type Boolean\n * @default false\n */\n statefullCache: false,\n\n /**\n * When `true`, cache does not get updated during scaling. The picture will get blocky if scaled\n * too much and will be redrawn with correct details at the end of scaling.\n * this setting is performance and application dependant.\n * default to true\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n noScaleCache: true,\n\n /**\n * When `false`, the stoke width will scale with the object.\n * When `true`, the stroke will always match the exact pixel size entered for stroke width.\n * default to false\n * @since 2.6.0\n * @type Boolean\n * @default false\n * @type Boolean\n * @default false\n */\n strokeUniform: false,\n\n /**\n * When set to `true`, object's cache will be rerendered next render call.\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n dirty: true,\n\n /**\n * keeps the value of the last hovered corner during mouse move.\n * 0 is no corner, or 'mt', 'ml', 'mtr' etc..\n * It should be private, but there is no harm in using it as\n * a read-only property.\n * @type number|string|any\n * @default 0\n */\n __corner: 0,\n\n /**\n * Determines if the fill or the stroke is drawn first (one of \"fill\" or \"stroke\")\n * @type String\n * @default\n */\n paintFirst: 'fill',\n\n /**\n * List of properties to consider when checking if state\n * of an object is changed (fabric.Object#hasStateChanged)\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: (\n 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' +\n 'stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit ' +\n 'angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor ' +\n 'skewX skewY fillRule paintFirst clipPath strokeUniform'\n ).split(' '),\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single\n * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty\n * and refreshed at the next render\n * @type Array\n */\n cacheProperties: (\n 'fill stroke strokeWidth strokeDashArray width height paintFirst strokeUniform' +\n ' strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath'\n ).split(' '),\n\n /**\n * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n * the clipPath object gets used when the object has rendered, and the context is placed in the center\n * of the object cacheCanvas.\n * If you want 0,0 of a clipPath to align with an object center, use clipPath.originX/Y to 'center'\n * @type fabric.Object\n */\n clipPath: undefined,\n\n /**\n * Meaningful ONLY when the object is used as clipPath.\n * if true, the clipPath will make the object clip to the outside of the clipPath\n * since 2.4.0\n * @type boolean\n * @default false\n */\n inverted: false,\n\n /**\n * Meaningful ONLY when the object is used as clipPath.\n * if true, the clipPath will have its top and left relative to canvas, and will\n * not be influenced by the object transform. This will make the clipPath relative\n * to the canvas, but clipping just a particular object.\n * WARNING this is beta, this feature may change or be renamed.\n * since 2.4.0\n * @type boolean\n * @default false\n */\n absolutePositioned: false,\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n if (options) {\n this.setOptions(options);\n }\n },\n\n /**\n * Create a the canvas used to keep the cached copy of the object\n * @private\n */\n _createCacheCanvas: function() {\n this._cacheProperties = {};\n this._cacheCanvas = fabric.util.createCanvasElement();\n this._cacheContext = this._cacheCanvas.getContext('2d');\n this._updateCacheCanvas();\n // if canvas gets created, is empty, so dirty.\n this.dirty = true;\n },\n\n /**\n * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal\n * and each side do not cross fabric.cacheSideLimit\n * those numbers are configurable so that you can get as much detail as you want\n * making bargain with performances.\n * @param {Object} dims\n * @param {Object} dims.width width of canvas\n * @param {Object} dims.height height of canvas\n * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _limitCacheSize: function(dims) {\n var perfLimitSizeTotal = fabric.perfLimitSizeTotal,\n width = dims.width, height = dims.height,\n max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit;\n if (width <= max && height <= max && width * height <= perfLimitSizeTotal) {\n if (width < min) {\n dims.width = min;\n }\n if (height < min) {\n dims.height = min;\n }\n return dims;\n }\n var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal),\n capValue = fabric.util.capValue,\n x = capValue(min, limitedDims.x, max),\n y = capValue(min, limitedDims.y, max);\n if (width > x) {\n dims.zoomX /= width / x;\n dims.width = x;\n dims.capped = true;\n }\n if (height > y) {\n dims.zoomY /= height / y;\n dims.height = y;\n dims.capped = true;\n }\n return dims;\n },\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @return {Object}.x width of object to be cached\n * @return {Object}.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions: function() {\n var objectScale = this.getTotalObjectScaling(),\n // caculate dimensions without skewing\n dim = this._getTransformedDimensions(0, 0),\n neededX = dim.x * objectScale.scaleX / this.scaleX,\n neededY = dim.y * objectScale.scaleY / this.scaleY;\n return {\n // for sure this ALIASING_LIMIT is slightly creating problem\n // in situation in which the cache canvas gets an upper limit\n // also objectScale contains already scaleX and scaleY\n width: neededX + ALIASING_LIMIT,\n height: neededY + ALIASING_LIMIT,\n zoomX: objectScale.scaleX,\n zoomY: objectScale.scaleY,\n x: neededX,\n y: neededY\n };\n },\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas: function() {\n var targetCanvas = this.canvas;\n if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {\n var target = targetCanvas._currentTransform.target,\n action = targetCanvas._currentTransform.action;\n if (this === target && action.slice && action.slice(0, 5) === 'scale') {\n return false;\n }\n }\n var canvas = this._cacheCanvas,\n dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n minCacheSize = fabric.minCacheSideLimit,\n width = dims.width, height = dims.height, drawingWidth, drawingHeight,\n zoomX = dims.zoomX, zoomY = dims.zoomY,\n dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight,\n zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY,\n shouldRedraw = dimensionsChanged || zoomChanged,\n additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false;\n if (dimensionsChanged) {\n var canvasWidth = this._cacheCanvas.width,\n canvasHeight = this._cacheCanvas.height,\n sizeGrowing = width > canvasWidth || height > canvasHeight,\n sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&\n canvasWidth > minCacheSize && canvasHeight > minCacheSize;\n shouldResizeCanvas = sizeGrowing || sizeShrinking;\n if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) {\n additionalWidth = width * 0.1;\n additionalHeight = height * 0.1;\n }\n }\n if (shouldRedraw) {\n if (shouldResizeCanvas) {\n canvas.width = Math.ceil(width + additionalWidth);\n canvas.height = Math.ceil(height + additionalHeight);\n }\n else {\n this._cacheContext.setTransform(1, 0, 0, 1, 0, 0);\n this._cacheContext.clearRect(0, 0, canvas.width, canvas.height);\n }\n drawingWidth = dims.x / 2;\n drawingHeight = dims.y / 2;\n this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;\n this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;\n this.cacheWidth = width;\n this.cacheHeight = height;\n this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY);\n this._cacheContext.scale(zoomX, zoomY);\n this.zoomX = zoomX;\n this.zoomY = zoomY;\n return true;\n }\n return false;\n },\n\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n setOptions: function(options) {\n this._setOptions(options);\n this._initGradient(options.fill, 'fill');\n this._initGradient(options.stroke, 'stroke');\n this._initClipping(options);\n this._initPattern(options.fill, 'fill');\n this._initPattern(options.stroke, 'stroke');\n },\n\n /**\n * Transforms context when rendering an object\n * @param {CanvasRenderingContext2D} ctx Context\n */\n transform: function(ctx) {\n var m;\n if (this.group && !this.group._transformDone) {\n m = this.calcTransformMatrix();\n }\n else {\n m = this.calcOwnMatrix();\n }\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n },\n\n /**\n * Returns an object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n\n object = {\n type: this.type,\n version: fabric.version,\n originX: this.originX,\n originY: this.originY,\n left: toFixed(this.left, NUM_FRACTION_DIGITS),\n top: toFixed(this.top, NUM_FRACTION_DIGITS),\n width: toFixed(this.width, NUM_FRACTION_DIGITS),\n height: toFixed(this.height, NUM_FRACTION_DIGITS),\n fill: (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill,\n stroke: (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke,\n strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),\n strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray,\n strokeLineCap: this.strokeLineCap,\n strokeDashOffset: this.strokeDashOffset,\n strokeLineJoin: this.strokeLineJoin,\n // TODO: add this before release\n // strokeUniform: this.strokeUniform,\n strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),\n scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS),\n scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS),\n angle: toFixed(this.angle, NUM_FRACTION_DIGITS),\n flipX: this.flipX,\n flipY: this.flipY,\n opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS),\n shadow: (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow,\n visible: this.visible,\n clipTo: this.clipTo && String(this.clipTo),\n backgroundColor: this.backgroundColor,\n fillRule: this.fillRule,\n paintFirst: this.paintFirst,\n globalCompositeOperation: this.globalCompositeOperation,\n transformMatrix: this.transformMatrix ? this.transformMatrix.concat() : null,\n skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS),\n skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS),\n };\n\n if (this.clipPath) {\n object.clipPath = this.clipPath.toObject(propertiesToInclude);\n object.clipPath.inverted = this.clipPath.inverted;\n object.clipPath.absolutePositioned = this.clipPath.absolutePositioned;\n }\n\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n if (!this.includeDefaultValues) {\n object = this._removeDefaultValues(object);\n }\n\n return object;\n },\n\n /**\n * Returns (dataless) object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n // will be overwritten by subclasses\n return this.toObject(propertiesToInclude);\n },\n\n /**\n * @private\n * @param {Object} object\n */\n _removeDefaultValues: function(object) {\n var prototype = fabric.util.getKlass(object.type).prototype,\n stateProperties = prototype.stateProperties;\n stateProperties.forEach(function(prop) {\n if (prop === 'left' || prop === 'top') {\n return;\n }\n if (object[prop] === prototype[prop]) {\n delete object[prop];\n }\n var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' &&\n Object.prototype.toString.call(prototype[prop]) === '[object Array]';\n\n // basically a check for [] === []\n if (isArray && object[prop].length === 0 && prototype[prop].length === 0) {\n delete object[prop];\n }\n });\n\n return object;\n },\n\n /**\n * Returns a string representation of an instance\n * @return {String}\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Return the object scale factor counting also the group scaling\n * @return {Object} object with scaleX and scaleY properties\n */\n getObjectScaling: function() {\n var options = fabric.util.qrDecompose(this.calcTransformMatrix());\n return { scaleX: Math.abs(options.scaleX), scaleY: Math.abs(options.scaleY) };\n },\n\n /**\n * Return the object scale factor counting also the group scaling, zoom and retina\n * @return {Object} object with scaleX and scaleY properties\n */\n getTotalObjectScaling: function() {\n var scale = this.getObjectScaling(), scaleX = scale.scaleX, scaleY = scale.scaleY;\n if (this.canvas) {\n var zoom = this.canvas.getZoom();\n var retina = this.canvas.getRetinaScaling();\n scaleX *= zoom * retina;\n scaleY *= zoom * retina;\n }\n return { scaleX: scaleX, scaleY: scaleY };\n },\n\n /**\n * Return the object opacity counting also the group property\n * @return {Number}\n */\n getObjectOpacity: function() {\n var opacity = this.opacity;\n if (this.group) {\n opacity *= this.group.getObjectOpacity();\n }\n return opacity;\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Object} thisArg\n */\n _set: function(key, value) {\n var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'),\n isChanged = this[key] !== value, groupNeedsUpdate = false;\n\n if (shouldConstrainValue) {\n value = this._constrainScale(value);\n }\n if (key === 'scaleX' && value < 0) {\n this.flipX = !this.flipX;\n value *= -1;\n }\n else if (key === 'scaleY' && value < 0) {\n this.flipY = !this.flipY;\n value *= -1;\n }\n else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) {\n value = new fabric.Shadow(value);\n }\n else if (key === 'dirty' && this.group) {\n this.group.set('dirty', value);\n }\n\n this[key] = value;\n\n if (isChanged) {\n groupNeedsUpdate = this.group && this.group.isOnACache();\n if (this.cacheProperties.indexOf(key) > -1) {\n this.dirty = true;\n groupNeedsUpdate && this.group.set('dirty', true);\n }\n else if (groupNeedsUpdate && this.stateProperties.indexOf(key) > -1) {\n this.group.set('dirty', true);\n }\n }\n\n return this;\n },\n\n /**\n * This callback function is called by the parent group of an object every\n * time a non-delegated property changes on the group. It is passed the key\n * and value as parameters. Not adding in this function's signature to avoid\n * Travis build error about unused variables.\n */\n setOnGroup: function() {\n // implemented by sub-classes, as needed.\n },\n\n /**\n * Retrieves viewportTransform from Object's canvas if possible\n * @method getViewportTransform\n * @memberOf fabric.Object.prototype\n * @return {Array}\n */\n getViewportTransform: function() {\n if (this.canvas && this.canvas.viewportTransform) {\n return this.canvas.viewportTransform;\n }\n return fabric.iMatrix.concat();\n },\n\n /*\n * @private\n * return if the object would be visible in rendering\n * @memberOf fabric.Object.prototype\n * @return {Boolean}\n */\n isNotVisible: function() {\n return this.opacity === 0 ||\n (this.width === 0 && this.height === 0 && this.strokeWidth === 0) ||\n !this.visible;\n },\n\n /**\n * Renders an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render: function(ctx) {\n // do not render if width/height are zeros or object is not visible\n if (this.isNotVisible()) {\n return;\n }\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n ctx.save();\n this._setupCompositeOperation(ctx);\n this.drawSelectionBackground(ctx);\n this.transform(ctx);\n this._setOpacity(ctx);\n this._setShadow(ctx, this);\n if (this.transformMatrix) {\n ctx.transform.apply(ctx, this.transformMatrix);\n }\n this.clipTo && fabric.util.clipContext(this, ctx);\n if (this.shouldCache()) {\n this.renderCache();\n this.drawCacheOnCanvas(ctx);\n }\n else {\n this._removeCacheCanvas();\n this.dirty = false;\n this.drawObject(ctx);\n if (this.objectCaching && this.statefullCache) {\n this.saveState({ propertySet: 'cacheProperties' });\n }\n }\n this.clipTo && ctx.restore();\n ctx.restore();\n },\n\n renderCache: function(options) {\n options = options || {};\n if (!this._cacheCanvas) {\n this._createCacheCanvas();\n }\n if (this.isCacheDirty()) {\n this.statefullCache && this.saveState({ propertySet: 'cacheProperties' });\n this.drawObject(this._cacheContext, options.forClipping);\n this.dirty = false;\n }\n },\n\n /**\n * Remove cacheCanvas and its dimensions from the objects\n */\n _removeCacheCanvas: function() {\n this._cacheCanvas = null;\n this.cacheWidth = 0;\n this.cacheHeight = 0;\n },\n\n /**\n * return true if the object will draw a stroke\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an aproximation and be fast.\n * wrote to avoid extra caching, it has to return true when stroke happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the stroke is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasStroke: function() {\n return this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0;\n },\n\n /**\n * return true if the object will draw a fill\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an aproximation and be fast.\n * wrote to avoid extra caching, it has to return true when fill happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the fill is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasFill: function() {\n return this.fill && this.fill !== 'transparent';\n },\n\n /**\n * When set to `true`, force the object to have its own cache, even if it is inside a group\n * it may be needed when your object behave in a particular way on the cache and always needs\n * its own isolated canvas to render correctly.\n * Created to be overridden\n * since 1.7.12\n * @returns Boolean\n */\n needsItsOwnCache: function() {\n if (this.paintFirst === 'stroke' &&\n this.hasFill() && this.hasStroke() && typeof this.shadow === 'object') {\n return true;\n }\n if (this.clipPath) {\n return true;\n }\n return false;\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * Read as: cache if is needed, or if the feature is enabled but we are not already caching.\n * @return {Boolean}\n */\n shouldCache: function() {\n this.ownCaching = this.needsItsOwnCache() || (\n this.objectCaching &&\n (!this.group || !this.group.isOnACache())\n );\n return this.ownCaching;\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * used by Group.shouldCache to know if child has a shadow recursively\n * @return {Boolean}\n */\n willDrawShadow: function() {\n return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0);\n },\n\n /**\n * Execute the drawing operation for an object clipPath\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawClipPathOnCache: function(ctx) {\n var path = this.clipPath;\n ctx.save();\n // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4\n if (path.inverted) {\n ctx.globalCompositeOperation = 'destination-out';\n }\n else {\n ctx.globalCompositeOperation = 'destination-in';\n }\n //ctx.scale(1 / 2, 1 / 2);\n if (path.absolutePositioned) {\n var m = fabric.util.invertTransform(this.calcTransformMatrix());\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n }\n path.transform(ctx);\n ctx.scale(1 / path.zoomX, 1 / path.zoomY);\n ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);\n ctx.restore();\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawObject: function(ctx, forClipping) {\n var originalFill = this.fill, originalStroke = this.stroke;\n if (forClipping) {\n this.fill = 'black';\n this.stroke = '';\n this._setClippingProperties(ctx);\n }\n else {\n this._renderBackground(ctx);\n this._setStrokeStyles(ctx, this);\n this._setFillStyles(ctx, this);\n }\n this._render(ctx);\n this._drawClipPath(ctx);\n this.fill = originalFill;\n this.stroke = originalStroke;\n },\n\n _drawClipPath: function(ctx) {\n var path = this.clipPath;\n if (!path) { return; }\n // needed to setup a couple of variables\n // path canvas gets overridden with this one.\n // TODO find a better solution?\n path.canvas = this.canvas;\n path.shouldCache();\n path._transformDone = true;\n path.renderCache({ forClipping: true });\n this.drawClipPathOnCache(ctx);\n },\n\n /**\n * Paint the cached copy of the object on the target context.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas: function(ctx) {\n ctx.scale(1 / this.zoomX, 1 / this.zoomY);\n ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY);\n },\n\n /**\n * Check if cache is dirty\n * @param {Boolean} skipCanvas skip canvas checks because this object is painted\n * on parent canvas.\n */\n isCacheDirty: function(skipCanvas) {\n if (this.isNotVisible()) {\n return false;\n }\n if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) {\n // in this case the context is already cleared.\n return true;\n }\n else {\n if (this.dirty ||\n (this.clipPath && this.clipPath.absolutePositioned) ||\n (this.statefullCache && this.hasStateChanged('cacheProperties'))\n ) {\n if (this._cacheCanvas && !skipCanvas) {\n var width = this.cacheWidth / this.zoomX;\n var height = this.cacheHeight / this.zoomY;\n this._cacheContext.clearRect(-width / 2, -height / 2, width, height);\n }\n return true;\n }\n }\n return false;\n },\n\n /**\n * Draws a background for the object big as its untransformed dimensions\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground: function(ctx) {\n if (!this.backgroundColor) {\n return;\n }\n var dim = this._getNonTransformedDimensions();\n ctx.fillStyle = this.backgroundColor;\n\n ctx.fillRect(\n -dim.x / 2,\n -dim.y / 2,\n dim.x,\n dim.y\n );\n // if there is background color no other shadows\n // should be casted\n this._removeShadow(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setOpacity: function(ctx) {\n if (this.group && !this.group._transformDone) {\n ctx.globalAlpha = this.getObjectOpacity();\n }\n else {\n ctx.globalAlpha *= this.opacity;\n }\n },\n\n _setStrokeStyles: function(ctx, decl) {\n if (decl.stroke) {\n ctx.lineWidth = decl.strokeWidth;\n ctx.lineCap = decl.strokeLineCap;\n ctx.lineDashOffset = decl.strokeDashOffset;\n ctx.lineJoin = decl.strokeLineJoin;\n ctx.miterLimit = decl.strokeMiterLimit;\n ctx.strokeStyle = decl.stroke.toLive\n ? decl.stroke.toLive(ctx, this)\n : decl.stroke;\n }\n },\n\n _setFillStyles: function(ctx, decl) {\n if (decl.fill) {\n ctx.fillStyle = decl.fill.toLive\n ? decl.fill.toLive(ctx, this)\n : decl.fill;\n }\n },\n\n _setClippingProperties: function(ctx) {\n ctx.globalAlpha = 1;\n ctx.strokeStyle = 'transparent';\n ctx.fillStyle = '#000000';\n },\n\n /**\n * @private\n * Sets line dash\n * @param {CanvasRenderingContext2D} ctx Context to set the dash line on\n * @param {Array} dashArray array representing dashes\n * @param {Function} alternative function to call if browser does not support lineDash\n */\n _setLineDash: function(ctx, dashArray, alternative) {\n if (!dashArray || dashArray.length === 0) {\n return;\n }\n // Spec requires the concatenation of two copies the dash list when the number of elements is odd\n if (1 & dashArray.length) {\n dashArray.push.apply(dashArray, dashArray);\n }\n if (supportsLineDash) {\n ctx.setLineDash(dashArray);\n }\n else {\n alternative && alternative(ctx);\n }\n },\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [styleOverride] properties to override the object style\n */\n _renderControls: function(ctx, styleOverride) {\n var vpt = this.getViewportTransform(),\n matrix = this.calcTransformMatrix(),\n options, drawBorders, drawControls;\n styleOverride = styleOverride || { };\n drawBorders = typeof styleOverride.hasBorders !== 'undefined' ? styleOverride.hasBorders : this.hasBorders;\n drawControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls;\n matrix = fabric.util.multiplyTransformMatrices(vpt, matrix);\n options = fabric.util.qrDecompose(matrix);\n ctx.save();\n ctx.translate(options.translateX, options.translateY);\n ctx.lineWidth = 1 * this.borderScaleFactor;\n if (!this.group) {\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n }\n if (styleOverride.forActiveSelection) {\n ctx.rotate(degreesToRadians(options.angle));\n drawBorders && this.drawBordersInGroup(ctx, options, styleOverride);\n }\n else {\n ctx.rotate(degreesToRadians(this.angle));\n drawBorders && this.drawBorders(ctx, styleOverride);\n }\n drawControls && this.drawControls(ctx, styleOverride);\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setShadow: function(ctx) {\n if (!this.shadow) {\n return;\n }\n\n var shadow = this.shadow, canvas = this.canvas, scaling,\n multX = (canvas && canvas.viewportTransform[0]) || 1,\n multY = (canvas && canvas.viewportTransform[3]) || 1;\n if (shadow.nonScaling) {\n scaling = { scaleX: 1, scaleY: 1 };\n }\n else {\n scaling = this.getObjectScaling();\n }\n if (canvas && canvas._isRetinaScaling()) {\n multX *= fabric.devicePixelRatio;\n multY *= fabric.devicePixelRatio;\n }\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * fabric.browserShadowBlurConstant *\n (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4;\n ctx.shadowOffsetX = shadow.offsetX * multX * scaling.scaleX;\n ctx.shadowOffsetY = shadow.offsetY * multY * scaling.scaleY;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _removeShadow: function(ctx) {\n if (!this.shadow) {\n return;\n }\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} filler fabric.Pattern or fabric.Gradient\n * @return {Object} offset.offsetX offset for text rendering\n * @return {Object} offset.offsetY offset for text rendering\n */\n _applyPatternGradientTransform: function(ctx, filler) {\n if (!filler || !filler.toLive) {\n return { offsetX: 0, offsetY: 0 };\n }\n var t = filler.gradientTransform || filler.patternTransform;\n var offsetX = -this.width / 2 + filler.offsetX || 0,\n offsetY = -this.height / 2 + filler.offsetY || 0;\n\n if (filler.gradientUnits === 'percentage') {\n ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY);\n }\n else {\n ctx.transform(1, 0, 0, 1, offsetX, offsetY);\n }\n if (t) {\n ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);\n }\n return { offsetX: offsetX, offsetY: offsetY };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderPaintInOrder: function(ctx) {\n if (this.paintFirst === 'stroke') {\n this._renderStroke(ctx);\n this._renderFill(ctx);\n }\n else {\n this._renderFill(ctx);\n this._renderStroke(ctx);\n }\n },\n\n /**\n * @private\n * function that actually render something on the context.\n * empty here to allow Obects to work on tests to benchmark fabric functionalites\n * not related to rendering\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(/* ctx */) {\n\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderFill: function(ctx) {\n if (!this.fill) {\n return;\n }\n\n ctx.save();\n this._applyPatternGradientTransform(ctx, this.fill);\n if (this.fillRule === 'evenodd') {\n ctx.fill('evenodd');\n }\n else {\n ctx.fill();\n }\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderStroke: function(ctx) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n if (this.strokeUniform && this.group) {\n var scaling = this.getObjectScaling();\n ctx.scale(1 / scaling.scaleX, 1 / scaling.scaleY);\n }\n else if (this.strokeUniform) {\n ctx.scale(1 / this.scaleX, 1 / this.scaleY);\n }\n this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);\n if (this.stroke.toLive && this.stroke.gradientUnits === 'percentage') {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n this._applyPatternForTransformedGradient(ctx, this.stroke);\n }\n else {\n this._applyPatternGradientTransform(ctx, this.stroke);\n }\n ctx.stroke();\n ctx.restore();\n },\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drwabacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {fabric.Gradient} filler a fabric gradient instance\n */\n _applyPatternForTransformedGradient: function(ctx, filler) {\n var dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n pCanvas = fabric.util.createCanvasElement(), pCtx, retinaScaling = this.canvas.getRetinaScaling(),\n width = dims.x / this.scaleX / retinaScaling, height = dims.y / this.scaleY / retinaScaling;\n pCanvas.width = width;\n pCanvas.height = height;\n pCtx = pCanvas.getContext('2d');\n pCtx.beginPath(); pCtx.moveTo(0, 0); pCtx.lineTo(width, 0); pCtx.lineTo(width, height);\n pCtx.lineTo(0, height); pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.scale(\n dims.zoomX / this.scaleX / retinaScaling,\n dims.zoomY / this.scaleY / retinaScaling\n );\n this._applyPatternGradientTransform(pCtx, filler);\n pCtx.fillStyle = filler.toLive(ctx);\n pCtx.fill();\n ctx.translate(-this.width / 2 - this.strokeWidth / 2, -this.height / 2 - this.strokeWidth / 2);\n ctx.scale(\n retinaScaling * this.scaleX / dims.zoomX,\n retinaScaling * this.scaleY / dims.zoomY\n );\n ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat');\n },\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Object} center point from element coordinates\n */\n _findCenterFromElement: function() {\n return { x: this.left + this.width / 2, y: this.top + this.height / 2 };\n },\n\n /**\n * This function is an helper for svg import. it decompose the transformMatrix\n * and assign properties to object.\n * untransformed coordinates\n * @private\n * @chainable\n */\n _assignTransformMatrixProps: function() {\n if (this.transformMatrix) {\n var options = fabric.util.qrDecompose(this.transformMatrix);\n this.flipX = false;\n this.flipY = false;\n this.set('scaleX', options.scaleX);\n this.set('scaleY', options.scaleY);\n this.angle = options.angle;\n this.skewX = options.skewX;\n this.skewY = 0;\n }\n },\n\n /**\n * This function is an helper for svg import. it removes the transform matrix\n * and set to object properties that fabricjs can handle\n * @private\n * @param {Object} preserveAspectRatioOptions\n * @return {thisArg}\n */\n _removeTransformMatrix: function(preserveAspectRatioOptions) {\n var center = this._findCenterFromElement();\n if (this.transformMatrix) {\n this._assignTransformMatrixProps();\n center = fabric.util.transformPoint(center, this.transformMatrix);\n }\n this.transformMatrix = null;\n if (preserveAspectRatioOptions) {\n this.scaleX *= preserveAspectRatioOptions.scaleX;\n this.scaleY *= preserveAspectRatioOptions.scaleY;\n this.cropX = preserveAspectRatioOptions.cropX;\n this.cropY = preserveAspectRatioOptions.cropY;\n center.x += preserveAspectRatioOptions.offsetLeft;\n center.y += preserveAspectRatioOptions.offsetTop;\n this.width = preserveAspectRatioOptions.width;\n this.height = preserveAspectRatioOptions.height;\n }\n this.setPositionByOrigin(center, 'center', 'center');\n },\n\n /**\n * Clones an instance, using a callback method will work for every object.\n * @param {Function} callback Callback is invoked with a clone as a first argument\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n */\n clone: function(callback, propertiesToInclude) {\n var objectForm = this.toObject(propertiesToInclude);\n if (this.constructor.fromObject) {\n this.constructor.fromObject(objectForm, callback);\n }\n else {\n fabric.Object._fromObject('Object', objectForm, callback);\n }\n },\n\n /**\n * Creates an instance of fabric.Image out of an object\n * could make use of both toDataUrl or toCanvasElement.\n * @param {Function} callback callback, invoked with an instance as a first argument\n * @param {Object} [options] for clone as image, passed to toDataURL\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {fabric.Object} thisArg\n */\n cloneAsImage: function(callback, options) {\n var canvasEl = this.toCanvasElement(options);\n if (callback) {\n callback(new fabric.Image(canvasEl));\n }\n return this;\n },\n\n /**\n * Converts an object into a HTMLCanvas element\n * @param {Object} options Options object\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {HTMLCanvasElement} Returns DOM element with the fabric.Object\n */\n toCanvasElement: function(options) {\n options || (options = { });\n\n var utils = fabric.util, origParams = utils.saveObjectTransform(this),\n originalGroup = this.group,\n originalShadow = this.shadow, abs = Math.abs,\n multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? fabric.devicePixelRatio : 1);\n delete this.group;\n if (options.withoutTransform) {\n utils.resetObjectTransform(this);\n }\n if (options.withoutShadow) {\n this.shadow = null;\n }\n\n var el = fabric.util.createCanvasElement(),\n // skip canvas zoom and calculate with setCoords now.\n boundingRect = this.getBoundingRect(true, true),\n shadow = this.shadow, scaling,\n shadowOffset = { x: 0, y: 0 }, shadowBlur,\n width, height;\n\n if (shadow) {\n shadowBlur = shadow.blur;\n if (shadow.nonScaling) {\n scaling = { scaleX: 1, scaleY: 1 };\n }\n else {\n scaling = this.getObjectScaling();\n }\n // consider non scaling shadow.\n shadowOffset.x = 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * (abs(scaling.scaleX));\n shadowOffset.y = 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * (abs(scaling.scaleY));\n }\n width = boundingRect.width + shadowOffset.x;\n height = boundingRect.height + shadowOffset.y;\n // if the current width/height is not an integer\n // we need to make it so.\n el.width = Math.ceil(width);\n el.height = Math.ceil(height);\n var canvas = new fabric.StaticCanvas(el, {\n enableRetinaScaling: false,\n renderOnAddRemove: false,\n skipOffscreen: false,\n });\n if (options.format === 'jpeg') {\n canvas.backgroundColor = '#fff';\n }\n this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center');\n\n var originalCanvas = this.canvas;\n canvas.add(this);\n var canvasEl = canvas.toCanvasElement(multiplier || 1, options);\n this.shadow = originalShadow;\n this.set('canvas', originalCanvas);\n if (originalGroup) {\n this.group = originalGroup;\n }\n this.set(origParams).setCoords();\n // canvas.dispose will call image.dispose that will nullify the elements\n // since this canvas is a simple element for the process, we remove references\n // to objects in this way in order to avoid object trashing.\n canvas._objects = [];\n canvas.dispose();\n canvas = null;\n\n return canvasEl;\n },\n\n /**\n * Converts an object into a data-url-like string\n * @param {Object} options Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n */\n toDataURL: function(options) {\n options || (options = { });\n return fabric.util.toDataURL(this.toCanvasElement(options), options.format || 'png', options.quality || 1);\n },\n\n /**\n * Returns true if specified type is identical to the type of an instance\n * @param {String} type Type to check against\n * @return {Boolean}\n */\n isType: function(type) {\n return this.type === type;\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance (is 1 unless subclassed)\n */\n complexity: function() {\n return 1;\n },\n\n /**\n * Returns a JSON representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} JSON\n */\n toJSON: function(propertiesToInclude) {\n // delegate, not alias\n return this.toObject(propertiesToInclude);\n },\n\n /**\n * Sets gradient (fill or stroke) of an object\n * percentages for x1,x2,y1,y2,r1,r2 together with gradientUnits 'pixels', are not supported.\n * Backwards incompatibility note: This method was named \"setGradientFill\" until v1.1.0\n * @param {String} property Property name 'stroke' or 'fill'\n * @param {Object} [options] Options object\n * @param {String} [options.type] Type of gradient 'radial' or 'linear'\n * @param {Number} [options.x1=0] x-coordinate of start point\n * @param {Number} [options.y1=0] y-coordinate of start point\n * @param {Number} [options.x2=0] x-coordinate of end point\n * @param {Number} [options.y2=0] y-coordinate of end point\n * @param {Number} [options.r1=0] Radius of start point (only for radial gradients)\n * @param {Number} [options.r2=0] Radius of end point (only for radial gradients)\n * @param {Object} [options.colorStops] Color stops object eg. {0: 'ff0000', 1: '000000'}\n * @param {Object} [options.gradientTransform] transformMatrix for gradient\n * @return {fabric.Object} thisArg\n * @chainable\n * @deprecated since 3.4.0\n * @see {@link http://jsfiddle.net/fabricjs/58y8b/|jsFiddle demo}\n * @example Set linear gradient\n * object.setGradient('fill', {\n * type: 'linear',\n * x1: -object.width / 2,\n * y1: 0,\n * x2: object.width / 2,\n * y2: 0,\n * colorStops: {\n * 0: 'red',\n * 0.5: '#005555',\n * 1: 'rgba(0,0,255,0.5)'\n * }\n * });\n * canvas.renderAll();\n * @example Set radial gradient\n * object.setGradient('fill', {\n * type: 'radial',\n * x1: 0,\n * y1: 0,\n * x2: 0,\n * y2: 0,\n * r1: object.width / 2,\n * r2: 10,\n * colorStops: {\n * 0: 'red',\n * 0.5: '#005555',\n * 1: 'rgba(0,0,255,0.5)'\n * }\n * });\n * canvas.renderAll();\n */\n setGradient: function(property, options) {\n options || (options = { });\n\n var gradient = { colorStops: [] };\n\n gradient.type = options.type || (options.r1 || options.r2 ? 'radial' : 'linear');\n gradient.coords = {\n x1: options.x1,\n y1: options.y1,\n x2: options.x2,\n y2: options.y2\n };\n gradient.gradientUnits = options.gradientUnits || 'pixels';\n if (options.r1 || options.r2) {\n gradient.coords.r1 = options.r1;\n gradient.coords.r2 = options.r2;\n }\n\n gradient.gradientTransform = options.gradientTransform;\n fabric.Gradient.prototype.addColorStop.call(gradient, options.colorStops);\n\n return this.set(property, fabric.Gradient.forObject(this, gradient));\n },\n\n /**\n * Sets pattern fill of an object\n * @param {Object} options Options object\n * @param {(String|HTMLImageElement)} options.source Pattern source\n * @param {String} [options.repeat=repeat] Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)\n * @param {Number} [options.offsetX=0] Pattern horizontal offset from object's left/top corner\n * @param {Number} [options.offsetY=0] Pattern vertical offset from object's left/top corner\n * @param {Function} [callback] Callback to invoke when image set as a pattern\n * @return {fabric.Object} thisArg\n * @chainable\n * @deprecated since 3.5.0\n * @see {@link http://jsfiddle.net/fabricjs/QT3pa/|jsFiddle demo}\n * @example Set pattern\n * object.setPatternFill({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png',\n * repeat: 'repeat'\n * },canvas.renderAll.bind(canvas));\n */\n setPatternFill: function(options, callback) {\n return this.set('fill', new fabric.Pattern(options, callback));\n },\n\n /**\n * Sets {@link fabric.Object#shadow|shadow} of an object\n * @param {Object|String} [options] Options object or string (e.g. \"2px 2px 10px rgba(0,0,0,0.2)\")\n * @param {String} [options.color=rgb(0,0,0)] Shadow color\n * @param {Number} [options.blur=0] Shadow blur\n * @param {Number} [options.offsetX=0] Shadow horizontal offset\n * @param {Number} [options.offsetY=0] Shadow vertical offset\n * @return {fabric.Object} thisArg\n * @chainable\n * @deprecated since 3.5.0\n * @see {@link http://jsfiddle.net/fabricjs/7gvJG/|jsFiddle demo}\n * @example Set shadow with string notation\n * object.setShadow('2px 2px 10px rgba(0,0,0,0.2)');\n * canvas.renderAll();\n * @example Set shadow with object notation\n * object.setShadow({\n * color: 'red',\n * blur: 10,\n * offsetX: 20,\n * offsetY: 20\n * });\n * canvas.renderAll();\n */\n setShadow: function(options) {\n return this.set('shadow', options ? new fabric.Shadow(options) : null);\n },\n\n /**\n * Sets \"color\" of an instance (alias of `set('fill', …)`)\n * @param {String} color Color value\n * @return {fabric.Object} thisArg\n * @deprecated since 3.5.0\n * @chainable\n */\n setColor: function(color) {\n this.set('fill', color);\n return this;\n },\n\n /**\n * Sets \"angle\" of an instance with centered rotation\n * @param {Number} angle Angle value (in degrees)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n rotate: function(angle) {\n var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation;\n\n if (shouldCenterOrigin) {\n this._setOriginToCenter();\n }\n\n this.set('angle', angle);\n\n if (shouldCenterOrigin) {\n this._resetOrigin();\n }\n\n return this;\n },\n\n /**\n * Centers object horizontally on canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n centerH: function () {\n this.canvas && this.canvas.centerObjectH(this);\n return this;\n },\n\n /**\n * Centers object horizontally on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenterH: function () {\n this.canvas && this.canvas.viewportCenterObjectH(this);\n return this;\n },\n\n /**\n * Centers object vertically on canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n centerV: function () {\n this.canvas && this.canvas.centerObjectV(this);\n return this;\n },\n\n /**\n * Centers object vertically on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenterV: function () {\n this.canvas && this.canvas.viewportCenterObjectV(this);\n return this;\n },\n\n /**\n * Centers object vertically and horizontally on canvas to which is was added last\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n center: function () {\n this.canvas && this.canvas.centerObject(this);\n return this;\n },\n\n /**\n * Centers object on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenter: function () {\n this.canvas && this.canvas.viewportCenterObject(this);\n return this;\n },\n\n /**\n * Returns coordinates of a pointer relative to an object\n * @param {Event} e Event to operate upon\n * @param {Object} [pointer] Pointer to operate upon (instead of event)\n * @return {Object} Coordinates of a pointer (x, y)\n */\n getLocalPointer: function(e, pointer) {\n pointer = pointer || this.canvas.getPointer(e);\n var pClicked = new fabric.Point(pointer.x, pointer.y),\n objectLeftTop = this._getLeftTopCoords();\n if (this.angle) {\n pClicked = fabric.util.rotatePoint(\n pClicked, objectLeftTop, degreesToRadians(-this.angle));\n }\n return {\n x: pClicked.x - objectLeftTop.x,\n y: pClicked.y - objectLeftTop.y\n };\n },\n\n /**\n * Sets canvas globalCompositeOperation for specific object\n * custom composition operation for the particular object can be specified using globalCompositeOperation property\n * @param {CanvasRenderingContext2D} ctx Rendering canvas context\n */\n _setupCompositeOperation: function (ctx) {\n if (this.globalCompositeOperation) {\n ctx.globalCompositeOperation = this.globalCompositeOperation;\n }\n }\n });\n\n fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object);\n\n extend(fabric.Object.prototype, fabric.Observable);\n\n /**\n * Defines the number of fraction digits to use when serializing object values.\n * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.\n * @static\n * @memberOf fabric.Object\n * @constant\n * @type Number\n */\n fabric.Object.NUM_FRACTION_DIGITS = 2;\n\n fabric.Object._fromObject = function(className, object, callback, extraParam) {\n var klass = fabric[className];\n object = clone(object, true);\n fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) {\n if (typeof patterns[0] !== 'undefined') {\n object.fill = patterns[0];\n }\n if (typeof patterns[1] !== 'undefined') {\n object.stroke = patterns[1];\n }\n fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {\n object.clipPath = enlivedProps[0];\n var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);\n callback && callback(instance);\n });\n });\n };\n\n /**\n * Unique id used internally when creating SVG elements\n * @static\n * @memberOf fabric.Object\n * @type Number\n */\n fabric.Object.__uid = 0;\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n var degreesToRadians = fabric.util.degreesToRadians,\n originXOffset = {\n left: -0.5,\n center: 0,\n right: 0.5\n },\n originYOffset = {\n top: -0.5,\n center: 0,\n bottom: 0.5\n };\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Translates the coordinates from a set of origin to another (based on the object's dimensions)\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @param {String} fromOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} fromOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @param {String} toOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} toOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) {\n var x = point.x,\n y = point.y,\n offsetX, offsetY, dim;\n\n if (typeof fromOriginX === 'string') {\n fromOriginX = originXOffset[fromOriginX];\n }\n else {\n fromOriginX -= 0.5;\n }\n\n if (typeof toOriginX === 'string') {\n toOriginX = originXOffset[toOriginX];\n }\n else {\n toOriginX -= 0.5;\n }\n\n offsetX = toOriginX - fromOriginX;\n\n if (typeof fromOriginY === 'string') {\n fromOriginY = originYOffset[fromOriginY];\n }\n else {\n fromOriginY -= 0.5;\n }\n\n if (typeof toOriginY === 'string') {\n toOriginY = originYOffset[toOriginY];\n }\n else {\n toOriginY -= 0.5;\n }\n\n offsetY = toOriginY - fromOriginY;\n\n if (offsetX || offsetY) {\n dim = this._getTransformedDimensions();\n x = point.x + offsetX * dim.x;\n y = point.y + offsetY * dim.y;\n }\n\n return new fabric.Point(x, y);\n },\n\n /**\n * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToCenterPoint: function(point, originX, originY) {\n var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center');\n if (this.angle) {\n return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle));\n }\n return p;\n },\n\n /**\n * Translates the coordinates from center to origin coordinates (based on the object's dimensions)\n * @param {fabric.Point} center The point which corresponds to center of the object\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToOriginPoint: function(center, originX, originY) {\n var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n if (this.angle) {\n return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle));\n }\n return p;\n },\n\n /**\n * Returns the real center coordinates of the object\n * @return {fabric.Point}\n */\n getCenterPoint: function() {\n var leftTop = new fabric.Point(this.left, this.top);\n return this.translateToCenterPoint(leftTop, this.originX, this.originY);\n },\n\n /**\n * Returns the coordinates of the object based on center coordinates\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @return {fabric.Point}\n */\n // getOriginPoint: function(center) {\n // return this.translateToOriginPoint(center, this.originX, this.originY);\n // },\n\n /**\n * Returns the coordinates of the object as if it has a different origin\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n getPointByOrigin: function(originX, originY) {\n var center = this.getCenterPoint();\n return this.translateToOriginPoint(center, originX, originY);\n },\n\n /**\n * Returns the point in local coordinates\n * @param {fabric.Point} point The point relative to the global coordinate system\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n toLocalPoint: function(point, originX, originY) {\n var center = this.getCenterPoint(),\n p, p2;\n\n if (typeof originX !== 'undefined' && typeof originY !== 'undefined' ) {\n p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n }\n else {\n p = new fabric.Point(this.left, this.top);\n }\n\n p2 = new fabric.Point(point.x, point.y);\n if (this.angle) {\n p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle));\n }\n return p2.subtractEquals(p);\n },\n\n /**\n * Returns the point in global coordinates\n * @param {fabric.Point} The point relative to the local coordinate system\n * @return {fabric.Point}\n */\n // toGlobalPoint: function(point) {\n // return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top));\n // },\n\n /**\n * Sets the position of the object taking into consideration the object's origin\n * @param {fabric.Point} pos The new position of the object\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {void}\n */\n setPositionByOrigin: function(pos, originX, originY) {\n var center = this.translateToCenterPoint(pos, originX, originY),\n position = this.translateToOriginPoint(center, this.originX, this.originY);\n this.set('left', position.x);\n this.set('top', position.y);\n },\n\n /**\n * @param {String} to One of 'left', 'center', 'right'\n */\n adjustPosition: function(to) {\n var angle = degreesToRadians(this.angle),\n hypotFull = this.getScaledWidth(),\n xFull = fabric.util.cos(angle) * hypotFull,\n yFull = fabric.util.sin(angle) * hypotFull,\n offsetFrom, offsetTo;\n\n //TODO: this function does not consider mixed situation like top, center.\n if (typeof this.originX === 'string') {\n offsetFrom = originXOffset[this.originX];\n }\n else {\n offsetFrom = this.originX - 0.5;\n }\n if (typeof to === 'string') {\n offsetTo = originXOffset[to];\n }\n else {\n offsetTo = to - 0.5;\n }\n this.left += xFull * (offsetTo - offsetFrom);\n this.top += yFull * (offsetTo - offsetFrom);\n this.setCoords();\n this.originX = to;\n },\n\n /**\n * Sets the origin/position of the object to it's center point\n * @private\n * @return {void}\n */\n _setOriginToCenter: function() {\n this._originalOriginX = this.originX;\n this._originalOriginY = this.originY;\n\n var center = this.getCenterPoint();\n\n this.originX = 'center';\n this.originY = 'center';\n\n this.left = center.x;\n this.top = center.y;\n },\n\n /**\n * Resets the origin/position of the object to it's original origin\n * @private\n * @return {void}\n */\n _resetOrigin: function() {\n var originPoint = this.translateToOriginPoint(\n this.getCenterPoint(),\n this._originalOriginX,\n this._originalOriginY);\n\n this.originX = this._originalOriginX;\n this.originY = this._originalOriginY;\n\n this.left = originPoint.x;\n this.top = originPoint.y;\n\n this._originalOriginX = null;\n this._originalOriginY = null;\n },\n\n /**\n * @private\n */\n _getLeftTopCoords: function() {\n return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top');\n },\n });\n\n})();\n\n\n(function() {\n\n function getCoords(coords) {\n return [\n new fabric.Point(coords.tl.x, coords.tl.y),\n new fabric.Point(coords.tr.x, coords.tr.y),\n new fabric.Point(coords.br.x, coords.br.y),\n new fabric.Point(coords.bl.x, coords.bl.y)\n ];\n }\n\n var degreesToRadians = fabric.util.degreesToRadians,\n multiplyMatrices = fabric.util.multiplyTransformMatrices,\n transformPoint = fabric.util.transformPoint;\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Describe object's corner position in canvas element coordinates.\n * properties are tl,mt,tr,ml,mr,bl,mb,br,mtr for the main controls.\n * each property is an object with x, y and corner.\n * The `corner` property contains in a similar manner the 4 points of the\n * interactive area of the corner.\n * The coordinates depends from this properties: width, height, scaleX, scaleY\n * skewX, skewY, angle, strokeWidth, viewportTransform, top, left, padding.\n * The coordinates get updated with @method setCoords.\n * You can calculate them without updating with @method calcCoords;\n * @memberOf fabric.Object.prototype\n */\n oCoords: null,\n\n /**\n * Describe object's corner position in canvas object absolute coordinates\n * properties are tl,tr,bl,br and describe the four main corner.\n * each property is an object with x, y, instance of Fabric.Point.\n * The coordinates depends from this properties: width, height, scaleX, scaleY\n * skewX, skewY, angle, strokeWidth, top, left.\n * Those coordinates are useful to understand where an object is. They get updated\n * with oCoords but they do not need to be updated when zoom or panning change.\n * The coordinates get updated with @method setCoords.\n * You can calculate them without updating with @method calcCoords(true);\n * @memberOf fabric.Object.prototype\n */\n aCoords: null,\n\n /**\n * storage for object transform matrix\n */\n ownMatrixCache: null,\n\n /**\n * storage for object full transform matrix\n */\n matrixCache: null,\n\n /**\n * return correct set of coordinates for intersection\n */\n getCoords: function(absolute, calculate) {\n if (!this.oCoords) {\n this.setCoords();\n }\n var coords = absolute ? this.aCoords : this.oCoords;\n return getCoords(calculate ? this.calcCoords(absolute) : coords);\n },\n\n /**\n * Checks if object intersects with an area formed by 2 points\n * @param {Object} pointTL top-left point of area\n * @param {Object} pointBR bottom-right point of area\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object intersects with an area formed by 2 points\n */\n intersectsWithRect: function(pointTL, pointBR, absolute, calculate) {\n var coords = this.getCoords(absolute, calculate),\n intersection = fabric.Intersection.intersectPolygonRectangle(\n coords,\n pointTL,\n pointBR\n );\n return intersection.status === 'Intersection';\n },\n\n /**\n * Checks if object intersects with another object\n * @param {Object} other Object to test\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object intersects with another object\n */\n intersectsWithObject: function(other, absolute, calculate) {\n var intersection = fabric.Intersection.intersectPolygonPolygon(\n this.getCoords(absolute, calculate),\n other.getCoords(absolute, calculate)\n );\n\n return intersection.status === 'Intersection'\n || other.isContainedWithinObject(this, absolute, calculate)\n || this.isContainedWithinObject(other, absolute, calculate);\n },\n\n /**\n * Checks if object is fully contained within area of another object\n * @param {Object} other Object to test\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within area of another object\n */\n isContainedWithinObject: function(other, absolute, calculate) {\n var points = this.getCoords(absolute, calculate),\n i = 0, lines = other._getImageLines(\n calculate ? other.calcCoords(absolute) : absolute ? other.aCoords : other.oCoords\n );\n for (; i < 4; i++) {\n if (!other.containsPoint(points[i], lines)) {\n return false;\n }\n }\n return true;\n },\n\n /**\n * Checks if object is fully contained within area formed by 2 points\n * @param {Object} pointTL top-left point of area\n * @param {Object} pointBR bottom-right point of area\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within area formed by 2 points\n */\n isContainedWithinRect: function(pointTL, pointBR, absolute, calculate) {\n var boundingRect = this.getBoundingRect(absolute, calculate);\n\n return (\n boundingRect.left >= pointTL.x &&\n boundingRect.left + boundingRect.width <= pointBR.x &&\n boundingRect.top >= pointTL.y &&\n boundingRect.top + boundingRect.height <= pointBR.y\n );\n },\n\n /**\n * Checks if point is inside the object\n * @param {fabric.Point} point Point to check against\n * @param {Object} [lines] object returned from @method _getImageLines\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if point is inside the object\n */\n containsPoint: function(point, lines, absolute, calculate) {\n var lines = lines || this._getImageLines(\n calculate ? this.calcCoords(absolute) : absolute ? this.aCoords : this.oCoords\n ),\n xPoints = this._findCrossPoints(point, lines);\n\n // if xPoints is odd then point is inside the object\n return (xPoints !== 0 && xPoints % 2 === 1);\n },\n\n /**\n * Checks if object is contained within the canvas with current viewportTransform\n * the check is done stopping at first point that appears on screen\n * @param {Boolean} [calculate] use coordinates of current position instead of .aCoords\n * @return {Boolean} true if object is fully or partially contained within canvas\n */\n isOnScreen: function(calculate) {\n if (!this.canvas) {\n return false;\n }\n var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;\n var points = this.getCoords(true, calculate), point;\n for (var i = 0; i < 4; i++) {\n point = points[i];\n if (point.x <= pointBR.x && point.x >= pointTL.x && point.y <= pointBR.y && point.y >= pointTL.y) {\n return true;\n }\n }\n // no points on screen, check intersection with absolute coordinates\n if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n return true;\n }\n return this._containsCenterOfCanvas(pointTL, pointBR, calculate);\n },\n\n /**\n * Checks if the object contains the midpoint between canvas extremities\n * Does not make sense outside the context of isOnScreen and isPartiallyOnScreen\n * @private\n * @param {Fabric.Point} pointTL Top Left point\n * @param {Fabric.Point} pointBR Top Right point\n * @param {Boolean} calculate use coordinates of current position instead of .oCoords\n * @return {Boolean} true if the object contains the point\n */\n _containsCenterOfCanvas: function(pointTL, pointBR, calculate) {\n // worst case scenario the object is so big that contains the screen\n var centerPoint = { x: (pointTL.x + pointBR.x) / 2, y: (pointTL.y + pointBR.y) / 2 };\n if (this.containsPoint(centerPoint, null, true, calculate)) {\n return true;\n }\n return false;\n },\n\n /**\n * Checks if object is partially contained within the canvas with current viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is partially contained within canvas\n */\n isPartiallyOnScreen: function(calculate) {\n if (!this.canvas) {\n return false;\n }\n var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;\n if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n return true;\n }\n return this._containsCenterOfCanvas(pointTL, pointBR, calculate);\n },\n\n /**\n * Method that returns an object with the object edges in it, given the coordinates of the corners\n * @private\n * @param {Object} oCoords Coordinates of the object corners\n */\n _getImageLines: function(oCoords) {\n return {\n topline: {\n o: oCoords.tl,\n d: oCoords.tr\n },\n rightline: {\n o: oCoords.tr,\n d: oCoords.br\n },\n bottomline: {\n o: oCoords.br,\n d: oCoords.bl\n },\n leftline: {\n o: oCoords.bl,\n d: oCoords.tl\n }\n };\n },\n\n /**\n * Helper method to determine how many cross points are between the 4 object edges\n * and the horizontal line determined by a point on canvas\n * @private\n * @param {fabric.Point} point Point to check\n * @param {Object} lines Coordinates of the object being evaluated\n */\n // remove yi, not used but left code here just in case.\n _findCrossPoints: function(point, lines) {\n var b1, b2, a1, a2, xi, // yi,\n xcount = 0,\n iLine;\n\n for (var lineKey in lines) {\n iLine = lines[lineKey];\n // optimisation 1: line below point. no cross\n if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) {\n continue;\n }\n // optimisation 2: line above point. no cross\n if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) {\n continue;\n }\n // optimisation 3: vertical line case\n if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) {\n xi = iLine.o.x;\n // yi = point.y;\n }\n // calculate the intersection point\n else {\n b1 = 0;\n b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x);\n a1 = point.y - b1 * point.x;\n a2 = iLine.o.y - b2 * iLine.o.x;\n\n xi = -(a1 - a2) / (b1 - b2);\n // yi = a1 + b1 * xi;\n }\n // dont count xi < point.x cases\n if (xi >= point.x) {\n xcount += 1;\n }\n // optimisation 4: specific for square images\n if (xcount === 2) {\n break;\n }\n }\n return xcount;\n },\n\n /**\n * Returns coordinates of object's bounding rectangle (left, top, width, height)\n * the box is intended as aligned to axis of canvas.\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords / .aCoords\n * @return {Object} Object with left, top, width, height properties\n */\n getBoundingRect: function(absolute, calculate) {\n var coords = this.getCoords(absolute, calculate);\n return fabric.util.makeBoundingBoxFromPoints(coords);\n },\n\n /**\n * Returns width of an object's bounding box counting transformations\n * before 2.0 it was named getWidth();\n * @return {Number} width value\n */\n getScaledWidth: function() {\n return this._getTransformedDimensions().x;\n },\n\n /**\n * Returns height of an object bounding box counting transformations\n * before 2.0 it was named getHeight();\n * @return {Number} height value\n */\n getScaledHeight: function() {\n return this._getTransformedDimensions().y;\n },\n\n /**\n * Makes sure the scale is valid and modifies it if necessary\n * @private\n * @param {Number} value\n * @return {Number}\n */\n _constrainScale: function(value) {\n if (Math.abs(value) < this.minScaleLimit) {\n if (value < 0) {\n return -this.minScaleLimit;\n }\n else {\n return this.minScaleLimit;\n }\n }\n else if (value === 0) {\n return 0.0001;\n }\n return value;\n },\n\n /**\n * Scales an object (equally by x and y)\n * @param {Number} value Scale factor\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scale: function(value) {\n this._set('scaleX', value);\n this._set('scaleY', value);\n return this.setCoords();\n },\n\n /**\n * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New width value\n * @param {Boolean} absolute ignore viewport\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scaleToWidth: function(value, absolute) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n var boundingRectFactor = this.getBoundingRect(absolute).width / this.getScaledWidth();\n return this.scale(value / this.width / boundingRectFactor);\n },\n\n /**\n * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New height value\n * @param {Boolean} absolute ignore viewport\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scaleToHeight: function(value, absolute) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n var boundingRectFactor = this.getBoundingRect(absolute).height / this.getScaledHeight();\n return this.scale(value / this.height / boundingRectFactor);\n },\n\n /**\n * Calculates and returns the .coords of an object.\n * @return {Object} Object with tl, tr, br, bl ....\n * @chainable\n */\n calcCoords: function(absolute) {\n var rotateMatrix = this._calcRotateMatrix(),\n translateMatrix = this._calcTranslateMatrix(),\n startMatrix = multiplyMatrices(translateMatrix, rotateMatrix),\n vpt = this.getViewportTransform(),\n finalMatrix = absolute ? startMatrix : multiplyMatrices(vpt, startMatrix),\n dim = this._getTransformedDimensions(),\n w = dim.x / 2, h = dim.y / 2,\n tl = transformPoint({ x: -w, y: -h }, finalMatrix),\n tr = transformPoint({ x: w, y: -h }, finalMatrix),\n bl = transformPoint({ x: -w, y: h }, finalMatrix),\n br = transformPoint({ x: w, y: h }, finalMatrix);\n if (!absolute) {\n var padding = this.padding, angle = degreesToRadians(this.angle),\n cos = fabric.util.cos(angle), sin = fabric.util.sin(angle),\n cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP,\n cosPMinusSinP = cosP - sinP;\n if (padding) {\n tl.x -= cosPMinusSinP;\n tl.y -= cosPSinP;\n tr.x += cosPSinP;\n tr.y -= cosPMinusSinP;\n bl.x -= cosPSinP;\n bl.y += cosPMinusSinP;\n br.x += cosPMinusSinP;\n br.y += cosPSinP;\n }\n var ml = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2),\n mt = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2),\n mr = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2),\n mb = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2),\n mtr = new fabric.Point(mt.x + sin * this.rotatingPointOffset, mt.y - cos * this.rotatingPointOffset);\n }\n\n // if (!absolute) {\n // var canvas = this.canvas;\n // setTimeout(function() {\n // canvas.contextTop.clearRect(0, 0, 700, 700);\n // canvas.contextTop.fillStyle = 'green';\n // canvas.contextTop.fillRect(mb.x, mb.y, 3, 3);\n // canvas.contextTop.fillRect(bl.x, bl.y, 3, 3);\n // canvas.contextTop.fillRect(br.x, br.y, 3, 3);\n // canvas.contextTop.fillRect(tl.x, tl.y, 3, 3);\n // canvas.contextTop.fillRect(tr.x, tr.y, 3, 3);\n // canvas.contextTop.fillRect(ml.x, ml.y, 3, 3);\n // canvas.contextTop.fillRect(mr.x, mr.y, 3, 3);\n // canvas.contextTop.fillRect(mt.x, mt.y, 3, 3);\n // canvas.contextTop.fillRect(mtr.x, mtr.y, 3, 3);\n // }, 50);\n // }\n\n var coords = {\n // corners\n tl: tl, tr: tr, br: br, bl: bl,\n };\n if (!absolute) {\n // middle\n coords.ml = ml;\n coords.mt = mt;\n coords.mr = mr;\n coords.mb = mb;\n // rotating point\n coords.mtr = mtr;\n }\n return coords;\n },\n\n /**\n * Sets corner position coordinates based on current angle, width and height.\n * See {@link https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords|When-to-call-setCoords}\n * @param {Boolean} [ignoreZoom] set oCoords with or without the viewport transform.\n * @param {Boolean} [skipAbsolute] skip calculation of aCoords, useful in setViewportTransform\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setCoords: function(ignoreZoom, skipAbsolute) {\n this.oCoords = this.calcCoords(ignoreZoom);\n if (!skipAbsolute) {\n this.aCoords = this.calcCoords(true);\n }\n\n // set coordinates of the draggable boxes in the corners used to scale/rotate the image\n ignoreZoom || (this._setCornerCoords && this._setCornerCoords());\n\n return this;\n },\n\n /**\n * calculate rotation matrix of an object\n * @return {Array} rotation matrix for the object\n */\n _calcRotateMatrix: function() {\n return fabric.util.calcRotateMatrix(this);\n },\n\n /**\n * calculate the translation matrix for an object transform\n * @return {Array} rotation matrix for the object\n */\n _calcTranslateMatrix: function() {\n var center = this.getCenterPoint();\n return [1, 0, 0, 1, center.x, center.y];\n },\n\n transformMatrixKey: function(skipGroup) {\n var sep = '_', prefix = '';\n if (!skipGroup && this.group) {\n prefix = this.group.transformMatrixKey(skipGroup) + sep;\n };\n return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY +\n sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.originX + sep + this.originY +\n sep + this.width + sep + this.height + sep + this.strokeWidth + this.flipX + this.flipY;\n },\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties.\n * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations\n * @return {Array} transform matrix for the object\n */\n calcTransformMatrix: function(skipGroup) {\n if (skipGroup) {\n return this.calcOwnMatrix();\n }\n var key = this.transformMatrixKey(), cache = this.matrixCache || (this.matrixCache = {});\n if (cache.key === key) {\n return cache.value;\n }\n var matrix = this.calcOwnMatrix();\n if (this.group) {\n matrix = multiplyMatrices(this.group.calcTransformMatrix(), matrix);\n }\n cache.key = key;\n cache.value = matrix;\n return matrix;\n },\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties, this matrix does not include the group transformation\n * @return {Array} transform matrix for the object\n */\n calcOwnMatrix: function() {\n var key = this.transformMatrixKey(true), cache = this.ownMatrixCache || (this.ownMatrixCache = {});\n if (cache.key === key) {\n return cache.value;\n }\n var tMatrix = this._calcTranslateMatrix();\n this.translateX = tMatrix[4];\n this.translateY = tMatrix[5];\n cache.key = key;\n cache.value = fabric.util.composeMatrix(this);\n return cache.value;\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n * @deprecated since 3.4.0, please use fabric.util._calcDimensionsTransformMatrix\n * not including or including flipX, flipY to emulate the flipping boolean\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) {\n return fabric.util.calcDimensionsMatrix({\n skewX: skewX,\n skewY: skewY,\n scaleX: this.scaleX * (flipping && this.flipX ? -1 : 1),\n scaleY: this.scaleY * (flipping && this.flipY ? -1 : 1)\n });\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _getNonTransformedDimensions: function() {\n var strokeWidth = this.strokeWidth,\n w = this.width + strokeWidth,\n h = this.height + strokeWidth;\n return { x: w, y: h };\n },\n\n /*\n * Calculate object bounding box dimensions from its properties scale, skew.\n * The skewX and skewY parameters are used in the skewing logic path and\n * do not provide something useful to common use cases.\n * @param {Number} [skewX], a value to override current skewX\n * @param {Number} [skewY], a value to override current skewY\n * @private\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _getTransformedDimensions: function(skewX, skewY) {\n if (typeof skewX === 'undefined') {\n skewX = this.skewX;\n }\n if (typeof skewY === 'undefined') {\n skewY = this.skewY;\n }\n var dimensions = this._getNonTransformedDimensions(), dimX, dimY,\n noSkew = skewX === 0 && skewY === 0;\n\n if (this.strokeUniform) {\n dimX = this.width;\n dimY = this.height;\n }\n else {\n dimX = dimensions.x;\n dimY = dimensions.y;\n }\n if (noSkew) {\n return this._finalizeDimensions(dimX * this.scaleX, dimY * this.scaleY);\n }\n else {\n dimX /= 2;\n dimY /= 2;\n }\n var points = [\n {\n x: -dimX,\n y: -dimY\n },\n {\n x: dimX,\n y: -dimY\n },\n {\n x: -dimX,\n y: dimY\n },\n {\n x: dimX,\n y: dimY\n }],\n transformMatrix = fabric.util.calcDimensionsMatrix({\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: skewX,\n skewY: skewY,\n }),\n bbox = fabric.util.makeBoundingBoxFromPoints(points, transformMatrix);\n return this._finalizeDimensions(bbox.width, bbox.height);\n },\n\n /*\n * Calculate object bounding box dimensions from its properties scale, skew.\n * @param Number width width of the bbox\n * @param Number height height of the bbox\n * @private\n * @return {Object} .x finalized width dimension\n * @return {Object} .y finalized height dimension\n */\n _finalizeDimensions: function(width, height) {\n return this.strokeUniform ?\n { x: width + this.strokeWidth, y: height + this.strokeWidth }\n :\n { x: width, y: height };\n },\n /*\n * Calculate object dimensions for controls, including padding and canvas zoom.\n * private\n */\n _calculateCurrentDimensions: function() {\n var vpt = this.getViewportTransform(),\n dim = this._getTransformedDimensions(),\n p = fabric.util.transformPoint(dim, vpt, true);\n\n return p.scalarAdd(2 * this.padding);\n },\n });\n})();\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Moves an object to the bottom of the stack of drawn objects\n * @return {fabric.Object} thisArg\n * @chainable\n */\n sendToBack: function() {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendToBack.call(this.group, this);\n }\n else if (this.canvas) {\n this.canvas.sendToBack(this);\n }\n return this;\n },\n\n /**\n * Moves an object to the top of the stack of drawn objects\n * @return {fabric.Object} thisArg\n * @chainable\n */\n bringToFront: function() {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringToFront.call(this.group, this);\n }\n else if (this.canvas) {\n this.canvas.bringToFront(this);\n }\n return this;\n },\n\n /**\n * Moves an object down in stack of drawn objects\n * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n sendBackwards: function(intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting);\n }\n else if (this.canvas) {\n this.canvas.sendBackwards(this, intersecting);\n }\n return this;\n },\n\n /**\n * Moves an object up in stack of drawn objects\n * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n bringForward: function(intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting);\n }\n else if (this.canvas) {\n this.canvas.bringForward(this, intersecting);\n }\n return this;\n },\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {Number} index New position of object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n moveTo: function(index) {\n if (this.group && this.group.type !== 'activeSelection') {\n fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index);\n }\n else if (this.canvas) {\n this.canvas.moveTo(this, index);\n }\n return this;\n }\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n function getSvgColorString(prop, value) {\n if (!value) {\n return prop + ': none; ';\n }\n else if (value.toLive) {\n return prop + ': url(#SVGID_' + value.id + '); ';\n }\n else {\n var color = new fabric.Color(value),\n str = prop + ': ' + color.toRgb() + '; ',\n opacity = color.getAlpha();\n if (opacity !== 1) {\n //change the color in rgb + opacity\n str += prop + '-opacity: ' + opacity.toString() + '; ';\n }\n return str;\n }\n }\n\n var toFixed = fabric.util.toFixed;\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles: function(skipShadow) {\n\n var fillRule = this.fillRule ? this.fillRule : 'nonzero',\n strokeWidth = this.strokeWidth ? this.strokeWidth : '0',\n strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none',\n strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0',\n strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',\n strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',\n strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',\n opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',\n visibility = this.visible ? '' : ' visibility: hidden;',\n filter = skipShadow ? '' : this.getSvgFilter(),\n fill = getSvgColorString('fill', this.fill),\n stroke = getSvgColorString('stroke', this.stroke);\n\n return [\n stroke,\n 'stroke-width: ', strokeWidth, '; ',\n 'stroke-dasharray: ', strokeDashArray, '; ',\n 'stroke-linecap: ', strokeLineCap, '; ',\n 'stroke-dashoffset: ', strokeDashOffset, '; ',\n 'stroke-linejoin: ', strokeLineJoin, '; ',\n 'stroke-miterlimit: ', strokeMiterLimit, '; ',\n fill,\n 'fill-rule: ', fillRule, '; ',\n 'opacity: ', opacity, ';',\n filter,\n visibility\n ].join('');\n },\n\n /**\n * Returns styles-string for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n * @return {String}\n */\n getSvgSpanStyles: function(style, useWhiteSpace) {\n var term = '; ';\n var fontFamily = style.fontFamily ?\n 'font-family: ' + (((style.fontFamily.indexOf('\\'') === -1 && style.fontFamily.indexOf('\"') === -1) ?\n '\\'' + style.fontFamily + '\\'' : style.fontFamily)) + term : '';\n var strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + term : '',\n fontFamily = fontFamily,\n fontSize = style.fontSize ? 'font-size: ' + style.fontSize + 'px' + term : '',\n fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + term : '',\n fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + term : '',\n fill = style.fill ? getSvgColorString('fill', style.fill) : '',\n stroke = style.stroke ? getSvgColorString('stroke', style.stroke) : '',\n textDecoration = this.getSvgTextDecoration(style),\n deltaY = style.deltaY ? 'baseline-shift: ' + (-style.deltaY) + '; ' : '';\n if (textDecoration) {\n textDecoration = 'text-decoration: ' + textDecoration + term;\n }\n\n return [\n stroke,\n strokeWidth,\n fontFamily,\n fontSize,\n fontStyle,\n fontWeight,\n textDecoration,\n fill,\n deltaY,\n useWhiteSpace ? 'white-space: pre; ' : ''\n ].join('');\n },\n\n /**\n * Returns text-decoration property for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @return {String}\n */\n getSvgTextDecoration: function(style) {\n return ['overline', 'underline', 'line-through'].filter(function(decoration) {\n return style[decoration.replace('-', '')];\n }).join(' ');\n },\n\n /**\n * Returns filter for svg shadow\n * @return {String}\n */\n getSvgFilter: function() {\n return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : '';\n },\n\n /**\n * Returns id attribute for svg output\n * @return {String}\n */\n getSvgCommons: function() {\n return [\n this.id ? 'id=\"' + this.id + '\" ' : '',\n this.clipPath ? 'clip-path=\"url(#' + this.clipPath.clipPathId + ')\" ' : '',\n ].join('');\n },\n\n /**\n * Returns transform-string for svg-export\n * @param {Boolean} use the full transform or the single object one.\n * @return {String}\n */\n getSvgTransform: function(full, additionalTransform) {\n var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),\n svgTransform = 'transform=\"' + fabric.util.matrixToSVG(transform);\n return svgTransform +\n (additionalTransform || '') + this.getSvgTransformMatrix() + '\" ';\n },\n\n /**\n * Returns transform-string for svg-export from the transform matrix of single elements\n * @return {String}\n */\n getSvgTransformMatrix: function() {\n return this.transformMatrix ? ' ' + fabric.util.matrixToSVG(this.transformMatrix) : '';\n },\n\n _setSVGBg: function(textBgRects) {\n if (this.backgroundColor) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n textBgRects.push(\n '\\t\\t\\n');\n }\n },\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n return this._createBaseSVGMarkup(this._toSVG(reviver), { reviver: reviver });\n },\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG: function(reviver) {\n return '\\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), { reviver: reviver });\n },\n\n /**\n * @private\n */\n _createBaseClipPathSVGMarkup: function(objectMarkup, options) {\n options = options || {};\n var reviver = options.reviver,\n additionalTransform = options.additionalTransform || '',\n commonPieces = [\n this.getSvgTransform(true, additionalTransform),\n this.getSvgCommons(),\n ].join(''),\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS');\n objectMarkup[index] = commonPieces;\n return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join('');\n },\n\n /**\n * @private\n */\n _createBaseSVGMarkup: function(objectMarkup, options) {\n options = options || {};\n var noStyle = options.noStyle,\n reviver = options.reviver,\n styleInfo = noStyle ? '' : 'style=\"' + this.getSvgStyles() + '\" ',\n shadowInfo = options.withShadow ? 'style=\"' + this.getSvgFilter() + '\" ' : '',\n clipPath = this.clipPath,\n vectorEffect = this.strokeUniform ? 'vector-effect=\"non-scaling-stroke\" ' : '',\n absoluteClipPath = clipPath && clipPath.absolutePositioned,\n stroke = this.stroke, fill = this.fill, shadow = this.shadow,\n commonPieces, markup = [], clipPathMarkup,\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS'),\n additionalTransform = options.additionalTransform;\n if (clipPath) {\n clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;\n clipPathMarkup = '\\n' +\n clipPath.toClipPathSVG(reviver) +\n '\\n';\n }\n if (absoluteClipPath) {\n markup.push(\n '\\n'\n );\n }\n markup.push(\n '\\n'\n );\n commonPieces = [\n styleInfo,\n vectorEffect,\n noStyle ? '' : this.addPaintOrder(), ' ',\n additionalTransform ? 'transform=\"' + additionalTransform + '\" ' : '',\n ].join('');\n objectMarkup[index] = commonPieces;\n if (fill && fill.toLive) {\n markup.push(fill.toSVG(this));\n }\n if (stroke && stroke.toLive) {\n markup.push(stroke.toSVG(this));\n }\n if (shadow) {\n markup.push(shadow.toSVG(this));\n }\n if (clipPath) {\n markup.push(clipPathMarkup);\n }\n markup.push(objectMarkup.join(''));\n markup.push('\\n');\n absoluteClipPath && markup.push('\\n');\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n\n addPaintOrder: function() {\n return this.paintFirst !== 'fill' ? ' paint-order=\"' + this.paintFirst + '\" ' : '';\n }\n });\n})();\n/* _TO_SVG_END_ */\n\n\n(function() {\n\n var extend = fabric.util.object.extend,\n originalSet = 'stateProperties';\n\n /*\n Depends on `stateProperties`\n */\n function saveProps(origin, destination, props) {\n var tmpObj = { }, deep = true;\n props.forEach(function(prop) {\n tmpObj[prop] = origin[prop];\n });\n extend(origin[destination], tmpObj, deep);\n }\n\n function _isEqual(origValue, currentValue, firstPass) {\n if (origValue === currentValue) {\n // if the objects are identical, return\n return true;\n }\n else if (Array.isArray(origValue)) {\n if (!Array.isArray(currentValue) || origValue.length !== currentValue.length) {\n return false;\n }\n for (var i = 0, len = origValue.length; i < len; i++) {\n if (!_isEqual(origValue[i], currentValue[i])) {\n return false;\n }\n }\n return true;\n }\n else if (origValue && typeof origValue === 'object') {\n var keys = Object.keys(origValue), key;\n if (!currentValue ||\n typeof currentValue !== 'object' ||\n (!firstPass && keys.length !== Object.keys(currentValue).length)\n ) {\n return false;\n }\n for (var i = 0, len = keys.length; i < len; i++) {\n key = keys[i];\n // since clipPath is in the statefull cache list and the clipPath objects\n // would be iterated as an object, this would lead to possible infinite recursion\n if (key === 'canvas') {\n continue;\n }\n if (!_isEqual(origValue[key], currentValue[key])) {\n return false;\n }\n }\n return true;\n }\n }\n\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Returns true if object state (one of its state properties) was changed\n * @param {String} [propertySet] optional name for the set of property we want to save\n * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called\n */\n hasStateChanged: function(propertySet) {\n propertySet = propertySet || originalSet;\n var dashedPropertySet = '_' + propertySet;\n if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) {\n return true;\n }\n return !_isEqual(this[dashedPropertySet], this, true);\n },\n\n /**\n * Saves state of an object\n * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n * @return {fabric.Object} thisArg\n */\n saveState: function(options) {\n var propertySet = options && options.propertySet || originalSet,\n destination = '_' + propertySet;\n if (!this[destination]) {\n return this.setupState(options);\n }\n saveProps(this, destination, this[propertySet]);\n if (options && options.stateProperties) {\n saveProps(this, destination, options.stateProperties);\n }\n return this;\n },\n\n /**\n * Setups state of an object\n * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n * @return {fabric.Object} thisArg\n */\n setupState: function(options) {\n options = options || { };\n var propertySet = options.propertySet || originalSet;\n options.propertySet = propertySet;\n this['_' + propertySet] = { };\n this.saveState(options);\n return this;\n }\n });\n})();\n\n\n(function() {\n\n var degreesToRadians = fabric.util.degreesToRadians;\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * The object interactivity controls.\n * @private\n */\n _controlsVisibility: null,\n\n /**\n * Determines which corner has been clicked\n * @private\n * @param {Object} pointer The pointer indicating the mouse position\n * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found\n */\n _findTargetCorner: function(pointer) {\n // objects in group, anykind, are not self modificable,\n // must not return an hovered corner.\n if (!this.hasControls || this.group || (!this.canvas || this.canvas._activeObject !== this)) {\n return false;\n }\n\n var ex = pointer.x,\n ey = pointer.y,\n xPoints,\n lines;\n this.__corner = 0;\n for (var i in this.oCoords) {\n\n if (!this.isControlVisible(i)) {\n continue;\n }\n\n if (i === 'mtr' && !this.hasRotatingPoint) {\n continue;\n }\n\n if (this.get('lockUniScaling') &&\n (i === 'mt' || i === 'mr' || i === 'mb' || i === 'ml')) {\n continue;\n }\n\n lines = this._getImageLines(this.oCoords[i].corner);\n\n // debugging\n\n // canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);\n\n // canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);\n\n // canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);\n\n // canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);\n // canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);\n\n xPoints = this._findCrossPoints({ x: ex, y: ey }, lines);\n if (xPoints !== 0 && xPoints % 2 === 1) {\n this.__corner = i;\n return i;\n }\n }\n return false;\n },\n\n /**\n * Sets the coordinates of the draggable boxes in the corners of\n * the image used to scale/rotate it.\n * @private\n */\n _setCornerCoords: function() {\n var coords = this.oCoords,\n newTheta = degreesToRadians(45 - this.angle),\n /* Math.sqrt(2 * Math.pow(this.cornerSize, 2)) / 2, */\n /* 0.707106 stands for sqrt(2)/2 */\n cornerHypotenuse = this.cornerSize * 0.707106,\n cosHalfOffset = cornerHypotenuse * fabric.util.cos(newTheta),\n sinHalfOffset = cornerHypotenuse * fabric.util.sin(newTheta),\n x, y;\n\n for (var point in coords) {\n x = coords[point].x;\n y = coords[point].y;\n coords[point].corner = {\n tl: {\n x: x - sinHalfOffset,\n y: y - cosHalfOffset\n },\n tr: {\n x: x + cosHalfOffset,\n y: y - sinHalfOffset\n },\n bl: {\n x: x - cosHalfOffset,\n y: y + sinHalfOffset\n },\n br: {\n x: x + sinHalfOffset,\n y: y + cosHalfOffset\n }\n };\n }\n },\n\n /**\n * Draws a colored layer behind the object, inside its selection borders.\n * Requires public options: padding, selectionBackgroundColor\n * this function is called when the context is transformed\n * has checks to be skipped when the object is on a staticCanvas\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawSelectionBackground: function(ctx) {\n if (!this.selectionBackgroundColor ||\n (this.canvas && !this.canvas.interactive) ||\n (this.canvas && this.canvas._activeObject !== this)\n ) {\n return this;\n }\n ctx.save();\n var center = this.getCenterPoint(), wh = this._calculateCurrentDimensions(),\n vpt = this.canvas.viewportTransform;\n ctx.translate(center.x, center.y);\n ctx.scale(1 / vpt[0], 1 / vpt[3]);\n ctx.rotate(degreesToRadians(this.angle));\n ctx.fillStyle = this.selectionBackgroundColor;\n ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);\n ctx.restore();\n return this;\n },\n\n /**\n * Draws borders of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Object} styleOverride object to override the object style\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawBorders: function(ctx, styleOverride) {\n styleOverride = styleOverride || {};\n var wh = this._calculateCurrentDimensions(),\n strokeWidth = this.borderScaleFactor,\n width = wh.x + strokeWidth,\n height = wh.y + strokeWidth,\n drawRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ?\n styleOverride.hasRotatingPoint : this.hasRotatingPoint,\n hasControls = typeof styleOverride.hasControls !== 'undefined' ?\n styleOverride.hasControls : this.hasControls,\n rotatingPointOffset = typeof styleOverride.rotatingPointOffset !== 'undefined' ?\n styleOverride.rotatingPointOffset : this.rotatingPointOffset;\n\n ctx.save();\n ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n\n ctx.strokeRect(\n -width / 2,\n -height / 2,\n width,\n height\n );\n\n if (drawRotatingPoint && this.isControlVisible('mtr') && hasControls) {\n\n var rotateHeight = -height / 2;\n\n ctx.beginPath();\n ctx.moveTo(0, rotateHeight);\n ctx.lineTo(0, rotateHeight - rotatingPointOffset);\n ctx.stroke();\n }\n\n ctx.restore();\n return this;\n },\n\n /**\n * Draws borders of an object's bounding box when it is inside a group.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {object} options object representing current object parameters\n * @param {Object} styleOverride object to override the object style\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawBordersInGroup: function(ctx, options, styleOverride) {\n styleOverride = styleOverride || {};\n var p = { x: this.width, y: this.height },\n matrix = fabric.util.composeMatrix({\n scaleX: options.scaleX,\n scaleY: options.scaleY,\n skewX: options.skewX\n }),\n wh = fabric.util.transformPoint(p, matrix),\n strokeWidth = this.strokeWidth,\n borderScaleFactor = this.borderScaleFactor,\n width =\n wh.x + strokeWidth * (this.strokeUniform ? this.canvas.getZoom() : options.scaleX) + borderScaleFactor,\n height =\n wh.y + strokeWidth * (this.strokeUniform ? this.canvas.getZoom() : options.scaleY) + borderScaleFactor;\n ctx.save();\n this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n\n ctx.strokeRect(\n -width / 2,\n -height / 2,\n width,\n height\n );\n\n ctx.restore();\n return this;\n },\n\n /**\n * Draws corners of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: cornerSize, padding\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Object} styleOverride object to override the object style\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawControls: function(ctx, styleOverride) {\n styleOverride = styleOverride || {};\n var wh = this._calculateCurrentDimensions(),\n width = wh.x,\n height = wh.y,\n scaleOffset = styleOverride.cornerSize || this.cornerSize,\n left = -(width + scaleOffset) / 2,\n top = -(height + scaleOffset) / 2,\n transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ?\n styleOverride.transparentCorners : this.transparentCorners,\n hasRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ?\n styleOverride.hasRotatingPoint : this.hasRotatingPoint,\n methodName = transparentCorners ? 'stroke' : 'fill';\n\n ctx.save();\n ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor;\n if (!this.transparentCorners) {\n ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor;\n }\n this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null);\n\n // top-left\n this._drawControl('tl', ctx, methodName,\n left,\n top, styleOverride);\n\n // top-right\n this._drawControl('tr', ctx, methodName,\n left + width,\n top, styleOverride);\n\n // bottom-left\n this._drawControl('bl', ctx, methodName,\n left,\n top + height, styleOverride);\n\n // bottom-right\n this._drawControl('br', ctx, methodName,\n left + width,\n top + height, styleOverride);\n\n if (!this.get('lockUniScaling')) {\n\n // middle-top\n this._drawControl('mt', ctx, methodName,\n left + width / 2,\n top, styleOverride);\n\n // middle-bottom\n this._drawControl('mb', ctx, methodName,\n left + width / 2,\n top + height, styleOverride);\n\n // middle-right\n this._drawControl('mr', ctx, methodName,\n left + width,\n top + height / 2, styleOverride);\n\n // middle-left\n this._drawControl('ml', ctx, methodName,\n left,\n top + height / 2, styleOverride);\n }\n\n // middle-top-rotate\n if (hasRotatingPoint) {\n this._drawControl('mtr', ctx, methodName,\n left + width / 2,\n top - this.rotatingPointOffset, styleOverride);\n }\n\n ctx.restore();\n\n return this;\n },\n\n /**\n * @private\n */\n _drawControl: function(control, ctx, methodName, left, top, styleOverride) {\n styleOverride = styleOverride || {};\n if (!this.isControlVisible(control)) {\n return;\n }\n var size = this.cornerSize, stroke = !this.transparentCorners && this.cornerStrokeColor;\n switch (styleOverride.cornerStyle || this.cornerStyle) {\n case 'circle':\n ctx.beginPath();\n ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI, false);\n ctx[methodName]();\n if (stroke) {\n ctx.stroke();\n }\n break;\n default:\n this.transparentCorners || ctx.clearRect(left, top, size, size);\n ctx[methodName + 'Rect'](left, top, size, size);\n if (stroke) {\n ctx.strokeRect(left, top, size, size);\n }\n }\n },\n\n /**\n * Returns true if the specified control is visible, false otherwise.\n * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * @returns {Boolean} true if the specified control is visible, false otherwise\n */\n isControlVisible: function(controlName) {\n return this._getControlsVisibility()[controlName];\n },\n\n /**\n * Sets the visibility of the specified control.\n * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * @param {Boolean} visible true to set the specified control visible, false otherwise\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setControlVisible: function(controlName, visible) {\n this._getControlsVisibility()[controlName] = visible;\n return this;\n },\n\n /**\n * Sets the visibility state of object controls.\n * @param {Object} [options] Options object\n * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it\n * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it\n * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it\n * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it\n * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it\n * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it\n * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it\n * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it\n * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setControlsVisibility: function(options) {\n options || (options = { });\n\n for (var p in options) {\n this.setControlVisible(p, options[p]);\n }\n return this;\n },\n\n /**\n * Returns the instance of the control visibility set for this object.\n * @private\n * @returns {Object}\n */\n _getControlsVisibility: function() {\n if (!this._controlsVisibility) {\n this._controlsVisibility = {\n tl: true,\n tr: true,\n br: true,\n bl: true,\n ml: true,\n mt: true,\n mr: true,\n mb: true,\n mtr: true\n };\n }\n return this._controlsVisibility;\n },\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to deselect this object. If the function returns true, the process is cancelled\n * @param {Object} [options] options sent from the upper functions\n * @param {Event} [options.e] event if the process is generated by an event\n */\n onDeselect: function() {\n // implemented by sub-classes, as needed.\n },\n\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to select this object. If the function returns true, the process is cancelled\n * @param {Object} [options] options sent from the upper functions\n * @param {Event} [options.e] event if the process is generated by an event\n */\n onSelect: function() {\n // implemented by sub-classes, as needed.\n }\n });\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Animation duration (in ms) for fx* methods\n * @type Number\n * @default\n */\n FX_DURATION: 500,\n\n /**\n * Centers object horizontally with animation.\n * @param {fabric.Object} object Object to center\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxCenterObjectH: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.left,\n endValue: this.getCenter().left,\n duration: this.FX_DURATION,\n onChange: function(value) {\n object.set('left', value);\n _this.requestRenderAll();\n onChange();\n },\n onComplete: function() {\n object.setCoords();\n onComplete();\n }\n });\n\n return this;\n },\n\n /**\n * Centers object vertically with animation.\n * @param {fabric.Object} object Object to center\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxCenterObjectV: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.top,\n endValue: this.getCenter().top,\n duration: this.FX_DURATION,\n onChange: function(value) {\n object.set('top', value);\n _this.requestRenderAll();\n onChange();\n },\n onComplete: function() {\n object.setCoords();\n onComplete();\n }\n });\n\n return this;\n },\n\n /**\n * Same as `fabric.Canvas#remove` but animated\n * @param {fabric.Object} object Object to remove\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxRemove: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.opacity,\n endValue: 0,\n duration: this.FX_DURATION,\n onChange: function(value) {\n object.set('opacity', value);\n _this.requestRenderAll();\n onChange();\n },\n onComplete: function () {\n _this.remove(object);\n onComplete();\n }\n });\n\n return this;\n }\n});\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n /**\n * Animates object's properties\n * @param {String|Object} property Property to animate (if string) or properties to animate (if object)\n * @param {Number|Object} value Value to animate property to (if string was given first) or options object\n * @return {fabric.Object} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}\n * @chainable\n *\n * As object — multiple properties\n *\n * object.animate({ left: ..., top: ... });\n * object.animate({ left: ..., top: ... }, { duration: ... });\n *\n * As string — one property\n *\n * object.animate('left', ...);\n * object.animate('left', { duration: ... });\n *\n */\n animate: function() {\n if (arguments[0] && typeof arguments[0] === 'object') {\n var propsToAnimate = [], prop, skipCallbacks;\n for (prop in arguments[0]) {\n propsToAnimate.push(prop);\n }\n for (var i = 0, len = propsToAnimate.length; i < len; i++) {\n prop = propsToAnimate[i];\n skipCallbacks = i !== len - 1;\n this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);\n }\n }\n else {\n this._animate.apply(this, arguments);\n }\n return this;\n },\n\n /**\n * @private\n * @param {String} property Property to animate\n * @param {String} to Value to animate to\n * @param {Object} [options] Options object\n * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked\n */\n _animate: function(property, to, options, skipCallbacks) {\n var _this = this, propPair;\n\n to = to.toString();\n\n if (!options) {\n options = { };\n }\n else {\n options = fabric.util.object.clone(options);\n }\n\n if (~property.indexOf('.')) {\n propPair = property.split('.');\n }\n\n var currentValue = propPair\n ? this.get(propPair[0])[propPair[1]]\n : this.get(property);\n\n if (!('from' in options)) {\n options.from = currentValue;\n }\n\n if (~to.indexOf('=')) {\n to = currentValue + parseFloat(to.replace('=', ''));\n }\n else {\n to = parseFloat(to);\n }\n\n fabric.util.animate({\n startValue: options.from,\n endValue: to,\n byValue: options.by,\n easing: options.easing,\n duration: options.duration,\n abort: options.abort && function() {\n return options.abort.call(_this);\n },\n onChange: function(value, valueProgress, timeProgress) {\n if (propPair) {\n _this[propPair[0]][propPair[1]] = value;\n }\n else {\n _this.set(property, value);\n }\n if (skipCallbacks) {\n return;\n }\n options.onChange && options.onChange(value, valueProgress, timeProgress);\n },\n onComplete: function(value, valueProgress, timeProgress) {\n if (skipCallbacks) {\n return;\n }\n\n _this.setCoords();\n options.onComplete && options.onComplete(value, valueProgress, timeProgress);\n }\n });\n }\n});\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 },\n supportsLineDash = fabric.StaticCanvas.supports('setLineDash');\n\n if (fabric.Line) {\n fabric.warn('fabric.Line is already defined');\n return;\n }\n\n /**\n * Line class\n * @class fabric.Line\n * @extends fabric.Object\n * @see {@link fabric.Line#initialize} for constructor definition\n */\n fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'line',\n\n /**\n * x value or first line edge\n * @type Number\n * @default\n */\n x1: 0,\n\n /**\n * y value or first line edge\n * @type Number\n * @default\n */\n y1: 0,\n\n /**\n * x value or second line edge\n * @type Number\n * @default\n */\n x2: 0,\n\n /**\n * y value or second line edge\n * @type Number\n * @default\n */\n y2: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'),\n\n /**\n * Constructor\n * @param {Array} [points] Array of points\n * @param {Object} [options] Options object\n * @return {fabric.Line} thisArg\n */\n initialize: function(points, options) {\n if (!points) {\n points = [0, 0, 0, 0];\n }\n\n this.callSuper('initialize', options);\n\n this.set('x1', points[0]);\n this.set('y1', points[1]);\n this.set('x2', points[2]);\n this.set('y2', points[3]);\n\n this._setWidthHeight(options);\n },\n\n /**\n * @private\n * @param {Object} [options] Options\n */\n _setWidthHeight: function(options) {\n options || (options = { });\n\n this.width = Math.abs(this.x2 - this.x1);\n this.height = Math.abs(this.y2 - this.y1);\n\n this.left = 'left' in options\n ? options.left\n : this._getLeftToOriginX();\n\n this.top = 'top' in options\n ? options.top\n : this._getTopToOriginY();\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n if (typeof coordProps[key] !== 'undefined') {\n this._setWidthHeight();\n }\n return this;\n },\n\n /**\n * @private\n * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line.\n */\n _getLeftToOriginX: makeEdgeToOriginGetter(\n { // property names\n origin: 'originX',\n axis1: 'x1',\n axis2: 'x2',\n dimension: 'width'\n },\n { // possible values of origin\n nearest: 'left',\n center: 'center',\n farthest: 'right'\n }\n ),\n\n /**\n * @private\n * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line.\n */\n _getTopToOriginY: makeEdgeToOriginGetter(\n { // property names\n origin: 'originY',\n axis1: 'y1',\n axis2: 'y2',\n dimension: 'height'\n },\n { // possible values of origin\n nearest: 'top',\n center: 'center',\n farthest: 'bottom'\n }\n ),\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n ctx.beginPath();\n\n if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) {\n // move from center (of virtual box) to its left/top corner\n // we can't assume x1, y1 is top left and x2, y2 is bottom right\n var p = this.calcLinePoints();\n ctx.moveTo(p.x1, p.y1);\n ctx.lineTo(p.x2, p.y2);\n }\n\n ctx.lineWidth = this.strokeWidth;\n\n // TODO: test this\n // make sure setting \"fill\" changes color of a line\n // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n var origStrokeStyle = ctx.strokeStyle;\n ctx.strokeStyle = this.stroke || ctx.fillStyle;\n this.stroke && this._renderStroke(ctx);\n ctx.strokeStyle = origStrokeStyle;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var p = this.calcLinePoints();\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray);\n ctx.closePath();\n },\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Object} center point from element coordinates\n */\n _findCenterFromElement: function() {\n return {\n x: (this.x1 + this.x2) / 2,\n y: (this.y1 + this.y2) / 2,\n };\n },\n\n /**\n * Returns object representation of an instance\n * @methd toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints());\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n */\n _getNonTransformedDimensions: function() {\n var dim = this.callSuper('_getNonTransformedDimensions');\n if (this.strokeLineCap === 'butt') {\n if (this.width === 0) {\n dim.y -= this.strokeWidth;\n }\n if (this.height === 0) {\n dim.x -= this.strokeWidth;\n }\n }\n return dim;\n },\n\n /**\n * Recalculates line points given width and height\n * @private\n */\n calcLinePoints: function() {\n var xMult = this.x1 <= this.x2 ? -1 : 1,\n yMult = this.y1 <= this.y2 ? -1 : 1,\n x1 = (xMult * this.width * 0.5),\n y1 = (yMult * this.height * 0.5),\n x2 = (xMult * this.width * -0.5),\n y2 = (yMult * this.height * -0.5);\n\n return {\n x1: x1,\n x2: x2,\n y1: y1,\n y2: y2\n };\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var p = this.calcLinePoints();\n return [\n '\\n'\n ];\n },\n /* _TO_SVG_END_ */\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement})\n * @static\n * @memberOf fabric.Line\n * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n */\n fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '));\n\n /**\n * Returns fabric.Line instance from an SVG element\n * @static\n * @memberOf fabric.Line\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {Function} [callback] callback function invoked after parsing\n */\n fabric.Line.fromElement = function(element, callback, options) {\n options = options || { };\n var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES),\n points = [\n parsedAttributes.x1 || 0,\n parsedAttributes.y1 || 0,\n parsedAttributes.x2 || 0,\n parsedAttributes.y2 || 0\n ];\n callback(new fabric.Line(points, extend(parsedAttributes, options)));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Line instance from an object representation\n * @static\n * @memberOf fabric.Line\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n */\n fabric.Line.fromObject = function(object, callback) {\n function _callback(instance) {\n delete instance.points;\n callback && callback(instance);\n };\n var options = clone(object, true);\n options.points = [object.x1, object.y1, object.x2, object.y2];\n fabric.Object._fromObject('Line', options, _callback, 'points');\n };\n\n /**\n * Produces a function that calculates distance from canvas edge to Line origin.\n */\n function makeEdgeToOriginGetter(propertyNames, originValues) {\n var origin = propertyNames.origin,\n axis1 = propertyNames.axis1,\n axis2 = propertyNames.axis2,\n dimension = propertyNames.dimension,\n nearest = originValues.nearest,\n center = originValues.center,\n farthest = originValues.farthest;\n\n return function() {\n switch (this.get(origin)) {\n case nearest:\n return Math.min(this.get(axis1), this.get(axis2));\n case center:\n return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension));\n case farthest:\n return Math.max(this.get(axis1), this.get(axis2));\n }\n };\n\n }\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n pi = Math.PI;\n\n if (fabric.Circle) {\n fabric.warn('fabric.Circle is already defined.');\n return;\n }\n\n /**\n * Circle class\n * @class fabric.Circle\n * @extends fabric.Object\n * @see {@link fabric.Circle#initialize} for constructor definition\n */\n fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'circle',\n\n /**\n * Radius of this circle\n * @type Number\n * @default\n */\n radius: 0,\n\n /**\n * Start angle of the circle, moving clockwise\n * deprectated type, this should be in degree, this was an oversight.\n * probably will change to degrees in next major version\n * @type Number\n * @default 0\n */\n startAngle: 0,\n\n /**\n * End angle of the circle\n * deprectated type, this should be in degree, this was an oversight.\n * probably will change to degrees in next major version\n * @type Number\n * @default 2Pi\n */\n endAngle: pi * 2,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius', 'startAngle', 'endAngle'),\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Circle} thisArg\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n\n if (key === 'radius') {\n this.setRadius(value);\n }\n\n return this;\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var svgString, x = 0, y = 0,\n angle = (this.endAngle - this.startAngle) % ( 2 * pi);\n\n if (angle === 0) {\n svgString = [\n '\\n'\n ];\n }\n else {\n var startX = fabric.util.cos(this.startAngle) * this.radius,\n startY = fabric.util.sin(this.startAngle) * this.radius,\n endX = fabric.util.cos(this.endAngle) * this.radius,\n endY = fabric.util.sin(this.endAngle) * this.radius,\n largeFlag = angle > pi ? '1' : '0';\n svgString = [\n '\\n'\n ];\n }\n return svgString;\n },\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render: function(ctx) {\n ctx.beginPath();\n ctx.arc(\n 0,\n 0,\n this.radius,\n this.startAngle,\n this.endAngle, false);\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusX: function() {\n return this.get('radius') * this.get('scaleX');\n },\n\n /**\n * Returns vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusY: function() {\n return this.get('radius') * this.get('scaleY');\n },\n\n /**\n * Sets radius of an object (and updates width accordingly)\n * @return {fabric.Circle} thisArg\n */\n setRadius: function(value) {\n this.radius = value;\n return this.set('width', value * 2).set('height', value * 2);\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement})\n * @static\n * @memberOf fabric.Circle\n * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement\n */\n fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' '));\n\n /**\n * Returns {@link fabric.Circle} instance from an SVG element\n * @static\n * @memberOf fabric.Circle\n * @param {SVGElement} element Element to parse\n * @param {Function} [callback] Options callback invoked after parsing is finished\n * @param {Object} [options] Options object\n * @throws {Error} If value of `r` attribute is missing or invalid\n */\n fabric.Circle.fromElement = function(element, callback) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);\n\n if (!isValidRadius(parsedAttributes)) {\n throw new Error('value of `r` attribute is required and can not be negative');\n }\n\n parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.radius;\n parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius;\n callback(new fabric.Circle(parsedAttributes));\n };\n\n /**\n * @private\n */\n function isValidRadius(attributes) {\n return (('radius' in attributes) && (attributes.radius >= 0));\n }\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Circle} instance from an object representation\n * @static\n * @memberOf fabric.Circle\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @return {Object} Instance of fabric.Circle\n */\n fabric.Circle.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Circle', object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Triangle) {\n fabric.warn('fabric.Triangle is already defined');\n return;\n }\n\n /**\n * Triangle class\n * @class fabric.Triangle\n * @extends fabric.Object\n * @return {fabric.Triangle} thisArg\n * @see {@link fabric.Triangle#initialize} for constructor definition\n */\n fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'triangle',\n\n /**\n * Width is set to 100 to compensate the old initialize code that was setting it to 100\n * @type Number\n * @default\n */\n width: 100,\n\n /**\n * Height is set to 100 to compensate the old initialize code that was setting it to 100\n * @type Number\n * @default\n */\n height: 100,\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n ctx.moveTo(-widthBy2, heightBy2);\n ctx.lineTo(0, -heightBy2);\n ctx.lineTo(widthBy2, heightBy2);\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray);\n ctx.closePath();\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2,\n points = [\n -widthBy2 + ' ' + heightBy2,\n '0 ' + -heightBy2,\n widthBy2 + ' ' + heightBy2\n ].join(',');\n return [\n ''\n ];\n },\n /* _TO_SVG_END_ */\n });\n\n /**\n * Returns {@link fabric.Triangle} instance from an object representation\n * @static\n * @memberOf fabric.Triangle\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n */\n fabric.Triangle.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Triangle', object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n piBy2 = Math.PI * 2;\n\n if (fabric.Ellipse) {\n fabric.warn('fabric.Ellipse is already defined.');\n return;\n }\n\n /**\n * Ellipse class\n * @class fabric.Ellipse\n * @extends fabric.Object\n * @return {fabric.Ellipse} thisArg\n * @see {@link fabric.Ellipse#initialize} for constructor definition\n */\n fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @lends fabric.Ellipse.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'ellipse',\n\n /**\n * Horizontal radius\n * @type Number\n * @default\n */\n rx: 0,\n\n /**\n * Vertical radius\n * @type Number\n * @default\n */\n ry: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {fabric.Ellipse} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this.set('rx', options && options.rx || 0);\n this.set('ry', options && options.ry || 0);\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Ellipse} thisArg\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n switch (key) {\n\n case 'rx':\n this.rx = value;\n this.set('width', value * 2);\n break;\n\n case 'ry':\n this.ry = value;\n this.set('height', value * 2);\n break;\n\n }\n return this;\n },\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRx: function() {\n return this.get('rx') * this.get('scaleX');\n },\n\n /**\n * Returns Vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRy: function() {\n return this.get('ry') * this.get('scaleY');\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n return [\n '\\n'\n ];\n },\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render: function(ctx) {\n ctx.beginPath();\n ctx.save();\n ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n ctx.arc(\n 0,\n 0,\n this.rx,\n 0,\n piBy2,\n false);\n ctx.restore();\n this._renderPaintInOrder(ctx);\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement})\n * @static\n * @memberOf fabric.Ellipse\n * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement\n */\n fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' '));\n\n /**\n * Returns {@link fabric.Ellipse} instance from an SVG element\n * @static\n * @memberOf fabric.Ellipse\n * @param {SVGElement} element Element to parse\n * @param {Function} [callback] Options callback invoked after parsing is finished\n * @return {fabric.Ellipse}\n */\n fabric.Ellipse.fromElement = function(element, callback) {\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);\n\n parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx;\n parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry;\n callback(new fabric.Ellipse(parsedAttributes));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Ellipse} instance from an object representation\n * @static\n * @memberOf fabric.Ellipse\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @return {fabric.Ellipse}\n */\n fabric.Ellipse.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Ellipse', object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend;\n\n if (fabric.Rect) {\n fabric.warn('fabric.Rect is already defined');\n return;\n }\n\n /**\n * Rectangle class\n * @class fabric.Rect\n * @extends fabric.Object\n * @return {fabric.Rect} thisArg\n * @see {@link fabric.Rect#initialize} for constructor definition\n */\n fabric.Rect = fabric.util.createClass(fabric.Object, /** @lends fabric.Rect.prototype */ {\n\n /**\n * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'),\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'rect',\n\n /**\n * Horizontal border radius\n * @type Number\n * @default\n */\n rx: 0,\n\n /**\n * Vertical border radius\n * @type Number\n * @default\n */\n ry: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this._initRxRy();\n },\n\n /**\n * Initializes rx/ry attributes\n * @private\n */\n _initRxRy: function() {\n if (this.rx && !this.ry) {\n this.ry = this.rx;\n }\n else if (this.ry && !this.rx) {\n this.rx = this.ry;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n\n // 1x1 case (used in spray brush) optimization was removed because\n // with caching and higher zoom level this makes more damage than help\n\n var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0,\n ry = this.ry ? Math.min(this.ry, this.height / 2) : 0,\n w = this.width,\n h = this.height,\n x = -this.width / 2,\n y = -this.height / 2,\n isRounded = rx !== 0 || ry !== 0,\n /* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\n k = 1 - 0.5522847498;\n ctx.beginPath();\n\n ctx.moveTo(x + rx, y);\n\n ctx.lineTo(x + w - rx, y);\n isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);\n\n ctx.lineTo(x + w, y + h - ry);\n isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h);\n\n ctx.lineTo(x + rx, y + h);\n isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);\n\n ctx.lineTo(x, y + ry);\n isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);\n\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n ctx.closePath();\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var x = -this.width / 2, y = -this.height / 2;\n return [\n '\\n'\n ];\n },\n /* _TO_SVG_END_ */\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`)\n * @static\n * @memberOf fabric.Rect\n * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement\n */\n fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' '));\n\n /**\n * Returns {@link fabric.Rect} instance from an SVG element\n * @static\n * @memberOf fabric.Rect\n * @param {SVGElement} element Element to parse\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n fabric.Rect.fromElement = function(element, callback, options) {\n if (!element) {\n return callback(null);\n }\n options = options || { };\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);\n\n parsedAttributes.left = parsedAttributes.left || 0;\n parsedAttributes.top = parsedAttributes.top || 0;\n parsedAttributes.height = parsedAttributes.height || 0;\n parsedAttributes.width = parsedAttributes.width || 0;\n var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n rect.visible = rect.visible && rect.width > 0 && rect.height > 0;\n callback(rect);\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Rect} instance from an object representation\n * @static\n * @memberOf fabric.Rect\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created\n */\n fabric.Rect.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Rect', object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n min = fabric.util.array.min,\n max = fabric.util.array.max,\n toFixed = fabric.util.toFixed;\n\n if (fabric.Polyline) {\n fabric.warn('fabric.Polyline is already defined');\n return;\n }\n\n /**\n * Polyline class\n * @class fabric.Polyline\n * @extends fabric.Object\n * @see {@link fabric.Polyline#initialize} for constructor definition\n */\n fabric.Polyline = fabric.util.createClass(fabric.Object, /** @lends fabric.Polyline.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'polyline',\n\n /**\n * Points array\n * @type Array\n * @default\n */\n points: null,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'),\n\n /**\n * Constructor\n * @param {Array} points Array of points (where each point is an object with x and y)\n * @param {Object} [options] Options object\n * @return {fabric.Polyline} thisArg\n * @example\n * var poly = new fabric.Polyline([\n * { x: 10, y: 10 },\n * { x: 50, y: 30 },\n * { x: 40, y: 70 },\n * { x: 60, y: 50 },\n * { x: 100, y: 150 },\n * { x: 40, y: 100 }\n * ], {\n * stroke: 'red',\n * left: 100,\n * top: 100\n * });\n */\n initialize: function(points, options) {\n options = options || {};\n this.points = points || [];\n this.callSuper('initialize', options);\n this._setPositionDimensions(options);\n },\n\n _setPositionDimensions: function(options) {\n var calcDim = this._calcDimensions(options), correctLeftTop;\n this.width = calcDim.width;\n this.height = calcDim.height;\n if (!options.fromSVG) {\n correctLeftTop = this.translateToGivenOrigin(\n { x: calcDim.left - this.strokeWidth / 2, y: calcDim.top - this.strokeWidth / 2 },\n 'left',\n 'top',\n this.originX,\n this.originY\n );\n }\n if (typeof options.left === 'undefined') {\n this.left = options.fromSVG ? calcDim.left : correctLeftTop.x;\n }\n if (typeof options.top === 'undefined') {\n this.top = options.fromSVG ? calcDim.top : correctLeftTop.y;\n }\n this.pathOffset = {\n x: calcDim.left + this.width / 2,\n y: calcDim.top + this.height / 2\n };\n },\n\n /**\n * Calculate the polygon min and max point from points array,\n * returning an object with left, top, widht, height to measure the\n * polygon size\n * @return {Object} object.left X coordinate of the polygon leftmost point\n * @return {Object} object.top Y coordinate of the polygon topmost point\n * @return {Object} object.width distance between X coordinates of the polygon leftmost and rightmost point\n * @return {Object} object.height distance between Y coordinates of the polygon topmost and bottommost point\n * @private\n */\n _calcDimensions: function() {\n\n var points = this.points,\n minX = min(points, 'x') || 0,\n minY = min(points, 'y') || 0,\n maxX = max(points, 'x') || 0,\n maxY = max(points, 'y') || 0,\n width = (maxX - minX),\n height = (maxY - minY);\n\n return {\n left: minX,\n top: minY,\n width: width,\n height: height\n };\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), {\n points: this.points.concat()\n });\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var points = [], diffX = this.pathOffset.x, diffY = this.pathOffset.y,\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n for (var i = 0, len = this.points.length; i < len; i++) {\n points.push(\n toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',',\n toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' '\n );\n }\n return [\n '<' + this.type + ' ', 'COMMON_PARTS',\n 'points=\"', points.join(''),\n '\" />\\n'\n ];\n },\n /* _TO_SVG_END_ */\n\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n commonRender: function(ctx) {\n var point, len = this.points.length,\n x = this.pathOffset.x,\n y = this.pathOffset.y;\n\n if (!len || isNaN(this.points[len - 1].y)) {\n // do not draw if no points or odd points\n // NaN comes from parseFloat of a empty string in parser\n return false;\n }\n ctx.beginPath();\n ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n for (var i = 0; i < len; i++) {\n point = this.points[i];\n ctx.lineTo(point.x - x, point.y - y);\n }\n return true;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n if (!this.commonRender(ctx)) {\n return;\n }\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var p1, p2;\n\n ctx.beginPath();\n for (var i = 0, len = this.points.length; i < len; i++) {\n p1 = this.points[i];\n p2 = this.points[i + 1] || p1;\n fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray);\n }\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance\n */\n complexity: function() {\n return this.get('points').length;\n }\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement})\n * @static\n * @memberOf fabric.Polyline\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n */\n fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n /**\n * Returns fabric.Polyline instance from an SVG element\n * @static\n * @memberOf fabric.Polyline\n * @param {SVGElement} element Element to parser\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n fabric.Polyline.fromElementGenerator = function(_class) {\n return function(element, callback, options) {\n if (!element) {\n return callback(null);\n }\n options || (options = { });\n\n var points = fabric.parsePointsAttribute(element.getAttribute('points')),\n parsedAttributes = fabric.parseAttributes(element, fabric[_class].ATTRIBUTE_NAMES);\n parsedAttributes.fromSVG = true;\n callback(new fabric[_class](points, extend(parsedAttributes, options)));\n };\n };\n\n fabric.Polyline.fromElement = fabric.Polyline.fromElementGenerator('Polyline');\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Polyline instance from an object representation\n * @static\n * @memberOf fabric.Polyline\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n */\n fabric.Polyline.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Polyline', object, callback, 'points');\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Polygon) {\n fabric.warn('fabric.Polygon is already defined');\n return;\n }\n\n /**\n * Polygon class\n * @class fabric.Polygon\n * @extends fabric.Polyline\n * @see {@link fabric.Polygon#initialize} for constructor definition\n */\n fabric.Polygon = fabric.util.createClass(fabric.Polyline, /** @lends fabric.Polygon.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'polygon',\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n if (!this.commonRender(ctx)) {\n return;\n }\n ctx.closePath();\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n this.callSuper('_renderDashedStroke', ctx);\n ctx.closePath();\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`)\n * @static\n * @memberOf fabric.Polygon\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement\n */\n fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n /**\n * Returns {@link fabric.Polygon} instance from an SVG element\n * @static\n * @memberOf fabric.Polygon\n * @param {SVGElement} element Element to parse\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n fabric.Polygon.fromElement = fabric.Polyline.fromElementGenerator('Polygon');\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Polygon instance from an object representation\n * @static\n * @memberOf fabric.Polygon\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n */\n fabric.Polygon.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Polygon', object, callback, 'points');\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n min = fabric.util.array.min,\n max = fabric.util.array.max,\n extend = fabric.util.object.extend,\n _toString = Object.prototype.toString,\n drawArc = fabric.util.drawArc,\n toFixed = fabric.util.toFixed,\n commandLengths = {\n m: 2,\n l: 2,\n h: 1,\n v: 1,\n c: 6,\n s: 4,\n q: 4,\n t: 2,\n a: 7\n },\n repeatedCommands = {\n m: 'l',\n M: 'L'\n };\n\n if (fabric.Path) {\n fabric.warn('fabric.Path is already defined');\n return;\n }\n\n /**\n * Path class\n * @class fabric.Path\n * @extends fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup}\n * @see {@link fabric.Path#initialize} for constructor definition\n */\n fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'path',\n\n /**\n * Array of path points\n * @type Array\n * @default\n */\n path: null,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'),\n\n stateProperties: fabric.Object.prototype.stateProperties.concat('path'),\n\n /**\n * Constructor\n * @param {Array|String} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {Object} [options] Options object\n * @return {fabric.Path} thisArg\n */\n initialize: function(path, options) {\n options = options || { };\n this.callSuper('initialize', options);\n\n if (!path) {\n path = [];\n }\n\n var fromArray = _toString.call(path) === '[object Array]';\n\n this.path = fromArray\n ? path\n // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values)\n : path.match && path.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);\n\n if (!this.path) {\n return;\n }\n\n if (!fromArray) {\n this.path = this._parsePath();\n }\n\n fabric.Polyline.prototype._setPositionDimensions.call(this, options);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _renderPathCommands: function(ctx) {\n var current, // current instruction\n previous = null,\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0, // current y\n controlX = 0, // current control point x\n controlY = 0, // current control point y\n tempX,\n tempY,\n l = -this.pathOffset.x,\n t = -this.pathOffset.y;\n\n ctx.beginPath();\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n\n current = this.path[i];\n\n switch (current[0]) { // first letter\n\n case 'l': // lineto, relative\n x += current[1];\n y += current[2];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'L': // lineto, absolute\n x = current[1];\n y = current[2];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'h': // horizontal lineto, relative\n x += current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'H': // horizontal lineto, absolute\n x = current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'v': // vertical lineto, relative\n y += current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'V': // verical lineto, absolute\n y = current[1];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'm': // moveTo, relative\n x += current[1];\n y += current[2];\n subpathStartX = x;\n subpathStartY = y;\n ctx.moveTo(x + l, y + t);\n break;\n\n case 'M': // moveTo, absolute\n x = current[1];\n y = current[2];\n subpathStartX = x;\n subpathStartY = y;\n ctx.moveTo(x + l, y + t);\n break;\n\n case 'c': // bezierCurveTo, relative\n tempX = x + current[5];\n tempY = y + current[6];\n controlX = x + current[3];\n controlY = y + current[4];\n ctx.bezierCurveTo(\n x + current[1] + l, // x1\n y + current[2] + t, // y1\n controlX + l, // x2\n controlY + t, // y2\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'C': // bezierCurveTo, absolute\n x = current[5];\n y = current[6];\n controlX = current[3];\n controlY = current[4];\n ctx.bezierCurveTo(\n current[1] + l,\n current[2] + t,\n controlX + l,\n controlY + t,\n x + l,\n y + t\n );\n break;\n\n case 's': // shorthand cubic bezierCurveTo, relative\n\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n ctx.bezierCurveTo(\n controlX + l,\n controlY + t,\n x + current[1] + l,\n y + current[2] + t,\n tempX + l,\n tempY + t\n );\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = x + current[1];\n controlY = y + current[2];\n\n x = tempX;\n y = tempY;\n break;\n\n case 'S': // shorthand cubic bezierCurveTo, absolute\n tempX = current[3];\n tempY = current[4];\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n ctx.bezierCurveTo(\n controlX + l,\n controlY + t,\n current[1] + l,\n current[2] + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = current[1];\n controlY = current[2];\n\n break;\n\n case 'q': // quadraticCurveTo, relative\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n\n controlX = x + current[1];\n controlY = y + current[2];\n\n ctx.quadraticCurveTo(\n controlX + l,\n controlY + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n tempX = current[3];\n tempY = current[4];\n\n ctx.quadraticCurveTo(\n current[1] + l,\n current[2] + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n controlX = current[1];\n controlY = current[2];\n break;\n\n case 't': // shorthand quadraticCurveTo, relative\n\n // transform to absolute x,y\n tempX = x + current[1];\n tempY = y + current[2];\n\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n ctx.quadraticCurveTo(\n controlX + l,\n controlY + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n\n break;\n\n case 'T':\n tempX = current[1];\n tempY = current[2];\n\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n ctx.quadraticCurveTo(\n controlX + l,\n controlY + t,\n tempX + l,\n tempY + t\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'a':\n // TODO: optimize this\n drawArc(ctx, x + l, y + t, [\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6] + x + l,\n current[7] + y + t\n ]);\n x += current[6];\n y += current[7];\n break;\n\n case 'A':\n // TODO: optimize this\n drawArc(ctx, x + l, y + t, [\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6] + l,\n current[7] + t\n ]);\n x = current[6];\n y = current[7];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n ctx.closePath();\n break;\n }\n previous = current;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _render: function(ctx) {\n this._renderPathCommands(ctx);\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} string representation of an instance\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), {\n path: this.path.map(function(item) { return item.slice(); }),\n });\n },\n\n /**\n * Returns dataless object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n var o = this.toObject(['sourcePath'].concat(propertiesToInclude));\n if (o.sourcePath) {\n delete o.path;\n }\n return o;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var path = this.path.map(function(path) {\n return path.join(' ');\n }).join(' ');\n return [\n '\\n'\n ];\n },\n\n _getOffsetTransform: function() {\n var digits = fabric.Object.NUM_FRACTION_DIGITS;\n return ' translate(' + toFixed(-this.pathOffset.x, digits) + ', ' +\n toFixed(-this.pathOffset.y, digits) + ')';\n },\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG: function(reviver) {\n var additionalTransform = this._getOffsetTransform();\n return '\\t' + this._createBaseClipPathSVGMarkup(\n this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform }\n );\n },\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var additionalTransform = this._getOffsetTransform();\n return this._createBaseSVGMarkup(this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform });\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns number representation of an instance complexity\n * @return {Number} complexity of this instance\n */\n complexity: function() {\n return this.path.length;\n },\n\n /**\n * @private\n */\n _parsePath: function() {\n var result = [],\n coords = [],\n currentPath,\n parsed,\n re = fabric.rePathCommand,\n match,\n coordsStr;\n\n for (var i = 0, coordsParsed, len = this.path.length; i < len; i++) {\n currentPath = this.path[i];\n\n coordsStr = currentPath.slice(1).trim();\n coords.length = 0;\n\n while ((match = re.exec(coordsStr))) {\n coords.push(match[0]);\n }\n\n coordsParsed = [currentPath.charAt(0)];\n\n for (var j = 0, jlen = coords.length; j < jlen; j++) {\n parsed = parseFloat(coords[j]);\n if (!isNaN(parsed)) {\n coordsParsed.push(parsed);\n }\n }\n\n var command = coordsParsed[0],\n commandLength = commandLengths[command.toLowerCase()],\n repeatedCommand = repeatedCommands[command] || command;\n\n if (coordsParsed.length - 1 > commandLength) {\n for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) {\n result.push([command].concat(coordsParsed.slice(k, k + commandLength)));\n command = repeatedCommand;\n }\n }\n else {\n result.push(coordsParsed);\n }\n }\n\n return result;\n },\n\n /**\n * @private\n */\n _calcDimensions: function() {\n\n var aX = [],\n aY = [],\n current, // current instruction\n previous = null,\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0, // current y\n controlX = 0, // current control point x\n controlY = 0, // current control point y\n tempX,\n tempY,\n bounds;\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n\n current = this.path[i];\n\n switch (current[0]) { // first letter\n\n case 'l': // lineto, relative\n x += current[1];\n y += current[2];\n bounds = [];\n break;\n\n case 'L': // lineto, absolute\n x = current[1];\n y = current[2];\n bounds = [];\n break;\n\n case 'h': // horizontal lineto, relative\n x += current[1];\n bounds = [];\n break;\n\n case 'H': // horizontal lineto, absolute\n x = current[1];\n bounds = [];\n break;\n\n case 'v': // vertical lineto, relative\n y += current[1];\n bounds = [];\n break;\n\n case 'V': // verical lineto, absolute\n y = current[1];\n bounds = [];\n break;\n\n case 'm': // moveTo, relative\n x += current[1];\n y += current[2];\n subpathStartX = x;\n subpathStartY = y;\n bounds = [];\n break;\n\n case 'M': // moveTo, absolute\n x = current[1];\n y = current[2];\n subpathStartX = x;\n subpathStartY = y;\n bounds = [];\n break;\n\n case 'c': // bezierCurveTo, relative\n tempX = x + current[5];\n tempY = y + current[6];\n controlX = x + current[3];\n controlY = y + current[4];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n x + current[1], // x1\n y + current[2], // y1\n controlX, // x2\n controlY, // y2\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'C': // bezierCurveTo, absolute\n controlX = current[3];\n controlY = current[4];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n current[1],\n current[2],\n controlX,\n controlY,\n current[5],\n current[6]\n );\n x = current[5];\n y = current[6];\n break;\n\n case 's': // shorthand cubic bezierCurveTo, relative\n\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n x + current[1],\n y + current[2],\n tempX,\n tempY\n );\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = x + current[1];\n controlY = y + current[2];\n x = tempX;\n y = tempY;\n break;\n\n case 'S': // shorthand cubic bezierCurveTo, absolute\n tempX = current[3];\n tempY = current[4];\n if (previous[0].match(/[CcSs]/) === null) {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n current[1],\n current[2],\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n // set control point to 2nd one of this command\n // \"... the first control point is assumed to be\n // the reflection of the second control point on\n // the previous command relative to the current point.\"\n controlX = current[1];\n controlY = current[2];\n break;\n\n case 'q': // quadraticCurveTo, relative\n // transform to absolute x,y\n tempX = x + current[3];\n tempY = y + current[4];\n controlX = x + current[1];\n controlY = y + current[2];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n controlX = current[1];\n controlY = current[2];\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n current[3],\n current[4]\n );\n x = current[3];\n y = current[4];\n break;\n\n case 't': // shorthand quadraticCurveTo, relative\n // transform to absolute x,y\n tempX = x + current[1];\n tempY = y + current[2];\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n\n break;\n\n case 'T':\n tempX = current[1];\n tempY = current[2];\n\n if (previous[0].match(/[QqTt]/) === null) {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n else {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n bounds = fabric.util.getBoundsOfCurve(x, y,\n controlX,\n controlY,\n controlX,\n controlY,\n tempX,\n tempY\n );\n x = tempX;\n y = tempY;\n break;\n\n case 'a':\n // TODO: optimize this\n bounds = fabric.util.getBoundsOfArc(x, y,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6] + x,\n current[7] + y\n );\n x += current[6];\n y += current[7];\n break;\n\n case 'A':\n // TODO: optimize this\n bounds = fabric.util.getBoundsOfArc(x, y,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n current[7]\n );\n x = current[6];\n y = current[7];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n break;\n }\n previous = current;\n bounds.forEach(function (point) {\n aX.push(point.x);\n aY.push(point.y);\n });\n aX.push(x);\n aY.push(y);\n }\n\n var minX = min(aX) || 0,\n minY = min(aY) || 0,\n maxX = max(aX) || 0,\n maxY = max(aY) || 0,\n deltaX = maxX - minX,\n deltaY = maxY - minY;\n\n return {\n left: minX,\n top: minY,\n width: deltaX,\n height: deltaY\n };\n }\n });\n\n /**\n * Creates an instance of fabric.Path from an object\n * @static\n * @memberOf fabric.Path\n * @param {Object} object\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n */\n fabric.Path.fromObject = function(object, callback) {\n if (typeof object.sourcePath === 'string') {\n var pathUrl = object.sourcePath;\n fabric.loadSVGFromURL(pathUrl, function (elements) {\n var path = elements[0];\n path.setOptions(object);\n callback && callback(path);\n });\n }\n else {\n fabric.Object._fromObject('Path', object, callback, 'path');\n }\n };\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`)\n * @static\n * @memberOf fabric.Path\n * @see http://www.w3.org/TR/SVG/paths.html#PathElement\n */\n fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']);\n\n /**\n * Creates an instance of fabric.Path from an SVG element\n * @static\n * @memberOf fabric.Path\n * @param {SVGElement} element to parse\n * @param {Function} callback Callback to invoke when an fabric.Path instance is created\n * @param {Object} [options] Options object\n * @param {Function} [callback] Options callback invoked after parsing is finished\n */\n fabric.Path.fromElement = function(element, callback, options) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES);\n parsedAttributes.fromSVG = true;\n callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options)));\n };\n /* _FROM_SVG_END_ */\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n min = fabric.util.array.min,\n max = fabric.util.array.max;\n\n if (fabric.Group) {\n return;\n }\n\n /**\n * Group class\n * @class fabric.Group\n * @extends fabric.Object\n * @mixes fabric.Collection\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n * @see {@link fabric.Group#initialize} for constructor definition\n */\n fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'group',\n\n /**\n * Width of stroke\n * @type Number\n * @default\n */\n strokeWidth: 0,\n\n /**\n * Indicates if click, mouseover, mouseout events & hoverCursor should also check for subtargets\n * @type Boolean\n * @default\n */\n subTargetCheck: false,\n\n /**\n * Groups are container, do not render anything on theyr own, ence no cache properties\n * @type Array\n * @default\n */\n cacheProperties: [],\n\n /**\n * setOnGroup is a method used for TextBox that is no more used since 2.0.0 The behavior is still\n * available setting this boolean to true.\n * @type Boolean\n * @since 2.0.0\n * @default\n */\n useSetOnGroup: false,\n\n /**\n * Constructor\n * @param {Object} objects Group objects\n * @param {Object} [options] Options object\n * @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already.\n * @return {Object} thisArg\n */\n initialize: function(objects, options, isAlreadyGrouped) {\n options = options || {};\n this._objects = [];\n // if objects enclosed in a group have been grouped already,\n // we cannot change properties of objects.\n // Thus we need to set options to group without objects,\n isAlreadyGrouped && this.callSuper('initialize', options);\n this._objects = objects || [];\n for (var i = this._objects.length; i--; ) {\n this._objects[i].group = this;\n }\n\n if (!isAlreadyGrouped) {\n var center = options && options.centerPoint;\n // we want to set origins before calculating the bounding box.\n // so that the topleft can be set with that in mind.\n // if specific top and left are passed, are overwritten later\n // with the callSuper('initialize', options)\n if (options.originX !== undefined) {\n this.originX = options.originX;\n }\n if (options.originY !== undefined) {\n this.originY = options.originY;\n }\n // if coming from svg i do not want to calc bounds.\n // i assume width and height are passed along options\n center || this._calcBounds();\n this._updateObjectsCoords(center);\n delete options.centerPoint;\n this.callSuper('initialize', options);\n }\n else {\n this._updateObjectsACoords();\n }\n\n this.setCoords();\n },\n\n /**\n * @private\n * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change\n */\n _updateObjectsACoords: function() {\n var ignoreZoom = true, skipAbsolute = true;\n for (var i = this._objects.length; i--; ){\n this._objects[i].setCoords(ignoreZoom, skipAbsolute);\n }\n },\n\n /**\n * @private\n * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change\n */\n _updateObjectsCoords: function(center) {\n var center = center || this.getCenterPoint();\n for (var i = this._objects.length; i--; ){\n this._updateObjectCoords(this._objects[i], center);\n }\n },\n\n /**\n * @private\n * @param {Object} object\n * @param {fabric.Point} center, current center of group.\n */\n _updateObjectCoords: function(object, center) {\n var objectLeft = object.left,\n objectTop = object.top,\n ignoreZoom = true, skipAbsolute = true;\n\n object.set({\n left: objectLeft - center.x,\n top: objectTop - center.y\n });\n object.group = this;\n object.setCoords(ignoreZoom, skipAbsolute);\n },\n\n /**\n * Returns string represenation of a group\n * @return {String}\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Adds an object to a group; Then recalculates group's dimension, position.\n * @param {Object} object\n * @return {fabric.Group} thisArg\n * @chainable\n */\n addWithUpdate: function(object) {\n this._restoreObjectsState();\n fabric.util.resetObjectTransform(this);\n if (object) {\n this._objects.push(object);\n object.group = this;\n object._set('canvas', this.canvas);\n }\n this._calcBounds();\n this._updateObjectsCoords();\n this.setCoords();\n this.dirty = true;\n return this;\n },\n\n /**\n * Removes an object from a group; Then recalculates group's dimension, position.\n * @param {Object} object\n * @return {fabric.Group} thisArg\n * @chainable\n */\n removeWithUpdate: function(object) {\n this._restoreObjectsState();\n fabric.util.resetObjectTransform(this);\n\n this.remove(object);\n this._calcBounds();\n this._updateObjectsCoords();\n this.setCoords();\n this.dirty = true;\n return this;\n },\n\n /**\n * @private\n */\n _onObjectAdded: function(object) {\n this.dirty = true;\n object.group = this;\n object._set('canvas', this.canvas);\n },\n\n /**\n * @private\n */\n _onObjectRemoved: function(object) {\n this.dirty = true;\n delete object.group;\n },\n\n /**\n * @private\n */\n _set: function(key, value) {\n var i = this._objects.length;\n if (this.useSetOnGroup) {\n while (i--) {\n this._objects[i].setOnGroup(key, value);\n }\n }\n if (key === 'canvas') {\n while (i--) {\n this._objects[i]._set(key, value);\n }\n }\n fabric.Object.prototype._set.call(this, key, value);\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var _includeDefaultValues = this.includeDefaultValues;\n var objsToObject = this._objects.map(function(obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n var _obj = obj.toObject(propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\n var obj = fabric.Object.prototype.toObject.call(this, propertiesToInclude);\n obj.objects = objsToObject;\n return obj;\n },\n\n /**\n * Returns object representation of an instance, in dataless mode.\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n var objsToObject, sourcePath = this.sourcePath;\n if (sourcePath) {\n objsToObject = sourcePath;\n }\n else {\n var _includeDefaultValues = this.includeDefaultValues;\n objsToObject = this._objects.map(function(obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n var _obj = obj.toDatalessObject(propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\n }\n var obj = fabric.Object.prototype.toDatalessObject.call(this, propertiesToInclude);\n obj.objects = objsToObject;\n return obj;\n },\n\n /**\n * Renders instance on a given context\n * @param {CanvasRenderingContext2D} ctx context to render instance on\n */\n render: function(ctx) {\n this._transformDone = true;\n this.callSuper('render', ctx);\n this._transformDone = false;\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group is already cached.\n * @return {Boolean}\n */\n shouldCache: function() {\n var ownCache = fabric.Object.prototype.shouldCache.call(this);\n if (ownCache) {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].willDrawShadow()) {\n this.ownCaching = false;\n return false;\n }\n }\n }\n return ownCache;\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * @return {Boolean}\n */\n willDrawShadow: function() {\n if (fabric.Object.prototype.willDrawShadow.call(this)) {\n return true;\n }\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].willDrawShadow()) {\n return true;\n }\n }\n return false;\n },\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache: function() {\n return this.ownCaching || (this.group && this.group.isOnACache());\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawObject: function(ctx) {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._objects[i].render(ctx);\n }\n this._drawClipPath(ctx);\n },\n\n /**\n * Check if cache is dirty\n */\n isCacheDirty: function(skipCanvas) {\n if (this.callSuper('isCacheDirty', skipCanvas)) {\n return true;\n }\n if (!this.statefullCache) {\n return false;\n }\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].isCacheDirty(true)) {\n if (this._cacheCanvas) {\n // if this group has not a cache canvas there is nothing to clean\n var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY;\n this._cacheContext.clearRect(-x / 2, -y / 2, x, y);\n }\n return true;\n }\n }\n return false;\n },\n\n /**\n * Retores original state of each of group objects (original state is that which was before group was created).\n * @private\n * @return {fabric.Group} thisArg\n * @chainable\n */\n _restoreObjectsState: function() {\n this._objects.forEach(this._restoreObjectState, this);\n return this;\n },\n\n /**\n * Realises the transform from this group onto the supplied object\n * i.e. it tells you what would happen if the supplied object was in\n * the group, and then the group was destroyed. It mutates the supplied\n * object.\n * @param {fabric.Object} object\n * @return {fabric.Object} transformedObject\n */\n realizeTransform: function(object) {\n var matrix = object.calcTransformMatrix(),\n options = fabric.util.qrDecompose(matrix),\n center = new fabric.Point(options.translateX, options.translateY);\n object.flipX = false;\n object.flipY = false;\n object.set('scaleX', options.scaleX);\n object.set('scaleY', options.scaleY);\n object.skewX = options.skewX;\n object.skewY = options.skewY;\n object.angle = options.angle;\n object.setPositionByOrigin(center, 'center', 'center');\n return object;\n },\n\n /**\n * Restores original state of a specified object in group\n * @private\n * @param {fabric.Object} object\n * @return {fabric.Group} thisArg\n */\n _restoreObjectState: function(object) {\n this.realizeTransform(object);\n object.setCoords();\n delete object.group;\n return this;\n },\n\n /**\n * Destroys a group (restoring state of its objects)\n * @return {fabric.Group} thisArg\n * @chainable\n */\n destroy: function() {\n // when group is destroyed objects needs to get a repaint to be eventually\n // displayed on canvas.\n this._objects.forEach(function(object) {\n object.set('dirty', true);\n });\n return this._restoreObjectsState();\n },\n\n /**\n * make a group an active selection, remove the group from canvas\n * the group has to be on canvas for this to work.\n * @return {fabric.ActiveSelection} thisArg\n * @chainable\n */\n toActiveSelection: function() {\n if (!this.canvas) {\n return;\n }\n var objects = this._objects, canvas = this.canvas;\n this._objects = [];\n var options = this.toObject();\n delete options.objects;\n var activeSelection = new fabric.ActiveSelection([]);\n activeSelection.set(options);\n activeSelection.type = 'activeSelection';\n canvas.remove(this);\n objects.forEach(function(object) {\n object.group = activeSelection;\n object.dirty = true;\n canvas.add(object);\n });\n activeSelection.canvas = canvas;\n activeSelection._objects = objects;\n canvas._activeObject = activeSelection;\n activeSelection.setCoords();\n return activeSelection;\n },\n\n /**\n * Destroys a group (restoring state of its objects)\n * @return {fabric.Group} thisArg\n * @chainable\n */\n ungroupOnCanvas: function() {\n return this._restoreObjectsState();\n },\n\n /**\n * Sets coordinates of all objects inside group\n * @return {fabric.Group} thisArg\n * @chainable\n */\n setObjectsCoords: function() {\n var ignoreZoom = true, skipAbsolute = true;\n this.forEachObject(function(object) {\n object.setCoords(ignoreZoom, skipAbsolute);\n });\n return this;\n },\n\n /**\n * @private\n */\n _calcBounds: function(onlyWidthHeight) {\n var aX = [],\n aY = [],\n o, prop,\n props = ['tr', 'br', 'bl', 'tl'],\n i = 0, iLen = this._objects.length,\n j, jLen = props.length,\n ignoreZoom = true;\n\n for ( ; i < iLen; ++i) {\n o = this._objects[i];\n o.setCoords(ignoreZoom);\n for (j = 0; j < jLen; j++) {\n prop = props[j];\n aX.push(o.oCoords[prop].x);\n aY.push(o.oCoords[prop].y);\n }\n }\n\n this._getBounds(aX, aY, onlyWidthHeight);\n },\n\n /**\n * @private\n */\n _getBounds: function(aX, aY, onlyWidthHeight) {\n var minXY = new fabric.Point(min(aX), min(aY)),\n maxXY = new fabric.Point(max(aX), max(aY)),\n top = minXY.y || 0, left = minXY.x || 0,\n width = (maxXY.x - minXY.x) || 0,\n height = (maxXY.y - minXY.y) || 0;\n this.width = width;\n this.height = height;\n if (!onlyWidthHeight) {\n // the bounding box always finds the topleft most corner.\n // whatever is the group origin, we set up here the left/top position.\n this.setPositionByOrigin({ x: left, y: top }, 'left', 'top');\n }\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n _toSVG: function(reviver) {\n var svgString = ['\\n'];\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n svgString.push('\\t\\t', this._objects[i].toSVG(reviver));\n }\n svgString.push('\\n');\n return svgString;\n },\n\n /**\n * Returns styles-string for svg-export, specific version for group\n * @return {String}\n */\n getSvgStyles: function() {\n var opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ?\n 'opacity: ' + this.opacity + ';' : '',\n visibility = this.visible ? '' : ' visibility: hidden;';\n return [\n opacity,\n this.getSvgFilter(),\n visibility\n ].join('');\n },\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG: function(reviver) {\n var svgString = [];\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n svgString.push('\\t', this._objects[i].toClipPathSVG(reviver));\n }\n\n return this._createBaseClipPathSVGMarkup(svgString, { reviver: reviver });\n },\n /* _TO_SVG_END_ */\n });\n\n /**\n * Returns {@link fabric.Group} instance from an object representation\n * @static\n * @memberOf fabric.Group\n * @param {Object} object Object to create a group from\n * @param {Function} [callback] Callback to invoke when an group instance is created\n */\n fabric.Group.fromObject = function(object, callback) {\n var objects = object.objects,\n options = fabric.util.object.clone(object, true);\n delete options.objects;\n if (typeof objects === 'string') {\n // it has to be an url or something went wrong.\n fabric.loadSVGFromURL(objects, function (elements) {\n var group = fabric.util.groupSVGElements(elements, object, objects);\n group.set(options);\n callback && callback(group);\n });\n return;\n }\n fabric.util.enlivenObjects(objects, function(enlivenedObjects) {\n fabric.util.enlivenObjects([object.clipPath], function(enlivedClipPath) {\n var options = fabric.util.object.clone(object, true);\n options.clipPath = enlivedClipPath[0];\n delete options.objects;\n callback && callback(new fabric.Group(enlivenedObjects, options, true));\n });\n });\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.ActiveSelection) {\n return;\n }\n\n /**\n * Group class\n * @class fabric.ActiveSelection\n * @extends fabric.Group\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n * @see {@link fabric.ActiveSelection#initialize} for constructor definition\n */\n fabric.ActiveSelection = fabric.util.createClass(fabric.Group, /** @lends fabric.ActiveSelection.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'activeSelection',\n\n /**\n * Constructor\n * @param {Object} objects ActiveSelection objects\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(objects, options) {\n options = options || {};\n this._objects = objects || [];\n for (var i = this._objects.length; i--; ) {\n this._objects[i].group = this;\n }\n\n if (options.originX) {\n this.originX = options.originX;\n }\n if (options.originY) {\n this.originY = options.originY;\n }\n this._calcBounds();\n this._updateObjectsCoords();\n fabric.Object.prototype.initialize.call(this, options);\n this.setCoords();\n },\n\n /**\n * Change te activeSelection to a normal group,\n * High level function that automatically adds it to canvas as\n * active object. no events fired.\n * @since 2.0.0\n * @return {fabric.Group}\n */\n toGroup: function() {\n var objects = this._objects.concat();\n this._objects = [];\n var options = fabric.Object.prototype.toObject.call(this);\n var newGroup = new fabric.Group([]);\n delete options.type;\n newGroup.set(options);\n objects.forEach(function(object) {\n object.canvas.remove(object);\n object.group = newGroup;\n });\n newGroup._objects = objects;\n if (!this.canvas) {\n return newGroup;\n }\n var canvas = this.canvas;\n canvas.add(newGroup);\n canvas._activeObject = newGroup;\n newGroup.setCoords();\n return newGroup;\n },\n\n /**\n * If returns true, deselection is cancelled.\n * @since 2.0.0\n * @return {Boolean} [cancel]\n */\n onDeselect: function() {\n this.destroy();\n return false;\n },\n\n /**\n * Returns string representation of a group\n * @return {String}\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @return {Boolean}\n */\n shouldCache: function() {\n return false;\n },\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache: function() {\n return false;\n },\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [styleOverride] properties to override the object style\n * @param {Object} [childrenOverride] properties to override the children overrides\n */\n _renderControls: function(ctx, styleOverride, childrenOverride) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n this.callSuper('_renderControls', ctx, styleOverride);\n childrenOverride = childrenOverride || { };\n if (typeof childrenOverride.hasControls === 'undefined') {\n childrenOverride.hasControls = false;\n }\n if (typeof childrenOverride.hasRotatingPoint === 'undefined') {\n childrenOverride.hasRotatingPoint = false;\n }\n childrenOverride.forActiveSelection = true;\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._objects[i]._renderControls(ctx, childrenOverride);\n }\n ctx.restore();\n },\n });\n\n /**\n * Returns {@link fabric.ActiveSelection} instance from an object representation\n * @static\n * @memberOf fabric.ActiveSelection\n * @param {Object} object Object to create a group from\n * @param {Function} [callback] Callback to invoke when an ActiveSelection instance is created\n */\n fabric.ActiveSelection.fromObject = function(object, callback) {\n fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {\n delete object.objects;\n callback && callback(new fabric.ActiveSelection(enlivenedObjects, object, true));\n });\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var extend = fabric.util.object.extend;\n\n if (!global.fabric) {\n global.fabric = { };\n }\n\n if (global.fabric.Image) {\n fabric.warn('fabric.Image is already defined.');\n return;\n }\n\n /**\n * Image class\n * @class fabric.Image\n * @extends fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}\n * @see {@link fabric.Image#initialize} for constructor definition\n */\n fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'image',\n\n /**\n * crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n * @type String\n * @default\n */\n crossOrigin: '',\n\n /**\n * Width of a stroke.\n * For image quality a stroke multiple of 2 gives better results.\n * @type Number\n * @default\n */\n strokeWidth: 0,\n\n /**\n * When calling {@link fabric.Image.getSrc}, return value from element src with `element.getAttribute('src')`.\n * This allows for relative urls as image src.\n * @since 2.7.0\n * @type Boolean\n * @default\n */\n srcFromAttribute: false,\n\n /**\n * private\n * contains last value of scaleX to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n _lastScaleX: 1,\n\n /**\n * private\n * contains last value of scaleY to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n _lastScaleY: 1,\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n _filterScalingX: 1,\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n _filterScalingY: 1,\n\n /**\n * minimum scale factor under which any resizeFilter is triggered to resize the image\n * 0 will disable the automatic resize. 1 will trigger automatically always.\n * number bigger than 1 are not implemented yet.\n * @type Number\n */\n minimumScaleTrigger: 0.5,\n\n /**\n * List of properties to consider when checking if\n * state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat('cropX', 'cropY'),\n\n /**\n * key used to retrieve the texture representing this image\n * @since 2.0.0\n * @type String\n * @default\n */\n cacheKey: '',\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n cropX: 0,\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n cropY: 0,\n\n /**\n * Constructor\n * @param {HTMLImageElement | String} element Image element\n * @param {Object} [options] Options object\n * @param {function} [callback] callback function to call after eventual filters applied.\n * @return {fabric.Image} thisArg\n */\n initialize: function(element, options) {\n options || (options = { });\n this.filters = [];\n this.cacheKey = 'texture' + fabric.Object.__uid++;\n this.callSuper('initialize', options);\n this._initElement(element, options);\n },\n\n /**\n * Returns image element which this instance if based on\n * @return {HTMLImageElement} Image element\n */\n getElement: function() {\n return this._element || {};\n },\n\n /**\n * Sets image element for this instance to a specified one.\n * If filters defined they are applied to new image.\n * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.\n * @param {HTMLImageElement} element\n * @param {Object} [options] Options object\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setElement: function(element, options) {\n this.removeTexture(this.cacheKey);\n this.removeTexture(this.cacheKey + '_filtered');\n this._element = element;\n this._originalElement = element;\n this._initConfig(options);\n if (this.filters.length !== 0) {\n this.applyFilters();\n }\n // resizeFilters work on the already filtered copy.\n // we need to apply resizeFilters AFTER normal filters.\n // applyResizeFilters is run more often than normal fiters\n // and is triggered by user interactions rather than dev code\n if (this.resizeFilter) {\n this.applyResizeFilters();\n }\n return this;\n },\n\n /**\n * Delete a single texture if in webgl mode\n */\n removeTexture: function(key) {\n var backend = fabric.filterBackend;\n if (backend && backend.evictCachesForKey) {\n backend.evictCachesForKey(key);\n }\n },\n\n /**\n * Delete textures, reference to elements and eventually JSDOM cleanup\n */\n dispose: function() {\n this.removeTexture(this.cacheKey);\n this.removeTexture(this.cacheKey + '_filtered');\n this._cacheContext = undefined;\n ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach((function(element) {\n fabric.util.cleanUpJsdomNode(this[element]);\n this[element] = undefined;\n }).bind(this));\n },\n\n /**\n * Sets crossOrigin value (on an instance and corresponding image element)\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setCrossOrigin: function(value) {\n this.crossOrigin = value;\n this._element.crossOrigin = value;\n\n return this;\n },\n\n /**\n * Returns original size of an image\n * @return {Object} Object with \"width\" and \"height\" properties\n */\n getOriginalSize: function() {\n var element = this.getElement();\n return {\n width: element.naturalWidth || element.width,\n height: element.naturalHeight || element.height\n };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _stroke: function(ctx) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n var w = this.width / 2, h = this.height / 2;\n ctx.beginPath();\n ctx.moveTo(-w, -h);\n ctx.lineTo(w, -h);\n ctx.lineTo(w, h);\n ctx.lineTo(-w, h);\n ctx.lineTo(-w, -h);\n ctx.closePath();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\n\n ctx.save();\n this._setStrokeStyles(ctx, this);\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n ctx.closePath();\n ctx.restore();\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var filters = [];\n\n this.filters.forEach(function(filterObj) {\n if (filterObj) {\n filters.push(filterObj.toObject());\n }\n });\n var object = extend(\n this.callSuper(\n 'toObject',\n ['crossOrigin', 'cropX', 'cropY'].concat(propertiesToInclude)\n ), {\n src: this.getSrc(),\n filters: filters,\n });\n if (this.resizeFilter) {\n object.resizeFilter = this.resizeFilter.toObject();\n }\n return object;\n },\n\n /**\n * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,hight.\n * @return {Boolean}\n */\n hasCrop: function() {\n return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var svgString = [], imageMarkup = [], strokeSvg,\n x = -this.width / 2, y = -this.height / 2, clipPath = '';\n if (this.hasCrop()) {\n var clipPathId = fabric.Object.__uid++;\n svgString.push(\n '\\n',\n '\\t\\n',\n '\\n'\n );\n clipPath = ' clip-path=\"url(#imageCrop_' + clipPathId + ')\" ';\n }\n imageMarkup.push('\\t element with actual transformation, then offsetting object to the top/left\n // so that object's center aligns with container's left/top\n '\" width=\"', this._element.width || this._element.naturalWidth,\n '\" height=\"', this._element.height || this._element.height,\n '\"', clipPath,\n '>\\n');\n\n if (this.stroke || this.strokeDashArray) {\n var origFill = this.fill;\n this.fill = null;\n strokeSvg = [\n '\\t\\n'\n ];\n this.fill = origFill;\n }\n if (this.paintFirst !== 'fill') {\n svgString = svgString.concat(strokeSvg, imageMarkup);\n }\n else {\n svgString = svgString.concat(imageMarkup, strokeSvg);\n }\n return svgString;\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns source of an image\n * @param {Boolean} filtered indicates if the src is needed for svg\n * @return {String} Source of an image\n */\n getSrc: function(filtered) {\n var element = filtered ? this._element : this._originalElement;\n if (element) {\n if (element.toDataURL) {\n return element.toDataURL();\n }\n\n if (this.srcFromAttribute) {\n return element.getAttribute('src');\n }\n else {\n return element.src;\n }\n }\n else {\n return this.src || '';\n }\n },\n\n /**\n * Sets source of an image\n * @param {String} src Source string (URL)\n * @param {Function} [callback] Callback is invoked when image has been loaded (and all filters have been applied)\n * @param {Object} [options] Options object\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setSrc: function(src, callback, options) {\n fabric.util.loadImage(src, function(img) {\n this.setElement(img, options);\n this._setWidthHeight();\n callback && callback(this);\n }, this, options && options.crossOrigin);\n return this;\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of an instance\n */\n toString: function() {\n return '#';\n },\n\n applyResizeFilters: function() {\n var filter = this.resizeFilter,\n minimumScale = this.minimumScaleTrigger,\n objectScale = this.getTotalObjectScaling(),\n scaleX = objectScale.scaleX,\n scaleY = objectScale.scaleY,\n elementToFilter = this._filteredEl || this._originalElement;\n if (this.group) {\n this.set('dirty', true);\n }\n if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) {\n this._element = elementToFilter;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n this._lastScaleX = scaleX;\n this._lastScaleY = scaleY;\n return;\n }\n if (!fabric.filterBackend) {\n fabric.filterBackend = fabric.initFilterBackend();\n }\n var canvasEl = fabric.util.createCanvasElement(),\n cacheKey = this._filteredEl ? (this.cacheKey + '_filtered') : this.cacheKey,\n sourceWidth = elementToFilter.width, sourceHeight = elementToFilter.height;\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._lastScaleX = filter.scaleX = scaleX;\n this._lastScaleY = filter.scaleY = scaleY;\n fabric.filterBackend.applyFilters(\n [filter], elementToFilter, sourceWidth, sourceHeight, this._element, cacheKey);\n this._filterScalingX = canvasEl.width / this._originalElement.width;\n this._filterScalingY = canvasEl.height / this._originalElement.height;\n },\n\n /**\n * Applies filters assigned to this image (from \"filters\" array) or from filter param\n * @method applyFilters\n * @param {Array} filters to be applied\n * @param {Boolean} forResizing specify if the filter operation is a resize operation\n * @return {thisArg} return the fabric.Image object\n * @chainable\n */\n applyFilters: function(filters) {\n\n filters = filters || this.filters || [];\n filters = filters.filter(function(filter) { return filter && !filter.isNeutralState(); });\n this.set('dirty', true);\n\n // needs to clear out or WEBGL will not resize correctly\n this.removeTexture(this.cacheKey + '_filtered');\n\n if (filters.length === 0) {\n this._element = this._originalElement;\n this._filteredEl = null;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n return this;\n }\n\n var imgElement = this._originalElement,\n sourceWidth = imgElement.naturalWidth || imgElement.width,\n sourceHeight = imgElement.naturalHeight || imgElement.height;\n\n if (this._element === this._originalElement) {\n // if the element is the same we need to create a new element\n var canvasEl = fabric.util.createCanvasElement();\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._filteredEl = canvasEl;\n }\n else {\n // clear the existing element to get new filter data\n // also dereference the eventual resized _element\n this._element = this._filteredEl;\n this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight);\n // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y\n this._lastScaleX = 1;\n this._lastScaleY = 1;\n }\n if (!fabric.filterBackend) {\n fabric.filterBackend = fabric.initFilterBackend();\n }\n fabric.filterBackend.applyFilters(\n filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey);\n if (this._originalElement.width !== this._element.width ||\n this._originalElement.height !== this._element.height) {\n this._filterScalingX = this._element.width / this._originalElement.width;\n this._filterScalingY = this._element.height / this._originalElement.height;\n }\n return this;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {\n this.applyResizeFilters();\n }\n this._stroke(ctx);\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * This is the special image version where we would like to avoid caching where possible.\n * Essentially images do not benefit from caching. They may require caching, and in that\n * case we do it. Also caching an image usually ends in a loss of details.\n * A full performance audit should be done.\n * @return {Boolean}\n */\n shouldCache: function() {\n return this.needsItsOwnCache();\n },\n\n _renderFill: function(ctx) {\n var elementToDraw = this._element;\n if (!elementToDraw) {\n return;\n }\n var scaleX = this._filterScalingX, scaleY = this._filterScalingY,\n w = this.width, h = this.height, min = Math.min, max = Math.max,\n // crop values cannot be lesser than 0.\n cropX = max(this.cropX, 0), cropY = max(this.cropY, 0),\n elWidth = elementToDraw.naturalWidth || elementToDraw.width,\n elHeight = elementToDraw.naturalHeight || elementToDraw.height,\n sX = cropX * scaleX,\n sY = cropY * scaleY,\n // the width height cannot exceed element width/height, starting from the crop offset.\n sW = min(w * scaleX, elWidth - sX),\n sH = min(h * scaleY, elHeight - sY),\n x = -w / 2, y = -h / 2,\n maxDestW = min(w, elWidth / scaleX - cropX),\n maxDestH = min(h, elHeight / scaleX - cropY);\n\n elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH);\n },\n\n /**\n * needed to check if image needs resize\n * @private\n */\n _needsResize: function() {\n var scale = this.getTotalObjectScaling();\n return (scale.scaleX !== this._lastScaleX || scale.scaleY !== this._lastScaleY);\n },\n\n /**\n * @private\n */\n _resetWidthHeight: function() {\n this.set(this.getOriginalSize());\n },\n\n /**\n * The Image class's initialization method. This method is automatically\n * called by the constructor.\n * @private\n * @param {HTMLImageElement|String} element The element representing the image\n * @param {Object} [options] Options object\n */\n _initElement: function(element, options) {\n this.setElement(fabric.util.getById(element), options);\n fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS);\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initConfig: function(options) {\n options || (options = { });\n this.setOptions(options);\n this._setWidthHeight(options);\n if (this._element && this.crossOrigin) {\n this._element.crossOrigin = this.crossOrigin;\n }\n },\n\n /**\n * @private\n * @param {Array} filters to be initialized\n * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created\n */\n _initFilters: function(filters, callback) {\n if (filters && filters.length) {\n fabric.util.enlivenObjects(filters, function(enlivenedObjects) {\n callback && callback(enlivenedObjects);\n }, 'fabric.Image.filters');\n }\n else {\n callback && callback();\n }\n },\n\n /**\n * @private\n * Set the width and the height of the image object, using the element or the\n * options.\n * @param {Object} [options] Object with width/height properties\n */\n _setWidthHeight: function(options) {\n options || (options = { });\n var el = this.getElement();\n this.width = options.width || el.naturalWidth || el.width || 0;\n this.height = options.height || el.naturalHeight || el.height || 0;\n },\n\n /**\n * Calculate offset for center and scale factor for the image in order to respect\n * the preserveAspectRatio attribute\n * @private\n * @return {Object}\n */\n parsePreserveAspectRatioAttribute: function() {\n var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''),\n rWidth = this._element.width, rHeight = this._element.height,\n scaleX = 1, scaleY = 1, offsetLeft = 0, offsetTop = 0, cropX = 0, cropY = 0,\n offset, pWidth = this.width, pHeight = this.height, parsedAttributes = { width: pWidth, height: pHeight };\n if (pAR && (pAR.alignX !== 'none' || pAR.alignY !== 'none')) {\n if (pAR.meetOrSlice === 'meet') {\n scaleX = scaleY = fabric.util.findScaleToFit(this._element, parsedAttributes);\n offset = (pWidth - rWidth * scaleX) / 2;\n if (pAR.alignX === 'Min') {\n offsetLeft = -offset;\n }\n if (pAR.alignX === 'Max') {\n offsetLeft = offset;\n }\n offset = (pHeight - rHeight * scaleY) / 2;\n if (pAR.alignY === 'Min') {\n offsetTop = -offset;\n }\n if (pAR.alignY === 'Max') {\n offsetTop = offset;\n }\n }\n if (pAR.meetOrSlice === 'slice') {\n scaleX = scaleY = fabric.util.findScaleToCover(this._element, parsedAttributes);\n offset = rWidth - pWidth / scaleX;\n if (pAR.alignX === 'Mid') {\n cropX = offset / 2;\n }\n if (pAR.alignX === 'Max') {\n cropX = offset;\n }\n offset = rHeight - pHeight / scaleY;\n if (pAR.alignY === 'Mid') {\n cropY = offset / 2;\n }\n if (pAR.alignY === 'Max') {\n cropY = offset;\n }\n rWidth = pWidth / scaleX;\n rHeight = pHeight / scaleY;\n }\n }\n else {\n scaleX = pWidth / rWidth;\n scaleY = pHeight / rHeight;\n }\n return {\n width: rWidth,\n height: rHeight,\n scaleX: scaleX,\n scaleY: scaleY,\n offsetLeft: offsetLeft,\n offsetTop: offsetTop,\n cropX: cropX,\n cropY: cropY\n };\n }\n });\n\n /**\n * Default CSS class name for canvas\n * @static\n * @type String\n * @default\n */\n fabric.Image.CSS_CANVAS = 'canvas-img';\n\n /**\n * Alias for getSrc\n * @static\n */\n fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;\n\n /**\n * Creates an instance of fabric.Image from its object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} callback Callback to invoke when an image instance is created\n */\n fabric.Image.fromObject = function(_object, callback) {\n var object = fabric.util.object.clone(_object);\n fabric.util.loadImage(object.src, function(img, error) {\n if (error) {\n callback && callback(null, error);\n return;\n }\n fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) {\n object.filters = filters || [];\n fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function(resizeFilters) {\n object.resizeFilter = resizeFilters[0];\n fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {\n object.clipPath = enlivedProps[0];\n var image = new fabric.Image(img, object);\n callback(image);\n });\n });\n });\n }, null, object.crossOrigin);\n };\n\n /**\n * Creates an instance of fabric.Image from an URL string\n * @static\n * @param {String} url URL to create an image from\n * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument)\n * @param {Object} [imgOptions] Options object\n */\n fabric.Image.fromURL = function(url, callback, imgOptions) {\n fabric.util.loadImage(url, function(img) {\n callback && callback(new fabric.Image(img, imgOptions));\n }, null, imgOptions && imgOptions.crossOrigin);\n };\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement})\n * @static\n * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}\n */\n fabric.Image.ATTRIBUTE_NAMES =\n fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href crossOrigin'.split(' '));\n\n /**\n * Returns {@link fabric.Image} instance from an SVG element\n * @static\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {Function} callback Callback to execute when fabric.Image object is created\n * @return {fabric.Image} Instance of fabric.Image\n */\n fabric.Image.fromElement = function(element, callback, options) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES);\n fabric.Image.fromURL(parsedAttributes['xlink:href'], callback,\n extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n };\n /* _FROM_SVG_END_ */\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * @private\n * @return {Number} angle value\n */\n _getAngleValueForStraighten: function() {\n var angle = this.angle % 360;\n if (angle > 0) {\n return Math.round((angle - 1) / 90) * 90;\n }\n return Math.round(angle / 90) * 90;\n },\n\n /**\n * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n straighten: function() {\n this.rotate(this._getAngleValueForStraighten());\n return this;\n },\n\n /**\n * Same as {@link fabric.Object.prototype.straighten} but with animation\n * @param {Object} callbacks Object with callback functions\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Object} thisArg\n * @chainable\n */\n fxStraighten: function(callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: this.get('angle'),\n endValue: this._getAngleValueForStraighten(),\n duration: this.FX_DURATION,\n onChange: function(value) {\n _this.rotate(value);\n onChange();\n },\n onComplete: function() {\n _this.setCoords();\n onComplete();\n },\n });\n\n return this;\n }\n});\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Straightens object, then rerenders canvas\n * @param {fabric.Object} object Object to straighten\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n straightenObject: function (object) {\n object.straighten();\n this.requestRenderAll();\n return this;\n },\n\n /**\n * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated\n * @param {fabric.Object} object Object to straighten\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxStraightenObject: function (object) {\n object.fxStraighten({\n onChange: this.requestRenderAllBound\n });\n return this;\n }\n});\n\n\n(function() {\n\n 'use strict';\n\n /**\n * Tests if webgl supports certain precision\n * @param {WebGL} Canvas WebGL context to test on\n * @param {String} Precision to test can be any of following: 'lowp', 'mediump', 'highp'\n * @returns {Boolean} Whether the user's browser WebGL supports given precision.\n */\n function testPrecision(gl, precision){\n var fragmentSource = 'precision ' + precision + ' float;\\nvoid main(){}';\n var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n return false;\n }\n return true;\n }\n\n /**\n * Indicate whether this filtering backend is supported by the user's browser.\n * @param {Number} tileSize check if the tileSize is supported\n * @returns {Boolean} Whether the user's browser supports WebGL.\n */\n fabric.isWebglSupported = function(tileSize) {\n if (fabric.isLikelyNode) {\n return false;\n }\n tileSize = tileSize || fabric.WebglFilterBackend.prototype.tileSize;\n var canvas = document.createElement('canvas');\n var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');\n var isSupported = false;\n // eslint-disable-next-line\n if (gl) {\n fabric.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n isSupported = fabric.maxTextureSize >= tileSize;\n var precisions = ['highp', 'mediump', 'lowp'];\n for (var i = 0; i < 3; i++){\n if (testPrecision(gl, precisions[i])){\n fabric.webGlPrecision = precisions[i];\n break;\n };\n }\n }\n this.isSupported = isSupported;\n return isSupported;\n };\n\n fabric.WebglFilterBackend = WebglFilterBackend;\n\n /**\n * WebGL filter backend.\n */\n function WebglFilterBackend(options) {\n if (options && options.tileSize) {\n this.tileSize = options.tileSize;\n }\n this.setupGLContext(this.tileSize, this.tileSize);\n this.captureGPUInfo();\n };\n\n WebglFilterBackend.prototype = /** @lends fabric.WebglFilterBackend.prototype */ {\n\n tileSize: 2048,\n\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you problably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: {\n\n },\n\n /**\n * Setup a WebGL context suitable for filtering, and bind any needed event handlers.\n */\n setupGLContext: function(width, height) {\n this.dispose();\n this.createWebGLCanvas(width, height);\n // eslint-disable-next-line\n this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]);\n this.chooseFastestCopyGLTo2DMethod(width, height);\n },\n\n /**\n * Pick a method to copy data from GL context to 2d canvas. In some browsers using\n * putImageData is faster than drawImage for that specific operation.\n */\n chooseFastestCopyGLTo2DMethod: function(width, height) {\n var canMeasurePerf = typeof window.performance !== 'undefined', canUseImageData;\n try {\n new ImageData(1, 1);\n canUseImageData = true;\n }\n catch (e) {\n canUseImageData = false;\n }\n // eslint-disable-next-line no-undef\n var canUseArrayBuffer = typeof ArrayBuffer !== 'undefined';\n // eslint-disable-next-line no-undef\n var canUseUint8Clamped = typeof Uint8ClampedArray !== 'undefined';\n\n if (!(canMeasurePerf && canUseImageData && canUseArrayBuffer && canUseUint8Clamped)) {\n return;\n }\n\n var targetCanvas = fabric.util.createCanvasElement();\n // eslint-disable-next-line no-undef\n var imageBuffer = new ArrayBuffer(width * height * 4);\n if (fabric.forceGLPutImageData) {\n this.imageBuffer = imageBuffer;\n this.copyGLTo2D = copyGLTo2DPutImageData;\n return;\n }\n var testContext = {\n imageBuffer: imageBuffer,\n destinationWidth: width,\n destinationHeight: height,\n targetCanvas: targetCanvas\n };\n var startTime, drawImageTime, putImageDataTime;\n targetCanvas.width = width;\n targetCanvas.height = height;\n\n startTime = window.performance.now();\n copyGLTo2DDrawImage.call(testContext, this.gl, testContext);\n drawImageTime = window.performance.now() - startTime;\n\n startTime = window.performance.now();\n copyGLTo2DPutImageData.call(testContext, this.gl, testContext);\n putImageDataTime = window.performance.now() - startTime;\n\n if (drawImageTime > putImageDataTime) {\n this.imageBuffer = imageBuffer;\n this.copyGLTo2D = copyGLTo2DPutImageData;\n }\n else {\n this.copyGLTo2D = copyGLTo2DDrawImage;\n }\n },\n\n /**\n * Create a canvas element and associated WebGL context and attaches them as\n * class properties to the GLFilterBackend class.\n */\n createWebGLCanvas: function(width, height) {\n var canvas = fabric.util.createCanvasElement();\n canvas.width = width;\n canvas.height = height;\n var glOptions = {\n alpha: true,\n premultipliedAlpha: false,\n depth: false,\n stencil: false,\n antialias: false\n },\n gl = canvas.getContext('webgl', glOptions);\n if (!gl) {\n gl = canvas.getContext('experimental-webgl', glOptions);\n }\n if (!gl) {\n return;\n }\n gl.clearColor(0, 0, 0, 0);\n // this canvas can fire webglcontextlost and webglcontextrestored\n this.canvas = canvas;\n this.gl = gl;\n },\n\n /**\n * Attempts to apply the requested filters to the source provided, drawing the filtered output\n * to the provided target canvas.\n *\n * @param {Array} filters The filters to apply.\n * @param {HTMLImageElement|HTMLCanvasElement} source The source to be filtered.\n * @param {Number} width The width of the source input.\n * @param {Number} height The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n * @param {String|undefined} cacheKey A key used to cache resources related to the source. If\n * omitted, caching will be skipped.\n */\n applyFilters: function(filters, source, width, height, targetCanvas, cacheKey) {\n var gl = this.gl;\n var cachedTexture;\n if (cacheKey) {\n cachedTexture = this.getCachedTexture(cacheKey, source);\n }\n var pipelineState = {\n originalWidth: source.width || source.originalWidth,\n originalHeight: source.height || source.originalHeight,\n sourceWidth: width,\n sourceHeight: height,\n destinationWidth: width,\n destinationHeight: height,\n context: gl,\n sourceTexture: this.createTexture(gl, width, height, !cachedTexture && source),\n targetTexture: this.createTexture(gl, width, height),\n originalTexture: cachedTexture ||\n this.createTexture(gl, width, height, !cachedTexture && source),\n passes: filters.length,\n webgl: true,\n aPosition: this.aPosition,\n programCache: this.programCache,\n pass: 0,\n filterBackend: this,\n targetCanvas: targetCanvas\n };\n var tempFbo = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo);\n filters.forEach(function(filter) { filter && filter.applyTo(pipelineState); });\n resizeCanvasIfNeeded(pipelineState);\n this.copyGLTo2D(gl, pipelineState);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.deleteTexture(pipelineState.sourceTexture);\n gl.deleteTexture(pipelineState.targetTexture);\n gl.deleteFramebuffer(tempFbo);\n targetCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0);\n return pipelineState;\n },\n\n /**\n * Detach event listeners, remove references, and clean up caches.\n */\n dispose: function() {\n if (this.canvas) {\n this.canvas = null;\n this.gl = null;\n }\n this.clearWebGLCaches();\n },\n\n /**\n * Wipe out WebGL-related caches.\n */\n clearWebGLCaches: function() {\n this.programCache = {};\n this.textureCache = {};\n },\n\n /**\n * Create a WebGL texture object.\n *\n * Accepts specific dimensions to initialize the textuer to or a source image.\n *\n * @param {WebGLRenderingContext} gl The GL context to use for creating the texture.\n * @param {Number} width The width to initialize the texture at.\n * @param {Number} height The height to initialize the texture.\n * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source for the texture data.\n * @returns {WebGLTexture}\n */\n createTexture: function(gl, width, height, textureImageSource) {\n var texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n if (textureImageSource) {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImageSource);\n }\n else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n }\n return texture;\n },\n\n /**\n * Can be optionally used to get a texture from the cache array\n *\n * If an existing texture is not found, a new texture is created and cached.\n *\n * @param {String} uniqueId A cache key to use to find an existing texture.\n * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the\n * texture cache entry if one does not already exist.\n */\n getCachedTexture: function(uniqueId, textureImageSource) {\n if (this.textureCache[uniqueId]) {\n return this.textureCache[uniqueId];\n }\n else {\n var texture = this.createTexture(\n this.gl, textureImageSource.width, textureImageSource.height, textureImageSource);\n this.textureCache[uniqueId] = texture;\n return texture;\n }\n },\n\n /**\n * Clear out cached resources related to a source image that has been\n * filtered previously.\n *\n * @param {String} cacheKey The cache key provided when the source image was filtered.\n */\n evictCachesForKey: function(cacheKey) {\n if (this.textureCache[cacheKey]) {\n this.gl.deleteTexture(this.textureCache[cacheKey]);\n delete this.textureCache[cacheKey];\n }\n },\n\n copyGLTo2D: copyGLTo2DDrawImage,\n\n /**\n * Attempt to extract GPU information strings from a WebGL context.\n *\n * Useful information when debugging or blacklisting specific GPUs.\n *\n * @returns {Object} A GPU info object with renderer and vendor strings.\n */\n captureGPUInfo: function() {\n if (this.gpuInfo) {\n return this.gpuInfo;\n }\n var gl = this.gl, gpuInfo = { renderer: '', vendor: '' };\n if (!gl) {\n return gpuInfo;\n }\n var ext = gl.getExtension('WEBGL_debug_renderer_info');\n if (ext) {\n var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);\n var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);\n if (renderer) {\n gpuInfo.renderer = renderer.toLowerCase();\n }\n if (vendor) {\n gpuInfo.vendor = vendor.toLowerCase();\n }\n }\n this.gpuInfo = gpuInfo;\n return gpuInfo;\n },\n };\n})();\n\nfunction resizeCanvasIfNeeded(pipelineState) {\n var targetCanvas = pipelineState.targetCanvas,\n width = targetCanvas.width, height = targetCanvas.height,\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight;\n\n if (width !== dWidth || height !== dHeight) {\n targetCanvas.width = dWidth;\n targetCanvas.height = dHeight;\n }\n}\n\n/**\n * Copy an input WebGL canvas on to an output 2D canvas.\n *\n * The WebGL canvas is assumed to be upside down, with the top-left pixel of the\n * desired output image appearing in the bottom-left corner of the WebGL canvas.\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\nfunction copyGLTo2DDrawImage(gl, pipelineState) {\n var glCanvas = gl.canvas, targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d');\n ctx.translate(0, targetCanvas.height); // move it down again\n ctx.scale(1, -1); // vertical flip\n // where is my image on the big glcanvas?\n var sourceY = glCanvas.height - targetCanvas.height;\n ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0,\n targetCanvas.width, targetCanvas.height);\n}\n\n/**\n * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData\n * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra).\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\nfunction copyGLTo2DPutImageData(gl, pipelineState) {\n var targetCanvas = pipelineState.targetCanvas, ctx = targetCanvas.getContext('2d'),\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight,\n numBytes = dWidth * dHeight * 4;\n\n // eslint-disable-next-line no-undef\n var u8 = new Uint8Array(this.imageBuffer, 0, numBytes);\n // eslint-disable-next-line no-undef\n var u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes);\n\n gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8);\n var imgData = new ImageData(u8Clamped, dWidth, dHeight);\n ctx.putImageData(imgData, 0, 0);\n}\n\n\n(function() {\n\n 'use strict';\n\n var noop = function() {};\n\n fabric.Canvas2dFilterBackend = Canvas2dFilterBackend;\n\n /**\n * Canvas 2D filter backend.\n */\n function Canvas2dFilterBackend() {};\n\n Canvas2dFilterBackend.prototype = /** @lends fabric.Canvas2dFilterBackend.prototype */ {\n evictCachesForKey: noop,\n dispose: noop,\n clearWebGLCaches: noop,\n\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you probably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: {\n\n },\n\n /**\n * Apply a set of filters against a source image and draw the filtered output\n * to the provided destination canvas.\n *\n * @param {EnhancedFilter} filters The filter to apply.\n * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered.\n * @param {Number} sourceWidth The width of the source input.\n * @param {Number} sourceHeight The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n */\n applyFilters: function(filters, sourceElement, sourceWidth, sourceHeight, targetCanvas) {\n var ctx = targetCanvas.getContext('2d');\n ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight);\n var imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n var originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n var pipelineState = {\n sourceWidth: sourceWidth,\n sourceHeight: sourceHeight,\n imageData: imageData,\n originalEl: sourceElement,\n originalImageData: originalImageData,\n canvasEl: targetCanvas,\n ctx: ctx,\n filterBackend: this,\n };\n filters.forEach(function(filter) { filter.applyTo(pipelineState); });\n if (pipelineState.imageData.width !== sourceWidth || pipelineState.imageData.height !== sourceHeight) {\n targetCanvas.width = pipelineState.imageData.width;\n targetCanvas.height = pipelineState.imageData.height;\n }\n ctx.putImageData(pipelineState.imageData, 0, 0);\n return pipelineState;\n },\n\n };\n})();\n\n\n/**\n * @namespace fabric.Image.filters\n * @memberOf fabric.Image\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters}\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n */\nfabric.Image = fabric.Image || { };\nfabric.Image.filters = fabric.Image.filters || { };\n\n/**\n * Root filter class from which all filter classes inherit from\n * @class fabric.Image.filters.BaseFilter\n * @memberOf fabric.Image.filters\n */\nfabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Image.filters.BaseFilter.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'BaseFilter',\n\n /**\n * Array of attributes to send with buffers. do not modify\n * @private\n */\n\n vertexSource: 'attribute vec2 aPosition;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vTexCoord = aPosition;\\n' +\n 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' +\n '}',\n\n fragmentSource: 'precision highp float;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'void main() {\\n' +\n 'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' +\n '}',\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n if (options) {\n this.setOptions(options);\n }\n },\n\n /**\n * Sets filter's properties from options\n * @param {Object} [options] Options object\n */\n setOptions: function(options) {\n for (var prop in options) {\n this[prop] = options[prop];\n }\n },\n\n /**\n * Compile this filter's shader program.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation.\n * @param {String} fragmentSource fragmentShader source for compilation\n * @param {String} vertexSource vertexShader source for compilation\n */\n createProgram: function(gl, fragmentSource, vertexSource) {\n fragmentSource = fragmentSource || this.fragmentSource;\n vertexSource = vertexSource || this.vertexSource;\n if (fabric.webGlPrecision !== 'highp'){\n fragmentSource = fragmentSource.replace(\n /precision highp float/g,\n 'precision ' + fabric.webGlPrecision + ' float'\n );\n }\n var vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n throw new Error(\n // eslint-disable-next-line prefer-template\n 'Vertex shader compile error for ' + this.type + ': ' +\n gl.getShaderInfoLog(vertexShader)\n );\n }\n\n var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n throw new Error(\n // eslint-disable-next-line prefer-template\n 'Fragment shader compile error for ' + this.type + ': ' +\n gl.getShaderInfoLog(fragmentShader)\n );\n }\n\n var program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error(\n // eslint-disable-next-line prefer-template\n 'Shader link error for \"${this.type}\" ' +\n gl.getProgramInfoLog(program)\n );\n }\n\n var attributeLocations = this.getAttributeLocations(gl, program);\n var uniformLocations = this.getUniformLocations(gl, program) || { };\n uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');\n uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');\n return {\n program: program,\n attributeLocations: attributeLocations,\n uniformLocations: uniformLocations\n };\n },\n\n /**\n * Return a map of attribute names to WebGLAttributeLocation objects.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take attribute locations.\n * @returns {Object} A map of attribute names to attribute locations.\n */\n getAttributeLocations: function(gl, program) {\n return {\n aPosition: gl.getAttribLocation(program, 'aPosition'),\n };\n },\n\n /**\n * Return a map of uniform names to WebGLUniformLocation objects.\n *\n * Intended to be overridden by subclasses.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take uniform locations.\n * @returns {Object} A map of uniform names to uniform locations.\n */\n getUniformLocations: function (/* gl, program */) {\n // in case i do not need any special uniform i need to return an empty object\n return { };\n },\n\n /**\n * Send attribute data from this filter to its shader program on the GPU.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {Object} attributeLocations A map of shader attribute names to their locations.\n */\n sendAttributeData: function(gl, attributeLocations, aPositionData) {\n var attributeLocation = attributeLocations.aPosition;\n var buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.enableVertexAttribArray(attributeLocation);\n gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);\n gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW);\n },\n\n _setupFrameBuffer: function(options) {\n var gl = options.context, width, height;\n if (options.passes > 1) {\n width = options.destinationWidth;\n height = options.destinationHeight;\n if (options.sourceWidth !== width || options.sourceHeight !== height) {\n gl.deleteTexture(options.targetTexture);\n options.targetTexture = options.filterBackend.createTexture(gl, width, height);\n }\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D,\n options.targetTexture, 0);\n }\n else {\n // draw last filter on canvas and not to framebuffer.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.finish();\n }\n },\n\n _swapTextures: function(options) {\n options.passes--;\n options.pass++;\n var temp = options.targetTexture;\n options.targetTexture = options.sourceTexture;\n options.sourceTexture = temp;\n },\n\n /**\n * Generic isNeutral implementation for one parameter based filters.\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * Other filters may need their own verison ( ColorMatrix, HueRotation, gamma, ComposedFilter )\n * @param {Object} options\n **/\n isNeutralState: function(/* options */) {\n var main = this.mainParameter,\n _class = fabric.Image.filters[this.type].prototype;\n if (main) {\n if (Array.isArray(_class[main])) {\n for (var i = _class[main].length; i--;) {\n if (this[main][i] !== _class[main][i]) {\n return false;\n }\n }\n return true;\n }\n else {\n return _class[main] === this[main];\n }\n }\n else {\n return false;\n }\n },\n\n /**\n * Apply this filter to the input image data provided.\n *\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo: function(options) {\n if (options.webgl) {\n this._setupFrameBuffer(options);\n this.applyToWebGL(options);\n this._swapTextures(options);\n }\n else {\n this.applyTo2d(options);\n }\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n if (!options.programCache.hasOwnProperty(this.type)) {\n options.programCache[this.type] = this.createProgram(options.context);\n }\n return options.programCache[this.type];\n },\n\n /**\n * Apply this filter using webgl.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.originalTexture The texture of the original input image.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyToWebGL: function(options) {\n var gl = options.context;\n var shader = this.retrieveShader(options);\n if (options.pass === 0 && options.originalTexture) {\n gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);\n }\n else {\n gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);\n }\n gl.useProgram(shader.program);\n this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);\n\n gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);\n gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);\n\n this.sendUniformData(gl, shader.uniformLocations);\n gl.viewport(0, 0, options.destinationWidth, options.destinationHeight);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n },\n\n bindAdditionalTexture: function(gl, texture, textureUnit) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n // reset active texture to 0 as usual\n gl.activeTexture(gl.TEXTURE0);\n },\n\n unbindAdditionalTexture: function(gl, textureUnit) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.activeTexture(gl.TEXTURE0);\n },\n\n getMainParameter: function() {\n return this[this.mainParameter];\n },\n\n setMainParameter: function(value) {\n this[this.mainParameter] = value;\n },\n\n /**\n * Send uniform data from this filter to its shader program on the GPU.\n *\n * Intended to be overridden by subclasses.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {Object} uniformLocations A map of shader uniform names to their locations.\n */\n sendUniformData: function(/* gl, uniformLocations */) {\n // Intentionally left blank. Override me in subclasses.\n },\n\n /**\n * If needed by a 2d filter, this functions can create an helper canvas to be used\n * remember that options.targetCanvas is available for use till end of chain.\n */\n createHelpLayer: function(options) {\n if (!options.helpLayer) {\n var helpLayer = document.createElement('canvas');\n helpLayer.width = options.sourceWidth;\n helpLayer.height = options.sourceHeight;\n options.helpLayer = helpLayer;\n }\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n var object = { type: this.type }, mainP = this.mainParameter;\n if (mainP) {\n object[mainP] = this[mainP];\n }\n return object;\n },\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON: function() {\n // delegate, not alias\n return this.toObject();\n }\n});\n\nfabric.Image.filters.BaseFilter.fromObject = function(object, callback) {\n var filter = new fabric.Image.filters[object.type](object);\n callback && callback(filter);\n return filter;\n};\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Color Matrix filter class\n * @class fabric.Image.filters.ColorMatrix\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.ColorMatrix#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @see {@Link http://www.webwasp.co.uk/tutorials/219/Color_Matrix_Filter.php}\n * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl}\n * @example Kodachrome filter\n * var filter = new fabric.Image.filters.ColorMatrix({\n * matrix: [\n 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n 0, 0, 0, 1, 0\n ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.ColorMatrix = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'ColorMatrix',\n\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'uniform mat4 uColorMatrix;\\n' +\n 'uniform vec4 uConstants;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'color *= uColorMatrix;\\n' +\n 'color += uConstants;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n /**\n * Colormatrix for pixels.\n * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n * outside the -1, 1 range.\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Array} matrix array of 20 numbers.\n * @default\n */\n matrix: [\n 1, 0, 0, 0, 0,\n 0, 1, 0, 0, 0,\n 0, 0, 1, 0, 0,\n 0, 0, 0, 1, 0\n ],\n\n mainParameter: 'matrix',\n\n /**\n * Lock the colormatrix on the color part, skipping alpha, manly for non webgl scenario\n * to save some calculation\n */\n colorsOnly: true,\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n // create a new array instead mutating the prototype with push\n this.matrix = this.matrix.slice(0);\n },\n\n /**\n * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data,\n iLen = data.length,\n m = this.matrix,\n r, g, b, a, i, colorsOnly = this.colorsOnly;\n\n for (i = 0; i < iLen; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n if (colorsOnly) {\n data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255;\n data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255;\n }\n else {\n a = data[i + 3];\n data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255;\n data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255;\n data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'),\n uConstants: gl.getUniformLocation(program, 'uConstants'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n var m = this.matrix,\n matrix = [\n m[0], m[1], m[2], m[3],\n m[5], m[6], m[7], m[8],\n m[10], m[11], m[12], m[13],\n m[15], m[16], m[17], m[18]\n ],\n constants = [m[4], m[9], m[14], m[19]];\n gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix);\n gl.uniform4fv(uniformLocations.uConstants, constants);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] function to invoke after filter creation\n * @return {fabric.Image.filters.ColorMatrix} Instance of fabric.Image.filters.ColorMatrix\n */\n fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Brightness filter class\n * @class fabric.Image.filters.Brightness\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Brightness({\n * brightness: 0.05\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Brightness = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Brightness',\n\n /**\n * Fragment source for the brightness program\n */\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uBrightness;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'color.rgb += uBrightness;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n /**\n * Brightness value, from -1 to 1.\n * translated to -255 to 255 for 2d\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Number} brightness\n * @default\n */\n brightness: 0,\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'brightness',\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n if (this.brightness === 0) {\n return;\n }\n var imageData = options.imageData,\n data = imageData.data, i, len = data.length,\n brightness = Math.round(this.brightness * 255);\n for (i = 0; i < len; i += 4) {\n data[i] = data[i] + brightness;\n data[i + 1] = data[i + 1] + brightness;\n data[i + 2] = data[i + 2] + brightness;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uBrightness: gl.getUniformLocation(program, 'uBrightness'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uBrightness, this.brightness);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness\n */\n fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Adapted from html5rocks article\n * @class fabric.Image.filters.Convolute\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example Sharpen filter\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 0, -1, 0,\n * -1, 5, -1,\n * 0, -1, 0 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Blur filter\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Emboss filter\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Emboss filter with opaqueness\n * var filter = new fabric.Image.filters.Convolute({\n * opaque: true,\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n filters.Convolute = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Convolute',\n\n /*\n * Opaque value (true/false)\n */\n opaque: false,\n\n /*\n * matrix for the filter, max 9x9\n */\n matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],\n\n /**\n * Fragment source for the brightness program\n */\n fragmentSource: {\n Convolute_3_1: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[9];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 0);\\n' +\n 'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\\n' +\n 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n Convolute_3_0: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[9];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 1);\\n' +\n 'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\\n' +\n 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n 'gl_FragColor = color;\\n' +\n 'gl_FragColor.a = alpha;\\n' +\n '}',\n Convolute_5_1: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[25];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 0);\\n' +\n 'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' +\n 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n Convolute_5_0: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[25];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 1);\\n' +\n 'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' +\n 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n 'gl_FragColor = color;\\n' +\n 'gl_FragColor.a = alpha;\\n' +\n '}',\n Convolute_7_1: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[49];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 0);\\n' +\n 'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' +\n 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n Convolute_7_0: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[49];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 1);\\n' +\n 'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' +\n 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n 'gl_FragColor = color;\\n' +\n 'gl_FragColor.a = alpha;\\n' +\n '}',\n Convolute_9_1: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[81];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 0);\\n' +\n 'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' +\n 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n Convolute_9_0: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[81];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 1);\\n' +\n 'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' +\n 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n 'gl_FragColor = color;\\n' +\n 'gl_FragColor.a = alpha;\\n' +\n '}',\n },\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Convolute.prototype\n * @param {Object} [options] Options object\n * @param {Boolean} [options.opaque=false] Opaque value (true/false)\n * @param {Array} [options.matrix] Filter matrix\n */\n\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n var size = Math.sqrt(this.matrix.length);\n var cacheKey = this.type + '_' + size + '_' + (this.opaque ? 1 : 0);\n var shaderSource = this.fragmentSource[cacheKey];\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n return options.programCache[cacheKey];\n },\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data,\n weights = this.matrix,\n side = Math.round(Math.sqrt(weights.length)),\n halfSide = Math.floor(side / 2),\n sw = imageData.width,\n sh = imageData.height,\n output = options.ctx.createImageData(sw, sh),\n dst = output.data,\n // go through the destination image pixels\n alphaFac = this.opaque ? 1 : 0,\n r, g, b, a, dstOff,\n scx, scy, srcOff, wt,\n x, y, cx, cy;\n\n for (y = 0; y < sh; y++) {\n for (x = 0; x < sw; x++) {\n dstOff = (y * sw + x) * 4;\n // calculate the weighed sum of the source image pixels that\n // fall under the convolution matrix\n r = 0; g = 0; b = 0; a = 0;\n\n for (cy = 0; cy < side; cy++) {\n for (cx = 0; cx < side; cx++) {\n scy = y + cy - halfSide;\n scx = x + cx - halfSide;\n\n // eslint-disable-next-line max-depth\n if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) {\n continue;\n }\n\n srcOff = (scy * sw + scx) * 4;\n wt = weights[cy * side + cx];\n\n r += data[srcOff] * wt;\n g += data[srcOff + 1] * wt;\n b += data[srcOff + 2] * wt;\n // eslint-disable-next-line max-depth\n if (!alphaFac) {\n a += data[srcOff + 3] * wt;\n }\n }\n }\n dst[dstOff] = r;\n dst[dstOff + 1] = g;\n dst[dstOff + 2] = b;\n if (!alphaFac) {\n dst[dstOff + 3] = a;\n }\n else {\n dst[dstOff + 3] = data[dstOff + 3];\n }\n }\n }\n options.imageData = output;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uMatrix: gl.getUniformLocation(program, 'uMatrix'),\n uOpaque: gl.getUniformLocation(program, 'uOpaque'),\n uHalfSize: gl.getUniformLocation(program, 'uHalfSize'),\n uSize: gl.getUniformLocation(program, 'uSize'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1fv(uniformLocations.uMatrix, this.matrix);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n opaque: this.opaque,\n matrix: this.matrix\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute\n */\n fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Grayscale image filter class\n * @class fabric.Image.filters.Grayscale\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Grayscale();\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Grayscale = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Grayscale',\n\n fragmentSource: {\n average: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'float average = (color.r + color.b + color.g) / 3.0;\\n' +\n 'gl_FragColor = vec4(average, average, average, color.a);\\n' +\n '}',\n lightness: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform int uMode;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 col = texture2D(uTexture, vTexCoord);\\n' +\n 'float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\\n' +\n 'gl_FragColor = vec4(average, average, average, col.a);\\n' +\n '}',\n luminosity: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform int uMode;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 col = texture2D(uTexture, vTexCoord);\\n' +\n 'float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\\n' +\n 'gl_FragColor = vec4(average, average, average, col.a);\\n' +\n '}',\n },\n\n\n /**\n * Grayscale mode, between 'average', 'lightness', 'luminosity'\n * @param {String} type\n * @default\n */\n mode: 'average',\n\n mainParameter: 'mode',\n\n /**\n * Apply the Grayscale operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data, i,\n len = data.length, value,\n mode = this.mode;\n for (i = 0; i < len; i += 4) {\n if (mode === 'average') {\n value = (data[i] + data[i + 1] + data[i + 2]) / 3;\n }\n else if (mode === 'lightness') {\n value = (Math.min(data[i], data[i + 1], data[i + 2]) +\n Math.max(data[i], data[i + 1], data[i + 2])) / 2;\n }\n else if (mode === 'luminosity') {\n value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];\n }\n data[i] = value;\n data[i + 1] = value;\n data[i + 2] = value;\n }\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n var cacheKey = this.type + '_' + this.mode;\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n var shaderSource = this.fragmentSource[this.mode];\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n return options.programCache[cacheKey];\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uMode: gl.getUniformLocation(program, 'uMode'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n // default average mode.\n var mode = 1;\n gl.uniform1i(uniformLocations.uMode, mode);\n },\n\n /**\n * Grayscale filter isNeutralState implementation\n * The filter is never neutral\n * on the image\n **/\n isNeutralState: function() {\n return false;\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale\n */\n fabric.Image.filters.Grayscale.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Invert filter class\n * @class fabric.Image.filters.Invert\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Invert();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Invert = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Invert',\n\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform int uInvert;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'if (uInvert == 1) {\\n' +\n 'gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\\n' +\n '} else {\\n' +\n 'gl_FragColor = color;\\n' +\n '}\\n' +\n '}',\n\n /**\n * Filter invert. if false, does nothing\n * @param {Boolean} invert\n * @default\n */\n invert: true,\n\n mainParameter: 'invert',\n\n /**\n * Apply the Invert operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data, i,\n len = data.length;\n for (i = 0; i < len; i += 4) {\n data[i] = 255 - data[i];\n data[i + 1] = 255 - data[i + 1];\n data[i + 2] = 255 - data[i + 2];\n }\n },\n\n /**\n * Invert filter isNeutralState implementation\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * @param {Object} options\n **/\n isNeutralState: function() {\n return !this.invert;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uInvert: gl.getUniformLocation(program, 'uInvert'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1i(uniformLocations.uInvert, this.invert);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert\n */\n fabric.Image.filters.Invert.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Noise filter class\n * @class fabric.Image.filters.Noise\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Noise({\n * noise: 700\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n filters.Noise = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Noise',\n\n /**\n * Fragment source for the noise program\n */\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uStepH;\\n' +\n 'uniform float uNoise;\\n' +\n 'uniform float uSeed;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'float rand(vec2 co, float seed, float vScale) {\\n' +\n 'return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\\n' +\n '}\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'noise',\n\n /**\n * Noise value, from\n * @param {Number} noise\n * @default\n */\n noise: 0,\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n if (this.noise === 0) {\n return;\n }\n var imageData = options.imageData,\n data = imageData.data, i, len = data.length,\n noise = this.noise, rand;\n\n for (i = 0, len = data.length; i < len; i += 4) {\n\n rand = (0.5 - Math.random()) * noise;\n\n data[i] += rand;\n data[i + 1] += rand;\n data[i + 2] += rand;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uNoise: gl.getUniformLocation(program, 'uNoise'),\n uSeed: gl.getUniformLocation(program, 'uSeed'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uNoise, this.noise / 255);\n gl.uniform1f(uniformLocations.uSeed, Math.random());\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n noise: this.noise\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise\n */\n fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Pixelate filter class\n * @class fabric.Image.filters.Pixelate\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Pixelate({\n * blocksize: 8\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Pixelate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Pixelate',\n\n blocksize: 4,\n\n mainParameter: 'blocksize',\n\n /**\n * Fragment source for the Pixelate program\n */\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uBlocksize;\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'float blockW = uBlocksize * uStepW;\\n' +\n 'float blockH = uBlocksize * uStepW;\\n' +\n 'int posX = int(vTexCoord.x / blockW);\\n' +\n 'int posY = int(vTexCoord.y / blockH);\\n' +\n 'float fposX = float(posX);\\n' +\n 'float fposY = float(posY);\\n' +\n 'vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\\n' +\n 'vec4 color = texture2D(uTexture, squareCoords);\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n /**\n * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data,\n iLen = imageData.height,\n jLen = imageData.width,\n index, i, j, r, g, b, a,\n _i, _j, _iLen, _jLen;\n\n for (i = 0; i < iLen; i += this.blocksize) {\n for (j = 0; j < jLen; j += this.blocksize) {\n\n index = (i * 4) * jLen + (j * 4);\n\n r = data[index];\n g = data[index + 1];\n b = data[index + 2];\n a = data[index + 3];\n\n _iLen = Math.min(i + this.blocksize, iLen);\n _jLen = Math.min(j + this.blocksize, jLen);\n for (_i = i; _i < _iLen; _i++) {\n for (_j = j; _j < _jLen; _j++) {\n index = (_i * 4) * jLen + (_j * 4);\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = a;\n }\n }\n }\n }\n },\n\n /**\n * Indicate when the filter is not gonna apply changes to the image\n **/\n isNeutralState: function() {\n return this.blocksize === 1;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uBlocksize: gl.getUniformLocation(program, 'uBlocksize'),\n uStepW: gl.getUniformLocation(program, 'uStepW'),\n uStepH: gl.getUniformLocation(program, 'uStepH'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uBlocksize, this.blocksize);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate\n */\n fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Remove white filter class\n * @class fabric.Image.filters.RemoveColor\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.RemoveColor#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.RemoveColor({\n * threshold: 0.2,\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n filters.RemoveColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveColor.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'RemoveColor',\n\n /**\n * Color to remove, in any format understood by fabric.Color.\n * @param {String} type\n * @default\n */\n color: '#FFFFFF',\n\n /**\n * Fragment source for the brightness program\n */\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform vec4 uLow;\\n' +\n 'uniform vec4 uHigh;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' +\n 'if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\\n' +\n 'gl_FragColor.a = 0.0;\\n' +\n '}\\n' +\n '}',\n\n /**\n * distance to actual color, as value up or down from each r,g,b\n * between 0 and 1\n **/\n distance: 0.02,\n\n /**\n * For color to remove inside distance, use alpha channel for a smoother deletion\n * NOT IMPLEMENTED YET\n **/\n useAlpha: false,\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.RemoveWhite.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.color=#RRGGBB] Threshold value\n * @param {Number} [options.distance=10] Distance value\n */\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data, i,\n distance = this.distance * 255,\n r, g, b,\n source = new fabric.Color(this.color).getSource(),\n lowC = [\n source[0] - distance,\n source[1] - distance,\n source[2] - distance,\n ],\n highC = [\n source[0] + distance,\n source[1] + distance,\n source[2] + distance,\n ];\n\n\n for (i = 0; i < data.length; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n if (r > lowC[0] &&\n g > lowC[1] &&\n b > lowC[2] &&\n r < highC[0] &&\n g < highC[1] &&\n b < highC[2]) {\n data[i + 3] = 0;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uLow: gl.getUniformLocation(program, 'uLow'),\n uHigh: gl.getUniformLocation(program, 'uHigh'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n var source = new fabric.Color(this.color).getSource(),\n distance = parseFloat(this.distance),\n lowC = [\n 0 + source[0] / 255 - distance,\n 0 + source[1] / 255 - distance,\n 0 + source[2] / 255 - distance,\n 1\n ],\n highC = [\n source[0] / 255 + distance,\n source[1] / 255 + distance,\n source[2] / 255 + distance,\n 1\n ];\n gl.uniform4fv(uniformLocations.uLow, lowC);\n gl.uniform4fv(uniformLocations.uHigh, highC);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n color: this.color,\n distance: this.distance\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.RemoveColor} Instance of fabric.Image.filters.RemoveWhite\n */\n fabric.Image.filters.RemoveColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n var matrices = {\n Brownie: [\n 0.59970,0.34553,-0.27082,0,0.186,\n -0.03770,0.86095,0.15059,0,-0.1449,\n 0.24113,-0.07441,0.44972,0,-0.02965,\n 0,0,0,1,0\n ],\n Vintage: [\n 0.62793,0.32021,-0.03965,0,0.03784,\n 0.02578,0.64411,0.03259,0,0.02926,\n 0.04660,-0.08512,0.52416,0,0.02023,\n 0,0,0,1,0\n ],\n Kodachrome: [\n 1.12855,-0.39673,-0.03992,0,0.24991,\n -0.16404,1.08352,-0.05498,0,0.09698,\n -0.16786,-0.56034,1.60148,0,0.13972,\n 0,0,0,1,0\n ],\n Technicolor: [\n 1.91252,-0.85453,-0.09155,0,0.04624,\n -0.30878,1.76589,-0.10601,0,-0.27589,\n -0.23110,-0.75018,1.84759,0,0.12137,\n 0,0,0,1,0\n ],\n Polaroid: [\n 1.438,-0.062,-0.062,0,0,\n -0.122,1.378,-0.122,0,0,\n -0.016,-0.016,1.483,0,0,\n 0,0,0,1,0\n ],\n Sepia: [\n 0.393, 0.769, 0.189, 0, 0,\n 0.349, 0.686, 0.168, 0, 0,\n 0.272, 0.534, 0.131, 0, 0,\n 0, 0, 0, 1, 0\n ],\n BlackWhite: [\n 1.5, 1.5, 1.5, 0, -1,\n 1.5, 1.5, 1.5, 0, -1,\n 1.5, 1.5, 1.5, 0, -1,\n 0, 0, 0, 1, 0,\n ]\n };\n\n for (var key in matrices) {\n filters[key] = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.Sepia.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: key,\n\n /**\n * Colormatrix for the effect\n * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n * outside the -1, 1 range.\n * @param {Array} matrix array of 20 numbers.\n * @default\n */\n matrix: matrices[key],\n\n /**\n * Lock the matrix export for this kind of static, parameter less filters.\n */\n mainParameter: false,\n /**\n * Lock the colormatrix on the color part, skipping alpha\n */\n colorsOnly: true,\n\n });\n fabric.Image.filters[key].fromObject = fabric.Image.filters.BaseFilter.fromObject;\n }\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n 'use strict';\n\n var fabric = global.fabric,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Color Blend filter class\n * @class fabric.Image.filter.BlendColor\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @example\n * var filter = new fabric.Image.filters.BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * var filter = new fabric.Image.filters.BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply',\n * alpha: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n\n filters.BlendColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */ {\n type: 'BlendColor',\n\n /**\n * Color to make the blend operation with. default to a reddish color since black or white\n * gives always strong result.\n **/\n color: '#F95C63',\n\n /**\n * Blend mode for the filter: one of multiply, add, diff, screen, subtract,\n * darken, lighten, overlay, exclusion, tint.\n **/\n mode: 'multiply',\n\n /**\n * alpha value. represent the strength of the blend color operation.\n **/\n alpha: 1,\n\n /**\n * Fragment source for the Multiply program\n */\n fragmentSource: {\n multiply: 'gl_FragColor.rgb *= uColor.rgb;\\n',\n screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\\n',\n add: 'gl_FragColor.rgb += uColor.rgb;\\n',\n diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\\n',\n subtract: 'gl_FragColor.rgb -= uColor.rgb;\\n',\n lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\\n',\n darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\\n',\n exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\\n',\n overlay: 'if (uColor.r < 0.5) {\\n' +\n 'gl_FragColor.r *= 2.0 * uColor.r;\\n' +\n '} else {\\n' +\n 'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\\n' +\n '}\\n' +\n 'if (uColor.g < 0.5) {\\n' +\n 'gl_FragColor.g *= 2.0 * uColor.g;\\n' +\n '} else {\\n' +\n 'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\\n' +\n '}\\n' +\n 'if (uColor.b < 0.5) {\\n' +\n 'gl_FragColor.b *= 2.0 * uColor.b;\\n' +\n '} else {\\n' +\n 'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\\n' +\n '}\\n',\n tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\\n' +\n 'gl_FragColor.rgb += uColor.rgb;\\n',\n },\n\n /**\n * build the fragment source for the filters, joining the common part with\n * the specific one.\n * @param {String} mode the mode of the filter, a key of this.fragmentSource\n * @return {String} the source to be compiled\n * @private\n */\n buildSource: function(mode) {\n return 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform vec4 uColor;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'gl_FragColor = color;\\n' +\n 'if (color.a > 0.0) {\\n' +\n this.fragmentSource[mode] +\n '}\\n' +\n '}';\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n var cacheKey = this.type + '_' + this.mode, shaderSource;\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n shaderSource = this.buildSource(this.mode);\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n return options.programCache[cacheKey];\n },\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data, iLen = data.length,\n tr, tg, tb,\n r, g, b,\n source, alpha1 = 1 - this.alpha;\n\n source = new fabric.Color(this.color).getSource();\n tr = source[0] * this.alpha;\n tg = source[1] * this.alpha;\n tb = source[2] * this.alpha;\n\n for (var i = 0; i < iLen; i += 4) {\n\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = r * tr / 255;\n data[i + 1] = g * tg / 255;\n data[i + 2] = b * tb / 255;\n break;\n case 'screen':\n data[i] = 255 - (255 - r) * (255 - tr) / 255;\n data[i + 1] = 255 - (255 - g) * (255 - tg) / 255;\n data[i + 2] = 255 - (255 - b) * (255 - tb) / 255;\n break;\n case 'add':\n data[i] = r + tr;\n data[i + 1] = g + tg;\n data[i + 2] = b + tb;\n break;\n case 'diff':\n case 'difference':\n data[i] = Math.abs(r - tr);\n data[i + 1] = Math.abs(g - tg);\n data[i + 2] = Math.abs(b - tb);\n break;\n case 'subtract':\n data[i] = r - tr;\n data[i + 1] = g - tg;\n data[i + 2] = b - tb;\n break;\n case 'darken':\n data[i] = Math.min(r, tr);\n data[i + 1] = Math.min(g, tg);\n data[i + 2] = Math.min(b, tb);\n break;\n case 'lighten':\n data[i] = Math.max(r, tr);\n data[i + 1] = Math.max(g, tg);\n data[i + 2] = Math.max(b, tb);\n break;\n case 'overlay':\n data[i] = tr < 128 ? (2 * r * tr / 255) : (255 - 2 * (255 - r) * (255 - tr) / 255);\n data[i + 1] = tg < 128 ? (2 * g * tg / 255) : (255 - 2 * (255 - g) * (255 - tg) / 255);\n data[i + 2] = tb < 128 ? (2 * b * tb / 255) : (255 - 2 * (255 - b) * (255 - tb) / 255);\n break;\n case 'exclusion':\n data[i] = tr + r - ((2 * tr * r) / 255);\n data[i + 1] = tg + g - ((2 * tg * g) / 255);\n data[i + 2] = tb + b - ((2 * tb * b) / 255);\n break;\n case 'tint':\n data[i] = tr + r * alpha1;\n data[i + 1] = tg + g * alpha1;\n data[i + 2] = tb + b * alpha1;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uColor: gl.getUniformLocation(program, 'uColor'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n var source = new fabric.Color(this.color).getSource();\n source[0] = this.alpha * source[0] / 255;\n source[1] = this.alpha * source[1] / 255;\n source[2] = this.alpha * source[2] / 255;\n source[3] = this.alpha;\n gl.uniform4fv(uniformLocations.uColor, source);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return {\n type: this.type,\n color: this.color,\n mode: this.mode,\n alpha: this.alpha\n };\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.BlendColor} Instance of fabric.Image.filters.BlendColor\n */\n fabric.Image.filters.BlendColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n 'use strict';\n\n var fabric = global.fabric,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Image Blend filter class\n * @class fabric.Image.filter.BlendImage\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @example\n * var filter = new fabric.Image.filters.BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * var filter = new fabric.Image.filters.BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply',\n * alpha: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n\n filters.BlendImage = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.BlendImage.prototype */ {\n type: 'BlendImage',\n\n /**\n * Color to make the blend operation with. default to a reddish color since black or white\n * gives always strong result.\n **/\n image: null,\n\n /**\n * Blend mode for the filter: one of multiply, add, diff, screen, subtract,\n * darken, lighten, overlay, exclusion, tint.\n **/\n mode: 'multiply',\n\n /**\n * alpha value. represent the strength of the blend image operation.\n * not implemented.\n **/\n alpha: 1,\n\n vertexSource: 'attribute vec2 aPosition;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'varying vec2 vTexCoord2;\\n' +\n 'uniform mat3 uTransformMatrix;\\n' +\n 'void main() {\\n' +\n 'vTexCoord = aPosition;\\n' +\n 'vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\\n' +\n 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' +\n '}',\n\n /**\n * Fragment source for the Multiply program\n */\n fragmentSource: {\n multiply: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform sampler2D uImage;\\n' +\n 'uniform vec4 uColor;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'varying vec2 vTexCoord2;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' +\n 'color.rgba *= color2.rgba;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n mask: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform sampler2D uImage;\\n' +\n 'uniform vec4 uColor;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'varying vec2 vTexCoord2;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' +\n 'color.a = color2.a;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n var cacheKey = this.type + '_' + this.mode;\n var shaderSource = this.fragmentSource[this.mode];\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n return options.programCache[cacheKey];\n },\n\n applyToWebGL: function(options) {\n // load texture to blend.\n var gl = options.context,\n texture = this.createTexture(options.filterBackend, this.image);\n this.bindAdditionalTexture(gl, texture, gl.TEXTURE1);\n this.callSuper('applyToWebGL', options);\n this.unbindAdditionalTexture(gl, gl.TEXTURE1);\n },\n\n createTexture: function(backend, image) {\n return backend.getCachedTexture(image.cacheKey, image._element);\n },\n\n /**\n * Calculate a transformMatrix to adapt the image to blend over\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n calculateMatrix: function() {\n var image = this.image,\n width = image._element.width,\n height = image._element.height;\n return [\n 1 / image.scaleX, 0, 0,\n 0, 1 / image.scaleY, 0,\n -image.left / width, -image.top / height, 1\n ];\n },\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n resources = options.filterBackend.resources,\n data = imageData.data, iLen = data.length,\n width = imageData.width,\n height = imageData.height,\n tr, tg, tb, ta,\n r, g, b, a,\n canvas1, context, image = this.image, blendData;\n\n if (!resources.blendImage) {\n resources.blendImage = fabric.util.createCanvasElement();\n }\n canvas1 = resources.blendImage;\n context = canvas1.getContext('2d');\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas1.width = width;\n canvas1.height = height;\n }\n else {\n context.clearRect(0, 0, width, height);\n }\n context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top);\n context.drawImage(image._element, 0, 0, width, height);\n blendData = context.getImageData(0, 0, width, height).data;\n for (var i = 0; i < iLen; i += 4) {\n\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n a = data[i + 3];\n\n tr = blendData[i];\n tg = blendData[i + 1];\n tb = blendData[i + 2];\n ta = blendData[i + 3];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = r * tr / 255;\n data[i + 1] = g * tg / 255;\n data[i + 2] = b * tb / 255;\n data[i + 3] = a * ta / 255;\n break;\n case 'mask':\n data[i + 3] = ta;\n break;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uTransformMatrix: gl.getUniformLocation(program, 'uTransformMatrix'),\n uImage: gl.getUniformLocation(program, 'uImage'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n var matrix = this.calculateMatrix();\n gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.\n gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return {\n type: this.type,\n image: this.image && this.image.toObject(),\n mode: this.mode,\n alpha: this.alpha\n };\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} callback to be invoked after filter creation\n * @return {fabric.Image.filters.BlendImage} Instance of fabric.Image.filters.BlendImage\n */\n fabric.Image.filters.BlendImage.fromObject = function(object, callback) {\n fabric.Image.fromObject(object.image, function(image) {\n var options = fabric.util.object.clone(object);\n options.image = image;\n callback(new fabric.Image.filters.BlendImage(options));\n });\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor,\n sqrt = Math.sqrt, abs = Math.abs, round = Math.round, sin = Math.sin,\n ceil = Math.ceil,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Resize image filter class\n * @class fabric.Image.filters.Resize\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Resize();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Resize = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Resize',\n\n /**\n * Resize type\n * for webgl resizeType is just lanczos, for canvas2d can be:\n * bilinear, hermite, sliceHack, lanczos.\n * @param {String} resizeType\n * @default\n */\n resizeType: 'hermite',\n\n /**\n * Scale factor for resizing, x axis\n * @param {Number} scaleX\n * @default\n */\n scaleX: 1,\n\n /**\n * Scale factor for resizing, y axis\n * @param {Number} scaleY\n * @default\n */\n scaleY: 1,\n\n /**\n * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos\n * @param {Number} lanczosLobes\n * @default\n */\n lanczosLobes: 3,\n\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uDelta: gl.getUniformLocation(program, 'uDelta'),\n uTaps: gl.getUniformLocation(program, 'uTaps'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]);\n gl.uniform1fv(uniformLocations.uTaps, this.taps);\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n var filterWindow = this.getFilterWindow(), cacheKey = this.type + '_' + filterWindow;\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n var fragmentShader = this.generateShader(filterWindow);\n options.programCache[cacheKey] = this.createProgram(options.context, fragmentShader);\n }\n return options.programCache[cacheKey];\n },\n\n getFilterWindow: function() {\n var scale = this.tempScale;\n return Math.ceil(this.lanczosLobes / scale);\n },\n\n getTaps: function() {\n var lobeFunction = this.lanczosCreate(this.lanczosLobes), scale = this.tempScale,\n filterWindow = this.getFilterWindow(), taps = new Array(filterWindow);\n for (var i = 1; i <= filterWindow; i++) {\n taps[i - 1] = lobeFunction(i * scale);\n }\n return taps;\n },\n\n /**\n * Generate vertex and shader sources from the necessary steps numbers\n * @param {Number} filterWindow\n */\n generateShader: function(filterWindow) {\n var offsets = new Array(filterWindow),\n fragmentShader = this.fragmentSourceTOP, filterWindow;\n\n for (var i = 1; i <= filterWindow; i++) {\n offsets[i - 1] = i + '.0 * uDelta';\n }\n\n fragmentShader += 'uniform float uTaps[' + filterWindow + '];\\n';\n fragmentShader += 'void main() {\\n';\n fragmentShader += ' vec4 color = texture2D(uTexture, vTexCoord);\\n';\n fragmentShader += ' float sum = 1.0;\\n';\n\n offsets.forEach(function(offset, i) {\n fragmentShader += ' color += texture2D(uTexture, vTexCoord + ' + offset + ') * uTaps[' + i + '];\\n';\n fragmentShader += ' color += texture2D(uTexture, vTexCoord - ' + offset + ') * uTaps[' + i + '];\\n';\n fragmentShader += ' sum += 2.0 * uTaps[' + i + '];\\n';\n });\n fragmentShader += ' gl_FragColor = color / sum;\\n';\n fragmentShader += '}';\n return fragmentShader;\n },\n\n fragmentSourceTOP: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform vec2 uDelta;\\n' +\n 'varying vec2 vTexCoord;\\n',\n\n /**\n * Apply the resize filter to the image\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo: function(options) {\n if (options.webgl) {\n options.passes++;\n this.width = options.sourceWidth;\n this.horizontal = true;\n this.dW = Math.round(this.width * this.scaleX);\n this.dH = options.sourceHeight;\n this.tempScale = this.dW / this.width;\n this.taps = this.getTaps();\n options.destinationWidth = this.dW;\n this._setupFrameBuffer(options);\n this.applyToWebGL(options);\n this._swapTextures(options);\n options.sourceWidth = options.destinationWidth;\n\n this.height = options.sourceHeight;\n this.horizontal = false;\n this.dH = Math.round(this.height * this.scaleY);\n this.tempScale = this.dH / this.height;\n this.taps = this.getTaps();\n options.destinationHeight = this.dH;\n this._setupFrameBuffer(options);\n this.applyToWebGL(options);\n this._swapTextures(options);\n options.sourceHeight = options.destinationHeight;\n }\n else {\n this.applyTo2d(options);\n }\n },\n\n isNeutralState: function() {\n return this.scaleX === 1 && this.scaleY === 1;\n },\n\n lanczosCreate: function(lobes) {\n return function(x) {\n if (x >= lobes || x <= -lobes) {\n return 0.0;\n }\n if (x < 1.19209290E-07 && x > -1.19209290E-07) {\n return 1.0;\n }\n x *= Math.PI;\n var xx = x / lobes;\n return (sin(x) / x) * sin(xx) / xx;\n };\n },\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Resize.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} scaleX\n * @param {Number} scaleY\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n scaleX = this.scaleX,\n scaleY = this.scaleY;\n\n this.rcpScaleX = 1 / scaleX;\n this.rcpScaleY = 1 / scaleY;\n\n var oW = imageData.width, oH = imageData.height,\n dW = round(oW * scaleX), dH = round(oH * scaleY),\n newData;\n\n if (this.resizeType === 'sliceHack') {\n newData = this.sliceByTwo(options, oW, oH, dW, dH);\n }\n else if (this.resizeType === 'hermite') {\n newData = this.hermiteFastResize(options, oW, oH, dW, dH);\n }\n else if (this.resizeType === 'bilinear') {\n newData = this.bilinearFiltering(options, oW, oH, dW, dH);\n }\n else if (this.resizeType === 'lanczos') {\n newData = this.lanczosResize(options, oW, oH, dW, dH);\n }\n options.imageData = newData;\n },\n\n /**\n * Filter sliceByTwo\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n sliceByTwo: function(options, oW, oH, dW, dH) {\n var imageData = options.imageData,\n mult = 0.5, doneW = false, doneH = false, stepW = oW * mult,\n stepH = oH * mult, resources = fabric.filterBackend.resources,\n tmpCanvas, ctx, sX = 0, sY = 0, dX = oW, dY = 0;\n if (!resources.sliceByTwo) {\n resources.sliceByTwo = document.createElement('canvas');\n }\n tmpCanvas = resources.sliceByTwo;\n if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) {\n tmpCanvas.width = oW * 1.5;\n tmpCanvas.height = oH;\n }\n ctx = tmpCanvas.getContext('2d');\n ctx.clearRect(0, 0, oW * 1.5, oH);\n ctx.putImageData(imageData, 0, 0);\n\n dW = floor(dW);\n dH = floor(dH);\n\n while (!doneW || !doneH) {\n oW = stepW;\n oH = stepH;\n if (dW < floor(stepW * mult)) {\n stepW = floor(stepW * mult);\n }\n else {\n stepW = dW;\n doneW = true;\n }\n if (dH < floor(stepH * mult)) {\n stepH = floor(stepH * mult);\n }\n else {\n stepH = dH;\n doneH = true;\n }\n ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH);\n sX = dX;\n sY = dY;\n dY += stepH;\n }\n return ctx.getImageData(sX, sY, dW, dH);\n },\n\n /**\n * Filter lanczosResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n lanczosResize: function(options, oW, oH, dW, dH) {\n\n function process(u) {\n var v, i, weight, idx, a, red, green,\n blue, alpha, fX, fY;\n center.x = (u + 0.5) * ratioX;\n icenter.x = floor(center.x);\n for (v = 0; v < dH; v++) {\n center.y = (v + 0.5) * ratioY;\n icenter.y = floor(center.y);\n a = 0; red = 0; green = 0; blue = 0; alpha = 0;\n for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n if (i < 0 || i >= oW) {\n continue;\n }\n fX = floor(1000 * abs(i - center.x));\n if (!cacheLanc[fX]) {\n cacheLanc[fX] = { };\n }\n for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n if (j < 0 || j >= oH) {\n continue;\n }\n fY = floor(1000 * abs(j - center.y));\n if (!cacheLanc[fX][fY]) {\n cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000);\n }\n weight = cacheLanc[fX][fY];\n if (weight > 0) {\n idx = (j * oW + i) * 4;\n a += weight;\n red += weight * srcData[idx];\n green += weight * srcData[idx + 1];\n blue += weight * srcData[idx + 2];\n alpha += weight * srcData[idx + 3];\n }\n }\n }\n idx = (v * dW + u) * 4;\n destData[idx] = red / a;\n destData[idx + 1] = green / a;\n destData[idx + 2] = blue / a;\n destData[idx + 3] = alpha / a;\n }\n\n if (++u < dW) {\n return process(u);\n }\n else {\n return destImg;\n }\n }\n\n var srcData = options.imageData.data,\n destImg = options.ctx.createImageData(dW, dH),\n destData = destImg.data,\n lanczos = this.lanczosCreate(this.lanczosLobes),\n ratioX = this.rcpScaleX, ratioY = this.rcpScaleY,\n rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY,\n range2X = ceil(ratioX * this.lanczosLobes / 2),\n range2Y = ceil(ratioY * this.lanczosLobes / 2),\n cacheLanc = { }, center = { }, icenter = { };\n\n return process(0);\n },\n\n /**\n * bilinearFiltering\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n bilinearFiltering: function(options, oW, oH, dW, dH) {\n var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl,\n color, offset = 0, origPix, ratioX = this.rcpScaleX,\n ratioY = this.rcpScaleY,\n w4 = 4 * (oW - 1), img = options.imageData,\n pixels = img.data, destImage = options.ctx.createImageData(dW, dH),\n destPixels = destImage.data;\n for (i = 0; i < dH; i++) {\n for (j = 0; j < dW; j++) {\n x = floor(ratioX * j);\n y = floor(ratioY * i);\n xDiff = ratioX * j - x;\n yDiff = ratioY * i - y;\n origPix = 4 * (y * oW + x);\n\n for (chnl = 0; chnl < 4; chnl++) {\n a = pixels[origPix + chnl];\n b = pixels[origPix + 4 + chnl];\n c = pixels[origPix + w4 + chnl];\n d = pixels[origPix + w4 + 4 + chnl];\n color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) +\n c * yDiff * (1 - xDiff) + d * xDiff * yDiff;\n destPixels[offset++] = color;\n }\n }\n }\n return destImage;\n },\n\n /**\n * hermiteFastResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n hermiteFastResize: function(options, oW, oH, dW, dH) {\n var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY,\n ratioWHalf = ceil(ratioW / 2),\n ratioHHalf = ceil(ratioH / 2),\n img = options.imageData, data = img.data,\n img2 = options.ctx.createImageData(dW, dH), data2 = img2.data;\n for (var j = 0; j < dH; j++) {\n for (var i = 0; i < dW; i++) {\n var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0,\n gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + 0.5) * ratioH;\n for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {\n var dy = abs(centerY - (yy + 0.5)) / ratioHHalf,\n centerX = (i + 0.5) * ratioW, w0 = dy * dy;\n for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {\n var dx = abs(centerX - (xx + 0.5)) / ratioWHalf,\n w = sqrt(w0 + dx * dx);\n /* eslint-disable max-depth */\n if (w > 1 && w < -1) {\n continue;\n }\n //hermite filter\n weight = 2 * w * w * w - 3 * w * w + 1;\n if (weight > 0) {\n dx = 4 * (xx + yy * oW);\n //alpha\n gxA += weight * data[dx + 3];\n weightsAlpha += weight;\n //colors\n if (data[dx + 3] < 255) {\n weight = weight * data[dx + 3] / 250;\n }\n gxR += weight * data[dx];\n gxG += weight * data[dx + 1];\n gxB += weight * data[dx + 2];\n weights += weight;\n }\n /* eslint-enable max-depth */\n }\n }\n data2[x2] = gxR / weights;\n data2[x2 + 1] = gxG / weights;\n data2[x2 + 2] = gxB / weights;\n data2[x2 + 3] = gxA / weightsAlpha;\n }\n }\n return img2;\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return {\n type: this.type,\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n resizeType: this.resizeType,\n lanczosLobes: this.lanczosLobes\n };\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize\n */\n fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Contrast filter class\n * @class fabric.Image.filters.Contrast\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Contrast#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Contrast({\n * contrast: 0.25\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Contrast = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Contrast.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Contrast',\n\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uContrast;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\\n' +\n 'color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n /**\n * contrast value, range from -1 to 1.\n * @param {Number} contrast\n * @default 0\n */\n contrast: 0,\n\n mainParameter: 'contrast',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Contrast.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.contrast=0] Value to contrast the image up (-1...1)\n */\n\n /**\n * Apply the Contrast operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function(options) {\n if (this.contrast === 0) {\n return;\n }\n var imageData = options.imageData, i, len,\n data = imageData.data, len = data.length,\n contrast = Math.floor(this.contrast * 255),\n contrastF = 259 * (contrast + 255) / (255 * (259 - contrast));\n\n for (i = 0; i < len; i += 4) {\n data[i] = contrastF * (data[i] - 128) + 128;\n data[i + 1] = contrastF * (data[i + 1] - 128) + 128;\n data[i + 2] = contrastF * (data[i + 2] - 128) + 128;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uContrast: gl.getUniformLocation(program, 'uContrast'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uContrast, this.contrast);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast\n */\n fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Saturate filter class\n * @class fabric.Image.filters.Saturation\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Saturation#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Saturation({\n * saturation: 100\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Saturation = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Saturation.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Saturation',\n\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uSaturation;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'float rgMax = max(color.r, color.g);\\n' +\n 'float rgbMax = max(rgMax, color.b);\\n' +\n 'color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\\n' +\n 'color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\\n' +\n 'color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n saturation: 0,\n\n mainParameter: 'saturation',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Saturate.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.saturate=0] Value to saturate the image (-1...1)\n */\n\n /**\n * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n if (this.saturation === 0) {\n return;\n }\n var imageData = options.imageData,\n data = imageData.data, len = data.length,\n adjust = -this.saturation, i, max;\n\n for (i = 0; i < len; i += 4) {\n max = Math.max(data[i], data[i + 1], data[i + 2]);\n data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uSaturation: gl.getUniformLocation(program, 'uSaturation'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uSaturation, -this.saturation);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Saturation} Instance of fabric.Image.filters.Saturate\n */\n fabric.Image.filters.Saturation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Blur filter class\n * @class fabric.Image.filters.Blur\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Blur#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Blur({\n * blur: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n filters.Blur = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blur.prototype */ {\n\n type: 'Blur',\n\n /*\n'gl_FragColor = vec4(0.0);',\n'gl_FragColor += texture2D(texture, vTexCoord + -7 * uDelta)*0.0044299121055113265;',\n'gl_FragColor += texture2D(texture, vTexCoord + -6 * uDelta)*0.00895781211794;',\n'gl_FragColor += texture2D(texture, vTexCoord + -5 * uDelta)*0.0215963866053;',\n'gl_FragColor += texture2D(texture, vTexCoord + -4 * uDelta)*0.0443683338718;',\n'gl_FragColor += texture2D(texture, vTexCoord + -3 * uDelta)*0.0776744219933;',\n'gl_FragColor += texture2D(texture, vTexCoord + -2 * uDelta)*0.115876621105;',\n'gl_FragColor += texture2D(texture, vTexCoord + -1 * uDelta)*0.147308056121;',\n'gl_FragColor += texture2D(texture, vTexCoord )*0.159576912161;',\n'gl_FragColor += texture2D(texture, vTexCoord + 1 * uDelta)*0.147308056121;',\n'gl_FragColor += texture2D(texture, vTexCoord + 2 * uDelta)*0.115876621105;',\n'gl_FragColor += texture2D(texture, vTexCoord + 3 * uDelta)*0.0776744219933;',\n'gl_FragColor += texture2D(texture, vTexCoord + 4 * uDelta)*0.0443683338718;',\n'gl_FragColor += texture2D(texture, vTexCoord + 5 * uDelta)*0.0215963866053;',\n'gl_FragColor += texture2D(texture, vTexCoord + 6 * uDelta)*0.00895781211794;',\n'gl_FragColor += texture2D(texture, vTexCoord + 7 * uDelta)*0.0044299121055113265;',\n*/\n\n /* eslint-disable max-len */\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform vec2 uDelta;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'const float nSamples = 15.0;\\n' +\n 'vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\\n' +\n 'float random(vec3 scale) {\\n' +\n /* use the fragment position for a different seed per-pixel */\n 'return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\\n' +\n '}\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0.0);\\n' +\n 'float total = 0.0;\\n' +\n 'float offset = random(v3offset);\\n' +\n 'for (float t = -nSamples; t <= nSamples; t++) {\\n' +\n 'float percent = (t + offset - 0.5) / nSamples;\\n' +\n 'float weight = 1.0 - abs(percent);\\n' +\n 'color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\\n' +\n 'total += weight;\\n' +\n '}\\n' +\n 'gl_FragColor = color / total;\\n' +\n '}',\n /* eslint-enable max-len */\n\n /**\n * blur value, in percentage of image dimensions.\n * specific to keep the image blur constant at different resolutions\n * range bewteen 0 and 1.\n */\n blur: 0,\n\n mainParameter: 'blur',\n\n applyTo: function(options) {\n if (options.webgl) {\n // this aspectRatio is used to give the same blur to vertical and horizontal\n this.aspectRatio = options.sourceWidth / options.sourceHeight;\n options.passes++;\n this._setupFrameBuffer(options);\n this.horizontal = true;\n this.applyToWebGL(options);\n this._swapTextures(options);\n this._setupFrameBuffer(options);\n this.horizontal = false;\n this.applyToWebGL(options);\n this._swapTextures(options);\n }\n else {\n this.applyTo2d(options);\n }\n },\n\n applyTo2d: function(options) {\n // paint canvasEl with current image data.\n //options.ctx.putImageData(options.imageData, 0, 0);\n options.imageData = this.simpleBlur(options);\n },\n\n simpleBlur: function(options) {\n var resources = options.filterBackend.resources, canvas1, canvas2,\n width = options.imageData.width,\n height = options.imageData.height;\n\n if (!resources.blurLayer1) {\n resources.blurLayer1 = fabric.util.createCanvasElement();\n resources.blurLayer2 = fabric.util.createCanvasElement();\n }\n canvas1 = resources.blurLayer1;\n canvas2 = resources.blurLayer2;\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas2.width = canvas1.width = width;\n canvas2.height = canvas1.height = height;\n }\n var ctx1 = canvas1.getContext('2d'),\n ctx2 = canvas2.getContext('2d'),\n nSamples = 15,\n random, percent, j, i,\n blur = this.blur * 0.06 * 0.5;\n\n // load first canvas\n ctx1.putImageData(options.imageData, 0, 0);\n ctx2.clearRect(0, 0, width, height);\n\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * width + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, j, random);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * height + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, random, j);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n options.ctx.drawImage(canvas1, 0, 0);\n var newImageData = options.ctx.getImageData(0, 0, canvas1.width, canvas1.height);\n ctx1.globalAlpha = 1;\n ctx1.clearRect(0, 0, canvas1.width, canvas1.height);\n return newImageData;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n delta: gl.getUniformLocation(program, 'uDelta'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n var delta = this.chooseRightDelta();\n gl.uniform2fv(uniformLocations.delta, delta);\n },\n\n /**\n * choose right value of image percentage to blur with\n * @returns {Array} a numeric array with delta values\n */\n chooseRightDelta: function() {\n var blurScale = 1, delta = [0, 0], blur;\n if (this.horizontal) {\n if (this.aspectRatio > 1) {\n // image is wide, i want to shrink radius horizontal\n blurScale = 1 / this.aspectRatio;\n }\n }\n else {\n if (this.aspectRatio < 1) {\n // image is tall, i want to shrink radius vertical\n blurScale = this.aspectRatio;\n }\n }\n blur = blurScale * this.blur * 0.12;\n if (this.horizontal) {\n delta[0] = blur;\n }\n else {\n delta[1] = blur;\n }\n return delta;\n },\n });\n\n /**\n * Deserialize a JSON definition of a BlurFilter into a concrete instance.\n */\n filters.Blur.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Gamma filter class\n * @class fabric.Image.filters.Gamma\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Gamma#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Gamma({\n * brightness: 200\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Gamma = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Gamma.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Gamma',\n\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform vec3 uGamma;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'vec3 correction = (1.0 / uGamma);\\n' +\n 'color.r = pow(color.r, correction.r);\\n' +\n 'color.g = pow(color.g, correction.g);\\n' +\n 'color.b = pow(color.b, correction.b);\\n' +\n 'gl_FragColor = color;\\n' +\n 'gl_FragColor.rgb *= color.a;\\n' +\n '}',\n\n /**\n * Gamma array value, from 0.01 to 2.2.\n * @param {Array} gamma\n * @default\n */\n gamma: [1, 1, 1],\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'gamma',\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n this.gamma = [1, 1, 1];\n filters.BaseFilter.prototype.initialize.call(this, options);\n },\n\n /**\n * Apply the Gamma operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData, data = imageData.data,\n gamma = this.gamma, len = data.length,\n rInv = 1 / gamma[0], gInv = 1 / gamma[1],\n bInv = 1 / gamma[2], i;\n\n if (!this.rVals) {\n // eslint-disable-next-line\n this.rVals = new Uint8Array(256);\n // eslint-disable-next-line\n this.gVals = new Uint8Array(256);\n // eslint-disable-next-line\n this.bVals = new Uint8Array(256);\n }\n\n // This is an optimization - pre-compute a look-up table for each color channel\n // instead of performing these pow calls for each pixel in the image.\n for (i = 0, len = 256; i < len; i++) {\n this.rVals[i] = Math.pow(i / 255, rInv) * 255;\n this.gVals[i] = Math.pow(i / 255, gInv) * 255;\n this.bVals[i] = Math.pow(i / 255, bInv) * 255;\n }\n for (i = 0, len = data.length; i < len; i += 4) {\n data[i] = this.rVals[data[i]];\n data[i + 1] = this.gVals[data[i + 1]];\n data[i + 2] = this.bVals[data[i + 2]];\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uGamma: gl.getUniformLocation(program, 'uGamma'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform3fv(uniformLocations.uGamma, this.gamma);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Gamma} Instance of fabric.Image.filters.Gamma\n */\n fabric.Image.filters.Gamma.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * A container class that knows how to apply a sequence of filters to an input image.\n */\n filters.Composed = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Composed.prototype */ {\n\n type: 'Composed',\n\n /**\n * A non sparse array of filters to apply\n */\n subFilters: [],\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n // create a new array instead mutating the prototype with push\n this.subFilters = this.subFilters.slice(0);\n },\n\n /**\n * Apply this container's filters to the input image provided.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be applied.\n */\n applyTo: function(options) {\n options.passes += this.subFilters.length - 1;\n this.subFilters.forEach(function(filter) {\n filter.applyTo(options);\n });\n },\n\n /**\n * Serialize this filter into JSON.\n *\n * @returns {Object} A JSON representation of this filter.\n */\n toObject: function() {\n return fabric.util.object.extend(this.callSuper('toObject'), {\n subFilters: this.subFilters.map(function(filter) { return filter.toObject(); }),\n });\n },\n\n isNeutralState: function() {\n return !this.subFilters.some(function(filter) { return !filter.isNeutralState(); });\n }\n });\n\n /**\n * Deserialize a JSON definition of a ComposedFilter into a concrete instance.\n */\n fabric.Image.filters.Composed.fromObject = function(object, callback) {\n var filters = object.subFilters || [],\n subFilters = filters.map(function(filter) {\n return new fabric.Image.filters[filter.type](filter);\n }),\n instance = new fabric.Image.filters.Composed({ subFilters: subFilters });\n callback && callback(instance);\n return instance;\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * HueRotation filter class\n * @class fabric.Image.filters.HueRotation\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.HueRotation#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.HueRotation({\n * rotation: -0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.HueRotation = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.HueRotation.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'HueRotation',\n\n /**\n * HueRotation value, from -1 to 1.\n * the unit is radians\n * @param {Number} myParameter\n * @default\n */\n rotation: 0,\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'rotation',\n\n calculateMatrix: function() {\n var rad = this.rotation * Math.PI, cos = fabric.util.cos(rad), sin = fabric.util.sin(rad),\n aThird = 1 / 3, aThirdSqtSin = Math.sqrt(aThird) * sin, OneMinusCos = 1 - cos;\n this.matrix = [\n 1, 0, 0, 0, 0,\n 0, 1, 0, 0, 0,\n 0, 0, 1, 0, 0,\n 0, 0, 0, 1, 0\n ];\n this.matrix[0] = cos + OneMinusCos / 3;\n this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[6] = cos + aThird * OneMinusCos;\n this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[12] = cos + aThird * OneMinusCos;\n },\n\n /**\n * HueRotation isNeutralState implementation\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * @param {Object} options\n **/\n isNeutralState: function(options) {\n this.calculateMatrix();\n return filters.BaseFilter.prototype.isNeutralState.call(this, options);\n },\n\n /**\n * Apply this filter to the input image data provided.\n *\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo: function(options) {\n this.calculateMatrix();\n filters.BaseFilter.prototype.applyTo.call(this, options);\n },\n\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.HueRotation} Instance of fabric.Image.filters.HueRotation\n */\n fabric.Image.filters.HueRotation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n clone = fabric.util.object.clone;\n\n if (fabric.Text) {\n fabric.warn('fabric.Text is already defined');\n return;\n }\n\n /**\n * Text class\n * @class fabric.Text\n * @extends fabric.Object\n * @return {fabric.Text} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}\n * @see {@link fabric.Text#initialize} for constructor definition\n */\n fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ {\n\n /**\n * Properties which when set cause object to change dimensions\n * @type Array\n * @private\n */\n _dimensionAffectingProps: [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign',\n 'styles',\n ],\n\n /**\n * @private\n */\n _reNewline: /\\r?\\n/,\n\n /**\n * Use this regular expression to filter for whitespaces that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n _reSpacesAndTabs: /[ \\t\\r]/g,\n\n /**\n * Use this regular expression to filter for whitespace that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n _reSpaceAndTab: /[ \\t\\r]/,\n\n /**\n * Use this regular expression to filter consecutive groups of non spaces.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n _reWords: /\\S+/g,\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'text',\n\n /**\n * Font size (in pixels)\n * @type Number\n * @default\n */\n fontSize: 40,\n\n /**\n * Font weight (e.g. bold, normal, 400, 600, 800)\n * @type {(Number|String)}\n * @default\n */\n fontWeight: 'normal',\n\n /**\n * Font family\n * @type String\n * @default\n */\n fontFamily: 'Times New Roman',\n\n /**\n * Text decoration underline.\n * @type Boolean\n * @default\n */\n underline: false,\n\n /**\n * Text decoration overline.\n * @type Boolean\n * @default\n */\n overline: false,\n\n /**\n * Text decoration linethrough.\n * @type Boolean\n * @default\n */\n linethrough: false,\n\n /**\n * Text alignment. Possible values: \"left\", \"center\", \"right\", \"justify\",\n * \"justify-left\", \"justify-center\" or \"justify-right\".\n * @type String\n * @default\n */\n textAlign: 'left',\n\n /**\n * Font style . Possible values: \"\", \"normal\", \"italic\" or \"oblique\".\n * @type String\n * @default\n */\n fontStyle: 'normal',\n\n /**\n * Line height\n * @type Number\n * @default\n */\n lineHeight: 1.16,\n\n /**\n * Superscript schema object (minimum overlap)\n * @type {Object}\n * @default\n */\n superscript: {\n size: 0.60, // fontSize factor\n baseline: -0.35 // baseline-shift factor (upwards)\n },\n\n /**\n * Subscript schema object (minimum overlap)\n * @type {Object}\n * @default\n */\n subscript: {\n size: 0.60, // fontSize factor\n baseline: 0.11 // baseline-shift factor (downwards)\n },\n\n /**\n * Background color of text lines\n * @type String\n * @default\n */\n textBackgroundColor: '',\n\n /**\n * List of properties to consider when checking if\n * state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat('fontFamily',\n 'fontWeight',\n 'fontSize',\n 'text',\n 'underline',\n 'overline',\n 'linethrough',\n 'textAlign',\n 'fontStyle',\n 'lineHeight',\n 'textBackgroundColor',\n 'charSpacing',\n 'styles'),\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * @type Array\n */\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('fontFamily',\n 'fontWeight',\n 'fontSize',\n 'text',\n 'underline',\n 'overline',\n 'linethrough',\n 'textAlign',\n 'fontStyle',\n 'lineHeight',\n 'textBackgroundColor',\n 'charSpacing',\n 'styles'),\n\n /**\n * When defined, an object is rendered via stroke and this property specifies its color.\n * Backwards incompatibility note: This property was named \"strokeStyle\" until v1.1.6\n * @type String\n * @default\n */\n stroke: null,\n\n /**\n * Shadow object representing shadow of this shape.\n * Backwards incompatibility note: This property was named \"textShadow\" (String) until v1.2.11\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * @private\n */\n _fontSizeFraction: 0.222,\n\n /**\n * @private\n */\n offsets: {\n underline: 0.10,\n linethrough: -0.315,\n overline: -0.88\n },\n\n /**\n * Text Line proportion to font Size (in pixels)\n * @type Number\n * @default\n */\n _fontSizeMult: 1.13,\n\n /**\n * additional space between characters\n * expressed in thousands of em unit\n * @type Number\n * @default\n */\n charSpacing: 0,\n\n /**\n * Object containing character styles - top-level properties -> line numbers,\n * 2nd-level properties - charater numbers\n * @type Object\n * @default\n */\n styles: null,\n\n /**\n * Reference to a context to measure text char or couple of chars\n * the cacheContext of the canvas will be used or a freshly created one if the object is not on canvas\n * once created it will be referenced on fabric._measuringContext to avoide creating a canvas for every\n * text object created.\n * @type {CanvasRenderingContext2D}\n * @default\n */\n _measuringContext: null,\n\n /**\n * Baseline shift, stlyes only, keep at 0 for the main text object\n * @type {Number}\n * @default\n */\n deltaY: 0,\n\n /**\n * Array of properties that define a style unit (of 'styles').\n * @type {Array}\n * @default\n */\n _styleProperties: [\n 'stroke',\n 'strokeWidth',\n 'fill',\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'fontStyle',\n 'underline',\n 'overline',\n 'linethrough',\n 'deltaY',\n 'textBackgroundColor',\n ],\n\n /**\n * contains characters bounding boxes\n */\n __charBounds: [],\n\n /**\n * use this size when measuring text. To avoid IE11 rounding errors\n * @type {Number}\n * @default\n * @readonly\n * @private\n */\n CACHE_FONT_SIZE: 400,\n\n /**\n * contains the min text width to avoid getting 0\n * @type {Number}\n * @default\n */\n MIN_TEXT_WIDTH: 2,\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.Text} thisArg\n */\n initialize: function(text, options) {\n this.styles = options ? (options.styles || { }) : { };\n this.text = text;\n this.__skipDimension = true;\n this.callSuper('initialize', options);\n this.__skipDimension = false;\n this.initDimensions();\n this.setCoords();\n this.setupState({ propertySet: '_dimensionAffectingProps' });\n },\n\n /**\n * Return a contex for measurement of text string.\n * if created it gets stored for reuse\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.Text} thisArg\n */\n getMeasuringContext: function() {\n // if we did not return we have to measure something.\n if (!fabric._measuringContext) {\n fabric._measuringContext = this.canvas && this.canvas.contextCache ||\n fabric.util.createCanvasElement().getContext('2d');\n }\n return fabric._measuringContext;\n },\n\n /**\n * @private\n * Divides text into lines of text and lines of graphemes.\n */\n _splitText: function() {\n var newLines = this._splitTextIntoLines(this.text);\n this.textLines = newLines.lines;\n this._textLines = newLines.graphemeLines;\n this._unwrappedTextLines = newLines._unwrappedLines;\n this._text = newLines.graphemeText;\n return newLines;\n },\n\n /**\n * Initialize or update text dimensions.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n */\n initDimensions: function() {\n if (this.__skipDimension) {\n return;\n }\n this._splitText();\n this._clearCache();\n this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH;\n if (this.textAlign.indexOf('justify') !== -1) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n this.height = this.calcTextHeight();\n this.saveState({ propertySet: '_dimensionAffectingProps' });\n },\n\n /**\n * Enlarge space boxes and shift the others\n */\n enlargeSpaces: function() {\n var diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces;\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n if (this.textAlign !== 'justify' && (i === len - 1 || this.isEndOfWrapping(i))) {\n continue;\n }\n accumulatedSpace = 0;\n line = this._textLines[i];\n currentLineWidth = this.getLineWidth(i);\n if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) {\n numberOfSpaces = spaces.length;\n diffSpace = (this.width - currentLineWidth) / numberOfSpaces;\n for (var j = 0, jlen = line.length; j <= jlen; j++) {\n charBound = this.__charBounds[i][j];\n if (this._reSpaceAndTab.test(line[j])) {\n charBound.width += diffSpace;\n charBound.kernedWidth += diffSpace;\n charBound.left += accumulatedSpace;\n accumulatedSpace += diffSpace;\n }\n else {\n charBound.left += accumulatedSpace;\n }\n }\n }\n }\n },\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @return {Boolean}\n */\n isEndOfWrapping: function(lineIndex) {\n return lineIndex === this._textLines.length - 1;\n },\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * It return always for text and Itext.\n * @return Number\n */\n missingNewlineOffset: function() {\n return 1;\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of text object\n */\n toString: function() {\n return '#';\n },\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @param {Object} dim.x width of object to be cached\n * @param {Object} dim.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions: function() {\n var dims = this.callSuper('_getCacheCanvasDimensions');\n var fontSize = this.fontSize;\n dims.width += fontSize * dims.zoomX;\n dims.height += fontSize * dims.zoomY;\n return dims;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n this._setTextStyles(ctx);\n this._renderTextLinesBackground(ctx);\n this._renderTextDecoration(ctx, 'underline');\n this._renderText(ctx);\n this._renderTextDecoration(ctx, 'overline');\n this._renderTextDecoration(ctx, 'linethrough');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderText: function(ctx) {\n if (this.paintFirst === 'stroke') {\n this._renderTextStroke(ctx);\n this._renderTextFill(ctx);\n }\n else {\n this._renderTextFill(ctx);\n this._renderTextStroke(ctx);\n }\n },\n\n /**\n * Set the font parameter of the context with the object properties or with charStyle\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [charStyle] object with font style properties\n * @param {String} [charStyle.fontFamily] Font Family\n * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )\n * @param {String} [charStyle.fontWeight] Font weight\n * @param {String} [charStyle.fontStyle] Font style (italic|normal)\n */\n _setTextStyles: function(ctx, charStyle, forMeasuring) {\n ctx.textBaseline = 'alphabetic';\n ctx.font = this._getFontDeclaration(charStyle, forMeasuring);\n },\n\n /**\n * calculate and return the text Width measuring each line.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {Number} Maximum width of fabric.Text object\n */\n calcTextWidth: function() {\n var maxWidth = this.getLineWidth(0);\n\n for (var i = 1, len = this._textLines.length; i < len; i++) {\n var currentLineWidth = this.getLineWidth(i);\n if (currentLineWidth > maxWidth) {\n maxWidth = currentLineWidth;\n }\n }\n return maxWidth;\n },\n\n /**\n * @private\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Text to render\n * @param {Number} left Left position of text\n * @param {Number} top Top position of text\n * @param {Number} lineIndex Index of a line in a text\n */\n _renderTextLine: function(method, ctx, line, left, top, lineIndex) {\n this._renderChars(method, ctx, line, left, top, lineIndex);\n },\n\n /**\n * Renders the text background for lines, taking care of style\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextLinesBackground: function(ctx) {\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {\n return;\n }\n var lineTopOffset = 0, heightOfLine,\n lineLeftOffset, originalFill = ctx.fillStyle,\n line, lastColor,\n leftOffset = this._getLeftOffset(),\n topOffset = this._getTopOffset(),\n boxStart = 0, boxWidth = 0, charBox, currentColor;\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this.getHeightOfLine(i);\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) {\n lineTopOffset += heightOfLine;\n continue;\n }\n line = this._textLines[i];\n lineLeftOffset = this._getLineLeftOffset(i);\n boxWidth = 0;\n boxStart = 0;\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charBox = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n ctx.fillStyle = lastColor;\n lastColor && ctx.fillRect(\n leftOffset + lineLeftOffset + boxStart,\n topOffset + lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight\n );\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n }\n else {\n boxWidth += charBox.kernedWidth;\n }\n }\n if (currentColor) {\n ctx.fillStyle = currentColor;\n ctx.fillRect(\n leftOffset + lineLeftOffset + boxStart,\n topOffset + lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight\n );\n }\n lineTopOffset += heightOfLine;\n }\n ctx.fillStyle = originalFill;\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n },\n\n /**\n * @private\n * @param {Object} decl style declaration for cache\n * @param {String} decl.fontFamily fontFamily\n * @param {String} decl.fontStyle fontStyle\n * @param {String} decl.fontWeight fontWeight\n * @return {Object} reference to cache\n */\n getFontCache: function(decl) {\n var fontFamily = decl.fontFamily.toLowerCase();\n if (!fabric.charWidthsCache[fontFamily]) {\n fabric.charWidthsCache[fontFamily] = { };\n }\n var cache = fabric.charWidthsCache[fontFamily],\n cacheProp = decl.fontStyle.toLowerCase() + '_' + (decl.fontWeight + '').toLowerCase();\n if (!cache[cacheProp]) {\n cache[cacheProp] = { };\n }\n return cache[cacheProp];\n },\n\n /**\n * apply all the character style to canvas for rendering\n * @private\n * @param {String} _char\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} [decl]\n */\n _applyCharStyles: function(method, ctx, lineIndex, charIndex, styleDeclaration) {\n\n this._setFillStyles(ctx, styleDeclaration);\n this._setStrokeStyles(ctx, styleDeclaration);\n\n ctx.font = this._getFontDeclaration(styleDeclaration);\n },\n\n /**\n * measure and return the width of a single character.\n * possibly overridden to accommodate different measure logic or\n * to hook some external lib for character measurement\n * @private\n * @param {String} _char, char to be measured\n * @param {Object} charStyle style of char to be measured\n * @param {String} [previousChar] previous char\n * @param {Object} [prevCharStyle] style of previous char\n */\n _measureChar: function(_char, charStyle, previousChar, prevCharStyle) {\n // first i try to return from cache\n var fontCache = this.getFontCache(charStyle), fontDeclaration = this._getFontDeclaration(charStyle),\n previousFontDeclaration = this._getFontDeclaration(prevCharStyle), couple = previousChar + _char,\n stylesAreEqual = fontDeclaration === previousFontDeclaration, width, coupleWidth, previousWidth,\n fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE, kernedWidth;\n\n if (previousChar && fontCache[previousChar] !== undefined) {\n previousWidth = fontCache[previousChar];\n }\n if (fontCache[_char] !== undefined) {\n kernedWidth = width = fontCache[_char];\n }\n if (stylesAreEqual && fontCache[couple] !== undefined) {\n coupleWidth = fontCache[couple];\n kernedWidth = coupleWidth - previousWidth;\n }\n if (width === undefined || previousWidth === undefined || coupleWidth === undefined) {\n var ctx = this.getMeasuringContext();\n // send a TRUE to specify measuring font size CACHE_FONT_SIZE\n this._setTextStyles(ctx, charStyle, true);\n }\n if (width === undefined) {\n kernedWidth = width = ctx.measureText(_char).width;\n fontCache[_char] = width;\n }\n if (previousWidth === undefined && stylesAreEqual && previousChar) {\n previousWidth = ctx.measureText(previousChar).width;\n fontCache[previousChar] = previousWidth;\n }\n if (stylesAreEqual && coupleWidth === undefined) {\n // we can measure the kerning couple and subtract the width of the previous character\n coupleWidth = ctx.measureText(couple).width;\n fontCache[couple] = coupleWidth;\n kernedWidth = coupleWidth - previousWidth;\n }\n return { width: width * fontMultiplier, kernedWidth: kernedWidth * fontMultiplier };\n },\n\n /**\n * Computes height of character at given position\n * @param {Number} line the line index number\n * @param {Number} _char the character index number\n * @return {Number} fontSize of the character\n */\n getHeightOfChar: function(line, _char) {\n return this.getValueOfPropertyAt(line, _char, 'fontSize');\n },\n\n /**\n * measure a text line measuring all characters.\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n measureLine: function(lineIndex) {\n var lineInfo = this._measureLine(lineIndex);\n if (this.charSpacing !== 0) {\n lineInfo.width -= this._getWidthOfCharSpacing();\n }\n if (lineInfo.width < 0) {\n lineInfo.width = 0;\n }\n return lineInfo;\n },\n\n /**\n * measure every grapheme of a line, populating __charBounds\n * @param {Number} lineIndex\n * @return {Object} object.width total width of characters\n * @return {Object} object.widthOfSpaces length of chars that match this._reSpacesAndTabs\n */\n _measureLine: function(lineIndex) {\n var width = 0, i, grapheme, line = this._textLines[lineIndex], prevGrapheme,\n graphemeInfo, numOfSpaces = 0, lineBounds = new Array(line.length);\n\n this.__charBounds[lineIndex] = lineBounds;\n for (i = 0; i < line.length; i++) {\n grapheme = line[i];\n graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);\n lineBounds[i] = graphemeInfo;\n width += graphemeInfo.kernedWidth;\n prevGrapheme = grapheme;\n }\n // this latest bound box represent the last character of the line\n // to simplify cursor handling in interactive mode.\n lineBounds[i] = {\n left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0,\n width: 0,\n kernedWidth: 0,\n height: this.fontSize\n };\n return { width: width, numOfSpaces: numOfSpaces };\n },\n\n /**\n * Measure and return the info of a single grapheme.\n * needs the the info of previous graphemes already filled\n * @private\n * @param {String} grapheme to be measured\n * @param {Number} lineIndex index of the line where the char is\n * @param {Number} charIndex position in the line\n * @param {String} [prevGrapheme] character preceding the one to be measured\n */\n _getGraphemeBox: function(grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) {\n var style = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n prevStyle = prevGrapheme ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1) : { },\n info = this._measureChar(grapheme, style, prevGrapheme, prevStyle),\n kernedWidth = info.kernedWidth,\n width = info.width, charSpacing;\n\n if (this.charSpacing !== 0) {\n charSpacing = this._getWidthOfCharSpacing();\n width += charSpacing;\n kernedWidth += charSpacing;\n }\n\n var box = {\n width: width,\n left: 0,\n height: style.fontSize,\n kernedWidth: kernedWidth,\n deltaY: style.deltaY,\n };\n if (charIndex > 0 && !skipLeft) {\n var previousBox = this.__charBounds[lineIndex][charIndex - 1];\n box.left = previousBox.left + previousBox.width + info.kernedWidth - info.width;\n }\n return box;\n },\n\n /**\n * Calculate height of line at 'lineIndex'\n * @param {Number} lineIndex index of line to calculate\n * @return {Number}\n */\n getHeightOfLine: function(lineIndex) {\n if (this.__lineHeights[lineIndex]) {\n return this.__lineHeights[lineIndex];\n }\n\n var line = this._textLines[lineIndex],\n // char 0 is measured before the line cycle because it nneds to char\n // emptylines\n maxHeight = this.getHeightOfChar(lineIndex, 0);\n for (var i = 1, len = line.length; i < len; i++) {\n maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);\n }\n\n return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult;\n },\n\n /**\n * Calculate text box height\n */\n calcTextHeight: function() {\n var lineHeight, height = 0;\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n lineHeight = this.getHeightOfLine(i);\n height += (i === len - 1 ? lineHeight / this.lineHeight : lineHeight);\n }\n return height;\n },\n\n /**\n * @private\n * @return {Number} Left offset\n */\n _getLeftOffset: function() {\n return -this.width / 2;\n },\n\n /**\n * @private\n * @return {Number} Top offset\n */\n _getTopOffset: function() {\n return -this.height / 2;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} filler fabric.Pattern or fabric.Gradient\n * @return {Object} offset.offsetX offset for text rendering\n * @return {Object} offset.offsetY offset for text rendering\n */\n _applyPatternGradientTransform: function(ctx, filler) {\n if (!filler || !filler.toLive) {\n return { offsetX: 0, offsetY: 0 };\n }\n var offsetX = -this.width / 2 + filler.offsetX || 0,\n offsetY = -this.height / 2 + filler.offsetY || 0;\n\n ctx.transform(1, 0, 0, 1, offsetX, offsetY);\n return { offsetX: offsetX, offsetY: offsetY };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n */\n _renderTextCommon: function(ctx, method) {\n ctx.save();\n var lineHeights = 0, left = this._getLeftOffset(), top = this._getTopOffset(),\n offsets = this._applyPatternGradientTransform(ctx, method === 'fillText' ? this.fill : this.stroke);\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n var heightOfLine = this.getHeightOfLine(i),\n maxHeight = heightOfLine / this.lineHeight,\n leftOffset = this._getLineLeftOffset(i);\n this._renderTextLine(\n method,\n ctx,\n this._textLines[i],\n left + leftOffset - offsets.offsetX,\n top + lineHeights + maxHeight - offsets.offsetY,\n i\n );\n lineHeights += heightOfLine;\n }\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextFill: function(ctx) {\n if (!this.fill && !this.styleHas('fill')) {\n return;\n }\n\n this._renderTextCommon(ctx, 'fillText');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextStroke: function(ctx) {\n if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n this._setLineDash(ctx, this.strokeDashArray);\n ctx.beginPath();\n this._renderTextCommon(ctx, 'strokeText');\n ctx.closePath();\n ctx.restore();\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Content of the line\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n * @param {Number} charOffset\n */\n _renderChars: function(method, ctx, line, left, top, lineIndex) {\n // set proper line offset\n var lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.indexOf('justify') !== -1,\n actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n boxWidth = 0,\n timeToRender,\n shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex);\n\n ctx.save();\n top -= lineHeight * this._fontSizeFraction / this.lineHeight;\n if (shortCut) {\n // render all the line in one pass without checking\n this._renderChar(method, ctx, lineIndex, 0, this.textLines[lineIndex], left, top, lineHeight);\n ctx.restore();\n return;\n }\n for (var i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n left += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n }\n else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = this._hasStyleChanged(actualStyle, nextStyle);\n }\n if (timeToRender) {\n this._renderChar(method, ctx, lineIndex, i, charsToRender, left, top, lineHeight);\n charsToRender = '';\n actualStyle = nextStyle;\n left += boxWidth;\n boxWidth = 0;\n }\n }\n ctx.restore();\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {String} _char\n * @param {Number} left Left coordinate\n * @param {Number} top Top coordinate\n * @param {Number} lineHeight Height of the line\n */\n _renderChar: function(method, ctx, lineIndex, charIndex, _char, left, top) {\n var decl = this._getStyleDeclaration(lineIndex, charIndex),\n fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n shouldFill = method === 'fillText' && fullDecl.fill,\n shouldStroke = method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth;\n\n if (!shouldStroke && !shouldFill) {\n return;\n }\n decl && ctx.save();\n\n this._applyCharStyles(method, ctx, lineIndex, charIndex, fullDecl);\n\n if (decl && decl.textBackgroundColor) {\n this._removeShadow(ctx);\n }\n if (decl && decl.deltaY) {\n top += decl.deltaY;\n }\n\n shouldFill && ctx.fillText(_char, left, top);\n shouldStroke && ctx.strokeText(_char, left, top);\n decl && ctx.restore();\n },\n\n /**\n * Turns the character into a 'superior figure' (i.e. 'superscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @returns {fabric.Text} thisArg\n * @chainable\n */\n setSuperscript: function(start, end) {\n return this._setScript(start, end, this.superscript);\n },\n\n /**\n * Turns the character into an 'inferior figure' (i.e. 'subscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @returns {fabric.Text} thisArg\n * @chainable\n */\n setSubscript: function(start, end) {\n return this._setScript(start, end, this.subscript);\n },\n\n /**\n * Applies 'schema' at given position\n * @private\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @param {Number} schema\n * @returns {fabric.Text} thisArg\n * @chainable\n */\n _setScript: function(start, end, schema) {\n var loc = this.get2DCursorLocation(start, true),\n fontSize = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'fontSize'),\n dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'),\n style = { fontSize: fontSize * schema.size, deltaY: dy + fontSize * schema.baseline };\n this.setSelectionStyles(style, start, end);\n return this;\n },\n\n /**\n * @private\n * @param {Object} prevStyle\n * @param {Object} thisStyle\n */\n _hasStyleChanged: function(prevStyle, thisStyle) {\n return prevStyle.fill !== thisStyle.fill ||\n prevStyle.stroke !== thisStyle.stroke ||\n prevStyle.strokeWidth !== thisStyle.strokeWidth ||\n prevStyle.fontSize !== thisStyle.fontSize ||\n prevStyle.fontFamily !== thisStyle.fontFamily ||\n prevStyle.fontWeight !== thisStyle.fontWeight ||\n prevStyle.fontStyle !== thisStyle.fontStyle ||\n prevStyle.deltaY !== thisStyle.deltaY;\n },\n\n /**\n * @private\n * @param {Object} prevStyle\n * @param {Object} thisStyle\n */\n _hasStyleChangedForSvg: function(prevStyle, thisStyle) {\n return this._hasStyleChanged(prevStyle, thisStyle) ||\n prevStyle.overline !== thisStyle.overline ||\n prevStyle.underline !== thisStyle.underline ||\n prevStyle.linethrough !== thisStyle.linethrough;\n },\n\n /**\n * @private\n * @param {Number} lineIndex index text line\n * @return {Number} Line left offset\n */\n _getLineLeftOffset: function(lineIndex) {\n var lineWidth = this.getLineWidth(lineIndex);\n if (this.textAlign === 'center') {\n return (this.width - lineWidth) / 2;\n }\n if (this.textAlign === 'right') {\n return this.width - lineWidth;\n }\n if (this.textAlign === 'justify-center' && this.isEndOfWrapping(lineIndex)) {\n return (this.width - lineWidth) / 2;\n }\n if (this.textAlign === 'justify-right' && this.isEndOfWrapping(lineIndex)) {\n return this.width - lineWidth;\n }\n return 0;\n },\n\n /**\n * @private\n */\n _clearCache: function() {\n this.__lineWidths = [];\n this.__lineHeights = [];\n this.__charBounds = [];\n },\n\n /**\n * @private\n */\n _shouldClearDimensionCache: function() {\n var shouldClear = this._forceClearCache;\n shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps'));\n if (shouldClear) {\n this.dirty = true;\n this._forceClearCache = false;\n }\n return shouldClear;\n },\n\n /**\n * Measure a single line given its index. Used to calculate the initial\n * text bounding box. The values are calculated and stored in __lineWidths cache.\n * @private\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n getLineWidth: function(lineIndex) {\n if (this.__lineWidths[lineIndex]) {\n return this.__lineWidths[lineIndex];\n }\n\n var width, line = this._textLines[lineIndex], lineInfo;\n\n if (line === '') {\n width = 0;\n }\n else {\n lineInfo = this.measureLine(lineIndex);\n width = lineInfo.width;\n }\n this.__lineWidths[lineIndex] = width;\n return width;\n },\n\n _getWidthOfCharSpacing: function() {\n if (this.charSpacing !== 0) {\n return this.fontSize * this.charSpacing / 1000;\n }\n return 0;\n },\n\n /**\n * Retrieves the value of property at given character position\n * @param {Number} lineIndex the line number\n * @param {Number} charIndex the charater number\n * @param {String} property the property name\n * @returns the value of 'property'\n */\n getValueOfPropertyAt: function(lineIndex, charIndex, property) {\n var charStyle = this._getStyleDeclaration(lineIndex, charIndex);\n if (charStyle && typeof charStyle[property] !== 'undefined') {\n return charStyle[property];\n }\n return this[property];\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration: function(ctx, type) {\n if (!this[type] && !this.styleHas(type)) {\n return;\n }\n var heightOfLine, size, _size,\n lineLeftOffset, dy, _dy,\n line, lastDecoration,\n leftOffset = this._getLeftOffset(),\n topOffset = this._getTopOffset(), top,\n boxStart, boxWidth, charBox, currentDecoration,\n maxHeight, currentFill, lastFill,\n charSpacing = this._getWidthOfCharSpacing();\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this.getHeightOfLine(i);\n if (!this[type] && !this.styleHas(type, i)) {\n topOffset += heightOfLine;\n continue;\n }\n line = this._textLines[i];\n maxHeight = heightOfLine / this.lineHeight;\n lineLeftOffset = this._getLineLeftOffset(i);\n boxStart = 0;\n boxWidth = 0;\n lastDecoration = this.getValueOfPropertyAt(i, 0, type);\n lastFill = this.getValueOfPropertyAt(i, 0, 'fill');\n top = topOffset + maxHeight * (1 - this._fontSizeFraction);\n size = this.getHeightOfChar(i, 0);\n dy = this.getValueOfPropertyAt(i, 0, 'deltaY');\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charBox = this.__charBounds[i][j];\n currentDecoration = this.getValueOfPropertyAt(i, j, type);\n currentFill = this.getValueOfPropertyAt(i, j, 'fill');\n _size = this.getHeightOfChar(i, j);\n _dy = this.getValueOfPropertyAt(i, j, 'deltaY');\n if ((currentDecoration !== lastDecoration || currentFill !== lastFill || _size !== size || _dy !== dy) &&\n boxWidth > 0) {\n ctx.fillStyle = lastFill;\n lastDecoration && lastFill && ctx.fillRect(\n leftOffset + lineLeftOffset + boxStart,\n top + this.offsets[type] * size + dy,\n boxWidth,\n this.fontSize / 15\n );\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastDecoration = currentDecoration;\n lastFill = currentFill;\n size = _size;\n dy = _dy;\n }\n else {\n boxWidth += charBox.kernedWidth;\n }\n }\n ctx.fillStyle = currentFill;\n currentDecoration && currentFill && ctx.fillRect(\n leftOffset + lineLeftOffset + boxStart,\n top + this.offsets[type] * size + dy,\n boxWidth - charSpacing,\n this.fontSize / 15\n );\n topOffset += heightOfLine;\n }\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n },\n\n /**\n * return font declaration string for canvas context\n * @param {Object} [styleObject] object\n * @returns {String} font declaration formatted for canvas context.\n */\n _getFontDeclaration: function(styleObject, forMeasuring) {\n var style = styleObject || this, family = this.fontFamily,\n fontIsGeneric = fabric.Text.genericFonts.indexOf(family.toLowerCase()) > -1;\n var fontFamily = family === undefined ||\n family.indexOf('\\'') > -1 || family.indexOf(',') > -1 ||\n family.indexOf('\"') > -1 || fontIsGeneric\n ? style.fontFamily : '\"' + style.fontFamily + '\"';\n return [\n // node-canvas needs \"weight style\", while browsers need \"style weight\"\n // verify if this can be fixed in JSDOM\n (fabric.isLikelyNode ? style.fontWeight : style.fontStyle),\n (fabric.isLikelyNode ? style.fontStyle : style.fontWeight),\n forMeasuring ? this.CACHE_FONT_SIZE + 'px' : style.fontSize + 'px',\n fontFamily\n ].join(' ');\n },\n\n /**\n * Renders text instance on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render: function(ctx) {\n // do not render if object is not visible\n if (!this.visible) {\n return;\n }\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n }\n this.callSuper('render', ctx);\n },\n\n /**\n * Returns the text as an array of lines.\n * @param {String} text text to split\n * @returns {Array} Lines in the text\n */\n _splitTextIntoLines: function(text) {\n var lines = text.split(this._reNewline),\n newLines = new Array(lines.length),\n newLine = ['\\n'],\n newText = [];\n for (var i = 0; i < lines.length; i++) {\n newLines[i] = fabric.util.string.graphemeSplit(lines[i]);\n newText = newText.concat(newLines[i], newLine);\n }\n newText.pop();\n return { _unwrappedLines: newLines, lines: lines, graphemeText: newText, graphemeLines: newLines };\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var additionalProperties = [\n 'text',\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n 'lineHeight',\n 'underline',\n 'overline',\n 'linethrough',\n 'textAlign',\n 'textBackgroundColor',\n 'charSpacing',\n ].concat(propertiesToInclude);\n var obj = this.callSuper('toObject', additionalProperties);\n obj.styles = clone(this.styles, true);\n return obj;\n },\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n set: function(key, value) {\n this.callSuper('set', key, value);\n var needsDims = false;\n if (typeof key === 'object') {\n for (var _key in key) {\n needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1;\n }\n }\n else {\n needsDims = this._dimensionAffectingProps.indexOf(key) !== -1;\n }\n if (needsDims) {\n this.initDimensions();\n this.setCoords();\n }\n return this;\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity\n */\n complexity: function() {\n return 1;\n }\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement})\n * @static\n * @memberOf fabric.Text\n * @see: http://www.w3.org/TR/SVG/text.html#TextElement\n */\n fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(\n 'x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(' '));\n\n /**\n * Default SVG font size\n * @static\n * @memberOf fabric.Text\n */\n fabric.Text.DEFAULT_SVG_FONT_SIZE = 16;\n\n /**\n * Returns fabric.Text instance from an SVG element (not yet implemented)\n * @static\n * @memberOf fabric.Text\n * @param {SVGElement} element Element to parse\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n fabric.Text.fromElement = function(element, callback, options) {\n if (!element) {\n return callback(null);\n }\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES),\n parsedAnchor = parsedAttributes.textAnchor || 'left';\n options = fabric.util.object.extend((options ? clone(options) : { }), parsedAttributes);\n\n options.top = options.top || 0;\n options.left = options.left || 0;\n if (parsedAttributes.textDecoration) {\n var textDecoration = parsedAttributes.textDecoration;\n if (textDecoration.indexOf('underline') !== -1) {\n options.underline = true;\n }\n if (textDecoration.indexOf('overline') !== -1) {\n options.overline = true;\n }\n if (textDecoration.indexOf('line-through') !== -1) {\n options.linethrough = true;\n }\n delete options.textDecoration;\n }\n if ('dx' in parsedAttributes) {\n options.left += parsedAttributes.dx;\n }\n if ('dy' in parsedAttributes) {\n options.top += parsedAttributes.dy;\n }\n if (!('fontSize' in options)) {\n options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\n\n var textContent = '';\n\n // The XML is not properly parsed in IE9 so a workaround to get\n // textContent is through firstChild.data. Another workaround would be\n // to convert XML loaded from a file to be converted using DOMParser (same way loadSVGFromString() does)\n if (!('textContent' in element)) {\n if ('firstChild' in element && element.firstChild !== null) {\n if ('data' in element.firstChild && element.firstChild.data !== null) {\n textContent = element.firstChild.data;\n }\n }\n }\n else {\n textContent = element.textContent;\n }\n\n textContent = textContent.replace(/^\\s+|\\s+$|\\n+/g, '').replace(/\\s+/g, ' ');\n var originalStrokeWidth = options.strokeWidth;\n options.strokeWidth = 0;\n\n var text = new fabric.Text(textContent, options),\n textHeightScaleFactor = text.getScaledHeight() / text.height,\n lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height,\n scaledDiff = lineHeightDiff * textHeightScaleFactor,\n textHeight = text.getScaledHeight() + scaledDiff,\n offX = 0;\n /*\n Adjust positioning:\n x/y attributes in SVG correspond to the bottom-left corner of text bounding box\n fabric output by default at top, left.\n */\n if (parsedAnchor === 'center') {\n offX = text.getScaledWidth() / 2;\n }\n if (parsedAnchor === 'right') {\n offX = text.getScaledWidth();\n }\n text.set({\n left: text.left - offX,\n top: text.top - (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) / text.lineHeight,\n strokeWidth: typeof originalStrokeWidth !== 'undefined' ? originalStrokeWidth : 1,\n });\n callback(text);\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Text instance from an object representation\n * @static\n * @memberOf fabric.Text\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created\n */\n fabric.Text.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Text', object, callback, 'text');\n };\n\n fabric.Text.genericFonts = ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'];\n\n fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text);\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ {\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles: function(lineIndex) {\n if (!this.styles) {\n return true;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return true;\n }\n var obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] };\n for (var p1 in obj) {\n for (var p2 in obj[p1]) {\n // eslint-disable-next-line no-unused-vars\n for (var p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n return true;\n },\n\n /**\n * Returns true if object has a style property or has it ina specified line\n * This function is used to detect if a text will use a particular property or not.\n * @param {String} property to check for\n * @param {Number} lineIndex to check the style on\n * @return {Boolean}\n */\n styleHas: function(property, lineIndex) {\n if (!this.styles || !property || property === '') {\n return false;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return false;\n }\n var obj = typeof lineIndex === 'undefined' ? this.styles : { 0: this.styles[lineIndex] };\n // eslint-disable-next-line\n for (var p1 in obj) {\n // eslint-disable-next-line\n for (var p2 in obj[p1]) {\n if (typeof obj[p1][p2][property] !== 'undefined') {\n return true;\n }\n }\n }\n return false;\n },\n\n /**\n * Check if characters in a text have a value for a property\n * whose value matches the textbox's value for that property. If so,\n * the character-level property is deleted. If the character\n * has no other properties, then it is also deleted. Finally,\n * if the line containing that character has no other characters\n * then it also is deleted.\n *\n * @param {string} property The property to compare between characters and text.\n */\n cleanStyle: function(property) {\n if (!this.styles || !property || property === '') {\n return false;\n }\n var obj = this.styles, stylesCount = 0, letterCount, stylePropertyValue,\n allStyleObjectPropertiesMatch = true, graphemeCount = 0, styleObject;\n // eslint-disable-next-line\n for (var p1 in obj) {\n letterCount = 0;\n // eslint-disable-next-line\n for (var p2 in obj[p1]) {\n var styleObject = obj[p1][p2],\n stylePropertyHasBeenSet = styleObject.hasOwnProperty(property);\n\n stylesCount++;\n\n if (stylePropertyHasBeenSet) {\n if (!stylePropertyValue) {\n stylePropertyValue = styleObject[property];\n }\n else if (styleObject[property] !== stylePropertyValue) {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (styleObject[property] === this[property]) {\n delete styleObject[property];\n }\n }\n else {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (Object.keys(styleObject).length !== 0) {\n letterCount++;\n }\n else {\n delete obj[p1][p2];\n }\n }\n\n if (letterCount === 0) {\n delete obj[p1];\n }\n }\n // if every grapheme has the same style set then\n // delete those styles and set it on the parent\n for (var i = 0; i < this._textLines.length; i++) {\n graphemeCount += this._textLines[i].length;\n }\n if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) {\n this[property] = stylePropertyValue;\n this.removeStyle(property);\n }\n },\n\n /**\n * Remove a style property or properties from all individual character styles\n * in a text object. Deletes the character style object if it contains no other style\n * props. Deletes a line style object if it contains no other character styles.\n *\n * @param {String} props The property to remove from character styles.\n */\n removeStyle: function(property) {\n if (!this.styles || !property || property === '') {\n return;\n }\n var obj = this.styles, line, lineNum, charNum;\n for (lineNum in obj) {\n line = obj[lineNum];\n for (charNum in line) {\n delete line[charNum][property];\n if (Object.keys(line[charNum]).length === 0) {\n delete line[charNum];\n }\n }\n if (Object.keys(line).length === 0) {\n delete obj[lineNum];\n }\n }\n },\n\n /**\n * @private\n */\n _extendStyles: function(index, styles) {\n var loc = this.get2DCursorLocation(index);\n\n if (!this._getLineStyle(loc.lineIndex)) {\n this._setLineStyle(loc.lineIndex);\n }\n\n if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) {\n this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {});\n }\n\n fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles);\n },\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. usefull to manage styles.\n */\n get2DCursorLocation: function(selectionStart, skipWrapping) {\n if (typeof selectionStart === 'undefined') {\n selectionStart = this.selectionStart;\n }\n var lines = skipWrapping ? this._unwrappedTextLines : this._textLines,\n len = lines.length;\n for (var i = 0; i < len; i++) {\n if (selectionStart <= lines[i].length) {\n return {\n lineIndex: i,\n charIndex: selectionStart\n };\n }\n selectionStart -= lines[i].length + this.missingNewlineOffset(i);\n }\n return {\n lineIndex: i - 1,\n charIndex: lines[i - 1].length < selectionStart ? lines[i - 1].length : selectionStart\n };\n },\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * if startIndex or endIndex are not provided, slectionStart or selectionEnd will be used.\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles: function(startIndex, endIndex, complete) {\n if (typeof startIndex === 'undefined') {\n startIndex = this.selectionStart || 0;\n }\n if (typeof endIndex === 'undefined') {\n endIndex = this.selectionEnd || startIndex;\n }\n var styles = [];\n for (var i = startIndex; i < endIndex; i++) {\n styles.push(this.getStyleAtPosition(i, complete));\n }\n return styles;\n },\n\n /**\n * Gets style of a current selection/cursor position\n * @param {Number} position to get styles at\n * @param {Boolean} [complete] full style if true\n * @return {Object} style Style object at a specified index\n * @private\n */\n getStyleAtPosition: function(position, complete) {\n var loc = this.get2DCursorLocation(position),\n style = complete ? this.getCompleteStyleDeclaration(loc.lineIndex, loc.charIndex) :\n this._getStyleDeclaration(loc.lineIndex, loc.charIndex);\n return style || {};\n },\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} [styles] Styles object\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @return {fabric.IText} thisArg\n * @chainable\n */\n setSelectionStyles: function(styles, startIndex, endIndex) {\n if (typeof startIndex === 'undefined') {\n startIndex = this.selectionStart || 0;\n }\n if (typeof endIndex === 'undefined') {\n endIndex = this.selectionEnd || startIndex;\n }\n for (var i = startIndex; i < endIndex; i++) {\n this._extendStyles(i, styles);\n }\n /* not included in _extendStyles to avoid clearing cache more than once */\n this._forceClearCache = true;\n return this;\n },\n\n /**\n * get the reference, not a clone, of the style object for a given character\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Object} style object\n */\n _getStyleDeclaration: function(lineIndex, charIndex) {\n var lineStyle = this.styles && this.styles[lineIndex];\n if (!lineStyle) {\n return null;\n }\n return lineStyle[charIndex];\n },\n\n /**\n * return a new object that contains all the style property for a character\n * the object returned is newly created\n * @param {Number} lineIndex of the line where the character is\n * @param {Number} charIndex position of the character on the line\n * @return {Object} style object\n */\n getCompleteStyleDeclaration: function(lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex) || { },\n styleObject = { }, prop;\n for (var i = 0; i < this._styleProperties.length; i++) {\n prop = this._styleProperties[i];\n styleObject[prop] = typeof style[prop] === 'undefined' ? this[prop] : style[prop];\n }\n return styleObject;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n _setStyleDeclaration: function(lineIndex, charIndex, style) {\n this.styles[lineIndex][charIndex] = style;\n },\n\n /**\n *\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _deleteStyleDeclaration: function(lineIndex, charIndex) {\n delete this.styles[lineIndex][charIndex];\n },\n\n /**\n * @param {Number} lineIndex\n * @return {Boolean} if the line exists or not\n * @private\n */\n _getLineStyle: function(lineIndex) {\n return !!this.styles[lineIndex];\n },\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @private\n */\n _setLineStyle: function(lineIndex) {\n this.styles[lineIndex] = {};\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _deleteLineStyle: function(lineIndex) {\n delete this.styles[lineIndex];\n }\n });\n})();\n\n\n(function() {\n\n function parseDecoration(object) {\n if (object.textDecoration) {\n object.textDecoration.indexOf('underline') > -1 && (object.underline = true);\n object.textDecoration.indexOf('line-through') > -1 && (object.linethrough = true);\n object.textDecoration.indexOf('overline') > -1 && (object.overline = true);\n delete object.textDecoration;\n }\n }\n\n /**\n * IText class (introduced in v1.4) Events are also fired with \"text:\"\n * prefix when observing canvas.\n * @class fabric.IText\n * @extends fabric.Text\n * @mixes fabric.Observable\n *\n * @fires changed\n * @fires selection:changed\n * @fires editing:entered\n * @fires editing:exited\n *\n * @return {fabric.IText} thisArg\n * @see {@link fabric.IText#initialize} for constructor definition\n *\n *

Supported key combinations:

\n *
\n   *   Move cursor:                    left, right, up, down\n   *   Select character:               shift + left, shift + right\n   *   Select text vertically:         shift + up, shift + down\n   *   Move cursor by word:            alt + left, alt + right\n   *   Select words:                   shift + alt + left, shift + alt + right\n   *   Move cursor to line start/end:  cmd + left, cmd + right or home, end\n   *   Select till start/end of line:  cmd + shift + left, cmd + shift + right or shift + home, shift + end\n   *   Jump to start/end of text:      cmd + up, cmd + down\n   *   Select till start/end of text:  cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n   *   Delete character:               backspace\n   *   Delete word:                    alt + backspace\n   *   Delete line:                    cmd + backspace\n   *   Forward delete:                 delete\n   *   Copy text:                      ctrl/cmd + c\n   *   Paste text:                     ctrl/cmd + v\n   *   Cut text:                       ctrl/cmd + x\n   *   Select entire text:             ctrl/cmd + a\n   *   Quit editing                    tab or esc\n   * 
\n *\n *

Supported mouse/touch combination

\n *
\n   *   Position cursor:                click/touch\n   *   Create selection:               click/touch & drag\n   *   Create selection:               click & shift + click\n   *   Select word:                    double click\n   *   Select line:                    triple click\n   * 
\n */\n fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, /** @lends fabric.IText.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'i-text',\n\n /**\n * Index where text selection starts (or where cursor is when there is no selection)\n * @type Number\n * @default\n */\n selectionStart: 0,\n\n /**\n * Index where text selection ends\n * @type Number\n * @default\n */\n selectionEnd: 0,\n\n /**\n * Color of text selection\n * @type String\n * @default\n */\n selectionColor: 'rgba(17,119,255,0.3)',\n\n /**\n * Indicates whether text is in editing mode\n * @type Boolean\n * @default\n */\n isEditing: false,\n\n /**\n * Indicates whether a text can be edited\n * @type Boolean\n * @default\n */\n editable: true,\n\n /**\n * Border color of text object while it's in editing mode\n * @type String\n * @default\n */\n editingBorderColor: 'rgba(102,153,255,0.25)',\n\n /**\n * Width of cursor (in px)\n * @type Number\n * @default\n */\n cursorWidth: 2,\n\n /**\n * Color of default cursor (when not overwritten by character style)\n * @type String\n * @default\n */\n cursorColor: '#333',\n\n /**\n * Delay between cursor blink (in ms)\n * @type Number\n * @default\n */\n cursorDelay: 1000,\n\n /**\n * Duration of cursor fadein (in ms)\n * @type Number\n * @default\n */\n cursorDuration: 600,\n\n /**\n * Indicates whether internal text char widths can be cached\n * @type Boolean\n * @default\n */\n caching: true,\n\n /**\n * @private\n */\n _reSpace: /\\s|\\n/,\n\n /**\n * @private\n */\n _currentCursorOpacity: 0,\n\n /**\n * @private\n */\n _selectionDirection: null,\n\n /**\n * @private\n */\n _abortCursorAnimation: false,\n\n /**\n * @private\n */\n __widthOfSpace: [],\n\n /**\n * Helps determining when the text is in composition, so that the cursor\n * rendering is altered.\n */\n inCompositionMode: false,\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.IText} thisArg\n */\n initialize: function(text, options) {\n this.callSuper('initialize', text, options);\n this.initBehavior();\n },\n\n /**\n * Sets selection start (left boundary of a selection)\n * @param {Number} index Index to set selection start to\n */\n setSelectionStart: function(index) {\n index = Math.max(index, 0);\n this._updateAndFire('selectionStart', index);\n },\n\n /**\n * Sets selection end (right boundary of a selection)\n * @param {Number} index Index to set selection end to\n */\n setSelectionEnd: function(index) {\n index = Math.min(index, this.text.length);\n this._updateAndFire('selectionEnd', index);\n },\n\n /**\n * @private\n * @param {String} property 'selectionStart' or 'selectionEnd'\n * @param {Number} index new position of property\n */\n _updateAndFire: function(property, index) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n this[property] = index;\n }\n this._updateTextarea();\n },\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged: function() {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n },\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @private\n */\n initDimensions: function() {\n this.isEditing && this.initDelayedCursor();\n this.clearContextTop();\n this.callSuper('initDimensions');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render: function(ctx) {\n this.clearContextTop();\n this.callSuper('render', ctx);\n // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n this.cursorOffsetCache = { };\n this.renderCursorOrSelection();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n this.callSuper('_render', ctx);\n },\n\n /**\n * Prepare and clean the contextTop\n */\n clearContextTop: function(skipRestore) {\n if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {\n return;\n }\n var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this.transform(ctx);\n this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix);\n this._clearTextArea(ctx);\n skipRestore || ctx.restore();\n },\n\n /**\n * Renders cursor or selection (depending on what exists)\n * it does on the contextTop. If contextTop is not available, do nothing.\n */\n renderCursorOrSelection: function() {\n if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {\n return;\n }\n var boundaries = this._getCursorBoundaries(),\n ctx = this.canvas.contextTop;\n this.clearContextTop(true);\n if (this.selectionStart === this.selectionEnd) {\n this.renderCursor(boundaries, ctx);\n }\n else {\n this.renderSelection(boundaries, ctx);\n }\n ctx.restore();\n },\n\n _clearTextArea: function(ctx) {\n // we add 4 pixel, to be sure to do not leave any pixel out\n var width = this.width + 4, height = this.height + 4;\n ctx.clearRect(-width / 2, -height / 2, width, height);\n },\n\n /**\n * Returns cursor boundaries (left, top, leftOffset, topOffset)\n * @private\n * @param {Array} chars Array of characters\n * @param {String} typeOfBoundaries\n */\n _getCursorBoundaries: function(position) {\n\n // left/top are left/top of entire text box\n // leftOffset/topOffset are offset from that left/top point of a text box\n\n if (typeof position === 'undefined') {\n position = this.selectionStart;\n }\n\n var left = this._getLeftOffset(),\n top = this._getTopOffset(),\n offsets = this._getCursorBoundariesOffsets(position);\n\n return {\n left: left,\n top: top,\n leftOffset: offsets.left,\n topOffset: offsets.top\n };\n },\n\n /**\n * @private\n */\n _getCursorBoundariesOffsets: function(position) {\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache;\n }\n var lineLeftOffset,\n lineIndex,\n charIndex,\n topOffset = 0,\n leftOffset = 0,\n boundaries,\n cursorPosition = this.get2DCursorLocation(position);\n charIndex = cursorPosition.charIndex;\n lineIndex = cursorPosition.lineIndex;\n for (var i = 0; i < lineIndex; i++) {\n topOffset += this.getHeightOfLine(i);\n }\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n var bound = this.__charBounds[lineIndex][charIndex];\n bound && (leftOffset = bound.left);\n if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\n boundaries = {\n top: topOffset,\n left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0),\n };\n this.cursorOffsetCache = boundaries;\n return this.cursorOffsetCache;\n },\n\n /**\n * Renders cursor\n * @param {Object} boundaries\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderCursor: function(boundaries, ctx) {\n var cursorLocation = this.get2DCursorLocation(),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),\n multiplier = this.scaleX * this.canvas.getZoom(),\n cursorWidth = this.cursorWidth / multiplier,\n topOffset = boundaries.topOffset,\n dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY');\n\n topOffset += (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight\n - charHeight * (1 - this._fontSizeFraction);\n\n if (this.inCompositionMode) {\n this.renderSelection(boundaries, ctx);\n }\n\n ctx.fillStyle = this.getValueOfPropertyAt(lineIndex, charIndex, 'fill');\n ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;\n ctx.fillRect(\n boundaries.left + boundaries.leftOffset - cursorWidth / 2,\n topOffset + boundaries.top + dy,\n cursorWidth,\n charHeight);\n },\n\n /**\n * Renders text selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderSelection: function(boundaries, ctx) {\n\n var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart,\n selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd,\n isJustify = this.textAlign.indexOf('justify') !== -1,\n start = this.get2DCursorLocation(selectionStart),\n end = this.get2DCursorLocation(selectionEnd),\n startLine = start.lineIndex,\n endLine = end.lineIndex,\n startChar = start.charIndex < 0 ? 0 : start.charIndex,\n endChar = end.charIndex < 0 ? 0 : end.charIndex;\n\n for (var i = startLine; i <= endLine; i++) {\n var lineOffset = this._getLineLeftOffset(i) || 0,\n lineHeight = this.getHeightOfLine(i),\n realLineHeight = 0, boxStart = 0, boxEnd = 0;\n\n if (i === startLine) {\n boxStart = this.__charBounds[startLine][startChar].left;\n }\n if (i >= startLine && i < endLine) {\n boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5?\n }\n else if (i === endLine) {\n if (endChar === 0) {\n boxEnd = this.__charBounds[endLine][endChar].left;\n }\n else {\n var charSpacing = this._getWidthOfCharSpacing();\n boxEnd = this.__charBounds[endLine][endChar - 1].left\n + this.__charBounds[endLine][endChar - 1].width - charSpacing;\n }\n }\n realLineHeight = lineHeight;\n if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n lineHeight /= this.lineHeight;\n }\n if (this.inCompositionMode) {\n ctx.fillStyle = this.compositionColor || 'black';\n ctx.fillRect(\n boundaries.left + lineOffset + boxStart,\n boundaries.top + boundaries.topOffset + lineHeight,\n boxEnd - boxStart,\n 1);\n }\n else {\n ctx.fillStyle = this.selectionColor;\n ctx.fillRect(\n boundaries.left + lineOffset + boxStart,\n boundaries.top + boundaries.topOffset,\n boxEnd - boxStart,\n lineHeight);\n }\n\n\n boundaries.topOffset += realLineHeight;\n }\n },\n\n /**\n * High level function to know the height of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns fontSize of char at the current cursor\n * Unused from the library, is for the end user\n * @return {Number} Character font size\n */\n getCurrentCharFontSize: function() {\n var cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');\n },\n\n /**\n * High level function to know the color of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns color (fill) of char at the current cursor\n * Unused from the library, is for the end user\n * @return {String} Character color (fill)\n */\n getCurrentCharColor: function() {\n var cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fill');\n },\n\n /**\n * Returns the cursor position for the getCurrent.. functions\n * @private\n */\n _getCurrentCharIndex: function() {\n var cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n return { l: cursorPosition.lineIndex, c: charIndex };\n }\n });\n\n /**\n * Returns fabric.IText instance from an object representation\n * @static\n * @memberOf fabric.IText\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as argument\n */\n fabric.IText.fromObject = function(object, callback) {\n parseDecoration(object);\n if (object.styles) {\n for (var i in object.styles) {\n for (var j in object.styles[i]) {\n parseDecoration(object.styles[i][j]);\n }\n }\n }\n fabric.Object._fromObject('IText', object, callback, 'text');\n };\n})();\n\n\n(function() {\n\n var clone = fabric.util.object.clone;\n\n fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior: function() {\n this.initAddedHandler();\n this.initRemovedHandler();\n this.initCursorSelectionHandlers();\n this.initDoubleClickSimulation();\n this.mouseMoveHandler = this.mouseMoveHandler.bind(this);\n },\n\n onDeselect: function() {\n this.isEditing && this.exitEditing();\n this.selected = false;\n },\n\n /**\n * Initializes \"added\" event handler\n */\n initAddedHandler: function() {\n var _this = this;\n this.on('added', function() {\n var canvas = _this.canvas;\n if (canvas) {\n if (!canvas._hasITextHandlers) {\n canvas._hasITextHandlers = true;\n _this._initCanvasHandlers(canvas);\n }\n canvas._iTextInstances = canvas._iTextInstances || [];\n canvas._iTextInstances.push(_this);\n }\n });\n },\n\n initRemovedHandler: function() {\n var _this = this;\n this.on('removed', function() {\n var canvas = _this.canvas;\n if (canvas) {\n canvas._iTextInstances = canvas._iTextInstances || [];\n fabric.util.removeFromArray(canvas._iTextInstances, _this);\n if (canvas._iTextInstances.length === 0) {\n canvas._hasITextHandlers = false;\n _this._removeCanvasHandlers(canvas);\n }\n }\n });\n },\n\n /**\n * register canvas event to manage exiting on other instances\n * @private\n */\n _initCanvasHandlers: function(canvas) {\n canvas._mouseUpITextHandler = function() {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function(obj) {\n obj.__isMousedown = false;\n });\n }\n };\n canvas.on('mouse:up', canvas._mouseUpITextHandler);\n },\n\n /**\n * remove canvas event to manage exiting on other instances\n * @private\n */\n _removeCanvasHandlers: function(canvas) {\n canvas.off('mouse:up', canvas._mouseUpITextHandler);\n },\n\n /**\n * @private\n */\n _tick: function() {\n this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete');\n },\n\n /**\n * @private\n */\n _animateCursor: function(obj, targetOpacity, duration, completeMethod) {\n\n var tickState;\n\n tickState = {\n isAborted: false,\n abort: function() {\n this.isAborted = true;\n },\n };\n\n obj.animate('_currentCursorOpacity', targetOpacity, {\n duration: duration,\n onComplete: function() {\n if (!tickState.isAborted) {\n obj[completeMethod]();\n }\n },\n onChange: function() {\n // we do not want to animate a selection, only cursor\n if (obj.canvas && obj.selectionStart === obj.selectionEnd) {\n obj.renderCursorOrSelection();\n }\n },\n abort: function() {\n return tickState.isAborted;\n }\n });\n return tickState;\n },\n\n /**\n * @private\n */\n _onTickComplete: function() {\n\n var _this = this;\n\n if (this._cursorTimeout1) {\n clearTimeout(this._cursorTimeout1);\n }\n this._cursorTimeout1 = setTimeout(function() {\n _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick');\n }, 100);\n },\n\n /**\n * Initializes delayed cursor\n */\n initDelayedCursor: function(restart) {\n var _this = this,\n delay = restart ? 0 : this.cursorDelay;\n\n this.abortCursorAnimation();\n this._currentCursorOpacity = 1;\n this._cursorTimeout2 = setTimeout(function() {\n _this._tick();\n }, delay);\n },\n\n /**\n * Aborts cursor animation and clears all timeouts\n */\n abortCursorAnimation: function() {\n var shouldClear = this._currentTickState || this._currentTickCompleteState,\n canvas = this.canvas;\n this._currentTickState && this._currentTickState.abort();\n this._currentTickCompleteState && this._currentTickCompleteState.abort();\n\n clearTimeout(this._cursorTimeout1);\n clearTimeout(this._cursorTimeout2);\n\n this._currentCursorOpacity = 0;\n // to clear just itext area we need to transform the context\n // it may not be worth it\n if (shouldClear && canvas) {\n canvas.clearContext(canvas.contextTop || canvas.contextContainer);\n }\n\n },\n\n /**\n * Selects entire text\n * @return {fabric.IText} thisArg\n * @chainable\n */\n selectAll: function() {\n this.selectionStart = 0;\n this.selectionEnd = this._text.length;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n },\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText: function() {\n return this._text.slice(this.selectionStart, this.selectionEnd).join('');\n },\n\n /**\n * Find new selection index representing start of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryLeft: function(startFrom) {\n var offset = 0, index = startFrom - 1;\n\n // remove space before cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index--;\n }\n }\n while (/\\S/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n },\n\n /**\n * Find new selection index representing end of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryRight: function(startFrom) {\n var offset = 0, index = startFrom;\n\n // remove space after cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index++;\n }\n }\n while (/\\S/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n },\n\n /**\n * Find new selection index representing start of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryLeft: function(startFrom) {\n var offset = 0, index = startFrom - 1;\n\n while (!/\\n/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n },\n\n /**\n * Find new selection index representing end of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryRight: function(startFrom) {\n var offset = 0, index = startFrom;\n\n while (!/\\n/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n },\n\n /**\n * Finds index corresponding to beginning or end of a word\n * @param {Number} selectionStart Index of a character\n * @param {Number} direction 1 or -1\n * @return {Number} Index of the beginning or end of a word\n */\n searchWordBoundary: function(selectionStart, direction) {\n var text = this._text,\n index = this._reSpace.test(text[selectionStart]) ? selectionStart - 1 : selectionStart,\n _char = text[index],\n // wrong\n reNonWord = fabric.reNonWord;\n\n while (!reNonWord.test(_char) && index > 0 && index < text.length) {\n index += direction;\n _char = text[index];\n }\n if (reNonWord.test(_char)) {\n index += direction === 1 ? 0 : 1;\n }\n return index;\n },\n\n /**\n * Selects a word based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectWord: function(selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.searchWordBoundary(selectionStart, -1), /* search backwards */\n newSelectionEnd = this.searchWordBoundary(selectionStart, 1); /* search forward */\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n },\n\n /**\n * Selects a line based on the index\n * @param {Number} selectionStart Index of a character\n * @return {fabric.IText} thisArg\n * @chainable\n */\n selectLine: function(selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n },\n\n /**\n * Enters editing state\n * @return {fabric.IText} thisArg\n * @chainable\n */\n enterEditing: function(e) {\n if (this.isEditing || !this.editable) {\n return;\n }\n\n if (this.canvas) {\n this.canvas.calcOffset();\n this.exitEditingOnOthers(this.canvas);\n }\n\n this.isEditing = true;\n\n this.initHiddenTextarea(e);\n this.hiddenTextarea.focus();\n this.hiddenTextarea.value = this.text;\n this._updateTextarea();\n this._saveEditingProps();\n this._setEditingProps();\n this._textBeforeEdit = this.text;\n\n this._tick();\n this.fire('editing:entered');\n this._fireSelectionChanged();\n if (!this.canvas) {\n return this;\n }\n this.canvas.fire('text:editing:entered', { target: this });\n this.initMouseMoveHandler();\n this.canvas.requestRenderAll();\n return this;\n },\n\n exitEditingOnOthers: function(canvas) {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function(obj) {\n obj.selected = false;\n if (obj.isEditing) {\n obj.exitEditing();\n }\n });\n }\n },\n\n /**\n * Initializes \"mousemove\" event handler\n */\n initMouseMoveHandler: function() {\n this.canvas.on('mouse:move', this.mouseMoveHandler);\n },\n\n /**\n * @private\n */\n mouseMoveHandler: function(options) {\n if (!this.__isMousedown || !this.isEditing) {\n return;\n }\n\n var newSelectionStart = this.getSelectionStartFromPointer(options.e),\n currentStart = this.selectionStart,\n currentEnd = this.selectionEnd;\n if (\n (newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd)\n &&\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n ) {\n return;\n }\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n }\n else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) {\n this.restartCursorIfNeeded();\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n },\n\n /**\n * @private\n */\n _setEditingProps: function() {\n this.hoverCursor = 'text';\n\n if (this.canvas) {\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n }\n\n this.borderColor = this.editingBorderColor;\n this.hasControls = this.selectable = false;\n this.lockMovementX = this.lockMovementY = true;\n },\n\n /**\n * convert from textarea to grapheme indexes\n */\n fromStringToGraphemeSelection: function(start, end, text) {\n var smallerTextStart = text.slice(0, start),\n graphemeStart = fabric.util.string.graphemeSplit(smallerTextStart).length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n var smallerTextEnd = text.slice(start, end),\n graphemeEnd = fabric.util.string.graphemeSplit(smallerTextEnd).length;\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd };\n },\n\n /**\n * convert from fabric to textarea values\n */\n fromGraphemeToStringSelection: function(start, end, _text) {\n var smallerTextStart = _text.slice(0, start),\n graphemeStart = smallerTextStart.join('').length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n var smallerTextEnd = _text.slice(start, end),\n graphemeEnd = smallerTextEnd.join('').length;\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd };\n },\n\n /**\n * @private\n */\n _updateTextarea: function() {\n this.cursorOffsetCache = { };\n if (!this.hiddenTextarea) {\n return;\n }\n if (!this.inCompositionMode) {\n var newSelection = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text);\n this.hiddenTextarea.selectionStart = newSelection.selectionStart;\n this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\n }\n this.updateTextareaPosition();\n },\n\n /**\n * @private\n */\n updateFromTextArea: function() {\n if (!this.hiddenTextarea) {\n return;\n }\n this.cursorOffsetCache = { };\n this.text = this.hiddenTextarea.value;\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n var newSelection = this.fromStringToGraphemeSelection(\n this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value);\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n if (!this.inCompositionMode) {\n this.selectionStart = newSelection.selectionStart;\n }\n this.updateTextareaPosition();\n },\n\n /**\n * @private\n */\n updateTextareaPosition: function() {\n if (this.selectionStart === this.selectionEnd) {\n var style = this._calcTextareaPosition();\n this.hiddenTextarea.style.left = style.left;\n this.hiddenTextarea.style.top = style.top;\n }\n },\n\n /**\n * @private\n * @return {Object} style contains style for hiddenTextarea\n */\n _calcTextareaPosition: function() {\n if (!this.canvas) {\n return { x: 1, y: 1 };\n }\n var desiredPosition = this.inCompositionMode ? this.compositionStart : this.selectionStart,\n boundaries = this._getCursorBoundaries(desiredPosition),\n cursorLocation = this.get2DCursorLocation(desiredPosition),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') * this.lineHeight,\n leftOffset = boundaries.leftOffset,\n m = this.calcTransformMatrix(),\n p = {\n x: boundaries.left + leftOffset,\n y: boundaries.top + boundaries.topOffset + charHeight\n },\n retinaScaling = this.canvas.getRetinaScaling(),\n upperCanvas = this.canvas.upperCanvasEl,\n upperCanvasWidth = upperCanvas.width / retinaScaling,\n upperCanvasHeight = upperCanvas.height / retinaScaling,\n maxWidth = upperCanvasWidth - charHeight,\n maxHeight = upperCanvasHeight - charHeight,\n scaleX = upperCanvas.clientWidth / upperCanvasWidth,\n scaleY = upperCanvas.clientHeight / upperCanvasHeight;\n\n p = fabric.util.transformPoint(p, m);\n p = fabric.util.transformPoint(p, this.canvas.viewportTransform);\n p.x *= scaleX;\n p.y *= scaleY;\n if (p.x < 0) {\n p.x = 0;\n }\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n if (p.y < 0) {\n p.y = 0;\n }\n if (p.y > maxHeight) {\n p.y = maxHeight;\n }\n\n // add canvas offset on document\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n\n return { left: p.x + 'px', top: p.y + 'px', fontSize: charHeight + 'px', charHeight: charHeight };\n },\n\n /**\n * @private\n */\n _saveEditingProps: function() {\n this._savedProps = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n lockMovementX: this.lockMovementX,\n lockMovementY: this.lockMovementY,\n hoverCursor: this.hoverCursor,\n selectable: this.selectable,\n defaultCursor: this.canvas && this.canvas.defaultCursor,\n moveCursor: this.canvas && this.canvas.moveCursor\n };\n },\n\n /**\n * @private\n */\n _restoreEditingProps: function() {\n if (!this._savedProps) {\n return;\n }\n\n this.hoverCursor = this._savedProps.hoverCursor;\n this.hasControls = this._savedProps.hasControls;\n this.borderColor = this._savedProps.borderColor;\n this.selectable = this._savedProps.selectable;\n this.lockMovementX = this._savedProps.lockMovementX;\n this.lockMovementY = this._savedProps.lockMovementY;\n\n if (this.canvas) {\n this.canvas.defaultCursor = this._savedProps.defaultCursor;\n this.canvas.moveCursor = this._savedProps.moveCursor;\n }\n },\n\n /**\n * Exits from editing state\n * @return {fabric.IText} thisArg\n * @chainable\n */\n exitEditing: function() {\n var isTextChanged = (this._textBeforeEdit !== this.text);\n var hiddenTextarea = this.hiddenTextarea;\n this.selected = false;\n this.isEditing = false;\n\n this.selectionEnd = this.selectionStart;\n\n if (hiddenTextarea) {\n hiddenTextarea.blur && hiddenTextarea.blur();\n hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea);\n }\n this.hiddenTextarea = null;\n this.abortCursorAnimation();\n this._restoreEditingProps();\n this._currentCursorOpacity = 0;\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n this.fire('editing:exited');\n isTextChanged && this.fire('modified');\n if (this.canvas) {\n this.canvas.off('mouse:move', this.mouseMoveHandler);\n this.canvas.fire('text:editing:exited', { target: this });\n isTextChanged && this.canvas.fire('object:modified', { target: this });\n }\n return this;\n },\n\n /**\n * @private\n */\n _removeExtraneousStyles: function() {\n for (var prop in this.styles) {\n if (!this._textLines[prop]) {\n delete this.styles[prop];\n }\n }\n },\n\n /**\n * remove and reflow a style block from start to end.\n * @param {Number} start linear start position for removal (included in removal)\n * @param {Number} end linear end position for removal ( excluded from removal )\n */\n removeStyleFromTo: function(start, end) {\n var cursorStart = this.get2DCursorLocation(start, true),\n cursorEnd = this.get2DCursorLocation(end, true),\n lineStart = cursorStart.lineIndex,\n charStart = cursorStart.charIndex,\n lineEnd = cursorEnd.lineIndex,\n charEnd = cursorEnd.charIndex,\n i, styleObj;\n if (lineStart !== lineEnd) {\n // step1 remove the trailing of lineStart\n if (this.styles[lineStart]) {\n for (i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) {\n delete this.styles[lineStart][i];\n }\n }\n // step2 move the trailing of lineEnd to lineStart if needed\n if (this.styles[lineEnd]) {\n for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) {\n styleObj = this.styles[lineEnd][i];\n if (styleObj) {\n this.styles[lineStart] || (this.styles[lineStart] = { });\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\n }\n }\n }\n // step3 detects lines will be completely removed.\n for (i = lineStart + 1; i <= lineEnd; i++) {\n delete this.styles[i];\n }\n // step4 shift remaining lines.\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n }\n else {\n // remove and shift left on the same line\n if (this.styles[lineStart]) {\n styleObj = this.styles[lineStart];\n var diff = charEnd - charStart, numericChar, _char;\n for (i = charStart; i < charEnd; i++) {\n delete styleObj[i];\n }\n for (_char in this.styles[lineStart]) {\n numericChar = parseInt(_char, 10);\n if (numericChar >= charEnd) {\n styleObj[numericChar - diff] = styleObj[_char];\n delete styleObj[_char];\n }\n }\n }\n }\n },\n\n /**\n * Shifts line styles up or down\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can any number?\n */\n shiftLineStyles: function(lineIndex, offset) {\n // shift all line styles by offset upward or downward\n // do not clone deep. we need new array, not new style objects\n var clonedStyles = clone(this.styles);\n for (var line in this.styles) {\n var numericLine = parseInt(line, 10);\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n },\n\n restartCursorIfNeeded: function() {\n if (!this._currentTickState || this._currentTickState.isAborted\n || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted\n ) {\n this.initDelayedCursor();\n }\n },\n\n /**\n * Handle insertion of more consecutive style lines for when one or more\n * newlines gets added to the text. Since current style needs to be shifted\n * first we shift the current style of the number lines needed, then we add\n * new lines from the last to the first.\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} qty number of lines to add\n * @param {Array} copiedStyle Array of objects styles\n */\n insertNewlineStyleObject: function(lineIndex, charIndex, qty, copiedStyle) {\n var currentCharStyle,\n newLineStyles = {},\n somethingAdded = false,\n isEndOfLine = this._unwrappedTextLines[lineIndex].length === charIndex;\n\n qty || (qty = 1);\n this.shiftLineStyles(lineIndex, qty);\n if (this.styles[lineIndex]) {\n currentCharStyle = this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1];\n }\n // we clone styles of all chars\n // after cursor onto the current line\n for (var index in this.styles[lineIndex]) {\n var numIndex = parseInt(index, 10);\n if (numIndex >= charIndex) {\n somethingAdded = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n // remove lines from the previous line since they're on a new line now\n if (!(isEndOfLine && charIndex === 0)) {\n delete this.styles[lineIndex][index];\n }\n }\n }\n var styleCarriedOver = false;\n if (somethingAdded && !isEndOfLine) {\n // if is end of line, the extra style we copied\n // is probably not something we want\n this.styles[lineIndex + qty] = newLineStyles;\n styleCarriedOver = true;\n }\n if (styleCarriedOver) {\n // skip the last line of since we already prepared it.\n qty--;\n }\n // for the all the lines or all the other lines\n // we clone current char style onto the next (otherwise empty) line\n while (qty > 0) {\n if (copiedStyle && copiedStyle[qty - 1]) {\n this.styles[lineIndex + qty] = { 0: clone(copiedStyle[qty - 1]) };\n }\n else if (currentCharStyle) {\n this.styles[lineIndex + qty] = { 0: clone(currentCharStyle) };\n }\n else {\n delete this.styles[lineIndex + qty];\n }\n qty--;\n }\n this._forceClearCache = true;\n },\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} quantity number Style object to insert, if given\n * @param {Array} copiedStyle array of style objects\n */\n insertCharStyleObject: function(lineIndex, charIndex, quantity, copiedStyle) {\n if (!this.styles) {\n this.styles = {};\n }\n var currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = currentLineStyles ? clone(currentLineStyles) : {};\n\n quantity || (quantity = 1);\n // shift all char styles by quantity forward\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n for (var index in currentLineStylesCloned) {\n var numericIndex = parseInt(index, 10);\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex];\n // only delete the style if there was nothing moved there\n if (!currentLineStylesCloned[numericIndex - quantity]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n this._forceClearCache = true;\n if (copiedStyle) {\n while (quantity--) {\n if (!Object.keys(copiedStyle[quantity]).length) {\n continue;\n }\n if (!this.styles[lineIndex]) {\n this.styles[lineIndex] = {};\n }\n this.styles[lineIndex][charIndex + quantity] = clone(copiedStyle[quantity]);\n }\n return;\n }\n if (!currentLineStyles) {\n return;\n }\n var newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n while (newStyle && quantity--) {\n this.styles[lineIndex][charIndex + quantity] = clone(newStyle);\n }\n },\n\n /**\n * Inserts style object(s)\n * @param {Array} insertedText Characters at the location where style is inserted\n * @param {Number} start cursor index for inserting style\n * @param {Array} [copiedStyle] array of style objects to insert.\n */\n insertNewStyleBlock: function(insertedText, start, copiedStyle) {\n var cursorLoc = this.get2DCursorLocation(start, true),\n addedLines = [0], linesLength = 0;\n // get an array of how many char per lines are being added.\n for (var i = 0; i < insertedText.length; i++) {\n if (insertedText[i] === '\\n') {\n linesLength++;\n addedLines[linesLength] = 0;\n }\n else {\n addedLines[linesLength]++;\n }\n }\n // for the first line copy the style from the current char position.\n if (addedLines[0] > 0) {\n this.insertCharStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex, addedLines[0], copiedStyle);\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\n }\n linesLength && this.insertNewlineStyleObject(\n cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLength);\n for (var i = 1; i < linesLength; i++) {\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);\n }\n else if (copiedStyle) {\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n }\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n }\n // we use i outside the loop to get it like linesLength\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);\n }\n },\n\n /**\n * Set the selectionStart and selectionEnd according to the new position of cursor\n * mimic the key - mouse navigation when shift is pressed.\n */\n setSelectionStartEndWithShift: function(start, end, newSelection) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = 'left';\n }\n else if (this._selectionDirection === 'right') {\n this._selectionDirection = 'left';\n this.selectionEnd = start;\n }\n this.selectionStart = newSelection;\n }\n else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === 'right') {\n this.selectionEnd = newSelection;\n }\n else {\n this.selectionStart = newSelection;\n }\n }\n else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = 'right';\n }\n else if (this._selectionDirection === 'left') {\n this._selectionDirection = 'right';\n this.selectionStart = end;\n }\n this.selectionEnd = newSelection;\n }\n },\n\n setSelectionInBoundaries: function() {\n var length = this.text.length;\n if (this.selectionStart > length) {\n this.selectionStart = length;\n }\n else if (this.selectionStart < 0) {\n this.selectionStart = 0;\n }\n if (this.selectionEnd > length) {\n this.selectionEnd = length;\n }\n else if (this.selectionEnd < 0) {\n this.selectionEnd = 0;\n }\n }\n });\n})();\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n /**\n * Initializes \"dbclick\" event handler\n */\n initDoubleClickSimulation: function() {\n\n // for double click\n this.__lastClickTime = +new Date();\n\n // for triple click\n this.__lastLastClickTime = +new Date();\n\n this.__lastPointer = { };\n\n this.on('mousedown', this.onMouseDown);\n },\n\n /**\n * Default event handler to simulate triple click\n * @private\n */\n onMouseDown: function(options) {\n if (!this.canvas) {\n return;\n }\n this.__newClickTime = +new Date();\n var newPointer = options.pointer;\n if (this.isTripleClick(newPointer)) {\n this.fire('tripleclick', options);\n this._stopEvent(options.e);\n }\n this.__lastLastClickTime = this.__lastClickTime;\n this.__lastClickTime = this.__newClickTime;\n this.__lastPointer = newPointer;\n this.__lastIsEditing = this.isEditing;\n this.__lastSelected = this.selected;\n },\n\n isTripleClick: function(newPointer) {\n return this.__newClickTime - this.__lastClickTime < 500 &&\n this.__lastClickTime - this.__lastLastClickTime < 500 &&\n this.__lastPointer.x === newPointer.x &&\n this.__lastPointer.y === newPointer.y;\n },\n\n /**\n * @private\n */\n _stopEvent: function(e) {\n e.preventDefault && e.preventDefault();\n e.stopPropagation && e.stopPropagation();\n },\n\n /**\n * Initializes event handlers related to cursor or selection\n */\n initCursorSelectionHandlers: function() {\n this.initMousedownHandler();\n this.initMouseupHandler();\n this.initClicks();\n },\n\n /**\n * Default handler for double click, select a word\n */\n doubleClickHandler: function(options) {\n if (!this.isEditing) {\n return;\n }\n this.selectWord(this.getSelectionStartFromPointer(options.e));\n },\n\n /**\n * Default handler for triple click, select a line\n */\n tripleClickHandler: function(options) {\n if (!this.isEditing) {\n return;\n }\n this.selectLine(this.getSelectionStartFromPointer(options.e));\n },\n\n /**\n * Initializes double and triple click event handlers\n */\n initClicks: function() {\n this.on('mousedblclick', this.doubleClickHandler);\n this.on('tripleclick', this.tripleClickHandler);\n },\n\n /**\n * Default event handler for the basic functionalities needed on _mouseDown\n * can be overridden to do something different.\n * Scope of this implementation is: find the click position, set selectionStart\n * find selectionEnd, initialize the drawing of either cursor or selection area\n */\n _mouseDownHandler: function(options) {\n if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) {\n return;\n }\n\n this.__isMousedown = true;\n\n if (this.selected) {\n this.setCursorByClick(options.e);\n }\n\n if (this.isEditing) {\n this.__selectionStartOnMouseDown = this.selectionStart;\n if (this.selectionStart === this.selectionEnd) {\n this.abortCursorAnimation();\n }\n this.renderCursorOrSelection();\n }\n },\n\n /**\n * Default event handler for the basic functionalities needed on mousedown:before\n * can be overridden to do something different.\n * Scope of this implementation is: verify the object is already selected when mousing down\n */\n _mouseDownHandlerBefore: function(options) {\n if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) {\n return;\n }\n // we want to avoid that an object that was selected and then becomes unselectable,\n // may trigger editing mode in some way.\n this.selected = this === this.canvas._activeObject;\n },\n\n /**\n * Initializes \"mousedown\" event handler\n */\n initMousedownHandler: function() {\n this.on('mousedown', this._mouseDownHandler);\n this.on('mousedown:before', this._mouseDownHandlerBefore);\n },\n\n /**\n * Initializes \"mouseup\" event handler\n */\n initMouseupHandler: function() {\n this.on('mouseup', this.mouseUpHandler);\n },\n\n /**\n * standard hander for mouse up, overridable\n * @private\n */\n mouseUpHandler: function(options) {\n this.__isMousedown = false;\n if (!this.editable || this.group ||\n (options.transform && options.transform.actionPerformed) ||\n (options.e.button && options.e.button !== 1)) {\n return;\n }\n\n if (this.canvas) {\n var currentActive = this.canvas._activeObject;\n if (currentActive && currentActive !== this) {\n // avoid running this logic when there is an active object\n // this because is possible with shift click and fast clicks,\n // to rapidly deselect and reselect this object and trigger an enterEdit\n return;\n }\n }\n\n if (this.__lastSelected && !this.__corner) {\n this.selected = false;\n this.__lastSelected = false;\n this.enterEditing(options.e);\n if (this.selectionStart === this.selectionEnd) {\n this.initDelayedCursor(true);\n }\n else {\n this.renderCursorOrSelection();\n }\n }\n else {\n this.selected = true;\n }\n },\n\n /**\n * Changes cursor location in a text depending on passed pointer (x/y) object\n * @param {Event} e Event object\n */\n setCursorByClick: function(e) {\n var newSelection = this.getSelectionStartFromPointer(e),\n start = this.selectionStart, end = this.selectionEnd;\n if (e.shiftKey) {\n this.setSelectionStartEndWithShift(start, end, newSelection);\n }\n else {\n this.selectionStart = newSelection;\n this.selectionEnd = newSelection;\n }\n if (this.isEditing) {\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Returns index of a character corresponding to where an object was clicked\n * @param {Event} e Event object\n * @return {Number} Index of a character\n */\n getSelectionStartFromPointer: function(e) {\n var mouseOffset = this.getLocalPointer(e),\n prevWidth = 0,\n width = 0,\n height = 0,\n charIndex = 0,\n lineIndex = 0,\n lineLeftOffset,\n line;\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n if (height <= mouseOffset.y) {\n height += this.getHeightOfLine(i) * this.scaleY;\n lineIndex = i;\n if (i > 0) {\n charIndex += this._textLines[i - 1].length + this.missingNewlineOffset(i - 1);\n }\n }\n else {\n break;\n }\n }\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n width = lineLeftOffset * this.scaleX;\n line = this._textLines[lineIndex];\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n prevWidth = width;\n // i removed something about flipX here, check.\n width += this.__charBounds[lineIndex][j].kernedWidth * this.scaleX;\n if (width <= mouseOffset.x) {\n charIndex++;\n }\n else {\n break;\n }\n }\n return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex, jlen);\n },\n\n /**\n * @private\n */\n _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) {\n // we need Math.abs because when width is after the last char, the offset is given as 1, while is 0\n var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth,\n distanceBtwNextCharAndCursor = width - mouseOffset.x,\n offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor ||\n distanceBtwNextCharAndCursor < 0 ? 0 : 1,\n newSelectionStart = index + offset;\n // if object is horizontally flipped, mirror cursor location from the end\n if (this.flipX) {\n newSelectionStart = jlen - newSelectionStart;\n }\n\n if (newSelectionStart > this._text.length) {\n newSelectionStart = this._text.length;\n }\n\n return newSelectionStart;\n }\n});\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n /**\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\n */\n initHiddenTextarea: function() {\n this.hiddenTextarea = fabric.document.createElement('textarea');\n this.hiddenTextarea.setAttribute('autocapitalize', 'off');\n this.hiddenTextarea.setAttribute('autocorrect', 'off');\n this.hiddenTextarea.setAttribute('autocomplete', 'off');\n this.hiddenTextarea.setAttribute('spellcheck', 'false');\n this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', '');\n this.hiddenTextarea.setAttribute('wrap', 'off');\n var style = this._calcTextareaPosition();\n // line-height: 1px; was removed from the style to fix this:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\n this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top +\n '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' +\n ' paddingーtop: ' + style.fontSize + ';';\n fabric.document.body.appendChild(this.hiddenTextarea);\n\n fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'cut', this.copy.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this));\n\n if (!this._clickHandlerInitialized && this.canvas) {\n fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this));\n this._clickHandlerInitialized = true;\n }\n },\n\n /**\n * For functionalities on keyDown\n * Map a special key to a function of the instance/prototype\n * If you need different behaviour for ESC or TAB or arrows, you have to change\n * this map setting the name of a function that you build on the fabric.Itext or\n * your prototype.\n * the map change will affect all Instances unless you need for only some text Instances\n * in that case you have to clone this object and assign your Instance.\n * this.keysMap = fabric.util.object.clone(this.keysMap);\n * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0]\n */\n keysMap: {\n 9: 'exitEditing',\n 27: 'exitEditing',\n 33: 'moveCursorUp',\n 34: 'moveCursorDown',\n 35: 'moveCursorRight',\n 36: 'moveCursorLeft',\n 37: 'moveCursorLeft',\n 38: 'moveCursorUp',\n 39: 'moveCursorRight',\n 40: 'moveCursorDown',\n },\n\n /**\n * For functionalities on keyUp + ctrl || cmd\n */\n ctrlKeysMapUp: {\n 67: 'copy',\n 88: 'cut'\n },\n\n /**\n * For functionalities on keyDown + ctrl || cmd\n */\n ctrlKeysMapDown: {\n 65: 'selectAll'\n },\n\n onClick: function() {\n // No need to trigger click event here, focus is enough to have the keyboard appear on Android\n this.hiddenTextarea && this.hiddenTextarea.focus();\n },\n\n /**\n * Handles keyup event\n * @param {Event} e Event object\n */\n onKeyDown: function(e) {\n if (!this.isEditing || this.inCompositionMode) {\n return;\n }\n if (e.keyCode in this.keysMap) {\n this[this.keysMap[e.keyCode]](e);\n }\n else if ((e.keyCode in this.ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapDown[e.keyCode]](e);\n }\n else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n if (e.keyCode >= 33 && e.keyCode <= 40) {\n // if i press an arrow key just update selection\n this.clearContextTop();\n this.renderCursorOrSelection();\n }\n else {\n this.canvas && this.canvas.requestRenderAll();\n }\n },\n\n /**\n * Handles keyup event\n * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n * if a copy/cut event fired, keyup is dismissed\n * @param {Event} e Event object\n */\n onKeyUp: function(e) {\n if (!this.isEditing || this._copyDone || this.inCompositionMode) {\n this._copyDone = false;\n return;\n }\n if ((e.keyCode in this.ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapUp[e.keyCode]](e);\n }\n else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n this.canvas && this.canvas.requestRenderAll();\n },\n\n /**\n * Handles onInput event\n * @param {Event} e Event object\n */\n onInput: function(e) {\n var fromPaste = this.fromPaste;\n this.fromPaste = false;\n e && e.stopPropagation();\n if (!this.isEditing) {\n return;\n }\n // decisions about style changes.\n var nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,\n charCount = this._text.length,\n nextCharCount = nextText.length,\n removedText, insertedText,\n charDiff = nextCharCount - charCount,\n selectionStart = this.selectionStart, selectionEnd = this.selectionEnd,\n selection = selectionStart !== selectionEnd,\n copiedStyle, removeFrom, removeTo;\n if (this.hiddenTextarea.value === '') {\n this.styles = { };\n this.updateFromTextArea();\n this.fire('changed');\n if (this.canvas) {\n this.canvas.fire('text:changed', { target: this });\n this.canvas.requestRenderAll();\n }\n return;\n }\n\n var textareaSelection = this.fromStringToGraphemeSelection(\n this.hiddenTextarea.selectionStart,\n this.hiddenTextarea.selectionEnd,\n this.hiddenTextarea.value\n );\n var backDelete = selectionStart > textareaSelection.selectionStart;\n\n if (selection) {\n removedText = this._text.slice(selectionStart, selectionEnd);\n charDiff += selectionEnd - selectionStart;\n }\n else if (nextCharCount < charCount) {\n if (backDelete) {\n removedText = this._text.slice(selectionEnd + charDiff, selectionEnd);\n }\n else {\n removedText = this._text.slice(selectionStart, selectionStart - charDiff);\n }\n }\n var copiedStyle;\n insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd);\n if (removedText && removedText.length) {\n if (insertedText.length) {\n // let's copy some style before deleting.\n // we want to copy the style before the cursor OR the style at the cursor if selection\n // is bigger than 0.\n copiedStyle = this.getSelectionStyles(selectionStart, selectionStart + 1, true);\n // now duplicate the style one for each inserted text.\n copiedStyle = insertedText.map(function() {\n // this return an array of references, but that is fine since we are\n // copying the style later.\n return copiedStyle[0];\n });\n }\n if (selection) {\n removeFrom = selectionStart;\n removeTo = selectionEnd;\n }\n else if (backDelete) {\n // detect differencies between forwardDelete and backDelete\n removeFrom = selectionEnd - removedText.length;\n removeTo = selectionEnd;\n }\n else {\n removeFrom = selectionEnd;\n removeTo = selectionEnd + removedText.length;\n }\n this.removeStyleFromTo(removeFrom, removeTo);\n }\n if (insertedText.length) {\n if (fromPaste && insertedText.join('') === fabric.copiedText && !fabric.disableStyleCopyPaste) {\n copiedStyle = fabric.copiedTextStyle;\n }\n this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle);\n }\n this.updateFromTextArea();\n this.fire('changed');\n if (this.canvas) {\n this.canvas.fire('text:changed', { target: this });\n this.canvas.requestRenderAll();\n }\n },\n /**\n * Composition start\n */\n onCompositionStart: function() {\n this.inCompositionMode = true;\n },\n\n /**\n * Composition end\n */\n onCompositionEnd: function() {\n this.inCompositionMode = false;\n },\n\n // /**\n // * Composition update\n // */\n onCompositionUpdate: function(e) {\n this.compositionStart = e.target.selectionStart;\n this.compositionEnd = e.target.selectionEnd;\n this.updateTextareaPosition();\n },\n\n /**\n * Copies selected text\n * @param {Event} e Event object\n */\n copy: function() {\n if (this.selectionStart === this.selectionEnd) {\n //do not cut-copy if no selection\n return;\n }\n\n fabric.copiedText = this.getSelectedText();\n if (!fabric.disableStyleCopyPaste) {\n fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true);\n }\n else {\n fabric.copiedTextStyle = null;\n }\n this._copyDone = true;\n },\n\n /**\n * Pastes text\n * @param {Event} e Event object\n */\n paste: function() {\n this.fromPaste = true;\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @return {Object} Clipboard data object\n */\n _getClipboardData: function(e) {\n return (e && e.clipboardData) || fabric.window.clipboardData;\n },\n\n /**\n * Finds the width in pixels before the cursor on the same line\n * @private\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Number} widthBeforeCursor width before cursor\n */\n _getWidthBeforeCursor: function(lineIndex, charIndex) {\n var widthBeforeCursor = this._getLineLeftOffset(lineIndex), bound;\n\n if (charIndex > 0) {\n bound = this.__charBounds[lineIndex][charIndex - 1];\n widthBeforeCursor += bound.left + bound.width;\n }\n return widthBeforeCursor;\n },\n\n /**\n * Gets start offset of a selection\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getDownCursorOffset: function(e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n // if on last line, down cursor goes to end of line\n if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) {\n // move to the end of a text\n return this._text.length - selectionProp;\n }\n var charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n return textAfterCursor.length + indexOnOtherLine + 1 + this.missingNewlineOffset(lineIndex);\n },\n\n /**\n * private\n * Helps finding if the offset should be counted from Start or End\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n _getSelectionForOffset: function(e, isRight) {\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n return this.selectionEnd;\n }\n else {\n return this.selectionStart;\n }\n },\n\n /**\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getUpCursorOffset: function(e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n // if on first line, up cursor goes to start of line\n return -selectionProp;\n }\n var charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\n missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1);\n // return a negative offset\n return -this._textLines[lineIndex - 1].length\n + indexOnOtherLine - textBeforeCursor.length + (1 - missingNewlineOffset);\n },\n\n /**\n * for a given width it founds the matching character.\n * @private\n */\n _getIndexOnLine: function(lineIndex, width) {\n\n var line = this._textLines[lineIndex],\n lineLeftOffset = this._getLineLeftOffset(lineIndex),\n widthOfCharsOnLine = lineLeftOffset,\n indexOnLine = 0, charWidth, foundMatch;\n\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charWidth = this.__charBounds[lineIndex][j].width;\n widthOfCharsOnLine += charWidth;\n if (widthOfCharsOnLine > width) {\n foundMatch = true;\n var leftEdge = widthOfCharsOnLine - charWidth,\n rightEdge = widthOfCharsOnLine,\n offsetFromLeftEdge = Math.abs(leftEdge - width),\n offsetFromRightEdge = Math.abs(rightEdge - width);\n\n indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1);\n break;\n }\n }\n\n // reached end\n if (!foundMatch) {\n indexOnLine = line.length - 1;\n }\n\n return indexOnLine;\n },\n\n\n /**\n * Moves cursor down\n * @param {Event} e Event object\n */\n moveCursorDown: function(e) {\n if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n return;\n }\n this._moveCursorUpOrDown('Down', e);\n },\n\n /**\n * Moves cursor up\n * @param {Event} e Event object\n */\n moveCursorUp: function(e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorUpOrDown('Up', e);\n },\n\n /**\n * Moves cursor up or down, fires the events\n * @param {String} direction 'Up' or 'Down'\n * @param {Event} e Event object\n */\n _moveCursorUpOrDown: function(direction, e) {\n // getUpCursorOffset\n // getDownCursorOffset\n var action = 'get' + direction + 'CursorOffset',\n offset = this[action](e, this._selectionDirection === 'right');\n if (e.shiftKey) {\n this.moveCursorWithShift(offset);\n }\n else {\n this.moveCursorWithoutShift(offset);\n }\n if (offset !== 0) {\n this.setSelectionInBoundaries();\n this.abortCursorAnimation();\n this._currentCursorOpacity = 1;\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor with shift\n * @param {Number} offset\n */\n moveCursorWithShift: function(offset) {\n var newSelection = this._selectionDirection === 'left'\n ? this.selectionStart + offset\n : this.selectionEnd + offset;\n this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection);\n return offset !== 0;\n },\n\n /**\n * Moves cursor up without shift\n * @param {Number} offset\n */\n moveCursorWithoutShift: function(offset) {\n if (offset < 0) {\n this.selectionStart += offset;\n this.selectionEnd = this.selectionStart;\n }\n else {\n this.selectionEnd += offset;\n this.selectionStart = this.selectionEnd;\n }\n return offset !== 0;\n },\n\n /**\n * Moves cursor left\n * @param {Event} e Event object\n */\n moveCursorLeft: function(e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorLeftOrRight('Left', e);\n },\n\n /**\n * @private\n * @return {Boolean} true if a change happened\n */\n _move: function(e, prop, direction) {\n var newValue;\n if (e.altKey) {\n newValue = this['findWordBoundary' + direction](this[prop]);\n }\n else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36 ) {\n newValue = this['findLineBoundary' + direction](this[prop]);\n }\n else {\n this[prop] += direction === 'Left' ? -1 : 1;\n return true;\n }\n if (typeof newValue !== undefined && this[prop] !== newValue) {\n this[prop] = newValue;\n return true;\n }\n },\n\n /**\n * @private\n */\n _moveLeft: function(e, prop) {\n return this._move(e, prop, 'Left');\n },\n\n /**\n * @private\n */\n _moveRight: function(e, prop) {\n return this._move(e, prop, 'Right');\n },\n\n /**\n * Moves cursor left without keeping selection\n * @param {Event} e\n */\n moveCursorLeftWithoutShift: function(e) {\n var change = true;\n this._selectionDirection = 'left';\n\n // only move cursor when there is no selection,\n // otherwise we discard it, and leave cursor on same place\n if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) {\n change = this._moveLeft(e, 'selectionStart');\n\n }\n this.selectionEnd = this.selectionStart;\n return change;\n },\n\n /**\n * Moves cursor left while keeping selection\n * @param {Event} e\n */\n moveCursorLeftWithShift: function(e) {\n if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) {\n return this._moveLeft(e, 'selectionEnd');\n }\n else if (this.selectionStart !== 0){\n this._selectionDirection = 'left';\n return this._moveLeft(e, 'selectionStart');\n }\n },\n\n /**\n * Moves cursor right\n * @param {Event} e Event object\n */\n moveCursorRight: function(e) {\n if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n return;\n }\n this._moveCursorLeftOrRight('Right', e);\n },\n\n /**\n * Moves cursor right or Left, fires event\n * @param {String} direction 'Left', 'Right'\n * @param {Event} e Event object\n */\n _moveCursorLeftOrRight: function(direction, e) {\n var actionName = 'moveCursor' + direction + 'With';\n this._currentCursorOpacity = 1;\n\n if (e.shiftKey) {\n actionName += 'Shift';\n }\n else {\n actionName += 'outShift';\n }\n if (this[actionName](e)) {\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor right while keeping selection\n * @param {Event} e\n */\n moveCursorRightWithShift: function(e) {\n if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) {\n return this._moveRight(e, 'selectionStart');\n }\n else if (this.selectionEnd !== this._text.length) {\n this._selectionDirection = 'right';\n return this._moveRight(e, 'selectionEnd');\n }\n },\n\n /**\n * Moves cursor right without keeping selection\n * @param {Event} e Event object\n */\n moveCursorRightWithoutShift: function(e) {\n var changed = true;\n this._selectionDirection = 'right';\n\n if (this.selectionStart === this.selectionEnd) {\n changed = this._moveRight(e, 'selectionStart');\n this.selectionEnd = this.selectionStart;\n }\n else {\n this.selectionStart = this.selectionEnd;\n }\n return changed;\n },\n\n /**\n * Removes characters from start/end\n * start/end ar per grapheme position in _text array.\n *\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n removeChars: function(start, end) {\n if (typeof end === 'undefined') {\n end = start + 1;\n }\n this.removeStyleFromTo(start, end);\n this._text.splice(start, end - start);\n this.text = this._text.join('');\n this.set('dirty', true);\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n this._removeExtraneousStyles();\n },\n\n /**\n * insert characters at start position, before start position.\n * start equal 1 it means the text get inserted between actual grapheme 0 and 1\n * if style array is provided, it must be as the same length of text in graphemes\n * if end is provided and is bigger than start, old text is replaced.\n * start/end ar per grapheme position in _text array.\n *\n * @param {String} text text to insert\n * @param {Array} style array of style objects\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n insertChars: function(text, style, start, end) {\n if (typeof end === 'undefined') {\n end = start;\n }\n if (end > start) {\n this.removeStyleFromTo(start, end);\n }\n var graphemes = fabric.util.string.graphemeSplit(text);\n this.insertNewStyleBlock(graphemes, start, style);\n this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end));\n this.text = this._text.join('');\n this.set('dirty', true);\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n this._removeExtraneousStyles();\n },\n\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n var toFixed = fabric.util.toFixed,\n multipleSpacesRegex = / +/g;\n\n fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ {\n\n /**\n * Returns SVG representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n _toSVG: function() {\n var offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n return this._wrapSVGTextAndBg(textAndBg);\n },\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n return this._createBaseSVGMarkup(\n this._toSVG(),\n { reviver: reviver, noStyle: true, withShadow: true }\n );\n },\n\n /**\n * @private\n */\n _getSVGLeftTopOffsets: function() {\n return {\n textLeft: -this.width / 2,\n textTop: -this.height / 2,\n lineTop: this.getHeightOfLine(0)\n };\n },\n\n /**\n * @private\n */\n _wrapSVGTextAndBg: function(textAndBg) {\n var noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [\n textAndBg.textBgRects.join(''),\n '\\t\\t',\n textAndBg.textSpans.join(''),\n '\\n'\n ];\n },\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n _getSVGTextAndBg: function(textTopOffset, textLeftOffset) {\n var textSpans = [],\n textBgRects = [],\n height = textTopOffset, lineOffset;\n // bounding-box background\n this._setSVGBg(textBgRects);\n\n // text and text-background\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height);\n }\n this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height);\n height += this.getHeightOfLine(i);\n }\n\n return {\n textSpans: textSpans,\n textBgRects: textBgRects\n };\n },\n\n /**\n * @private\n */\n _createTextCharSpan: function(_char, styleDecl, left, top) {\n var shouldUseWhitespace = _char !== _char.trim() || _char.match(multipleSpacesRegex),\n styleProps = this.getSvgSpanStyles(styleDecl, shouldUseWhitespace),\n fillStyles = styleProps ? 'style=\"' + styleProps + '\"' : '',\n dy = styleDecl.deltaY, dySpan = '',\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n if (dy) {\n dySpan = ' dy=\"' + toFixed(dy, NUM_FRACTION_DIGITS) + '\" ';\n }\n return [\n '',\n fabric.util.string.escapeXml(_char),\n ''\n ].join('');\n },\n\n _setSVGTextLineText: function(textSpans, lineIndex, textLeftOffset, textTopOffset) {\n // set proper line offset\n var lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.indexOf('justify') !== -1,\n actualStyle,\n nextStyle,\n charsToRender = '',\n charBox, style,\n boxWidth = 0,\n line = this._textLines[lineIndex],\n timeToRender;\n\n textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight;\n for (var i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n }\n else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle);\n }\n if (timeToRender) {\n style = this._getStyleDeclaration(lineIndex, i) || { };\n textSpans.push(this._createTextCharSpan(charsToRender, style, textLeftOffset, textTopOffset));\n charsToRender = '';\n actualStyle = nextStyle;\n textLeftOffset += boxWidth;\n boxWidth = 0;\n }\n }\n },\n\n _pushTextBgRect: function(textBgRects, color, left, top, width, height) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n textBgRects.push(\n '\\t\\t\\n');\n },\n\n _setSVGTextLineBg: function(textBgRects, i, leftOffset, textTopOffset) {\n var line = this._textLines[i],\n heightOfLine = this.getHeightOfLine(i) / this.lineHeight,\n boxWidth = 0,\n boxStart = 0,\n charBox, currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charBox = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n lastColor && this._pushTextBgRect(textBgRects, lastColor, leftOffset + boxStart,\n textTopOffset, boxWidth, heightOfLine);\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n }\n else {\n boxWidth += charBox.kernedWidth;\n }\n }\n currentColor && this._pushTextBgRect(textBgRects, currentColor, leftOffset + boxStart,\n textTopOffset, boxWidth, heightOfLine);\n },\n\n /**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n *\n * @private\n * @param {*} value\n * @return {String}\n */\n _getFillAttributes: function(value) {\n var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : '';\n if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) {\n return 'fill=\"' + value + '\"';\n }\n return 'opacity=\"' + fillColor.getAlpha() + '\" fill=\"' + fillColor.setAlpha(1).toRgb() + '\"';\n },\n\n /**\n * @private\n */\n _getSVGLineTopOffset: function(lineIndex) {\n var lineTopOffset = 0, lastHeight = 0;\n for (var j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\n lastHeight = this.getHeightOfLine(j);\n return {\n lineTop: lineTopOffset,\n offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)\n };\n },\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles: function(skipShadow) {\n var svgStyle = fabric.Object.prototype.getSvgStyles.call(this, skipShadow);\n return svgStyle + ' white-space: pre;';\n },\n });\n})();\n/* _TO_SVG_END_ */\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\n\n /**\n * Textbox class, based on IText, allows the user to resize the text rectangle\n * and wraps lines automatically. Textboxes have their Y scaling locked, the\n * user can only change width. Height is adjusted automatically based on the\n * wrapping of lines.\n * @class fabric.Textbox\n * @extends fabric.IText\n * @mixes fabric.Observable\n * @return {fabric.Textbox} thisArg\n * @see {@link fabric.Textbox#initialize} for constructor definition\n */\n fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'textbox',\n\n /**\n * Minimum width of textbox, in pixels.\n * @type Number\n * @default\n */\n minWidth: 20,\n\n /**\n * Minimum calculated width of a textbox, in pixels.\n * fixed to 2 so that an empty textbox cannot go to 0\n * and is still selectable without text.\n * @type Number\n * @default\n */\n dynamicMinWidth: 2,\n\n /**\n * Cached array of text wrapping.\n * @type Array\n */\n __cachedLines: null,\n\n /**\n * Override standard Object class values\n */\n lockScalingFlip: true,\n\n /**\n * Override standard Object class values\n * Textbox needs this on false\n */\n noScaleCache: false,\n\n /**\n * Properties which when set cause object to change dimensions\n * @type Object\n * @private\n */\n _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'),\n\n /**\n * Use this regular expression to split strings in breakable lines\n * @private\n */\n _wordJoiners: /[ \\t\\r]/,\n\n /**\n * Use this boolean property in order to split strings that have no white space concept.\n * this is a cheap way to help with chinese/japaense\n * @type Boolean\n * @since 2.6.0\n */\n splitByGrapheme: false,\n\n /**\n * Unlike superclass's version of this function, Textbox does not update\n * its width.\n * @private\n * @override\n */\n initDimensions: function() {\n if (this.__skipDimension) {\n return;\n }\n this.isEditing && this.initDelayedCursor();\n this.clearContextTop();\n this._clearCache();\n // clear dynamicMinWidth as it will be different after we re-wrap line\n this.dynamicMinWidth = 0;\n // wrap lines\n this._styleMap = this._generateStyleMap(this._splitText());\n // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n if (this.dynamicMinWidth > this.width) {\n this._set('width', this.dynamicMinWidth);\n }\n if (this.textAlign.indexOf('justify') !== -1) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n // clear cache and re-calculate height\n this.height = this.calcTextHeight();\n this.saveState({ propertySet: '_dimensionAffectingProps' });\n },\n\n /**\n * Generate an object that translates the style object so that it is\n * broken up by visual lines (new lines and automatic wrapping).\n * The original text styles object is broken up by actual lines (new lines only),\n * which is only sufficient for Text / IText\n * @private\n */\n _generateStyleMap: function(textInfo) {\n var realLineCount = 0,\n realLineCharCount = 0,\n charCount = 0,\n map = {};\n\n for (var i = 0; i < textInfo.graphemeLines.length; i++) {\n if (textInfo.graphemeText[charCount] === '\\n' && i > 0) {\n realLineCharCount = 0;\n charCount++;\n realLineCount++;\n }\n else if (!this.splitByGrapheme && this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) && i > 0) {\n // this case deals with space's that are removed from end of lines when wrapping\n realLineCharCount++;\n charCount++;\n }\n\n map[i] = { line: realLineCount, offset: realLineCharCount };\n\n charCount += textInfo.graphemeLines[i].length;\n realLineCharCount += textInfo.graphemeLines[i].length;\n }\n\n return map;\n },\n\n /**\n * Returns true if object has a style property or has it on a specified line\n * @param {Number} lineIndex\n * @return {Boolean}\n */\n styleHas: function(property, lineIndex) {\n if (this._styleMap && !this.isWrapping) {\n var map = this._styleMap[lineIndex];\n if (map) {\n lineIndex = map.line;\n }\n }\n return fabric.Text.prototype.styleHas.call(this, property, lineIndex);\n },\n\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles: function(lineIndex) {\n if (!this.styles) {\n return true;\n }\n var offset = 0, nextLineIndex = lineIndex + 1, nextOffset, obj, shouldLimit = false,\n map = this._styleMap[lineIndex], mapNextLine = this._styleMap[lineIndex + 1];\n if (map) {\n lineIndex = map.line;\n offset = map.offset;\n }\n if (mapNextLine) {\n nextLineIndex = mapNextLine.line;\n shouldLimit = nextLineIndex === lineIndex;\n nextOffset = mapNextLine.offset;\n }\n obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] };\n for (var p1 in obj) {\n for (var p2 in obj[p1]) {\n if (p2 >= offset && (!shouldLimit || p2 < nextOffset)) {\n // eslint-disable-next-line no-unused-vars\n for (var p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n }\n return true;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _getStyleDeclaration: function(lineIndex, charIndex) {\n if (this._styleMap && !this.isWrapping) {\n var map = this._styleMap[lineIndex];\n if (!map) {\n return null;\n }\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n }\n return this.callSuper('_getStyleDeclaration', lineIndex, charIndex);\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n _setStyleDeclaration: function(lineIndex, charIndex, style) {\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n\n this.styles[lineIndex][charIndex] = style;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _deleteStyleDeclaration: function(lineIndex, charIndex) {\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n delete this.styles[lineIndex][charIndex];\n },\n\n /**\n * probably broken need a fix\n * Returns the real style line that correspond to the wrapped lineIndex line\n * Used just to verify if the line does exist or not.\n * @param {Number} lineIndex\n * @returns {Boolean} if the line exists or not\n * @private\n */\n _getLineStyle: function(lineIndex) {\n var map = this._styleMap[lineIndex];\n return !!this.styles[map.line];\n },\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @param {Object} style\n * @private\n */\n _setLineStyle: function(lineIndex) {\n var map = this._styleMap[lineIndex];\n this.styles[map.line] = {};\n },\n\n /**\n * Wraps text using the 'width' property of Textbox. First this function\n * splits text on newlines, so we preserve newlines entered by the user.\n * Then it wraps each line using the width of the Textbox by calling\n * _wrapLine().\n * @param {Array} lines The string array of text that is split into lines\n * @param {Number} desiredWidth width you want to wrap to\n * @returns {Array} Array of lines\n */\n _wrapText: function(lines, desiredWidth) {\n var wrapped = [], i;\n this.isWrapping = true;\n for (i = 0; i < lines.length; i++) {\n wrapped = wrapped.concat(this._wrapLine(lines[i], i, desiredWidth));\n }\n this.isWrapping = false;\n return wrapped;\n },\n\n /**\n * Helper function to measure a string of text, given its lineIndex and charIndex offset\n * it gets called when charBounds are not available yet.\n * @param {CanvasRenderingContext2D} ctx\n * @param {String} text\n * @param {number} lineIndex\n * @param {number} charOffset\n * @returns {number}\n * @private\n */\n _measureWord: function(word, lineIndex, charOffset) {\n var width = 0, prevGrapheme, skipLeft = true;\n charOffset = charOffset || 0;\n for (var i = 0, len = word.length; i < len; i++) {\n var box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft);\n width += box.kernedWidth;\n prevGrapheme = word[i];\n }\n return width;\n },\n\n /**\n * Wraps a line of text using the width of the Textbox and a context.\n * @param {Array} line The grapheme array that represent the line\n * @param {Number} lineIndex\n * @param {Number} desiredWidth width you want to wrap the line to\n * @param {Number} reservedSpace space to remove from wrapping for custom functionalities\n * @returns {Array} Array of line(s) into which the given text is wrapped\n * to.\n */\n _wrapLine: function(_line, lineIndex, desiredWidth, reservedSpace) {\n var lineWidth = 0,\n splitByGrapheme = this.splitByGrapheme,\n graphemeLines = [],\n line = [],\n // spaces in different languges?\n words = splitByGrapheme ? fabric.util.string.graphemeSplit(_line) : _line.split(this._wordJoiners),\n word = '',\n offset = 0,\n infix = splitByGrapheme ? '' : ' ',\n wordWidth = 0,\n infixWidth = 0,\n largestWordWidth = 0,\n lineJustStarted = true,\n additionalSpace = splitByGrapheme ? 0 : this._getWidthOfCharSpacing(),\n reservedSpace = reservedSpace || 0;\n // fix a difference between split and graphemeSplit\n if (words.length === 0) {\n words.push([]);\n }\n desiredWidth -= reservedSpace;\n for (var i = 0; i < words.length; i++) {\n // if using splitByGrapheme words are already in graphemes.\n word = splitByGrapheme ? words[i] : fabric.util.string.graphemeSplit(words[i]);\n wordWidth = this._measureWord(word, lineIndex, offset);\n offset += word.length;\n\n lineWidth += infixWidth + wordWidth - additionalSpace;\n\n if (lineWidth >= desiredWidth && !lineJustStarted) {\n graphemeLines.push(line);\n line = [];\n lineWidth = wordWidth;\n lineJustStarted = true;\n }\n else {\n lineWidth += additionalSpace;\n }\n\n if (!lineJustStarted && !splitByGrapheme) {\n line.push(infix);\n }\n line = line.concat(word);\n\n infixWidth = this._measureWord([infix], lineIndex, offset);\n offset++;\n lineJustStarted = false;\n // keep track of largest word\n if (wordWidth > largestWordWidth) {\n largestWordWidth = wordWidth;\n }\n }\n\n i && graphemeLines.push(line);\n\n if (largestWordWidth + reservedSpace > this.dynamicMinWidth) {\n this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace;\n }\n\n return graphemeLines;\n },\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @param {Number} lineIndex text to split\n * @return {Boolean}\n */\n isEndOfWrapping: function(lineIndex) {\n if (!this._styleMap[lineIndex + 1]) {\n // is last line, return true;\n return true;\n }\n if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) {\n // this is last line before a line break, return true;\n return true;\n }\n return false;\n },\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * @return Number\n */\n missingNewlineOffset: function(lineIndex) {\n if (this.splitByGrapheme) {\n return this.isEndOfWrapping(lineIndex) ? 1 : 0;\n }\n return 1;\n },\n\n /**\n * Gets lines of text to render in the Textbox. This function calculates\n * text wrapping on the fly every time it is called.\n * @param {String} text text to split\n * @returns {Array} Array of lines in the Textbox.\n * @override\n */\n _splitTextIntoLines: function(text) {\n var newText = fabric.Text.prototype._splitTextIntoLines.call(this, text),\n graphemeLines = this._wrapText(newText.lines, this.width),\n lines = new Array(graphemeLines.length);\n for (var i = 0; i < graphemeLines.length; i++) {\n lines[i] = graphemeLines[i].join('');\n }\n newText.lines = lines;\n newText.graphemeLines = graphemeLines;\n return newText;\n },\n\n getMinWidth: function() {\n return Math.max(this.minWidth, this.dynamicMinWidth);\n },\n\n _removeExtraneousStyles: function() {\n var linesToKeep = {};\n for (var prop in this._styleMap) {\n if (this._textLines[prop]) {\n linesToKeep[this._styleMap[prop].line] = 1;\n }\n }\n for (var prop in this.styles) {\n if (!linesToKeep[prop]) {\n delete this.styles[prop];\n }\n }\n },\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['minWidth', 'splitByGrapheme'].concat(propertiesToInclude));\n }\n });\n\n /**\n * Returns fabric.Textbox instance from an object representation\n * @static\n * @memberOf fabric.Textbox\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created\n */\n fabric.Textbox.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Textbox', object, callback, 'text');\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n"],"sourceRoot":""}