12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286362873628836289362903629136292362933629436295362963629736298362993630036301363023630336304363053630636307363083630936310363113631236313363143631536316363173631836319363203632136322363233632436325363263632736328363293633036331363323633336334363353633636337363383633936340363413634236343363443634536346363473634836349363503635136352363533635436355363563635736358363593636036361363623636336364363653636636367363683636936370363713637236373363743637536376363773637836379363803638136382363833638436385363863638736388363893639036391363923639336394363953639636397363983639936400364013640236403364043640536406364073640836409364103641136412364133641436415364163641736418364193642036421364223642336424364253642636427364283642936430364313643236433364343643536436364373643836439364403644136442364433644436445364463644736448364493645036451364523645336454364553645636457364583645936460364613646236463364643646536466364673646836469364703647136472364733647436475364763647736478364793648036481364823648336484364853648636487364883648936490364913649236493364943649536496364973649836499365003650136502365033650436505365063650736508365093651036511365123651336514365153651636517365183651936520365213652236523365243652536526365273652836529365303653136532365333653436535365363653736538365393654036541365423654336544365453654636547365483654936550365513655236553365543655536556365573655836559365603656136562365633656436565365663656736568365693657036571365723657336574365753657636577365783657936580365813658236583365843658536586365873658836589365903659136592365933659436595365963659736598365993660036601366023660336604366053660636607366083660936610366113661236613366143661536616366173661836619366203662136622366233662436625366263662736628366293663036631366323663336634366353663636637366383663936640366413664236643366443664536646366473664836649366503665136652366533665436655366563665736658366593666036661366623666336664366653666636667366683666936670366713667236673366743667536676366773667836679366803668136682366833668436685366863668736688366893669036691366923669336694366953669636697366983669936700367013670236703367043670536706367073670836709367103671136712367133671436715367163671736718367193672036721367223672336724367253672636727367283672936730367313673236733367343673536736367373673836739367403674136742367433674436745367463674736748367493675036751367523675336754367553675636757367583675936760367613676236763367643676536766367673676836769367703677136772367733677436775367763677736778367793678036781367823678336784367853678636787367883678936790367913679236793367943679536796367973679836799368003680136802368033680436805368063680736808368093681036811368123681336814368153681636817368183681936820368213682236823368243682536826368273682836829368303683136832368333683436835368363683736838368393684036841368423684336844368453684636847368483684936850368513685236853368543685536856368573685836859368603686136862368633686436865368663686736868368693687036871368723687336874368753687636877368783687936880368813688236883368843688536886368873688836889368903689136892368933689436895368963689736898368993690036901369023690336904369053690636907369083690936910369113691236913369143691536916369173691836919369203692136922369233692436925369263692736928369293693036931369323693336934369353693636937369383693936940369413694236943369443694536946369473694836949369503695136952369533695436955369563695736958369593696036961369623696336964369653696636967369683696936970369713697236973369743697536976369773697836979369803698136982369833698436985369863698736988369893699036991369923699336994369953699636997369983699937000370013700237003370043700537006370073700837009370103701137012370133701437015370163701737018370193702037021370223702337024370253702637027370283702937030370313703237033370343703537036370373703837039370403704137042370433704437045370463704737048370493705037051370523705337054370553705637057370583705937060370613706237063370643706537066370673706837069370703707137072370733707437075370763707737078370793708037081370823708337084370853708637087370883708937090370913709237093370943709537096370973709837099371003710137102371033710437105371063710737108371093711037111371123711337114371153711637117371183711937120371213712237123371243712537126371273712837129371303713137132371333713437135371363713737138371393714037141371423714337144371453714637147371483714937150371513715237153371543715537156371573715837159371603716137162371633716437165371663716737168371693717037171371723717337174371753717637177371783717937180371813718237183371843718537186371873718837189371903719137192371933719437195371963719737198371993720037201372023720337204372053720637207372083720937210372113721237213372143721537216372173721837219372203722137222372233722437225372263722737228372293723037231372323723337234372353723637237372383723937240372413724237243372443724537246372473724837249372503725137252372533725437255372563725737258372593726037261372623726337264372653726637267372683726937270372713727237273372743727537276372773727837279372803728137282372833728437285372863728737288372893729037291372923729337294372953729637297372983729937300373013730237303373043730537306373073730837309373103731137312373133731437315373163731737318373193732037321373223732337324373253732637327373283732937330373313733237333373343733537336373373733837339373403734137342373433734437345373463734737348373493735037351373523735337354373553735637357373583735937360373613736237363373643736537366373673736837369373703737137372373733737437375373763737737378373793738037381373823738337384373853738637387373883738937390373913739237393373943739537396373973739837399374003740137402374033740437405374063740737408374093741037411374123741337414374153741637417374183741937420374213742237423374243742537426374273742837429374303743137432374333743437435374363743737438374393744037441374423744337444374453744637447374483744937450374513745237453374543745537456374573745837459374603746137462374633746437465374663746737468374693747037471374723747337474374753747637477374783747937480374813748237483374843748537486374873748837489374903749137492374933749437495374963749737498374993750037501375023750337504375053750637507375083750937510375113751237513375143751537516375173751837519375203752137522375233752437525375263752737528375293753037531375323753337534375353753637537375383753937540375413754237543375443754537546375473754837549375503755137552375533755437555375563755737558375593756037561375623756337564375653756637567375683756937570375713757237573375743757537576375773757837579375803758137582375833758437585375863758737588375893759037591375923759337594375953759637597375983759937600376013760237603376043760537606376073760837609376103761137612376133761437615376163761737618376193762037621376223762337624376253762637627376283762937630376313763237633376343763537636376373763837639376403764137642376433764437645376463764737648376493765037651376523765337654376553765637657376583765937660376613766237663376643766537666376673766837669376703767137672376733767437675376763767737678376793768037681376823768337684376853768637687376883768937690376913769237693376943769537696376973769837699377003770137702377033770437705377063770737708377093771037711377123771337714377153771637717377183771937720377213772237723377243772537726377273772837729377303773137732377333773437735377363773737738377393774037741377423774337744377453774637747377483774937750377513775237753377543775537756377573775837759377603776137762377633776437765377663776737768377693777037771377723777337774377753777637777377783777937780377813778237783377843778537786377873778837789377903779137792377933779437795377963779737798377993780037801378023780337804378053780637807378083780937810378113781237813378143781537816378173781837819378203782137822378233782437825378263782737828378293783037831378323783337834378353783637837378383783937840378413784237843378443784537846378473784837849378503785137852378533785437855378563785737858378593786037861378623786337864378653786637867378683786937870378713787237873378743787537876378773787837879378803788137882378833788437885378863788737888378893789037891378923789337894378953789637897378983789937900379013790237903379043790537906379073790837909379103791137912379133791437915379163791737918379193792037921379223792337924379253792637927379283792937930379313793237933379343793537936379373793837939379403794137942379433794437945379463794737948379493795037951379523795337954379553795637957379583795937960379613796237963379643796537966379673796837969379703797137972379733797437975379763797737978379793798037981379823798337984379853798637987379883798937990379913799237993379943799537996379973799837999380003800138002380033800438005380063800738008380093801038011380123801338014380153801638017380183801938020380213802238023380243802538026380273802838029380303803138032380333803438035380363803738038380393804038041380423804338044380453804638047380483804938050380513805238053380543805538056380573805838059380603806138062380633806438065380663806738068380693807038071380723807338074380753807638077380783807938080380813808238083380843808538086380873808838089380903809138092380933809438095380963809738098380993810038101381023810338104381053810638107381083810938110381113811238113381143811538116381173811838119381203812138122381233812438125381263812738128381293813038131381323813338134381353813638137381383813938140381413814238143381443814538146381473814838149381503815138152381533815438155381563815738158381593816038161381623816338164381653816638167381683816938170381713817238173381743817538176381773817838179381803818138182381833818438185381863818738188381893819038191381923819338194381953819638197381983819938200382013820238203382043820538206382073820838209382103821138212382133821438215382163821738218382193822038221382223822338224382253822638227382283822938230382313823238233382343823538236382373823838239382403824138242382433824438245382463824738248382493825038251382523825338254382553825638257382583825938260382613826238263382643826538266382673826838269382703827138272382733827438275382763827738278382793828038281382823828338284382853828638287382883828938290382913829238293382943829538296382973829838299383003830138302383033830438305383063830738308383093831038311383123831338314383153831638317383183831938320383213832238323383243832538326383273832838329383303833138332383333833438335383363833738338383393834038341383423834338344383453834638347383483834938350383513835238353383543835538356383573835838359383603836138362383633836438365383663836738368383693837038371383723837338374383753837638377383783837938380383813838238383383843838538386383873838838389383903839138392383933839438395383963839738398383993840038401384023840338404384053840638407384083840938410384113841238413384143841538416384173841838419384203842138422384233842438425384263842738428384293843038431384323843338434384353843638437384383843938440384413844238443384443844538446384473844838449384503845138452384533845438455384563845738458384593846038461384623846338464384653846638467384683846938470384713847238473384743847538476384773847838479384803848138482384833848438485384863848738488384893849038491384923849338494384953849638497384983849938500385013850238503385043850538506385073850838509385103851138512385133851438515385163851738518385193852038521385223852338524385253852638527385283852938530385313853238533385343853538536385373853838539385403854138542385433854438545385463854738548385493855038551385523855338554385553855638557385583855938560385613856238563385643856538566385673856838569385703857138572385733857438575385763857738578385793858038581385823858338584385853858638587385883858938590385913859238593385943859538596385973859838599386003860138602386033860438605386063860738608386093861038611386123861338614386153861638617386183861938620386213862238623386243862538626386273862838629386303863138632386333863438635386363863738638386393864038641386423864338644386453864638647386483864938650386513865238653386543865538656386573865838659386603866138662386633866438665386663866738668386693867038671386723867338674386753867638677386783867938680386813868238683386843868538686386873868838689386903869138692386933869438695386963869738698386993870038701387023870338704387053870638707387083870938710387113871238713387143871538716387173871838719387203872138722387233872438725387263872738728387293873038731387323873338734387353873638737387383873938740387413874238743387443874538746387473874838749387503875138752387533875438755387563875738758387593876038761387623876338764387653876638767387683876938770387713877238773387743877538776387773877838779387803878138782387833878438785387863878738788387893879038791387923879338794387953879638797387983879938800388013880238803388043880538806388073880838809388103881138812388133881438815388163881738818388193882038821388223882338824388253882638827388283882938830388313883238833388343883538836388373883838839388403884138842388433884438845388463884738848388493885038851388523885338854388553885638857388583885938860388613886238863388643886538866388673886838869388703887138872388733887438875388763887738878388793888038881388823888338884388853888638887388883888938890388913889238893388943889538896388973889838899389003890138902389033890438905389063890738908389093891038911389123891338914389153891638917389183891938920389213892238923389243892538926389273892838929389303893138932389333893438935389363893738938389393894038941389423894338944389453894638947389483894938950389513895238953389543895538956389573895838959389603896138962389633896438965389663896738968389693897038971389723897338974389753897638977389783897938980389813898238983389843898538986389873898838989389903899138992389933899438995389963899738998389993900039001390023900339004390053900639007390083900939010390113901239013390143901539016390173901839019390203902139022390233902439025390263902739028390293903039031390323903339034390353903639037390383903939040390413904239043390443904539046390473904839049390503905139052390533905439055390563905739058390593906039061390623906339064390653906639067390683906939070390713907239073390743907539076390773907839079390803908139082390833908439085390863908739088390893909039091390923909339094390953909639097390983909939100391013910239103391043910539106391073910839109391103911139112391133911439115391163911739118391193912039121391223912339124391253912639127391283912939130391313913239133391343913539136391373913839139391403914139142391433914439145391463914739148391493915039151391523915339154391553915639157391583915939160391613916239163391643916539166391673916839169391703917139172391733917439175391763917739178391793918039181391823918339184391853918639187391883918939190391913919239193391943919539196391973919839199392003920139202392033920439205392063920739208392093921039211392123921339214392153921639217392183921939220392213922239223392243922539226392273922839229392303923139232392333923439235392363923739238392393924039241392423924339244392453924639247392483924939250392513925239253392543925539256392573925839259392603926139262392633926439265392663926739268392693927039271392723927339274392753927639277392783927939280392813928239283392843928539286392873928839289392903929139292392933929439295392963929739298392993930039301393023930339304393053930639307393083930939310393113931239313393143931539316393173931839319393203932139322393233932439325393263932739328393293933039331393323933339334393353933639337393383933939340393413934239343393443934539346393473934839349393503935139352393533935439355393563935739358393593936039361393623936339364393653936639367393683936939370393713937239373393743937539376393773937839379393803938139382393833938439385393863938739388393893939039391393923939339394393953939639397393983939939400394013940239403394043940539406394073940839409394103941139412394133941439415394163941739418394193942039421394223942339424394253942639427394283942939430394313943239433394343943539436394373943839439394403944139442394433944439445394463944739448394493945039451394523945339454394553945639457394583945939460394613946239463394643946539466394673946839469394703947139472394733947439475394763947739478394793948039481394823948339484394853948639487394883948939490394913949239493394943949539496394973949839499395003950139502395033950439505395063950739508395093951039511395123951339514395153951639517395183951939520395213952239523395243952539526395273952839529395303953139532395333953439535395363953739538395393954039541395423954339544395453954639547395483954939550395513955239553395543955539556395573955839559395603956139562395633956439565395663956739568395693957039571395723957339574395753957639577395783957939580395813958239583395843958539586395873958839589395903959139592395933959439595395963959739598395993960039601396023960339604396053960639607396083960939610396113961239613396143961539616396173961839619396203962139622396233962439625396263962739628396293963039631396323963339634396353963639637396383963939640396413964239643396443964539646396473964839649396503965139652396533965439655396563965739658396593966039661396623966339664396653966639667396683966939670396713967239673396743967539676396773967839679396803968139682396833968439685396863968739688396893969039691396923969339694396953969639697396983969939700397013970239703397043970539706397073970839709397103971139712397133971439715397163971739718397193972039721397223972339724397253972639727397283972939730397313973239733397343973539736397373973839739397403974139742397433974439745397463974739748397493975039751397523975339754397553975639757397583975939760397613976239763397643976539766397673976839769397703977139772397733977439775397763977739778397793978039781397823978339784397853978639787397883978939790397913979239793397943979539796397973979839799398003980139802398033980439805398063980739808398093981039811398123981339814398153981639817398183981939820398213982239823398243982539826398273982839829398303983139832398333983439835398363983739838398393984039841398423984339844398453984639847398483984939850398513985239853398543985539856398573985839859398603986139862398633986439865398663986739868398693987039871398723987339874398753987639877398783987939880398813988239883398843988539886398873988839889398903989139892398933989439895398963989739898398993990039901399023990339904399053990639907399083990939910399113991239913399143991539916399173991839919399203992139922399233992439925399263992739928399293993039931399323993339934399353993639937399383993939940399413994239943399443994539946399473994839949399503995139952399533995439955399563995739958399593996039961399623996339964399653996639967399683996939970399713997239973399743997539976399773997839979399803998139982399833998439985399863998739988399893999039991399923999339994399953999639997399983999940000400014000240003400044000540006400074000840009400104001140012400134001440015400164001740018400194002040021400224002340024400254002640027400284002940030400314003240033400344003540036400374003840039400404004140042400434004440045400464004740048400494005040051400524005340054400554005640057400584005940060400614006240063400644006540066400674006840069400704007140072400734007440075400764007740078400794008040081400824008340084400854008640087400884008940090400914009240093400944009540096400974009840099401004010140102401034010440105401064010740108401094011040111401124011340114401154011640117401184011940120401214012240123401244012540126401274012840129401304013140132401334013440135401364013740138401394014040141401424014340144401454014640147401484014940150401514015240153401544015540156401574015840159401604016140162401634016440165401664016740168401694017040171401724017340174401754017640177401784017940180401814018240183401844018540186401874018840189401904019140192401934019440195401964019740198401994020040201402024020340204402054020640207402084020940210402114021240213402144021540216402174021840219402204022140222402234022440225402264022740228402294023040231402324023340234402354023640237402384023940240402414024240243402444024540246402474024840249402504025140252402534025440255402564025740258402594026040261402624026340264402654026640267402684026940270402714027240273402744027540276402774027840279402804028140282402834028440285402864028740288402894029040291402924029340294402954029640297402984029940300403014030240303403044030540306403074030840309403104031140312403134031440315403164031740318403194032040321403224032340324403254032640327403284032940330403314033240333403344033540336403374033840339403404034140342403434034440345403464034740348403494035040351403524035340354403554035640357403584035940360403614036240363403644036540366403674036840369403704037140372403734037440375403764037740378403794038040381403824038340384403854038640387403884038940390403914039240393403944039540396403974039840399404004040140402404034040440405404064040740408404094041040411404124041340414404154041640417404184041940420404214042240423404244042540426404274042840429404304043140432404334043440435404364043740438404394044040441404424044340444404454044640447404484044940450404514045240453404544045540456404574045840459404604046140462404634046440465404664046740468404694047040471404724047340474404754047640477404784047940480404814048240483404844048540486404874048840489404904049140492404934049440495404964049740498404994050040501405024050340504405054050640507405084050940510405114051240513405144051540516405174051840519405204052140522405234052440525405264052740528405294053040531405324053340534405354053640537405384053940540405414054240543405444054540546405474054840549405504055140552405534055440555405564055740558405594056040561405624056340564405654056640567405684056940570405714057240573405744057540576405774057840579405804058140582405834058440585405864058740588405894059040591405924059340594405954059640597405984059940600406014060240603406044060540606406074060840609406104061140612406134061440615406164061740618406194062040621406224062340624406254062640627406284062940630406314063240633406344063540636406374063840639406404064140642406434064440645406464064740648406494065040651406524065340654406554065640657406584065940660406614066240663406644066540666406674066840669406704067140672406734067440675406764067740678406794068040681406824068340684406854068640687406884068940690406914069240693406944069540696406974069840699407004070140702407034070440705407064070740708407094071040711407124071340714407154071640717407184071940720407214072240723407244072540726407274072840729407304073140732407334073440735407364073740738407394074040741407424074340744407454074640747407484074940750407514075240753407544075540756407574075840759407604076140762407634076440765407664076740768407694077040771407724077340774407754077640777407784077940780407814078240783407844078540786407874078840789407904079140792407934079440795407964079740798407994080040801408024080340804408054080640807408084080940810408114081240813408144081540816408174081840819408204082140822408234082440825408264082740828408294083040831408324083340834408354083640837408384083940840408414084240843408444084540846408474084840849408504085140852408534085440855408564085740858408594086040861408624086340864408654086640867408684086940870408714087240873408744087540876408774087840879408804088140882408834088440885408864088740888408894089040891408924089340894408954089640897408984089940900409014090240903409044090540906409074090840909409104091140912409134091440915409164091740918409194092040921409224092340924409254092640927409284092940930409314093240933409344093540936409374093840939409404094140942409434094440945409464094740948409494095040951409524095340954409554095640957409584095940960409614096240963409644096540966409674096840969409704097140972409734097440975409764097740978409794098040981409824098340984409854098640987409884098940990409914099240993409944099540996409974099840999410004100141002410034100441005410064100741008410094101041011410124101341014410154101641017410184101941020410214102241023410244102541026410274102841029410304103141032410334103441035410364103741038410394104041041410424104341044410454104641047410484104941050410514105241053410544105541056410574105841059410604106141062410634106441065410664106741068410694107041071410724107341074410754107641077410784107941080410814108241083410844108541086410874108841089410904109141092410934109441095410964109741098410994110041101411024110341104411054110641107411084110941110411114111241113411144111541116411174111841119411204112141122411234112441125411264112741128411294113041131411324113341134411354113641137411384113941140411414114241143411444114541146411474114841149411504115141152411534115441155411564115741158411594116041161411624116341164411654116641167411684116941170411714117241173411744117541176411774117841179411804118141182411834118441185411864118741188411894119041191411924119341194411954119641197411984119941200412014120241203412044120541206412074120841209412104121141212412134121441215412164121741218412194122041221412224122341224412254122641227412284122941230412314123241233412344123541236412374123841239412404124141242412434124441245412464124741248412494125041251412524125341254412554125641257412584125941260412614126241263412644126541266412674126841269412704127141272412734127441275412764127741278412794128041281412824128341284412854128641287412884128941290412914129241293412944129541296412974129841299413004130141302413034130441305413064130741308413094131041311413124131341314413154131641317413184131941320413214132241323413244132541326413274132841329413304133141332413334133441335413364133741338413394134041341413424134341344413454134641347413484134941350413514135241353413544135541356413574135841359413604136141362413634136441365413664136741368413694137041371413724137341374413754137641377413784137941380413814138241383413844138541386413874138841389413904139141392413934139441395413964139741398413994140041401414024140341404414054140641407414084140941410414114141241413414144141541416414174141841419414204142141422414234142441425414264142741428414294143041431414324143341434414354143641437414384143941440414414144241443414444144541446414474144841449414504145141452414534145441455414564145741458414594146041461414624146341464414654146641467414684146941470414714147241473414744147541476414774147841479414804148141482414834148441485414864148741488414894149041491414924149341494414954149641497414984149941500415014150241503415044150541506415074150841509415104151141512415134151441515415164151741518415194152041521415224152341524415254152641527415284152941530415314153241533415344153541536415374153841539415404154141542415434154441545415464154741548415494155041551415524155341554415554155641557415584155941560415614156241563415644156541566415674156841569415704157141572415734157441575415764157741578415794158041581415824158341584415854158641587415884158941590415914159241593415944159541596415974159841599416004160141602416034160441605416064160741608416094161041611416124161341614416154161641617416184161941620416214162241623416244162541626416274162841629416304163141632416334163441635416364163741638416394164041641416424164341644416454164641647416484164941650416514165241653416544165541656416574165841659416604166141662416634166441665416664166741668416694167041671416724167341674416754167641677416784167941680416814168241683416844168541686416874168841689416904169141692416934169441695416964169741698416994170041701417024170341704417054170641707417084170941710417114171241713417144171541716417174171841719417204172141722417234172441725417264172741728417294173041731417324173341734417354173641737417384173941740417414174241743417444174541746417474174841749417504175141752417534175441755417564175741758417594176041761417624176341764417654176641767417684176941770417714177241773417744177541776417774177841779417804178141782417834178441785417864178741788417894179041791417924179341794417954179641797417984179941800418014180241803418044180541806418074180841809418104181141812418134181441815418164181741818418194182041821418224182341824418254182641827418284182941830418314183241833418344183541836418374183841839418404184141842418434184441845418464184741848418494185041851418524185341854418554185641857418584185941860418614186241863418644186541866418674186841869418704187141872418734187441875418764187741878418794188041881418824188341884418854188641887418884188941890418914189241893418944189541896418974189841899419004190141902419034190441905419064190741908419094191041911419124191341914419154191641917419184191941920419214192241923419244192541926419274192841929419304193141932419334193441935419364193741938419394194041941419424194341944419454194641947419484194941950419514195241953419544195541956419574195841959419604196141962419634196441965419664196741968419694197041971419724197341974419754197641977419784197941980419814198241983419844198541986419874198841989419904199141992419934199441995419964199741998419994200042001420024200342004420054200642007420084200942010420114201242013420144201542016420174201842019420204202142022420234202442025420264202742028420294203042031420324203342034420354203642037420384203942040420414204242043420444204542046420474204842049420504205142052420534205442055420564205742058420594206042061420624206342064420654206642067420684206942070420714207242073420744207542076420774207842079420804208142082420834208442085420864208742088420894209042091420924209342094420954209642097420984209942100421014210242103421044210542106421074210842109421104211142112421134211442115421164211742118421194212042121421224212342124421254212642127421284212942130421314213242133421344213542136421374213842139421404214142142421434214442145421464214742148421494215042151421524215342154421554215642157421584215942160421614216242163421644216542166421674216842169421704217142172421734217442175421764217742178421794218042181421824218342184421854218642187421884218942190421914219242193421944219542196421974219842199422004220142202422034220442205422064220742208422094221042211422124221342214422154221642217422184221942220422214222242223422244222542226422274222842229422304223142232422334223442235422364223742238422394224042241422424224342244422454224642247422484224942250422514225242253422544225542256422574225842259422604226142262422634226442265422664226742268422694227042271422724227342274422754227642277422784227942280422814228242283422844228542286422874228842289422904229142292422934229442295422964229742298422994230042301423024230342304423054230642307423084230942310423114231242313423144231542316423174231842319423204232142322423234232442325423264232742328423294233042331423324233342334423354233642337423384233942340423414234242343423444234542346423474234842349423504235142352423534235442355423564235742358423594236042361423624236342364423654236642367423684236942370423714237242373423744237542376423774237842379423804238142382423834238442385423864238742388423894239042391423924239342394423954239642397423984239942400424014240242403424044240542406424074240842409424104241142412424134241442415424164241742418424194242042421424224242342424424254242642427424284242942430424314243242433424344243542436424374243842439424404244142442424434244442445424464244742448424494245042451424524245342454424554245642457424584245942460424614246242463424644246542466424674246842469424704247142472424734247442475424764247742478424794248042481424824248342484424854248642487424884248942490424914249242493424944249542496424974249842499425004250142502425034250442505425064250742508425094251042511425124251342514425154251642517425184251942520 |
- /*!
- * Pintura Image Editor 8.13.1
- * (c) 2018-2021 PQINA Inc. - All Rights Reserved
- * License: https://pqina.nl/pintura/license/
- */
- /* eslint-disable */
- const JFIF_MARKER = 0xffe0;
- const EXIF_MARKER = 0xffe1;
- const SOS_MARKER = 0xffda;
- const Markers = {
- [EXIF_MARKER]: 'exif',
- [JFIF_MARKER]: 'jfif',
- [SOS_MARKER]: 'sos',
- };
- const JPEG_SOI_MARKER = 0xffd8; // start of JPEG
- const JPEG_MARKER_PREFIX = 0xff;
- var dataViewGetApplicationMarkers = (view) => {
- // If no SOI marker exit here because we're not going to find the APP1 header in a non-jpeg file
- if (view.getUint16(0) !== JPEG_SOI_MARKER)
- return undefined;
- const markerTypes = Object.keys(Markers).map((v) => parseInt(v, 10));
- const length = view.byteLength; // cache the length here
- let offset = 2; // start at 2 as we skip the SOI marker
- let marker; // this will hold the current marker
- // resulting markers
- let res = undefined;
- while (offset < length) {
- // test if marker is valid JPEG marker (starts with ff)
- if (view.getUint8(offset) !== JPEG_MARKER_PREFIX)
- break;
- // let's read the full marker
- marker = view.getUint16(offset);
- // read marker if included in marker types, don't
- if (markerTypes.includes(marker)) {
- const key = Markers[marker];
- if (!res)
- res = {};
- // prevent overwriting by double markers
- if (!res[key]) {
- res[key] = {
- offset,
- size: view.getUint16(offset + 2),
- };
- }
- }
- // Image stream starts here, no markers found
- if (marker === SOS_MARKER)
- break;
- // next offset is 2 to skip over marker type and then we add marker data size to skip to next marker
- offset += 2 + view.getUint16(offset + 2);
- }
- // no APP markers found
- return res;
- };
- const APP1_MARKER = 0xffe1;
- const APP1_EXIF_IDENTIFIER = 0x45786966;
- const TIFF_MARKER = 0x002a;
- const BYTE_ALIGN_MOTOROLA = 0x4d4d;
- const BYTE_ALIGN_INTEL = 0x4949;
- // offset = start of APP1_MARKER
- var dataViewGetExifTags = (view, offset) => {
- // If no APP1 marker exit here because we're not going to find the EXIF id header outside of APP1
- if (view.getUint16(offset) !== APP1_MARKER)
- return undefined;
- // get marker size
- const size = view.getUint16(offset + 2); // 14197
- // Let's skip over app1 marker and size marker (2 + 2 bytes)
- offset += 4;
- // We're now at the EXIF header marker (we'll only check the first 4 bytes, reads "exif"), if not there, exit
- if (view.getUint32(offset) !== APP1_EXIF_IDENTIFIER)
- return undefined;
- // Let's skip over 6 byte EXIF marker
- offset += 6;
- // Read byte alignment
- let byteAlignment = view.getUint16(offset);
- if (byteAlignment !== BYTE_ALIGN_INTEL && byteAlignment !== BYTE_ALIGN_MOTOROLA)
- return undefined;
- const storedAsLittleEndian = byteAlignment === BYTE_ALIGN_INTEL;
- // Skip over byte alignment
- offset += 2;
- // Test if valid tiff marker data, should always be 0x002a
- if (view.getUint16(offset, storedAsLittleEndian) !== TIFF_MARKER)
- return undefined;
- // Skip to first IDF, position of IDF is read after tiff marker (offset 2)
- offset += view.getUint32(offset + 2, storedAsLittleEndian);
- // helper method to find tag offset by marker
- const getTagOffsets = (marker) => {
- let offsets = [];
- let i = offset;
- let max = offset + size - 16;
- for (; i < max; i += 12) {
- let tagOffset = i;
- // see if is match, if not, next entry
- if (view.getUint16(tagOffset, storedAsLittleEndian) !== marker)
- continue;
- // add offset
- offsets.push(tagOffset);
- }
- return offsets;
- };
- return {
- read: (address) => {
- const tagOffsets = getTagOffsets(address);
- if (!tagOffsets.length)
- return undefined;
- // only return first found tag
- return view.getUint16(tagOffsets[0] + 8, storedAsLittleEndian);
- },
- write: (address, value) => {
- const tagOffsets = getTagOffsets(address);
- if (!tagOffsets.length)
- return false;
- // overwrite all found tags (sometimes images can have multiple tags with the same value, let's make sure they're all set)
- tagOffsets.forEach((offset) => view.setUint16(offset + 8, value, storedAsLittleEndian));
- return true;
- },
- };
- };
- const ORIENTATION_TAG = 0x0112;
- var arrayBufferImageExif = (data, key, value) => {
- // no data, no go!
- if (!data)
- return;
- const view = new DataView(data);
- // Get app1 header offset
- const markers = dataViewGetApplicationMarkers(view);
- if (!markers || !markers.exif)
- return;
- // Get EXIF tags read/writer
- const tags = dataViewGetExifTags(view, markers.exif.offset);
- if (!tags)
- return;
- // Read the exif orientation marker
- return value === undefined ? tags.read(key) : tags.write(key, value);
- };
- const backup = '__pqina_webapi__';
- var getNativeAPIRef = (API) => (window[backup] ? window[backup][API] : window[API]);
- var noop$1 = (...args) => { };
- const FileReaderDataFormat = {
- ArrayBuffer: 'readAsArrayBuffer',
- };
- var readFile = (file, onprogress = noop$1, options = {}) => new Promise((resolve, reject) => {
- const { dataFormat = FileReaderDataFormat.ArrayBuffer } = options;
- const reader = new (getNativeAPIRef('FileReader'))();
- reader.onload = () => resolve(reader.result);
- reader.onerror = reject;
- reader.onprogress = onprogress;
- reader[dataFormat](file);
- });
- var blobReadSection = async (blob, slice = [0, blob.size], onprogress) => (await readFile(blob.slice(...slice), onprogress));
- var getImageOrientationFromFile = async (file, onprogress) => {
- const head = await blobReadSection(file, [0, 64 * 1024], onprogress);
- return arrayBufferImageExif(head, ORIENTATION_TAG) || 1;
- };
- let result$a = null;
- var isBrowser = () => {
- if (result$a === null)
- result$a = typeof window !== 'undefined' && typeof window.document !== 'undefined';
- return result$a;
- };
- let result$9 = null;
- var canOrientImages = () => new Promise((resolve) => {
- if (result$9 === null) {
- // 2x1 pixel image 90CW rotated with orientation EXIF header
- const testSrc = 'data:image/jpg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4QA6RXhpZgAATU0AKgAAAAgAAwESAAMAAAABAAYAAAEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAD/2wBDAP//////////////////////////////////////////////////////////////////////////////////////wAALCAABAAIBASIA/8QAJgABAAAAAAAAAAAAAAAAAAAAAxABAAAAAAAAAAAAAAAAAAAAAP/aAAgBAQAAPwBH/9k=';
- let testImage = isBrowser() ? new Image() : {};
- testImage.onload = () => {
- // should correct orientation if is presented in landscape,
- // in which case the browser doesn't autocorrect
- result$9 = testImage.naturalWidth === 1;
- testImage = undefined;
- resolve(result$9);
- };
- testImage.src = testSrc;
- return;
- }
- return resolve(result$9);
- });
- var canvasToImageData = (canvas) => {
- const imageData = canvas
- .getContext('2d')
- .getImageData(0, 0, canvas.width, canvas.height);
- return imageData;
- };
- var h = (name, attributes, children = []) => {
- const el = document.createElement(name);
- // @ts-ignore
- const descriptors = Object.getOwnPropertyDescriptors(el.__proto__);
- for (const key in attributes) {
- if (key === 'style') {
- el.style.cssText = attributes[key];
- }
- else if ((descriptors[key] && descriptors[key].set) ||
- /textContent|innerHTML/.test(key) ||
- typeof attributes[key] === 'function') {
- el[key] = attributes[key];
- }
- else {
- el.setAttribute(key, attributes[key]);
- }
- }
- children.forEach((child) => el.appendChild(child));
- return el;
- };
- const MATRICES = {
- 1: () => [1, 0, 0, 1, 0, 0],
- 2: (width) => [-1, 0, 0, 1, width, 0],
- 3: (width, height) => [-1, 0, 0, -1, width, height],
- 4: (width, height) => [1, 0, 0, -1, 0, height],
- 5: () => [0, 1, 1, 0, 0, 0],
- 6: (width, height) => [0, 1, -1, 0, height, 0],
- 7: (width, height) => [0, -1, -1, 0, height, width],
- 8: (width) => [0, -1, 1, 0, 0, width],
- };
- var getImageOrientationMatrix = (width, height, orientation = -1) => {
- if (orientation === -1)
- orientation = 1;
- return MATRICES[orientation](width, height);
- };
- var releaseCanvas = (canvas) => {
- canvas.width = 1;
- canvas.height = 1;
- const ctx = canvas.getContext('2d');
- ctx && ctx.clearRect(0, 0, 1, 1);
- };
- var isImageData = (obj) => 'data' in obj;
- var imageDataToCanvas = async (imageData, orientation = 1) => {
- const [width, height] = (await canOrientImages()) || orientation < 5
- ? [imageData.width, imageData.height]
- : [imageData.height, imageData.width];
- const canvas = h('canvas', { width, height });
- const ctx = canvas.getContext('2d');
- // transform image data ojects into in memory canvas elements so we can transform them (putImageData isn't affect by transforms)
- if (isImageData(imageData) && !(await canOrientImages()) && orientation > 1) {
- const inMemoryCanvas = h('canvas', {
- width: imageData.width,
- height: imageData.height,
- });
- const ctx = inMemoryCanvas.getContext('2d');
- ctx.putImageData(imageData, 0, 0);
- imageData = inMemoryCanvas;
- }
- // get base transformation matrix
- if (!(await canOrientImages()) && orientation > 1) {
- ctx.transform.apply(ctx, getImageOrientationMatrix(imageData.width, imageData.height, orientation));
- }
- // can't test for instanceof ImageBitmap as Safari doesn't support it
- // if still imageData object by this point, we'll use put
- if (isImageData(imageData)) {
- ctx.putImageData(imageData, 0, 0);
- }
- else {
- ctx.drawImage(imageData, 0, 0);
- }
- // if image data is of type canvas, clean it up
- if (imageData instanceof HTMLCanvasElement)
- releaseCanvas(imageData);
- return canvas;
- };
- var orientImageData = async (imageData, orientation = 1) => {
- if (orientation === 1)
- return imageData;
- // correct image data for when the browser does not correctly read exif orientation headers
- if (!(await canOrientImages()))
- return canvasToImageData(await imageDataToCanvas(imageData, orientation));
- return imageData;
- };
- var isObject = (v) => typeof v === 'object';
- const copy = (val) => (isObject(val) ? deepCopy(val) : val);
- const deepCopy = (src) => {
- let dst;
- if (Array.isArray(src)) {
- dst = [];
- src.forEach((val, i) => {
- dst[i] = copy(val);
- });
- }
- else {
- dst = {};
- Object.keys(src).forEach((key) => {
- const val = src[key];
- dst[key] = copy(val);
- });
- }
- return dst;
- };
- var isString = (v) => typeof v === 'string';
- var imageToCanvas = (image, canvasMemoryLimit) => {
- // if these are 0 it's possible that we're trying to convert an SVG that doesn't have width or height attributes
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1328124
- let canvasWidth = image.naturalWidth;
- let canvasHeight = image.naturalHeight;
- // determine if requires more memory than limit, if so limit target size
- const requiredCanvasMemory = canvasWidth * canvasHeight;
- if (canvasMemoryLimit && requiredCanvasMemory > canvasMemoryLimit) {
- const canvasScalar = Math.sqrt(canvasMemoryLimit) / Math.sqrt(requiredCanvasMemory);
- canvasWidth = Math.floor(canvasWidth * canvasScalar);
- canvasHeight = Math.floor(canvasHeight * canvasScalar);
- }
- // create new canvas element
- const canvas = h('canvas');
- canvas.width = canvasWidth;
- canvas.height = canvasHeight;
- const ctx = canvas.getContext('2d');
- ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight);
- return canvas;
- };
- // turns image into canvas only after it's fully loaded
- var imageToCanvasSafe = (image, canvasMemoryLimit) => new Promise((resolve, reject) => {
- const ready = () => resolve(imageToCanvas(image, canvasMemoryLimit));
- if (image.complete && image.width) {
- // need to test for image.width, on ie11 it will be 0 for object urls
- ready();
- }
- else {
- image.onload = ready;
- image.onerror = reject;
- }
- });
- var blobToCanvas = async (imageBlob, canvasMemoryLimit) => {
- const imageElement = h('img', { src: URL.createObjectURL(imageBlob) });
- const canvas = await imageToCanvasSafe(imageElement, canvasMemoryLimit);
- URL.revokeObjectURL(imageElement.src);
- return canvas;
- };
- var canCreateImageBitmap = () => 'createImageBitmap' in window;
- var canCreateOffscreenCanvas = () => 'OffscreenCanvas' in window;
- var isSVGFile = (blob) => /svg/.test(blob.type);
- var getUniqueId = () => Math.random()
- .toString(36)
- .substr(2, 9);
- var functionToBlob = (fn) => new Blob(['(', typeof fn === 'function' ? fn.toString() : fn, ')()'], {
- type: 'application/javascript',
- });
- const wrapFunction = (fn) => `function () {self.onmessage = function (message) {(${fn.toString()}).apply(null, message.data.content.concat([function (err, response) {
- response = response || {};
- const transfer = 'data' in response ? [response.data.buffer] : 'width' in response ? [response] : [];
- return self.postMessage({ id: message.data.id, content: response, error: err }, transfer);
- }]))}}`;
- const workerPool = new Map();
- var thread = (fn, args, transferList) => new Promise((resolve, reject) => {
- let workerKey = fn.toString();
- let pooledWorker = workerPool.get(workerKey);
- if (!pooledWorker) {
- // create worker for this function
- const workerFn = wrapFunction(fn);
- // create a new web worker
- const url = URL.createObjectURL(functionToBlob(workerFn));
- const messages = new Map();
- const worker = new Worker(url);
- // create a pooled worker, this object will contain the worker and active messages
- pooledWorker = {
- url,
- worker,
- messages,
- terminate: () => {
- pooledWorker.worker.terminate();
- URL.revokeObjectURL(url);
- },
- };
- // handle received messages
- worker.onmessage = function (e) {
- // should receive message id and message
- const { id, content, error } = e.data;
- // message route no longer valid
- if (!messages.has(id))
- return;
- // get related thread and resolve with returned content
- const message = messages.get(id);
- // remove thread from threads cache
- messages.delete(id);
- // resolve or reject message based on response from worker
- error != null ? message.reject(error) : message.resolve(content);
- };
- // pool this worker
- workerPool.set(workerKey, pooledWorker);
- }
- // we need a way to remember this message so we generate a unique id and use that as a key for this request, that way we can link the response back to request in the pooledWorker.onmessage handler
- const messageId = getUniqueId();
- pooledWorker.messages.set(messageId, { resolve, reject });
- // use pooled worker and await response
- pooledWorker.worker.postMessage({ id: messageId, content: args }, transferList);
- });
- var blobToImageData = async (imageBlob, canvasMemoryLimit) => {
- let imageData;
- // if can use OffscreenCanvas let's go for it as it will mean we can run this operation on a separate thread
- if (canCreateImageBitmap() && !isSVGFile(imageBlob) && canCreateOffscreenCanvas()) {
- try {
- imageData = await thread((file, canvasMemoryLimit, done) => {
- createImageBitmap(file)
- .then((bitmap) => {
- let canvasWidth = bitmap.width;
- let canvasHeight = bitmap.height;
- // determine if requires more memory than limit, if so limit target size
- const requiredCanvasMemory = canvasWidth * canvasHeight;
- if (canvasMemoryLimit && requiredCanvasMemory > canvasMemoryLimit) {
- const canvasScalar = Math.sqrt(canvasMemoryLimit) / Math.sqrt(requiredCanvasMemory);
- canvasWidth = Math.floor(canvasWidth * canvasScalar);
- canvasHeight = Math.floor(canvasHeight * canvasScalar);
- }
- const canvas = new OffscreenCanvas(canvasWidth, canvasHeight);
- const ctx = canvas.getContext('2d');
- ctx.drawImage(bitmap, 0, 0, canvasWidth, canvasHeight);
- const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
- done(null, imageData);
- })
- .catch((err) => {
- // fail silently
- done(err);
- });
- }, [imageBlob, canvasMemoryLimit]);
- }
- catch (err) {
- // fails silently on purpose, we'll try to turn the blob into image data in the main thread
- // console.error(err);
- }
- }
- // use main thread to generate ImageData
- if (!imageData || !imageData.width) {
- const canvas = await blobToCanvas(imageBlob, canvasMemoryLimit);
- imageData = canvasToImageData(canvas);
- releaseCanvas(canvas);
- }
- return imageData;
- };
- var canvasToBlob = (canvas, mimeType = undefined, quality = undefined) => new Promise((resolve, reject) => {
- try {
- canvas.toBlob((blob) => {
- resolve(blob);
- }, mimeType, quality);
- }
- catch (err) {
- reject(err);
- }
- });
- var imageDataToBlob = async (imageData, mimeType, quality) => {
- const canvas = await imageDataToCanvas(imageData);
- const blob = await canvasToBlob(canvas, mimeType, quality);
- releaseCanvas(canvas);
- return blob;
- };
- var blobWriteSection = (blob, section, slice = [0, blob.size]) => {
- if (!section)
- return blob;
- return new Blob([section, blob.slice(...slice)], { type: blob.type });
- };
- var getExtensionFromMimeType = (mimeType) => (mimeType.match(/\/([a-z]+)/) || [])[1];
- var getFilenameWithoutExtension = (name) => name.substr(0, name.lastIndexOf('.')) || name;
- var getExtensionFromFilename = (filename) => filename.split('.').pop();
- const ImageExtensionsRegex = /avif|bmp|gif|jpg|jpeg|jpe|jif|jfif|png|svg|tiff|webp/;
- /*
- Support image mime types
- - image/webp
- - image/gif
- - image/avif
- - image/jpeg
- - image/png
- - image/bmp
- - image/svg+xml
- */
- var getMimeTypeFromExtension = (ext) => {
- // empty string returned if extension not found
- if (!ImageExtensionsRegex.test(ext))
- return '';
- // return MimeType for this extension
- return 'image/' + (/jfif|jif|jpe|jpg/.test(ext) ? 'jpeg' : ext === 'svg' ? 'svg+xml' : ext);
- };
- var getMimeTypeFromFilename = (name) => name && getMimeTypeFromExtension(getExtensionFromFilename(name).toLowerCase());
- var matchFilenameToMimeType = (filename, mimeType) => {
- // get the mime type that matches this extension
- const fileMimeType = getMimeTypeFromFilename(filename);
- // test if type already matches current mime type, no need to change name
- if (fileMimeType === mimeType)
- return filename;
- // get the extension for this mimetype (gets all characters after the "image/" part)
- // if mimeType doesn't yield an extension, use the fileMimeType
- const targetMimeTypeExtension = getExtensionFromMimeType(mimeType) || fileMimeType;
- return `${getFilenameWithoutExtension(filename)}.${targetMimeTypeExtension}`;
- };
- var blobToFile = (blob, filename, mimetype) => {
- const lastModified = new Date().getTime();
- const blobHasMimeType = blob.type.length && !/null|text/.test(blob.type);
- const blobMimeType = blobHasMimeType ? blob.type : mimetype;
- const name = matchFilenameToMimeType(filename, blobMimeType);
- try {
- return new (getNativeAPIRef('File'))([blob], name, {
- lastModified,
- type: blobHasMimeType ? blob.type : blobMimeType,
- });
- }
- catch (err) {
- const file = blobHasMimeType ? blob.slice() : blob.slice(0, blob.size, blobMimeType);
- file.lastModified = lastModified;
- file.name = name;
- return file;
- }
- };
- var getAspectRatio = (w, h) => w / h;
- var passthrough = (v) => (v);
- const PI = Math.PI;
- const HALF_PI = Math.PI / 2;
- const QUART_PI = HALF_PI / 2;
- var isRotatedSideways = (a) => {
- const rotationLimited = Math.abs(a) % Math.PI;
- return rotationLimited > QUART_PI && rotationLimited < Math.PI - QUART_PI;
- };
- //
- // generic
- //
- const scale = (value, scalar, pivot) => pivot + (value - pivot) * scalar;
- const ellipseCreateFromRect = (rect) => ({
- x: rect.x + rect.width * 0.5,
- y: rect.y + rect.height * 0.5,
- rx: rect.width * 0.5,
- ry: rect.height * 0.5,
- });
- //
- // vector
- //
- const vectorCreateEmpty = () => vectorCreate(0, 0);
- const vectorCreate = (x, y) => ({ x, y });
- const vectorCreateFromSize = (size) => vectorCreate(size.width, size.height);
- const vectorCreateFromPointerEvent = (e) => vectorCreate(e.pageX, e.pageY);
- const vectorCreateFromPointerEventOffset = (e) => vectorCreate(e.offsetX, e.offsetY);
- const vectorClone = (v) => vectorCreate(v.x, v.y);
- const vectorInvert = (v) => {
- v.x = -v.x;
- v.y = -v.y;
- return v;
- };
- const vectorPerpendicular = (v) => {
- const x = v.x;
- v.x = -v.y;
- v.y = x;
- return v;
- };
- const vectorRotate = (v, radians, pivot = vectorCreateEmpty()) => {
- const cos = Math.cos(radians);
- const sin = Math.sin(radians);
- const tx = v.x - pivot.x;
- const ty = v.y - pivot.y;
- v.x = pivot.x + cos * tx - sin * ty;
- v.y = pivot.y + sin * tx + cos * ty;
- return v;
- };
- const vectorLength = (v) => Math.sqrt(v.x * v.x + v.y * v.y);
- const vectorNormalize = (v) => {
- const length = Math.sqrt(v.x * v.x + v.y * v.y);
- if (length === 0)
- return vectorCreateEmpty();
- v.x /= length;
- v.y /= length;
- return v;
- };
- const vectorAngle = (v) => Math.atan2(v.y, v.x);
- const vectorAngleBetween = (a, b) => Math.atan2(b.y - a.y, b.x - a.x);
- const vectorEqual = (a, b) => a.x === b.x && a.y === b.y;
- const vectorApply = (v, fn) => {
- v.x = fn(v.x);
- v.y = fn(v.y);
- return v;
- };
- const vectorAdd = (a, b) => {
- a.x += b.x;
- a.y += b.y;
- return a;
- };
- const vectorSubtract = (a, b) => {
- a.x -= b.x;
- a.y -= b.y;
- return a;
- };
- const vectorMultiply = (v, f) => {
- v.x *= f;
- v.y *= f;
- return v;
- };
- const vectorDot = (a, b) => a.x * b.x + a.y * b.y;
- const vectorDistanceSquared = (a, b = vectorCreateEmpty()) => {
- const x = a.x - b.x;
- const y = a.y - b.y;
- return x * x + y * y;
- };
- const vectorDistance = (a, b = vectorCreateEmpty()) => Math.sqrt(vectorDistanceSquared(a, b));
- const vectorCenter = (v) => {
- let x = 0;
- let y = 0;
- v.forEach((v) => {
- x += v.x;
- y += v.y;
- });
- return vectorCreate(x / v.length, y / v.length);
- };
- const vectorsFlip = (points, flipX, flipY, cx, cy) => {
- points.forEach((point) => {
- point.x = flipX ? cx - (point.x - cx) : point.x;
- point.y = flipY ? cy - (point.y - cy) : point.y;
- });
- return points;
- };
- const vectorsRotate = (points, angle, cx, cy) => {
- const s = Math.sin(angle);
- const c = Math.cos(angle);
- points.forEach((p) => {
- p.x -= cx;
- p.y -= cy;
- const rx = p.x * c - p.y * s;
- const ry = p.x * s + p.y * c;
- p.x = cx + rx;
- p.y = cy + ry;
- });
- return points;
- };
- //
- // size
- //
- const toSize = (width, height) => ({ width, height });
- const sizeClone = (size) => toSize(size.width, size.height);
- const sizeCreateFromAny = (obj) => toSize(obj.width, obj.height);
- const sizeCreateFromRect = (r) => toSize(r.width, r.height);
- const sizeCreateFromArray = (a) => toSize(a[0], a[1]);
- const sizeCreateFromImageNaturalSize = (image) => toSize(image.naturalWidth, image.naturalHeight);
- const sizeCreateFromElement = (element) => {
- if (/img/i.test(element.nodeName)) {
- return sizeCreateFromImageNaturalSize(element);
- }
- return sizeCreateFromAny(element);
- };
- const sizeCreate = (width, height) => toSize(width, height);
- const sizeEqual = (a, b, format = passthrough) => format(a.width) === format(b.width) && format(a.height) === format(b.height);
- const sizeScale = (size, scalar) => {
- size.width *= scalar;
- size.height *= scalar;
- return size;
- };
- const sizeCenter = (size) => vectorCreate(size.width * 0.5, size.height * 0.5);
- const sizeRotate = (size, radians) => {
- const r = Math.abs(radians);
- const cos = Math.cos(r);
- const sin = Math.sin(r);
- const w = cos * size.width + sin * size.height;
- const h = sin * size.width + cos * size.height;
- size.width = w;
- size.height = h;
- return size;
- };
- const sizeTurn = (size, radians) => {
- const w = size.width;
- const h = size.height;
- if (isRotatedSideways(radians)) {
- size.width = h;
- size.height = w;
- }
- return size;
- };
- const sizeContains = (a, b) => a.width >= b.width && a.height >= b.height;
- const sizeApply = (size, fn) => {
- size.width = fn(size.width);
- size.height = fn(size.height);
- return size;
- };
- const sizeHypotenuse = (size) => Math.sqrt(size.width * size.width + size.height * size.height);
- const sizeMin = (a, b) => sizeCreate(Math.min(a.width, b.width), Math.min(a.height, b.height));
- //
- // line
- //
- const lineCreate = (start, end) => ({ start, end });
- const lineClone = (line) => lineCreate(vectorClone(line.start), vectorClone(line.end));
- const lineExtend = (line, amount) => {
- if (amount === 0)
- return line;
- const v = vectorCreate(line.start.x - line.end.x, line.start.y - line.end.y);
- const n = vectorNormalize(v);
- const m = vectorMultiply(n, amount);
- line.start.x += m.x;
- line.start.y += m.y;
- line.end.x -= m.x;
- line.end.y -= m.y;
- return line;
- };
- const lineMultiply = (line, amount) => {
- if (amount === 0)
- return line;
- const v = vectorCreate(line.start.x - line.end.x, line.start.y - line.end.y);
- const n = vectorNormalize(v);
- const m = vectorMultiply(n, amount);
- line.end.x += m.x;
- line.end.y += m.y;
- return line;
- };
- const lineExtrude = ({ start, end }, amount) => {
- if (amount === 0)
- return [
- vectorCreate(start.x, start.y),
- vectorCreate(start.x, start.y),
- vectorCreate(end.x, end.y),
- vectorCreate(end.x, end.y),
- ];
- const a = Math.atan2(end.y - start.y, end.x - start.x);
- const sina = Math.sin(a) * amount;
- const cosa = Math.cos(a) * amount;
- return [
- vectorCreate(sina + start.x, -cosa + start.y),
- vectorCreate(-sina + start.x, cosa + start.y),
- vectorCreate(-sina + end.x, cosa + end.y),
- vectorCreate(sina + end.x, -cosa + end.y),
- ];
- };
- //
- // rect
- //
- const CornerSigns = [
- vectorCreate(-1, -1),
- vectorCreate(-1, 1),
- vectorCreate(1, 1),
- vectorCreate(1, -1),
- ];
- const toRect = (x, y, width, height) => ({
- x,
- y,
- width,
- height,
- });
- const rectClone = (rect) => toRect(rect.x, rect.y, rect.width, rect.height);
- const rectCreateEmpty = () => toRect(0, 0, 0, 0);
- const rectCreateFromDimensions = (width, height) => toRect(0, 0, width, height);
- const rectCreateFromSize = (size) => toRect(0, 0, size.width, size.height);
- const rectCreateFromAny = (obj) => toRect(obj.x || 0, obj.y || 0, obj.width || 0, obj.height || 0);
- const rectCreateFromPoints = (...args) => {
- const pts = Array.isArray(args[0]) ? args[0] : args;
- let xMin = pts[0].x;
- let xMax = pts[0].x;
- let yMin = pts[0].y;
- let yMax = pts[0].y;
- pts.forEach((point) => {
- xMin = Math.min(xMin, point.x);
- xMax = Math.max(xMax, point.x);
- yMin = Math.min(yMin, point.y);
- yMax = Math.max(yMax, point.y);
- });
- return toRect(xMin, yMin, xMax - xMin, yMax - yMin);
- };
- const rectCreateFromEllipse = (ellipse) => rectCreate(ellipse.x - ellipse.rx, ellipse.y - ellipse.ry, ellipse.rx * 2, ellipse.ry * 2);
- const rectCreateWithCenter = (center, size) => toRect(center.x - size.width * 0.5, center.y - size.height * 0.5, size.width, size.height);
- const rectCreate = (x, y, width, height) => toRect(x, y, width, height);
- const rectCenter = (rect) => vectorCreate(rect.x + rect.width * 0.5, rect.y + rect.height * 0.5);
- const rectTranslate = (rect, t) => {
- rect.x += t.x;
- rect.y += t.y;
- return rect;
- };
- const rectScale = (rect, scalar, pivot) => {
- pivot = pivot || rectCenter(rect);
- rect.x = scalar * (rect.x - pivot.x) + pivot.x;
- rect.y = scalar * (rect.y - pivot.y) + pivot.y;
- rect.width = scalar * rect.width;
- rect.height = scalar * rect.height;
- return rect;
- };
- const rectMultiply = (rect, factor) => {
- rect.x *= factor;
- rect.y *= factor;
- rect.width *= factor;
- rect.height *= factor;
- return rect;
- };
- const rectDivide = (rect, factor) => {
- rect.x /= factor;
- rect.y /= factor;
- rect.width /= factor;
- rect.height /= factor;
- return rect;
- };
- const rectSubtract = (a, b) => {
- a.x -= b.x;
- a.y -= b.y;
- a.width -= b.width;
- a.height -= b.height;
- return a;
- };
- const rectAdd = (a, b) => {
- a.x += b.x;
- a.y += b.y;
- a.width += b.width;
- a.height += b.height;
- return a;
- };
- const rectEqual = (a, b, format = passthrough) => format(a.x) === format(b.x) &&
- format(a.y) === format(b.y) &&
- format(a.width) === format(b.width) &&
- format(a.height) === format(b.height);
- const rectAspectRatio = (rect) => getAspectRatio(rect.width, rect.height);
- const rectUpdate = (rect, x, y, width, height) => {
- rect.x = x;
- rect.y = y;
- rect.width = width;
- rect.height = height;
- return rect;
- };
- const rectUpdateWithRect = (a, b) => {
- a.x = b.x;
- a.y = b.y;
- a.width = b.width;
- a.height = b.height;
- return a;
- };
- const rectRotate = (rect, radians, pivot) => {
- if (!pivot)
- pivot = rectCenter(rect);
- return rectGetCorners(rect).map((vertex) => vectorRotate(vertex, radians, pivot));
- };
- const rectCenterRect = (a, b) => toRect(a.width * 0.5 - b.width * 0.5, a.height * 0.5 - b.height * 0.5, b.width, b.height);
- const rectContainsPoint = (rect, point) => {
- if (point.x < rect.x)
- return false;
- if (point.y < rect.y)
- return false;
- if (point.x > rect.x + rect.width)
- return false;
- if (point.y > rect.y + rect.height)
- return false;
- return true;
- };
- const rectCoverRect = (rect, aspectRatio, offset = vectorCreateEmpty()) => {
- if (rect.width === 0 || rect.height === 0)
- return rectCreateEmpty();
- const inputAspectRatio = rectAspectRatio(rect);
- if (!aspectRatio)
- aspectRatio = inputAspectRatio;
- let width = rect.width;
- let height = rect.height;
- if (aspectRatio > inputAspectRatio) {
- // height remains the same, width is expanded
- width = height * aspectRatio;
- }
- else {
- // width remains the same, height is expanded
- height = width / aspectRatio;
- }
- return toRect(offset.x + (rect.width - width) * 0.5, offset.y + (rect.height - height) * 0.5, width, height);
- };
- const rectContainRect = (rect, aspectRatio = rectAspectRatio(rect), offset = vectorCreateEmpty()) => {
- if (rect.width === 0 || rect.height === 0)
- return rectCreateEmpty();
- let width = rect.width;
- let height = width / aspectRatio;
- if (height > rect.height) {
- height = rect.height;
- width = height * aspectRatio;
- }
- return toRect(offset.x + (rect.width - width) * 0.5, offset.y + (rect.height - height) * 0.5, width, height);
- };
- const rectToBounds = (rect) => [
- Math.min(rect.y, rect.y + rect.height),
- Math.max(rect.x, rect.x + rect.width),
- Math.max(rect.y, rect.y + rect.height),
- Math.min(rect.x, rect.x + rect.width),
- ];
- const rectGetCorners = (rect) => [
- vectorCreate(rect.x, rect.y),
- vectorCreate(rect.x + rect.width, rect.y),
- vectorCreate(rect.x + rect.width, rect.y + rect.height),
- vectorCreate(rect.x, rect.y + rect.height),
- ];
- const rectApply = (rect, fn) => {
- if (!rect)
- return;
- rect.x = fn(rect.x);
- rect.y = fn(rect.y);
- rect.width = fn(rect.width);
- rect.height = fn(rect.height);
- return rect;
- };
- const rectApplyPerspective = (rect, perspective, pivot = rectCenter(rect)) => rectGetCorners(rect).map((corner, index) => {
- const sign = CornerSigns[index];
- return vectorCreate(scale(corner.x, 1.0 + sign.x * perspective.x, pivot.x), scale(corner.y, 1.0 + sign.y * perspective.y, pivot.y));
- });
- const rectNormalizeOffset = (rect) => {
- rect.x = 0;
- rect.y = 0;
- return rect;
- };
- const convexPolyCentroid = (vertices) => {
- const first = vertices[0];
- const last = vertices[vertices.length - 1];
- // make sure is closed loop
- vertices = vectorEqual(first, last) ? vertices : [...vertices, first];
- let twiceArea = 0;
- let i = 0;
- let x = 0;
- let y = 0;
- let fx = first.x;
- let fy = first.y;
- let a;
- let b;
- let f;
- const l = vertices.length;
- for (; i < l; i++) {
- // current vertex
- a = vertices[i];
- // next vertex
- b = vertices[i + 1 > l - 1 ? 0 : i + 1];
- f = (a.y - fy) * (b.x - fx) - (b.y - fy) * (a.x - fx);
- twiceArea += f;
- x += (a.x + b.x - 2 * fx) * f;
- y += (a.y + b.y - 2 * fy) * f;
- }
- f = twiceArea * 3;
- return vectorCreate(fx + x / f, fy + y / f);
- };
- const lineLineIntersection = (a, b) => getLineLineIntersectionPoint(a.start, a.end, b.start, b.end);
- const getLineLineIntersectionPoint = (a, b, c, d) => {
- const denominator = (d.y - c.y) * (b.x - a.x) - (d.x - c.x) * (b.y - a.y);
- // lines are parallel
- if (denominator === 0)
- return undefined;
- const uA = ((d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x)) / denominator;
- const uB = ((b.x - a.x) * (a.y - c.y) - (b.y - a.y) * (a.x - c.x)) / denominator;
- // intersection is not on the line itself
- if (uA < 0 || uA > 1 || uB < 0 || uB > 1)
- return undefined;
- // return intersection point
- return vectorCreate(a.x + uA * (b.x - a.x), a.y + uA * (b.y - a.y));
- };
- // checks if line intersects with one of the lines that can be drawn between the points (in sequence)
- const linePointsIntersection = (line, points) => {
- const l = points.length;
- const intersections = [];
- for (let i = 0; i < l - 1; i++) {
- const intersection = getLineLineIntersectionPoint(line.start, line.end, points[i], points[i + 1]);
- if (!intersection)
- continue;
- intersections.push(intersection);
- }
- return intersections.length ? intersections : undefined;
- };
- // tests if a point is located in a convex polygon
- const pointInPoly = (point, vertices) => {
- let i;
- let a;
- let b;
- let aX;
- let aY;
- let bX;
- let bY;
- let edgeX;
- let edgeY;
- let d;
- const l = vertices.length;
- for (i = 0; i < l; i++) {
- // current vertex
- a = vertices[i];
- // next vertex
- b = vertices[i + 1 > l - 1 ? 0 : i + 1];
- // translate so that point is the origin of the calculation
- aX = a.x - point.x;
- aY = a.y - point.y;
- bX = b.x - point.x;
- bY = b.y - point.y;
- edgeX = aX - bX;
- edgeY = aY - bY;
- d = edgeX * aY - edgeY * aX;
- // 0 is ON the edge, but we check for -0.00001 to fix floating point errors
- if (d < -0.00001)
- return false;
- }
- return true;
- };
- // first tests if points of a are to be found in b, then does the reverse
- const polyIntersectsWithPoly = (a, b) => !!(a.find((point) => pointInPoly(point, b)) || b.find((point) => pointInPoly(point, a)));
- const quadLines = (vertices) => {
- const arr = [];
- for (let i = 0; i < vertices.length; i++) {
- let next = i + 1;
- if (next === vertices.length)
- next = 0;
- arr.push(lineCreate(vectorClone(vertices[i]), vectorClone(vertices[next])));
- }
- return arr;
- };
- const ellipseToPolygon = (center, rx, ry, rotation = 0, flipX = false, flipY = false, resolution = 12) => {
- const points = [];
- for (let i = 0; i < resolution; i++) {
- points.push(vectorCreate(center.x + rx * Math.cos((i * (Math.PI * 2)) / resolution), center.y + ry * Math.sin((i * (Math.PI * 2)) / resolution)));
- }
- if (flipX || flipY)
- vectorsFlip(points, flipX, flipY, center.x, center.y);
- if (rotation)
- vectorsRotate(points, rotation, center.x, center.y);
- return points;
- };
- var getImageTransformedRect = (imageSize, imageRotation) => {
- const imageRect = rectCreateFromSize(imageSize);
- const imageCenter = rectCenter(imageRect);
- const imageTransformedVertices = rectRotate(imageRect, imageRotation, imageCenter);
- return rectNormalizeOffset(rectCreateFromPoints(imageTransformedVertices));
- };
- var isElement = (v, name) => v instanceof HTMLElement && (name ? new RegExp(`^${name}$`, 'i').test(v.nodeName) : true);
- var isFile = (v) => v instanceof File;
- var canvasToFile = async (canvas, mimeType, quality) => {
- const blob = await canvasToBlob(canvas, mimeType, quality);
- return blobToFile(blob, 'canvas');
- };
- var getFilenameFromURL = (url) => url
- .split('/')
- .pop()
- .split(/\?|\#/)
- .shift();
- let isSafari = null;
- var isSafari$1 = () => {
- if (isSafari === null)
- isSafari = isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
- return isSafari;
- };
- var getImageElementSize = (imageElement) => new Promise((resolve, reject) => {
- let shouldAutoRemove = false;
- // test if image is attached to DOM, if not attached, attach so measurement is correct on Safari
- if (!imageElement.parentNode && isSafari$1()) {
- shouldAutoRemove = true;
- // has width 0 and height 0 to prevent rendering very big SVGs (without width and height) that will for one frame overflow the window and show a scrollbar
- imageElement.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;left:0;top:0;width:0;height:0;`;
- document.body.appendChild(imageElement);
- }
- // start testing size
- const measure = () => {
- const width = imageElement.naturalWidth;
- const height = imageElement.naturalHeight;
- const hasSize = width && height;
- if (!hasSize)
- return;
- // clean up image if was attached for measuring
- if (shouldAutoRemove)
- imageElement.parentNode.removeChild(imageElement);
- clearInterval(intervalId);
- resolve({ width, height });
- };
- imageElement.onerror = (err) => {
- clearInterval(intervalId);
- reject(err);
- };
- const intervalId = setInterval(measure, 1);
- measure();
- });
- var getImageSize = async (image) => {
- // the image element we'll use to load the image
- let imageElement = image;
- // if is not an image element, it must be a valid image source
- if (!imageElement.src) {
- imageElement = new Image();
- imageElement.src = isString(image) ? image : URL.createObjectURL(image);
- }
- let size;
- try {
- size = await getImageElementSize(imageElement);
- }
- finally {
- isFile(image) && URL.revokeObjectURL(imageElement.src);
- }
- return size;
- };
- const awaitComplete = (image) => new Promise((resolve, reject) => {
- if (image.complete)
- return resolve(image);
- image.onload = () => resolve(image);
- image.onerror = reject;
- });
- var imageToFile = async (imageElement) => {
- try {
- const size = await getImageSize(imageElement);
- const image = await awaitComplete(imageElement);
- const canvas = document.createElement('canvas');
- canvas.width = size.width;
- canvas.height = size.height;
- const ctx = canvas.getContext('2d');
- ctx.drawImage(image, 0, 0);
- const blob = await canvasToBlob(canvas);
- return blobToFile(blob, getFilenameFromURL(image.src));
- }
- catch (err) {
- throw err;
- }
- };
- var isDataURI = (str) => /^data:/.test(str);
- var createProgressEvent = (loaded = 0, lengthComputable = true) => new (getNativeAPIRef('ProgressEvent'))('progress', {
- loaded: loaded * 100,
- total: 100,
- lengthComputable,
- });
- var isImage = (file) => /^image/.test(file.type);
- var dataURIToFile = async (dataURI, filename = 'data-uri', onprogress = noop$1) => {
- // basic loader, no size info
- onprogress(createProgressEvent(0));
- const res = await fetch(dataURI);
- onprogress(createProgressEvent(0.33));
- const blob = await res.blob();
- let mimeType;
- if (!isImage(blob))
- mimeType = `image/${dataURI.includes(',/9j/') ? 'jpeg' : 'png'}`;
- onprogress(createProgressEvent(0.66));
- const file = blobToFile(blob, filename, mimeType);
- onprogress(createProgressEvent(1));
- return file;
- };
- var getResponseHeader = (xhr, header, parse = (header) => header) => xhr.getAllResponseHeaders().indexOf(header) >= 0
- ? parse(xhr.getResponseHeader(header))
- : undefined;
- var getFilenameFromContentDisposition = (header) => {
- if (!header)
- return null;
- const matches = header.split(/filename=|filename\*=.+''/)
- .splice(1)
- .map(name => name.trim().replace(/^["']|[;"']{0,2}$/g, ''))
- .filter(name => name.length);
- return matches.length ? decodeURI(matches[matches.length - 1]) : null;
- };
- const EditorErrorCode = {
- URL_REQUEST: 'URL_REQUEST',
- DOCTYPE_MISSING: 'DOCTYPE_MISSING',
- };
- class EditorError extends Error {
- constructor(message, code, metadata) {
- super(message);
- this.name = 'EditorError';
- this.code = code;
- this.metadata = metadata;
- }
- }
- var fetchFile = (url, onprogress) => new Promise((resolve, reject) => {
- const handleError = () => reject(new EditorError('Error fetching image', EditorErrorCode.URL_REQUEST, xhr));
- const xhr = new XMLHttpRequest();
- xhr.onprogress = onprogress;
- (xhr.onerror = handleError),
- (xhr.onload = () => {
- if (!xhr.response || xhr.status >= 300 || xhr.status < 200)
- return handleError();
- // we store the response mime type so we can add it to the blob later on, if it's missing (happens on Safari 10)
- const mimetype = getResponseHeader(xhr, 'Content-Type');
- // try to get filename and any file instructions as well
- const filename = getResponseHeader(xhr, 'Content-Disposition', getFilenameFromContentDisposition) || getFilenameFromURL(url);
- // convert to actual file if possible
- resolve(blobToFile(xhr.response, filename, mimetype || getMimeTypeFromFilename(filename)));
- });
- xhr.open('GET', url);
- xhr.responseType = 'blob';
- xhr.send();
- });
- var urlToFile = (url, onprogress) => {
- // use fetch to create blob from data uri
- if (isDataURI(url))
- return dataURIToFile(url, undefined, onprogress);
- // load file from url
- return fetchFile(url, onprogress);
- };
- var isBlob = (v) => v instanceof Blob && !(v instanceof File);
- var srcToFile = async (src, onprogress) => {
- if (isFile(src) || isBlob(src))
- return src;
- else if (isString(src))
- return await urlToFile(src, onprogress);
- else if (isElement(src, 'canvas'))
- return await canvasToFile(src);
- else if (isElement(src, 'img'))
- return await imageToFile(src);
- else {
- throw new EditorError('Invalid image source', 'invalid-image-source');
- }
- };
- let result$8 = null;
- var isMac = () => {
- if (result$8 === null)
- result$8 = isBrowser() && /^mac/i.test(navigator.platform);
- return result$8;
- };
- var isUserAgent = (test) => (isBrowser() ? RegExp(test).test(window.navigator.userAgent) : undefined);
- let result$7 = null;
- var isIOS = () => {
- if (result$7 === null)
- // first part is for iPhones and iPads iOS 12 and below second part is for iPads with iOS 13 and up
- result$7 =
- isBrowser() &&
- (isUserAgent(/iPhone|iPad|iPod/) || (isMac() && navigator.maxTouchPoints >= 1));
- return result$7;
- };
- var orientImageSize = async (size, orientation = 1) => {
- // browser can handle image orientation
- if ((await canOrientImages()) || isIOS())
- return size;
- // no need to correct size
- if (orientation < 5)
- return size;
- // correct image size
- return sizeCreate(size.height, size.width);
- };
- var isJPEG = (file) => /jpeg/.test(file.type);
- var isPlainObject = (obj) => typeof obj == 'object' && obj.constructor == Object;
- var stringify = (value) => (!isPlainObject(value) ? value : JSON.stringify(value));
- var post = (url, dataset, options) => new Promise((resolve, reject) => {
- const { token = {}, beforeSend = noop$1, onprogress = noop$1 } = options;
- token.cancel = () => request.abort();
- const request = new XMLHttpRequest();
- request.upload.onprogress = onprogress;
- request.onload = () => request.status >= 200 && request.status < 300 ? resolve(request) : reject(request);
- request.onerror = () => reject(request);
- request.ontimeout = () => reject(request);
- request.open('POST', encodeURI(url));
- beforeSend(request);
- request.send(dataset.reduce((formData, args) => {
- // @ts-ignore
- formData.append(...args.map(stringify));
- return formData;
- }, new FormData()));
- });
- var ctxRotate = (ctx, rotation = 0, pivot) => {
- if (rotation === 0)
- return ctx;
- ctx.translate(pivot.x, pivot.y);
- ctx.rotate(rotation);
- ctx.translate(-pivot.x, -pivot.y);
- return ctx;
- };
- var ctxTranslate = (ctx, x, y) => {
- ctx.translate(x, y);
- return ctx;
- };
- var ctxScale = (ctx, x, y) => {
- ctx.scale(x, y);
- return ctx;
- };
- var cropImageData = async (imageData, options = {}) => {
- const { flipX, flipY, rotation, crop } = options;
- const imageSize = sizeCreateFromAny(imageData);
- const shouldFlip = flipX || flipY;
- const shouldRotate = !!rotation;
- const cropDefined = crop && (crop.x || crop.y || crop.width || crop.height);
- const cropCoversImage = cropDefined && rectEqual(crop, rectCreateFromSize(imageSize));
- const shouldCrop = cropDefined && !cropCoversImage;
- // skip!
- if (!shouldFlip && !shouldRotate && !shouldCrop)
- return imageData;
- // create drawing context
- let imageDataOut;
- let image = h('canvas', {
- width: imageData.width,
- height: imageData.height,
- });
- image.getContext('2d').putImageData(imageData, 0, 0);
- // flip image data
- if (shouldFlip) {
- const ctx = h('canvas', {
- width: image.width,
- height: image.height,
- }).getContext('2d');
- ctxScale(ctx, flipX ? -1 : 1, flipY ? -1 : 1);
- ctx.drawImage(image, flipX ? -image.width : 0, flipY ? -image.height : 0);
- ctx.restore();
- releaseCanvas(image);
- image = ctx.canvas;
- }
- // rotate image data
- if (shouldRotate) {
- // if shouldRotate is true we also receive a crop rect
- const outputSize = sizeApply(sizeCreateFromRect(rectCreateFromPoints(rectRotate(rectCreateFromAny(image), rotation))), Math.floor);
- const ctx = h('canvas', {
- width: crop.width,
- height: crop.height,
- }).getContext('2d');
- ctxTranslate(ctx, -crop.x, -crop.y);
- ctxRotate(ctx, rotation, sizeCenter(outputSize));
- ctx.drawImage(image, (outputSize.width - image.width) * 0.5, (outputSize.height - image.height) * 0.5);
- ctx.restore();
- releaseCanvas(image);
- image = ctx.canvas;
- }
- // crop image data
- else if (shouldCrop) {
- const ctx = image.getContext('2d');
- imageDataOut = ctx.getImageData(crop.x, crop.y, crop.width, crop.height);
- releaseCanvas(image);
- return imageDataOut;
- }
- // done, return resulting image data
- const ctx = image.getContext('2d');
- imageDataOut = ctx.getImageData(0, 0, image.width, image.height);
- releaseCanvas(image);
- return imageDataOut;
- };
- var resizeTransform = (options, done) => {
- const { imageData, width, height } = options;
- const originWidth = imageData.width;
- const originHeight = imageData.height;
- const targetWidth = Math.round(width);
- const targetHeight = Math.round(height);
- const inputData = imageData.data;
- const outputData = new Uint8ClampedArray(targetWidth * targetHeight * 4);
- const ratioWidth = originWidth / targetWidth;
- const ratioHeight = originHeight / targetHeight;
- const ratioWidthHalf = Math.ceil(ratioWidth * 0.5);
- const ratioHeightHalf = Math.ceil(ratioHeight * 0.5);
- for (let j = 0; j < targetHeight; j++) {
- for (let i = 0; i < targetWidth; i++) {
- const x2 = (i + j * targetWidth) * 4;
- let weight = 0;
- let weights = 0;
- let weightsAlpha = 0;
- let r = 0;
- let g = 0;
- let b = 0;
- let a = 0;
- const centerY = (j + 0.5) * ratioHeight;
- for (let yy = Math.floor(j * ratioHeight); yy < (j + 1) * ratioHeight; yy++) {
- const dy = Math.abs(centerY - (yy + 0.5)) / ratioHeightHalf;
- const centerX = (i + 0.5) * ratioWidth;
- const w0 = dy * dy;
- for (let xx = Math.floor(i * ratioWidth); xx < (i + 1) * ratioWidth; xx++) {
- let dx = Math.abs(centerX - (xx + 0.5)) / ratioWidthHalf;
- const w = Math.sqrt(w0 + dx * dx);
- if (w >= -1 && w <= 1) {
- weight = 2 * w * w * w - 3 * w * w + 1;
- if (weight > 0) {
- dx = 4 * (xx + yy * originWidth);
- const ref = inputData[dx + 3];
- a += weight * ref;
- weightsAlpha += weight;
- if (ref < 255) {
- weight = (weight * ref) / 250;
- }
- r += weight * inputData[dx];
- g += weight * inputData[dx + 1];
- b += weight * inputData[dx + 2];
- weights += weight;
- }
- }
- }
- }
- outputData[x2] = r / weights;
- outputData[x2 + 1] = g / weights;
- outputData[x2 + 2] = b / weights;
- outputData[x2 + 3] = a / weightsAlpha;
- }
- }
- done(null, {
- data: outputData,
- width: targetWidth,
- height: targetHeight,
- });
- };
- var imageDataObjectToImageData = (obj) => {
- if (obj instanceof ImageData) {
- return obj;
- }
- let imageData;
- try {
- imageData = new ImageData(obj.width, obj.height);
- }
- catch (err) {
- // IE + Old EDGE (tested on 12)
- const canvas = h('canvas');
- imageData = canvas.getContext('2d').createImageData(obj.width, obj.height);
- }
- imageData.data.set(obj.data);
- return imageData;
- };
- var resizeImageData = async (imageData, options = {}) => {
- const { width, height, fit, upscale } = options;
- // no need to rescale
- if (!width && !height)
- return imageData;
- let targetWidth = width;
- let targetHeight = height;
- if (!width) {
- targetWidth = height;
- }
- else if (!height) {
- targetHeight = width;
- }
- if (fit !== 'force') {
- let scalarWidth = targetWidth / imageData.width;
- let scalarHeight = targetHeight / imageData.height;
- let scalar = 1;
- if (fit === 'cover') {
- scalar = Math.max(scalarWidth, scalarHeight);
- }
- else if (fit === 'contain') {
- scalar = Math.min(scalarWidth, scalarHeight);
- }
- // if image is too small, exit here with original image
- if (scalar > 1 && upscale === false)
- return imageData;
- targetWidth = Math.round(imageData.width * scalar);
- targetHeight = Math.round(imageData.height * scalar);
- }
- // no need to resize?
- if (imageData.width === targetWidth && imageData.height === targetHeight)
- return imageData;
- // let's resize!
- imageData = await thread(resizeTransform, [{ imageData: imageData, width: targetWidth, height: targetHeight }], [imageData.data.buffer]);
- // the resizer returns a plain object, not an actual image data object, lets create one
- return imageDataObjectToImageData(imageData);
- };
- var colorEffect = (options, done) => {
- const { imageData, matrix } = options;
- if (!matrix)
- return done(null, imageData);
- const outputData = new Uint8ClampedArray(imageData.width * imageData.height * 4);
- const data = imageData.data;
- const l = data.length;
- const m11 = matrix[0];
- const m12 = matrix[1];
- const m13 = matrix[2];
- const m14 = matrix[3];
- const m15 = matrix[4];
- const m21 = matrix[5];
- const m22 = matrix[6];
- const m23 = matrix[7];
- const m24 = matrix[8];
- const m25 = matrix[9];
- const m31 = matrix[10];
- const m32 = matrix[11];
- const m33 = matrix[12];
- const m34 = matrix[13];
- const m35 = matrix[14];
- const m41 = matrix[15];
- const m42 = matrix[16];
- const m43 = matrix[17];
- const m44 = matrix[18];
- const m45 = matrix[19];
- let index = 0;
- let r = 0.0;
- let g = 0.0;
- let b = 0.0;
- let a = 0.0;
- let mr = 0.0;
- let mg = 0.0;
- let mb = 0.0;
- let ma = 0.0;
- let or = 0.0;
- let og = 0.0;
- let ob = 0.0;
- for (; index < l; index += 4) {
- r = data[index] / 255;
- g = data[index + 1] / 255;
- b = data[index + 2] / 255;
- a = data[index + 3] / 255;
- mr = r * m11 + g * m12 + b * m13 + a * m14 + m15;
- mg = r * m21 + g * m22 + b * m23 + a * m24 + m25;
- mb = r * m31 + g * m32 + b * m33 + a * m34 + m35;
- ma = r * m41 + g * m42 + b * m43 + a * m44 + m45;
- or = Math.max(0, mr * ma) + (1.0 - ma);
- og = Math.max(0, mg * ma) + (1.0 - ma);
- ob = Math.max(0, mb * ma) + (1.0 - ma);
- outputData[index] = Math.max(0.0, Math.min(1.0, or)) * 255;
- outputData[index + 1] = Math.max(0.0, Math.min(1.0, og)) * 255;
- outputData[index + 2] = Math.max(0.0, Math.min(1.0, ob)) * 255;
- outputData[index + 3] = a * 255;
- }
- done(null, {
- data: outputData,
- width: imageData.width,
- height: imageData.height,
- });
- };
- var convolutionEffect = (options, done) => {
- const { imageData, matrix } = options;
- if (!matrix)
- return done(null, imageData);
- // calculate kernel weight
- let kernelWeight = matrix.reduce((prev, curr) => prev + curr);
- kernelWeight = kernelWeight <= 0 ? 1 : kernelWeight;
- // input info
- const inputWidth = imageData.width;
- const inputHeight = imageData.height;
- const inputData = imageData.data;
- let i = 0;
- let x = 0;
- let y = 0;
- const side = Math.round(Math.sqrt(matrix.length));
- const sideHalf = Math.floor(side / 2);
- let r = 0, g = 0, b = 0, a = 0, cx = 0, cy = 0, scy = 0, scx = 0, srcOff = 0, weight = 0;
- const outputData = new Uint8ClampedArray(inputWidth * inputHeight * 4);
- for (y = 0; y < inputHeight; y++) {
- for (x = 0; x < inputWidth; x++) {
- // calculate the weighed sum of the source image pixels that
- // fall under the convolution matrix
- r = 0;
- g = 0;
- b = 0;
- a = 0;
- for (cy = 0; cy < side; cy++) {
- for (cx = 0; cx < side; cx++) {
- scy = y + cy - sideHalf;
- scx = x + cx - sideHalf;
- if (scy < 0) {
- scy = inputHeight - 1;
- }
- if (scy >= inputHeight) {
- scy = 0;
- }
- if (scx < 0) {
- scx = inputWidth - 1;
- }
- if (scx >= inputWidth) {
- scx = 0;
- }
- srcOff = (scy * inputWidth + scx) * 4;
- weight = matrix[cy * side + cx];
- r += inputData[srcOff] * weight;
- g += inputData[srcOff + 1] * weight;
- b += inputData[srcOff + 2] * weight;
- a += inputData[srcOff + 3] * weight;
- }
- }
- outputData[i] = r / kernelWeight;
- outputData[i + 1] = g / kernelWeight;
- outputData[i + 2] = b / kernelWeight;
- outputData[i + 3] = a / kernelWeight;
- i += 4;
- }
- }
- done(null, {
- data: outputData,
- width: inputWidth,
- height: inputHeight,
- });
- };
- var vignetteEffect = (options, done) => {
- let { imageData, strength } = options;
- if (!strength)
- return done(null, imageData);
- const outputData = new Uint8ClampedArray(imageData.width * imageData.height * 4);
- const inputWidth = imageData.width;
- const inputHeight = imageData.height;
- const inputData = imageData.data;
- const dist = (x, y) => {
- dx = x - cx;
- dy = y - cy;
- return Math.sqrt(dx * dx + dy * dy);
- };
- let x = 0;
- let y = 0;
- let cx = inputWidth * 0.5;
- let cy = inputHeight * 0.5;
- let dx;
- let dy;
- let dm = dist(0, 0);
- let fr, fg, fb;
- let br, bg, bb, ba;
- let fa;
- let ca;
- const blend = (index, input, output, alpha) => {
- br = input[index] / 255;
- bg = input[index + 1] / 255;
- bb = input[index + 2] / 255;
- ba = input[index + 3] / 255;
- fa = 1.0 - alpha;
- ca = fa * ba + alpha;
- output[index] = ((fa * ba * br + alpha * fr) / ca) * 255;
- output[index + 1] = ((fa * ba * bg + alpha * fg) / ca) * 255;
- output[index + 2] = ((fa * ba * bb + alpha * fb) / ca) * 255;
- output[index + 3] = ca * 255;
- };
- if (strength > 0) {
- fr = 0;
- fg = 0;
- fb = 0;
- }
- else {
- strength = Math.abs(strength);
- fr = 1;
- fg = 1;
- fb = 1;
- }
- for (y = 0; y < inputHeight; y++) {
- for (x = 0; x < inputWidth; x++) {
- blend(
- // index
- (x + y * inputWidth) * 4,
- // data in
- inputData,
- // data out
- outputData,
- // opacity
- (dist(x, y) * strength) / dm);
- }
- }
- done(null, {
- data: outputData,
- width: imageData.width,
- height: imageData.height,
- });
- };
- var noiseEffect = (options, done) => {
- const { imageData, level, monochrome = false } = options;
- if (!level)
- return done(null, imageData);
- const outputData = new Uint8ClampedArray(imageData.width * imageData.height * 4);
- const data = imageData.data;
- const l = data.length;
- let index = 0;
- let r;
- let g;
- let b;
- const rand = () => (-1 + Math.random() * 2) * 255 * level;
- const pixel = monochrome
- ? () => {
- const average = rand();
- return [average, average, average];
- }
- : () => {
- return [rand(), rand(), rand()];
- };
- for (; index < l; index += 4) {
- [r, g, b] = pixel();
- outputData[index] = data[index] + r;
- outputData[index + 1] = data[index + 1] + g;
- outputData[index + 2] = data[index + 2] + b;
- outputData[index + 3] = data[index + 3];
- }
- done(null, {
- data: outputData,
- width: imageData.width,
- height: imageData.height,
- });
- };
- var gammaEffect = (options, done) => {
- const { imageData, level } = options;
- if (!level)
- return done(null, imageData);
- const outputData = new Uint8ClampedArray(imageData.width * imageData.height * 4);
- const data = imageData.data;
- const l = data.length;
- let index = 0;
- let r;
- let g;
- let b;
- for (; index < l; index += 4) {
- r = data[index] / 255;
- g = data[index + 1] / 255;
- b = data[index + 2] / 255;
- outputData[index] = Math.pow(r, level) * 255;
- outputData[index + 1] = Math.pow(g, level) * 255;
- outputData[index + 2] = Math.pow(b, level) * 255;
- outputData[index + 3] = data[index + 3];
- }
- done(null, {
- data: outputData,
- width: imageData.width,
- height: imageData.height,
- });
- };
- var isIdentityMatrix = (matrix) => {
- /*
- [
- 1, 0, 0, 0, 0
- 0, 1, 0, 0, 0
- 0, 0, 1, 0, 0
- 0, 0, 0, 1, 0
- ]
- */
- const l = matrix.length;
- let v;
- let s = l >= 20 ? 6 : l >= 16 ? 5 : 3;
- for (let i = 0; i < l; i++) {
- v = matrix[i];
- if (v === 1 && i % s !== 0)
- return false;
- else if (v !== 0 && v !== 1)
- return false;
- }
- return true;
- };
- var filterImageData = async (imageData, options = {}) => {
- const { colorMatrix, convolutionMatrix, gamma: gammaLevel, noise: noiseLevel, vignette: vignetteStrength, } = options;
- // filters
- const filters = [];
- // apply convolution matrix
- if (convolutionMatrix) {
- filters.push([convolutionEffect, { matrix: convolutionMatrix.clarity }]);
- }
- // apply noise
- if (gammaLevel > 0) {
- filters.push([gammaEffect, { level: 1.0 / gammaLevel }]);
- }
- // apply color matrix
- if (colorMatrix && !isIdentityMatrix(colorMatrix)) {
- filters.push([colorEffect, { matrix: colorMatrix }]);
- }
- // apply noise
- if (noiseLevel > 0 || noiseLevel < 0) {
- filters.push([noiseEffect, { level: noiseLevel }]);
- }
- // apply vignette
- if (vignetteStrength > 0 || vignetteStrength < 0) {
- filters.push([vignetteEffect, { strength: vignetteStrength }]);
- }
- // no changes
- if (!filters.length)
- return imageData;
- // builds effect chain
- const chain = (transforms, i) => `(err, imageData) => {
- (${transforms[i][0].toString()})(Object.assign({ imageData: imageData }, filterInstructions[${i}]),
- ${transforms[i + 1] ? chain(transforms, i + 1) : 'done'})
- }`;
- const filterChain = `function (options, done) {
- const filterInstructions = options.filterInstructions;
- const imageData = options.imageData;
- (${chain(filters, 0)})(null, imageData)
- }`;
- imageData = await thread(filterChain, [
- {
- imageData: imageData,
- filterInstructions: filters.map((t) => t[1]),
- },
- ], [imageData.data.buffer]);
- // the resizer returns a plain object, not an actual image data object, lets create one
- return imageDataObjectToImageData(imageData);
- };
- var isNumber = (v) => typeof v === 'number';
- var isEmoji = (str) => isString(str) &&
- str.match(/(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g) !== null;
- var hasProp = (obj, key) => obj.hasOwnProperty(key);
- var isFunction = (v) => typeof v === 'function';
- var isArray = (arr) => Array.isArray(arr);
- var isApple = () => isIOS() || isMac();
- var isWindows = () => /^win/i.test(navigator.platform);
- // macos: font-size: 123, x: 63.5, y: 110
- // windows: font-size: 112, x: 64, y: 103
- // android: font-size: 112, x: 64, y: 102
- let x = 64;
- let y = 102;
- let fontSize = 112;
- let hasSetValues = false;
- var getEmojiSVG = (emoji, alt) => {
- if (!hasSetValues && isBrowser()) {
- if (isWindows())
- y = 103;
- if (isApple()) {
- x = 63.5;
- y = 110;
- fontSize = 123;
- }
- hasSetValues = true;
- }
- return `<svg${alt ? ` aria-label="${alt}"` : ''} width="128" height="128" viewBox="0 0 128 128" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg"><text x="${x}" y="${y}" alignment-baseline="text-top" dominant-baseline="text-top" text-anchor="middle" font-size="${fontSize}px">${emoji}</text></svg>`;
- };
- var SVGToDataURL = (svg) => `data:image/svg+xml,${svg.replace('<', '%3C').replace('>', '%3E')}`;
- var isBinary = (v) => v instanceof Blob;
- var toPercentage = (value, total) => `${(value / total) * 100}%`;
- var colorArrayToRGBA = (color) => `rgba(${Math.round(color[0] * 255)}, ${Math.round(color[1] * 255)}, ${Math.round(color[2] * 255)}, ${isNumber(color[3]) ? color[3] : 1})`;
- const textPadding = 20;
- // font offset
- // font size 16 -> 2, 4
- // font size 32 -> 4, 6
- // font size 64 -> 8, 12
- // font size 128 -> 16, 24
- // font size 256 -> 32, 48
- let fontOffsetBrowser = undefined;
- const getBrowserFontOffset = (fontSize) => {
- if (!fontOffsetBrowser) {
- // size
- const size = 32;
- // let's calculate it
- const ctx = createSimpleContext(size, size);
- updateTextContext(ctx, { fontSize: 100, color: '#fff' });
- ctx.fillText('F', 0, 0);
- // get pixel data so we can find the white pixels
- const data = ctx.getImageData(0, 0, size, size).data;
- // find x offset
- let p = 0;
- let step = 4;
- let to = data.length;
- let from = to - size * 4;
- for (p = from; p < to; p += step) {
- if (data[p])
- break;
- }
- const x = (p - from) / step;
- // find y offset
- from = (size - 1) * 4;
- step = size * 4;
- for (p = from; p < to; p += step) {
- if (data[p])
- break;
- }
- const y = (p - from) / step;
- fontOffsetBrowser = vectorCreate(x, y);
- // done with canvas
- releaseCanvas(ctx.canvas);
- }
- return vectorCreate(-fontOffsetBrowser.x * fontSize * 0.01, -fontOffsetBrowser.y * fontSize * 0.01);
- };
- const createSimpleContext = (width = 1, height = 1) => {
- const canvas = h('canvas');
- const ctx = canvas.getContext('2d');
- ctx.canvas.width = width;
- ctx.canvas.height = height;
- return ctx;
- };
- const updateTextContext = (ctx, options) => {
- const { fontSize = 16, fontFamily = 'sans-serif', fontWeight = 'normal', fontVariant = 'normal', fontStyle = 'normal', textAlign = 'left', color = '#000', } = options;
- ctx.font = `${fontStyle} ${fontVariant} ${fontWeight} ${fontSize}px ${fontFamily}`;
- ctx.textBaseline = 'top';
- ctx.textAlign = textAlign;
- ctx.fillStyle = Array.isArray(color) ? colorArrayToRGBA(color) : color;
- };
- const createSimpleTextContext = (options) => {
- const ctx = createSimpleContext();
- updateTextContext(ctx, options);
- return ctx;
- };
- const computeLineHeight = (fontSize, lineHeight) => isFunction(lineHeight) ? lineHeight(fontSize) : lineHeight;
- const getMeasureVisibleWidth = (measure) => Math.abs(measure.actualBoundingBoxLeft) + Math.abs(measure.actualBoundingBoxRight);
- const resizeContextToFitText = (ctx, text, options) => {
- const { width, height } = measureTextContext(ctx, text, computeLineHeight(options.fontSize, options.lineHeight));
- ctx.canvas.width = Math.ceil(width);
- ctx.canvas.height = Math.ceil(height);
- return ctx;
- };
- const measureTextContext = (ctx, text, computedLineHeight) => {
- const storedTextAlign = ctx.textAlign;
- ctx.textAlign = 'left';
- // calculate width
- const lines = text.split('\n');
- const width = lines.reduce((prev, curr) => {
- const lineWidth = getMeasureVisibleWidth(ctx.measureText(curr));
- if (lineWidth > prev) {
- prev = lineWidth;
- }
- return prev;
- }, 1);
- ctx.textAlign = storedTextAlign;
- // calculate height
- const height = computedLineHeight * lines.length;
- return sizeCreate(Math.ceil(width), Math.ceil(height));
- };
- const TextSizeCache = new Map();
- const createTextSizeHash = (text, { fontSize, fontFamily, lineHeight, fontWeight, fontStyle, fontVariant }) => `${[text, fontSize, fontWeight, fontStyle, fontVariant, fontFamily].join('_')}_${isFunction(lineHeight) ? lineHeight(fontSize) : lineHeight}`;
- const textSize = (text, options) => {
- const ctx = createSimpleTextContext(options);
- if (options.width)
- text = wrapText(ctx, text, options.width);
- const hash = createTextSizeHash(text, options);
- let size = TextSizeCache.get(hash);
- if (size)
- return { ...size };
- size = measureTextContext(ctx, text, computeLineHeight(options.fontSize, options.lineHeight));
- TextSizeCache.set(hash, size);
- return { ...size };
- };
- const wrapText = (ctx, text, lineWidth) => {
- // exit if no text
- if (text.length === 0)
- return '';
- const res = [];
- let lineBuffer = '';
- let lineIndex = 0;
- let measureWidth;
- const paragraphs = text.split('\n\n');
- // draw the current line
- const pushLine = () => {
- if (!lineBuffer.length)
- return;
- if (!res[lineIndex]) {
- res[lineIndex] = [];
- }
- res[lineIndex].push(lineBuffer);
- // clear buffer
- lineBuffer = '';
- };
- const fitChar = (char) => {
- const testLine = lineBuffer + char;
- // measure width of entire line if adding these chars
- measureWidth = ctx.measureText(testLine).width;
- // fits on line?
- if (measureWidth < lineWidth) {
- lineBuffer = testLine;
- }
- else {
- // doesn't fit but line buffer is empty, just print the character and move to next line
- if (!lineBuffer.length) {
- lineBuffer = testLine;
- pushLine();
- }
- // fits, lets print current line and move char to next line
- else {
- pushLine();
- lineBuffer = char;
- }
- lineIndex++;
- }
- };
- const fitWord = (word) => {
- const testLine = lineBuffer.length ? lineBuffer + ' ' + word : word;
- // measure width of entire line if adding these chars
- measureWidth = ctx.measureText(testLine).width;
- // fits on line?
- if (measureWidth < lineWidth) {
- lineBuffer = testLine;
- }
- // wrap to next line
- else {
- // if line buffer is empty, whole word doesn't fit, need to cut it up
- if (!lineBuffer.length) {
- word.split('').forEach(fitChar);
- }
- // there are words in the buffer that do fit, let's draw the line and move this word to the next line
- else {
- // draw current buffer
- pushLine();
- lineIndex++;
- // retry to fit this word
- fitWord(word);
- }
- }
- };
- paragraphs.forEach((p) => {
- const lines = p.split('\n');
- lines.forEach((l) => {
- l.split(' ').forEach(fitWord);
- // end of line reached, if we have words in our buffer
- // at this point we need to draw them and then move to the next line
- if (lineBuffer.length)
- pushLine();
- // forced new line
- lineIndex++;
- });
- // forced new line
- lineIndex++;
- });
- return res.map((line) => line.join(' ')).join('\n');
- };
- const drawText$1 = (ctx, text = '', options = {}) => {
- // exit if no text
- if (text.length === 0)
- return ctx;
- const { x = 0, y = 0, lineWidth = 0, textAlign, fontSize, lineHeight } = options;
- // determine where the browser will render the font and correct for browser differences
- const browserFontOffset = vectorAdd(getBrowserFontOffset(fontSize), vectorCreate(fontSize / 12, fontSize / 3.75));
- const fontOffsetX = x + browserFontOffset.x;
- const fontOffsetY = y + browserFontOffset.y;
- const lineHeightComputed = isFunction(lineHeight) ? lineHeight(fontSize) : lineHeight;
- let offset = textAlign === 'right' ? lineWidth : textAlign === 'center' ? lineWidth * 0.5 : 0;
- text.split('\n').forEach((line, i) => {
- ctx.fillText(line, fontOffsetX + offset, fontOffsetY + i * lineHeightComputed);
- });
- return ctx;
- };
- var fixPrecision = (value, precision = 12) => parseFloat(value.toFixed(precision));
- const shapeEqual = (a, b) => {
- return JSON.stringify(a) === JSON.stringify(b);
- };
- const shapeDeepCopy = (shape) => {
- const shapeShallowCopy = { ...shape };
- const shapeDeepCopy = deepCopy(shapeShallowCopy);
- return shapeDeepCopy;
- };
- const getContextSize = (context, size = {}) => {
- const contextAspectRatio = rectAspectRatio(context);
- let xOut;
- let yOut;
- const xIn = size.width || size.rx;
- const yIn = size.height || size.ry;
- if (xIn && yIn)
- return sizeClone(size);
- if (xIn || yIn) {
- xOut = parseFloat(xIn || Number.MAX_SAFE_INTEGER);
- yOut = parseFloat(yIn || Number.MAX_SAFE_INTEGER);
- const min = Math.min(xOut, yOut);
- if (isString(xIn) || isString(yIn)) {
- xOut = `${min}%`;
- yOut = `${min * contextAspectRatio}%`;
- }
- else {
- xOut = min;
- yOut = min;
- }
- }
- else {
- const min = 10;
- xOut = `${min}%`;
- yOut = `${min * contextAspectRatio}%`;
- }
- const xProp = size.width ? 'width' : size.rx ? 'rx' : undefined;
- const yProp = size.width ? 'height' : size.rx ? 'ry' : undefined;
- return {
- [xProp || 'width']: xOut,
- [yProp || 'height']: yOut,
- };
- };
- const shapeCreateFromEmoji = (emoji, props = {}) => {
- return {
- width: undefined,
- height: undefined,
- ...props,
- aspectRatio: 1,
- backgroundImage: SVGToDataURL(getEmojiSVG(emoji)),
- };
- };
- const shapeCreateFromImage = (src, shapeProps = {}) => {
- const shapeDefaultLayout = shapeIsEllipse(shapeProps)
- ? {}
- : {
- width: undefined,
- height: undefined,
- aspectRatio: undefined,
- };
- const shape = {
- // required/default image shape props
- backgroundColor: [0, 0, 0, 0],
- // set default layout props
- ...shapeDefaultLayout,
- // merge with custom props
- ...shapeProps,
- // set image
- backgroundImage:
- // is svg or URL
- isString(src) ? src : isBinary(src) ? URL.createObjectURL(src) : src,
- };
- return shape;
- };
- const shapeCreateFromPreset = (preset, parentRect) => {
- let shape;
- if (isString(preset) || isBinary(preset)) {
- // default props for "quick" preset
- const shapeOptions = {
- ...getContextSize(parentRect),
- backgroundSize: 'contain',
- };
- // if is emoji, create default markup,
- if (isEmoji(preset)) {
- shape = shapeCreateFromEmoji(preset, shapeOptions);
- }
- // is URL, create default markup for image
- else {
- shape = shapeCreateFromImage(preset, shapeOptions);
- }
- }
- else {
- // is using src shortcut
- if (preset.src) {
- const contextSize = getContextSize(parentRect, preset.shape || preset);
- // shape options
- const shapeOptions = {
- // default shape styles
- ...preset.shape,
- // precalcualte size of shape in context
- ...contextSize,
- };
- // should auto-fix aspect ratio
- if (preset.width && preset.height && !hasProp(shapeOptions, 'aspectRatio')) {
- const width = shapeGetPropPixelValue(contextSize, 'width', parentRect);
- const height = shapeGetPropPixelValue(contextSize, 'height', parentRect);
- shapeOptions.aspectRatio = getAspectRatio(width, height);
- }
- // should auto-contain sticker in container
- if (!shapeOptions.backgroundSize && !preset.shape && (!preset.width || !preset.height))
- shapeOptions.backgroundSize = 'contain';
- // emoji markup
- if (isEmoji(preset.src)) {
- shape = shapeCreateFromEmoji(preset.src, shapeOptions);
- }
- // is url
- else {
- shape = shapeCreateFromImage(preset.src, shapeOptions);
- }
- }
- // should have markup defined
- else if (preset.shape) {
- shape = shapeDeepCopy(preset.shape);
- }
- }
- if (hasProp(shape, 'backgroundImage')) {
- // set transparent background if no background color defined
- if (!hasProp(shape, 'backgroundColor')) {
- shape.backgroundColor = [0, 0, 0, 0];
- }
- // for image presets, disable styles by default
- if (!hasProp(shape, 'disableStyle')) {
- shape.disableStyle = ['backgroundColor', 'strokeColor', 'strokeWidth'];
- }
- // by default don't allow flipping
- if (!hasProp(shape, 'disableFlip')) {
- shape.disableFlip = true;
- }
- }
- return parentRect ? shapeComputeDisplay(shape, parentRect) : shape;
- };
- const shapeLineGetStartPoint = (line) => vectorCreate(line.x1, line.y1);
- const shapeLineGetEndPoint = (line) => vectorCreate(line.x2, line.y2);
- const shapeTextUID = ({ text, textAlign, fontSize, fontFamily, lineHeight, fontWeight, fontStyle, fontVariant, }) => `${[text, textAlign, fontSize, fontWeight, fontStyle, fontVariant, fontFamily].join('_')}_${isFunction(lineHeight) ? lineHeight(fontSize) : lineHeight}`;
- //#endregion
- //#region shape testing
- // shape types
- const shapeIsText = (shape) => hasProp(shape, 'text');
- const shapeIsTextLine = (shape) => shapeIsText(shape) && !(shapeHasRelativeSize(shape) || hasProp(shape, 'width'));
- const shapeIsTextBox = (shape) => shapeIsText(shape) && (shapeHasRelativeSize(shape) || hasProp(shape, 'width'));
- const shapeIsRect = (shape) => !shapeIsText(shape) && shapeHasComputedSize(shape);
- const shapeIsEllipse = (shape) => hasProp(shape, 'rx');
- const shapeIsLine = (shape) => hasProp(shape, 'x1') && !shapeIsTriangle(shape);
- const shapeIsTriangle = (shape) => hasProp(shape, 'x3');
- const shapeIsPath = (shape) => hasProp(shape, 'points');
- // shape state
- const shapeIsTextEmpty = (shape) => shapeIsText(shape) && !shape.text.length;
- const shapeIsTextEditing = (shape) => shapeIsText(shape) && shape.isEditing;
- const shapeIsVisible = (shape) => hasProp(shape, 'opacity') ? shape.opacity > 0 : true;
- const shapeIsSelected = (shape) => shape.isSelected;
- const shapeIsDraft = (shape) => shape._isDraft;
- const shapeHasSize = (shape) => hasProp(shape, 'width') && hasProp(shape, 'height');
- const shapeHasNumericStroke = (shape) => isNumber(shape.strokeWidth) && shape.strokeWidth > 0; // only relevant if is bigger than 0
- const shapeHasRelativePosition = (shape) => {
- const hasRight = hasProp(shape, 'right');
- const hasBottom = hasProp(shape, 'bottom');
- return hasRight || hasBottom;
- };
- const shapeHasTexture = (shape) => hasProp(shape, 'backgroundImage') || hasProp(shape, 'text');
- const shapeHasRelativeSize = (shape) => ((hasProp(shape, 'x') || hasProp(shape, 'left')) && hasProp(shape, 'right')) ||
- ((hasProp(shape, 'y') || hasProp(shape, 'top')) && hasProp(shape, 'bottom'));
- const shapeHasComputedSize = (shape) => shapeHasSize(shape) || shapeHasRelativeSize(shape);
- // actions
- const shapeSelect = (shape) => {
- shape.isSelected = true;
- return shape;
- };
- const shapeMakeDraft = (shape) => {
- shape._isDraft = true;
- return shape;
- };
- const shapeMakeFinal = (shape) => {
- shape._isDraft = false;
- return shape;
- };
- // rights
- const shapeCanStyle = (shape, style) => {
- if (shape.disableStyle === true)
- return false;
- if (isArray(shape.disableStyle) && style) {
- return !shape.disableStyle.includes(style);
- }
- return true;
- };
- const shapeCanSelect = (shape) => shape.disableSelect !== true && !shapeIsTriangle(shape);
- const shapeCanRemove = (shape) => shape.disableRemove !== true;
- const shapeCanDuplicate = (shape) => shape.disableDuplicate !== true && shapeCanMove(shape);
- const shapeCanReorder = (shape) => shape.disableReorder !== true;
- const shapeCanFlip = (shape) => {
- if (shape.disableFlip)
- return false;
- if (shapeIsDraft(shape) || shapeHasRelativePosition(shape))
- return false;
- return shapeHasTexture(shape);
- };
- const shapeCanInput = (shape, input) => {
- if (!shapeIsText(shape))
- return false;
- if (shape.disableInput === true)
- return false;
- if (isFunction(shape.disableInput))
- return shape.disableInput(input != null ? input : shape.text);
- return input || true;
- };
- const shapeCanChangeTextLayout = (shape, layout) => {
- if (shape.disableTextLayout === true)
- return false;
- if (isArray(shape.disableTextLayout) && layout) {
- return !shape.disableTextLayout.includes(layout);
- }
- return true;
- };
- const shapeCanManipulate = (shape) => shape.disableManipulate !== true && !shapeIsDraft(shape) && !shapeHasRelativePosition(shape);
- const shapeCanMove = (shape) => shapeCanManipulate(shape) && shape.disableMove !== true;
- const shapeCanResize = (shape) => shapeCanManipulate(shape) &&
- shapeCanMove(shape) &&
- shape.disableResize !== true &&
- (shapeHasSize(shape) || shapeIsTextBox(shape) || shapeIsEllipse(shape) || shapeIsLine(shape));
- const shapeCanRotate = (shape) => shapeCanManipulate(shape) &&
- shape.disableRotate !== true &&
- (shapeHasSize(shape) || hasProp(shape, 'text') || shapeIsEllipse(shape));
- //#endregion
- //#region shape formatting
- const shapeDeleteRelativeProps = (shape) => {
- delete shape.left;
- delete shape.right;
- delete shape.top;
- delete shape.bottom;
- return shape;
- };
- const shapeDeleteTransformProps = (shape) => {
- delete shape.rotation;
- return shape;
- };
- const shapeFormatStroke = (shape) => {
- shape.strokeWidth = shape.strokeWidth || 1;
- shape.strokeColor = shape.strokeColor || [0, 0, 0];
- return shape;
- };
- const shapeFormatFill = (shape) => {
- shape.backgroundColor = shape.backgroundColor
- ? shape.backgroundColor
- : shape.strokeWidth || shape.backgroundImage
- ? undefined
- : [0, 0, 0];
- return shape;
- };
- const autoLineHeight = (fontSize) => fontSize * 1.2;
- const shapeFormatText = (shape) => {
- shape.fontSize = shape.fontSize || 16;
- shape.fontFamily = shape.fontFamily || 'sans-serif';
- shape.fontWeight = shape.fontWeight || 'normal';
- shape.fontStyle = shape.fontStyle || 'normal';
- shape.fontVariant = shape.fontVariant || 'normal';
- shape.lineHeight = isNumber(shape.lineHeight) ? shape.lineHeight : autoLineHeight;
- shape.color = shape.color || [0, 0, 0];
- return shapeIsTextLine(shape) ? shapeFormatTextLine(shape) : shapeFormatTextBox(shape);
- };
- const shapeFormatTextLine = (shape) => {
- delete shape.textAlign;
- return shapeDeleteRelativeProps(shape);
- };
- const shapeFormatTextBox = (shape) => {
- shape.textAlign = shape.textAlign || 'left';
- return shape;
- };
- const shapeFormatRect = (shape) => {
- shape.cornerRadius = shape.cornerRadius || 0;
- shape.strokeWidth = shape.strokeWidth || 0;
- shape.strokeColor = shape.strokeColor || [0, 0, 0];
- return shapeFormatFill(shape);
- };
- const shapeFormatTriangle = (shape) => {
- shape.strokeWidth = shape.strokeWidth || 0;
- shape.strokeColor = shape.strokeColor || [0, 0, 0];
- shapeFormatFill(shape);
- return shapeDeleteRelativeProps(shape);
- };
- const shapeFormatEllipse = (shape) => {
- shape.strokeWidth = shape.strokeWidth || 0;
- shape.strokeColor = shape.strokeColor || [0, 0, 0];
- return shapeFormatFill(shape);
- };
- const shapeFormatPath = (shape) => {
- shapeFormatStroke(shape);
- shapeDeleteTransformProps(shape);
- return shapeDeleteRelativeProps(shape);
- };
- const shapeFormatLine = (shape) => {
- shapeFormatStroke(shape);
- shape.lineStart = shape.lineStart || undefined;
- shape.lineEnd = shape.lineEnd || undefined;
- shapeDeleteTransformProps(shape);
- return shapeDeleteRelativeProps(shape);
- };
- const shapeFormatDefaults = (shape) => {
- if (!isString(shape.id))
- shape.id = getUniqueId();
- if (!hasProp(shape, 'rotation'))
- shape.rotation = 0;
- if (!hasProp(shape, 'opacity'))
- shape.opacity = 1;
- if (!hasProp(shape, 'disableErase'))
- shape.disableErase = true;
- };
- const shapeFormat = (shape) => {
- shapeFormatDefaults(shape);
- if (shapeIsText(shape)) {
- shapeFormatText(shape);
- }
- else if (shapeIsRect(shape)) {
- shapeFormatRect(shape);
- }
- else if (shapeIsPath(shape)) {
- shapeFormatPath(shape);
- }
- else if (shapeIsLine(shape)) {
- shapeFormatLine(shape);
- }
- else if (shapeIsEllipse(shape)) {
- shapeFormatEllipse(shape);
- }
- else if (shapeIsTriangle(shape)) {
- shapeFormatTriangle(shape);
- }
- return shape;
- };
- const shapeGetDescription = (shape) => {
- if (shapeIsText(shape)) {
- return 'text';
- }
- else if (shapeIsRect(shape)) {
- return 'rectangle';
- }
- else if (shapeIsPath(shape)) {
- return 'path';
- }
- else if (shapeIsLine(shape)) {
- return 'line';
- }
- else if (shapeIsEllipse(shape)) {
- return 'ellipse';
- }
- else if (shapeIsTriangle(shape)) {
- return 'triangle';
- }
- return;
- };
- //#endregion
- const toPixelValue = (percentage, total) => (parseFloat(percentage) / 100) * total;
- //#region shape transforming
- const xRegExp = new RegExp(/^x|left|^width|rx|fontSize|cornerRadius|strokeWidth/, 'i');
- const yRegExp = new RegExp(/^y|top|^height|ry/, 'i');
- const rightRegExp = new RegExp(/right/, 'i');
- const bottomRegExp = new RegExp(/bottom/, 'i');
- const compute = (key, value, { width, height }) => {
- // handle array of percentage values
- if (Array.isArray(value)) {
- return value.map((v) => {
- if (isObject(v)) {
- // update the object itself
- computeProps(v, { width, height });
- }
- return v;
- });
- }
- // no need to compute (test with typeof instead of for perf)
- if (typeof value !== 'string')
- return value;
- if (!value.endsWith('%'))
- return value;
- const f = parseFloat(value) / 100;
- if (xRegExp.test(key))
- return fixPrecision(width * f, 6);
- if (yRegExp.test(key))
- return fixPrecision(height * f, 6);
- if (rightRegExp.test(key))
- return fixPrecision(width - width * f, 6);
- if (bottomRegExp.test(key))
- return fixPrecision(height - height * f, 6);
- // dont auto-compute
- return value;
- };
- const computeProps = (obj, size) => {
- return Object.entries(obj).map(([key, value]) => {
- obj[key] = compute(key, value, size);
- });
- };
- const shapeComputeDisplay = (shape, parentRect) => {
- computeProps(shape, parentRect);
- shapeComputeRect(shape, parentRect);
- return shape;
- };
- const shapeGetPropPixelTotal = (prop, parentRect) => {
- let total;
- if (/^x|width|rx|fontSize|strokeWidth|cornerRadius/.test(prop)) {
- total = parentRect.width;
- }
- else if (/^y|height|ry/.test(prop)) {
- total = parentRect.height;
- }
- return total;
- };
- const shapeUpdateProp = (shape, prop, value, parentRect) => {
- if (!isString(shape[prop])) {
- shape[prop] = value;
- return shape;
- }
- const total = shapeGetPropPixelTotal(prop, parentRect);
- shape[prop] = total === undefined ? value : toPercentage(value, total);
- return shape;
- };
- const shapeGetPropPixelValue = (shape, prop, parentRect) => {
- if (!isString(shape[prop]))
- return shape[prop];
- return toPixelValue(shape[prop], shapeGetPropPixelTotal(prop, parentRect));
- };
- const shapeGetPropsPixelValues = (shape, props, parentRect) => {
- return props.reduce((prev, prop) => {
- const value = shapeGetPropPixelValue(shape, prop, parentRect);
- prev[prop] = value;
- return prev;
- }, {});
- };
- const shapeUpdateProps = (shape, props, parentRect) => {
- Object.keys(props).forEach((key) => shapeUpdateProp(shape, key, props[key], parentRect));
- return shape;
- };
- const shapeBounds = (shape) => {
- const rect = rectCreateEmpty();
- const strokeWidth = shape.strokeWidth || 0;
- if (shapeIsRect(shape)) {
- rect.x = shape.x - strokeWidth * 0.5;
- rect.y = shape.y - strokeWidth * 0.5;
- rect.width = shape.width + strokeWidth;
- rect.height = shape.height + strokeWidth;
- }
- else if (shapeIsLine(shape)) {
- const { x1, y1, x2, y2 } = shape;
- const left = Math.abs(Math.min(x1, x2));
- const right = Math.abs(Math.max(x1, x2));
- const top = Math.abs(Math.min(y1, y2));
- const bottom = Math.abs(Math.min(y1, y2));
- rect.x = left + strokeWidth * 0.5;
- rect.y = right + strokeWidth * 0.5;
- rect.width = right - left + strokeWidth;
- rect.height = bottom - top + strokeWidth;
- }
- else if (shapeIsEllipse(shape)) {
- rect.x = shape.x - shape.rx + strokeWidth * 0.5;
- rect.y = shape.y - shape.ry + strokeWidth * 0.5;
- rect.width = shape.rx * 2 + strokeWidth;
- rect.height = shape.ry * 2 + strokeWidth;
- }
- if (rect && hasProp(shape, 'rotation')) {
- rectRotate(rect, shape.rotation);
- }
- return rectToBounds(rect);
- };
- const shapesBounds = (shapes, parentRect) => {
- const bounds = shapes
- .filter((shape) => shape.x < 0 || shape.y < 0 || shape.x1 < 0 || shape.y1 < 0)
- .reduce((bounds, shape) => {
- const [top, right, bottom, left] = shapeBounds(shape);
- bounds.top = Math.min(top, bounds.top);
- bounds.left = Math.min(left, bounds.left);
- bounds.bottom = Math.max(bottom, bounds.bottom);
- bounds.right = Math.max(right, bounds.right);
- return bounds;
- }, {
- top: 0,
- right: 0,
- bottom: 0,
- left: 0,
- });
- if (bounds.right > 0)
- bounds.right -= parentRect.width;
- if (bounds.bottom > 0)
- bounds.bottom -= parentRect.height;
- return bounds;
- };
- const shapesFromCompositShape = (shape, parentRect, parser) => {
- const shapeCopy = shapeDeepCopy(shape);
- shapeComputeDisplay(shapeCopy, parentRect);
- return parser(shapeCopy);
- };
- const shapeComputeRect = (shape, parentRect) => {
- if (hasProp(shape, 'left'))
- shape.x = shape.left;
- if (hasProp(shape, 'right')) {
- const r = parentRect.width - shape.right;
- if (hasProp(shape, 'left')) {
- shape.x = shape.left;
- shape.width = Math.max(0, r - shape.left);
- }
- else if (hasProp(shape, 'width')) {
- shape.x = r - shape.width;
- }
- }
- if (hasProp(shape, 'top'))
- shape.y = shape.top;
- if (hasProp(shape, 'bottom')) {
- const b = parentRect.height - shape.bottom;
- if (hasProp(shape, 'top')) {
- shape.y = shape.top;
- shape.height = Math.max(0, b - shape.top);
- }
- else if (hasProp(shape, 'height')) {
- shape.y = b - shape.height;
- }
- }
- return shape;
- };
- const shapeComputeTransform = (shape, translate, scale) => {
- if (shapeIsPath(shape)) {
- shape.points
- .filter((point) => isNumber(point.x))
- .forEach((point) => {
- point.x *= scale;
- point.y *= scale;
- point.x += translate.x;
- point.y += translate.y;
- });
- }
- if (shapeIsTriangle(shape) && isNumber(shape.x1)) {
- shape.x1 *= scale;
- shape.y1 *= scale;
- shape.x2 *= scale;
- shape.y2 *= scale;
- shape.x3 *= scale;
- shape.y3 *= scale;
- shape.x1 += translate.x;
- shape.y1 += translate.y;
- shape.x2 += translate.x;
- shape.y2 += translate.y;
- shape.x3 += translate.x;
- shape.y3 += translate.y;
- }
- if (shapeIsLine(shape) && isNumber(shape.x1)) {
- shape.x1 *= scale;
- shape.y1 *= scale;
- shape.x2 *= scale;
- shape.y2 *= scale;
- shape.x1 += translate.x;
- shape.y1 += translate.y;
- shape.x2 += translate.x;
- shape.y2 += translate.y;
- }
- if (isNumber(shape.x) && isNumber(shape.y)) {
- shape.x *= scale;
- shape.y *= scale;
- shape.x += translate.x;
- shape.y += translate.y;
- }
- if (isNumber(shape.width) && isNumber(shape.height)) {
- shape.width *= scale;
- shape.height *= scale;
- }
- if (isNumber(shape.rx) && isNumber(shape.ry)) {
- shape.rx *= scale;
- shape.ry *= scale;
- }
- if (shapeHasNumericStroke(shape)) {
- shape.strokeWidth *= scale;
- }
- if (shapeIsText(shape) && isNumber(shape.fontSize)) {
- shape.fontSize *= scale;
- if (isNumber(shape.width) && !isNumber(shape.width))
- shape.width *= scale;
- }
- if (hasProp(shape, 'cornerRadius') && isNumber(shape.cornerRadius)) {
- shape.cornerRadius *= scale;
- }
- return shape;
- };
- const shapeGetCenter = (shape) => {
- if (shapeIsRect(shape)) {
- return vectorCreate(shape.x + shape.width * 0.5, shape.y + shape.height * 0.5);
- }
- if (shapeIsEllipse(shape)) {
- return vectorCreate(shape.x, shape.y);
- }
- if (shapeIsTextBox(shape)) {
- const height = shape.height || textSize(shape.text, shape).height;
- return vectorCreate(shape.x + shape.width * 0.5, shape.y + height * 0.5);
- }
- if (shapeIsTextLine(shape)) {
- const size = textSize(shape.text, shape);
- return vectorCreate(shape.x + size.width * 0.5, shape.y + size.height * 0.5);
- }
- if (shapeIsPath(shape)) {
- return vectorCenter(shape.points);
- }
- if (shapeIsLine(shape)) {
- return vectorCenter([
- shapeLineGetStartPoint(shape),
- shapeLineGetEndPoint(shape),
- ]);
- }
- return undefined;
- };
- //#endregion
- var ctxRoundRect = (ctx, x, y, width, height, radius) => {
- if (width < 2 * radius)
- radius = width / 2;
- if (height < 2 * radius)
- radius = height / 2;
- ctx.beginPath();
- ctx.moveTo(x + radius, y);
- ctx.arcTo(x + width, y, x + width, y + height, radius);
- ctx.arcTo(x + width, y + height, x, y + height, radius);
- ctx.arcTo(x, y + height, x, y, radius);
- ctx.arcTo(x, y, x + width, y, radius);
- ctx.closePath();
- return ctx;
- };
- var isCanvas = (element) => /canvas/i.test(element.nodeName);
- var isRemoteURL = (url) => new URL(url, location.href).origin !== location.origin;
- var loadImage = (image, onSize = undefined) => new Promise((resolve, reject) => {
- // the image element we'll use to load the image
- let imageElement = image;
- let sizeCalculated = false;
- const reportSize = () => {
- if (sizeCalculated)
- return;
- sizeCalculated = true;
- isFunction(onSize) &&
- /* Use Promise.resolve to make async but place before resolve of parent promise */
- Promise.resolve().then(() => onSize(sizeCreate(imageElement.naturalWidth, imageElement.naturalHeight)));
- };
- // if is not an image element, it must be a valid image source
- if (!imageElement.src) {
- imageElement = new Image();
- // if is remote image, set crossOrigin
- // why not always set crossOrigin? -> because when set this fires two requests,
- // one for asking permission and one for downloading the image
- if (isString(image) && isRemoteURL(image))
- imageElement.crossOrigin = 'anonymous';
- imageElement.src = isString(image) ? image : URL.createObjectURL(image);
- }
- if (imageElement.complete) {
- reportSize();
- return resolve(imageElement);
- }
- // try to calculate size faster
- if (isFunction(onSize))
- getImageElementSize(imageElement).then(reportSize).catch(reject);
- imageElement.onload = () => {
- reportSize();
- resolve(imageElement);
- };
- imageElement.onerror = reject;
- });
- var pubsub = () => {
- let subs = [];
- return {
- sub: (event, callback) => {
- subs.push({ event, callback });
- return () => (subs = subs.filter((subscriber) => subscriber.event !== event || subscriber.callback !== callback));
- },
- pub: (event, value) => {
- subs
- .filter((sub) => sub.event === event)
- .forEach((sub) => sub.callback(value));
- }
- };
- };
- const cache = new Map([]);
- const getImage = (src, options = {}) => new Promise((resolve, reject) => {
- const { onMetadata = noop$1, onLoad = resolve, onError = reject, onComplete = noop$1, } = options;
- let imageLoadState = cache.get(src);
- // start loading
- if (!imageLoadState) {
- imageLoadState = {
- loading: false,
- complete: false,
- error: false,
- image: undefined,
- size: undefined,
- bus: pubsub(),
- };
- // store
- cache.set(src, imageLoadState);
- }
- // wait for load
- imageLoadState.bus.sub('meta', onMetadata);
- imageLoadState.bus.sub('load', onLoad);
- imageLoadState.bus.sub('error', onError);
- imageLoadState.bus.sub('complete', onComplete);
- // if is canvas, it's already done
- if (isCanvas(src)) {
- const canvas = src;
- // get image
- const image = canvas.cloneNode();
- // update state
- imageLoadState.complete = true;
- imageLoadState.image = image;
- imageLoadState.size = sizeCreateFromElement(canvas);
- }
- // already loaded
- if (imageLoadState.complete) {
- imageLoadState.bus.pub('meta', { size: imageLoadState.size });
- if (imageLoadState.error) {
- imageLoadState.bus.pub('error', imageLoadState.error);
- }
- else {
- imageLoadState.bus.pub('load', imageLoadState.image);
- }
- imageLoadState.bus.pub('complete');
- // reset subscribers
- imageLoadState.bus = pubsub();
- return;
- }
- // already loading, exit here
- if (imageLoadState.loading)
- return;
- // now loading
- imageLoadState.loading = true;
- // resource needs to be loaded
- loadImage(src, (size) => {
- imageLoadState.size = size;
- imageLoadState.bus.pub('meta', { size });
- })
- .then((image) => {
- imageLoadState.image = image;
- imageLoadState.bus.pub('load', image);
- })
- .catch((err) => {
- imageLoadState.error = err;
- imageLoadState.bus.pub('error', err);
- })
- .finally(() => {
- imageLoadState.complete = true;
- imageLoadState.loading = false;
- imageLoadState.bus.pub('complete');
- // reset subscribers
- imageLoadState.bus = pubsub();
- });
- });
- const drawCanvas = (ctx, image, srcRect, destRect) => ctx.drawImage(image, srcRect.x, srcRect.x, srcRect.width, srcRect.height, destRect.x, destRect.y, destRect.width, destRect.height);
- var ctxDrawImage = async (ctx, image, srcRect, destRect, draw = drawCanvas) => {
- ctx.save();
- ctx.clip();
- await draw(ctx, image, srcRect, destRect);
- ctx.restore();
- };
- const getDrawImageParams = (container, backgroundSize, imageSize) => {
- let srcRect = rectCreate(0, 0, imageSize.width, imageSize.height);
- const destRect = rectClone(container);
- if (backgroundSize === 'contain') {
- const rect = rectContainRect(container, rectAspectRatio(srcRect));
- destRect.width = rect.width;
- destRect.height = rect.height;
- destRect.x += rect.x;
- destRect.y += rect.y;
- }
- else if (backgroundSize === 'cover') {
- srcRect = rectContainRect(rectCreate(0, 0, srcRect.width, srcRect.height), rectAspectRatio(destRect));
- }
- return {
- srcRect,
- destRect,
- };
- };
- const defineRectShape = (ctx, shape) => {
- shape.cornerRadius > 0
- ? ctxRoundRect(ctx, shape.x, shape.y, shape.width, shape.height, shape.cornerRadius)
- : ctx.rect(shape.x, shape.y, shape.width, shape.height);
- return ctx;
- };
- const fillRectShape = (ctx, shape) => {
- shape.backgroundColor && ctx.fill();
- return ctx;
- };
- const strokeRectShape = (ctx, shape) => {
- shape.strokeWidth && ctx.stroke();
- return ctx;
- };
- var drawRect = async (ctx, shape, options = {}) => new Promise(async (resolve, reject) => {
- const { drawImage } = options;
- ctx.lineWidth = shape.strokeWidth ? shape.strokeWidth : 1; // 1 is default value for lineWidth prop
- ctx.strokeStyle = shape.strokeColor ? colorArrayToRGBA(shape.strokeColor) : 'none';
- ctx.fillStyle = shape.backgroundColor ? colorArrayToRGBA(shape.backgroundColor) : 'none';
- ctx.globalAlpha = shape.opacity;
- if (shape.backgroundImage) {
- let image;
- try {
- if (isCanvas(shape.backgroundImage)) {
- image = shape.backgroundImage;
- }
- else {
- image = await getImage(shape.backgroundImage);
- }
- }
- catch (err) {
- reject(err);
- }
- defineRectShape(ctx, shape);
- fillRectShape(ctx, shape);
- const { srcRect, destRect } = getDrawImageParams(shape, shape.backgroundSize, sizeCreateFromElement(image));
- await ctxDrawImage(ctx, image, srcRect, destRect, drawImage);
- strokeRectShape(ctx, shape);
- resolve([]);
- }
- else {
- defineRectShape(ctx, shape);
- fillRectShape(ctx, shape);
- strokeRectShape(ctx, shape);
- resolve([]);
- }
- });
- var drawEllipse = async (ctx, shape, options = {}) => new Promise(async (resolve, reject) => {
- const { drawImage } = options;
- ctx.lineWidth = shape.strokeWidth || 1; // 1 is default value for lineWidth prop
- ctx.strokeStyle = shape.strokeColor ? colorArrayToRGBA(shape.strokeColor) : 'none';
- ctx.fillStyle = shape.backgroundColor ? colorArrayToRGBA(shape.backgroundColor) : 'none';
- ctx.globalAlpha = shape.opacity;
- ctx.ellipse(shape.x, shape.y, shape.rx, shape.ry, 0, 0, Math.PI * 2);
- shape.backgroundColor && ctx.fill();
- if (shape.backgroundImage) {
- let image;
- try {
- image = await getImage(shape.backgroundImage);
- }
- catch (err) {
- reject(err);
- }
- const bounds = rectCreate(shape.x - shape.rx, shape.y - shape.ry, shape.rx * 2, shape.ry * 2);
- const { srcRect, destRect } = getDrawImageParams(bounds, shape.backgroundSize, sizeCreateFromElement(image));
- // @ts-ignore
- await ctxDrawImage(ctx, image, srcRect, destRect, drawImage);
- shape.strokeWidth && ctx.stroke();
- resolve([]);
- }
- else {
- shape.strokeWidth && ctx.stroke();
- resolve([]);
- }
- });
- var drawText = async (ctx, shape, options) => {
- const size = shape.width && shape.height
- ? sizeCreateFromAny(shape)
- : textSize(shape.text, shape);
- const rect = {
- x: shape.x,
- y: shape.y,
- width: shape.width || size.width,
- height: size.height,
- };
- drawRect(ctx, {
- ...shape,
- ...rect,
- options,
- });
- updateTextContext(ctx, shape);
- let tx = 0;
- if (shape.textAlign == 'center') {
- tx = -textPadding * 0.5;
- }
- else if (shape.textAlign === 'right') {
- tx = -textPadding;
- }
- ctx.rect(shape.x + tx, shape.y, shape.width + textPadding * 2, shape.height);
- ctx.save();
- ctx.clip();
- drawText$1(ctx, shape.width ? wrapText(ctx, shape.text, shape.width) : shape.text, {
- x: shape.x,
- y: shape.y,
- fontSize: shape.fontSize,
- textAlign: shape.textAlign,
- lineHeight: shape.lineHeight,
- lineWidth: shape.width,
- });
- ctx.restore();
- return [];
- };
- // TODO! START
- // -----------
- var drawLine = async (ctx, shape) => new Promise(async (resolve) => {
- ctx.lineWidth = shape.strokeWidth || 1; // 1 is default value for lineWidth prop
- ctx.strokeStyle = shape.strokeColor ? colorArrayToRGBA(shape.strokeColor) : 'none';
- ctx.globalAlpha = shape.opacity;
- let lineStartPosition = shapeLineGetStartPoint(shape);
- let lineEndPosition = shapeLineGetEndPoint(shape);
- // draw line
- ctx.moveTo(lineStartPosition.x, lineStartPosition.y);
- ctx.lineTo(lineEndPosition.x, lineEndPosition.y);
- shape.strokeWidth && ctx.stroke();
- // draw other shapes
- resolve([]);
- });
- // TODO! END
- // -----------
- var drawPath = async (ctx, shape) => new Promise((resolve, reject) => {
- ctx.lineWidth = shape.strokeWidth || 1; // 1 is default value for lineWidth prop
- ctx.strokeStyle = shape.strokeColor ? colorArrayToRGBA(shape.strokeColor) : 'none';
- ctx.fillStyle = shape.backgroundColor ? colorArrayToRGBA(shape.backgroundColor) : 'none';
- ctx.globalAlpha = shape.opacity;
- // draw line
- const { points } = shape;
- if (shape.pathClose)
- ctx.beginPath();
- ctx.moveTo(points[0].x, points[0].y);
- const l = points.length;
- for (let i = 1; i < l; i++) {
- ctx.lineTo(points[i].x, points[i].y);
- }
- if (shape.pathClose)
- ctx.closePath();
- shape.strokeWidth && ctx.stroke();
- shape.backgroundColor && ctx.fill();
- resolve([]);
- });
- var ctxFlip = (ctx, flipX, flipY, pivot) => {
- if (!flipX && !flipY)
- return ctx;
- ctx.translate(pivot.x, pivot.y);
- ctx.scale(flipX ? -1 : 1, flipY ? -1 : 1);
- ctx.translate(-pivot.x, -pivot.y);
- return ctx;
- };
- const drawShape = async (ctx, shape, options) => {
- // center, needed for transforms
- const center = shapeGetCenter(shape);
- // rotate context
- ctxRotate(ctx, shape.rotation, center);
- // flip context
- ctxFlip(ctx, shape.flipX, shape.flipY, center);
- let fn;
- if (shapeIsRect(shape)) {
- fn = drawRect;
- }
- else if (shapeIsEllipse(shape)) {
- fn = drawEllipse;
- }
- else if (shapeIsLine(shape)) {
- fn = drawLine;
- }
- else if (shapeIsPath(shape)) {
- fn = drawPath;
- }
- else if (shapeIsText(shape)) {
- fn = drawText;
- }
- // get shapes
- return fn ? [shape, ...(await drawShapes(ctx, await fn(ctx, shape, options), options))] : [];
- };
- var drawShapes = async (ctx, shapes, options) => {
- let drawnShapes = [];
- for (const shape of shapes) {
- ctx.save();
- // clears previous shape's path
- ctx.beginPath();
- // wait for shape to draw before drawing next shape
- drawnShapes = [...drawnShapes, ...(await drawShape(ctx, shape, options))];
- ctx.restore();
- }
- return drawnShapes;
- };
- var drawImageData = async (imageData, options = {}) => {
- const { shapes = [], context = imageData, contextBounds = imageData, transform = noop$1, drawImage, preprocessShape = passthrough, } = options;
- // no shapes to draw
- if (!shapes.length)
- return imageData;
- // create drawing context
- const canvas = h('canvas');
- canvas.width = contextBounds.width;
- canvas.height = contextBounds.height;
- const ctx = canvas.getContext('2d');
- ctx.putImageData(imageData, contextBounds.x || 0, contextBounds.y || 0);
- // compute the position of all shapes
- const computedShapes = shapes
- .map(shapeDeepCopy)
- .map((shape) => shapeComputeDisplay(shape, {
- x: 0,
- y: 0,
- width: context.width,
- height: context.height,
- })) // need to take into account output size?
- .map(preprocessShape)
- .flat();
- // compute transforms for all shapes
- transform(ctx);
- // draw shapes to canvas
- await drawShapes(ctx, computedShapes, {
- drawImage,
- });
- const imageDataOut = ctx.getImageData(0, 0, canvas.width, canvas.height);
- releaseCanvas(canvas);
- return imageDataOut;
- };
- var fillImageData = async (imageData, options = {}) => {
- const { backgroundColor } = options;
- // no background color set or is fully transparent background color
- if (!backgroundColor || (backgroundColor && backgroundColor[3] === 0))
- return imageData;
- // fill
- let imageDataOut;
- let image = h('canvas');
- image.width = imageData.width;
- image.height = imageData.height;
- const ctx = image.getContext('2d');
- ctx.putImageData(imageData, 0, 0);
- // fill behind image
- ctx.globalCompositeOperation = 'destination-over';
- ctx.fillStyle = colorArrayToRGBA(backgroundColor);
- ctx.fillRect(0, 0, image.width, image.height);
- imageDataOut = ctx.getImageData(0, 0, image.width, image.height);
- releaseCanvas(image);
- return imageDataOut;
- };
- var dotColorMatrix = (a, b) => {
- const res = new Array(20);
- // R
- res[0] = a[0] * b[0] + a[1] * b[5] + a[2] * b[10] + a[3] * b[15];
- res[1] = a[0] * b[1] + a[1] * b[6] + a[2] * b[11] + a[3] * b[16];
- res[2] = a[0] * b[2] + a[1] * b[7] + a[2] * b[12] + a[3] * b[17];
- res[3] = a[0] * b[3] + a[1] * b[8] + a[2] * b[13] + a[3] * b[18];
- res[4] = a[0] * b[4] + a[1] * b[9] + a[2] * b[14] + a[3] * b[19] + a[4];
- // G
- res[5] = a[5] * b[0] + a[6] * b[5] + a[7] * b[10] + a[8] * b[15];
- res[6] = a[5] * b[1] + a[6] * b[6] + a[7] * b[11] + a[8] * b[16];
- res[7] = a[5] * b[2] + a[6] * b[7] + a[7] * b[12] + a[8] * b[17];
- res[8] = a[5] * b[3] + a[6] * b[8] + a[7] * b[13] + a[8] * b[18];
- res[9] = a[5] * b[4] + a[6] * b[9] + a[7] * b[14] + a[8] * b[19] + a[9];
- // B
- res[10] = a[10] * b[0] + a[11] * b[5] + a[12] * b[10] + a[13] * b[15];
- res[11] = a[10] * b[1] + a[11] * b[6] + a[12] * b[11] + a[13] * b[16];
- res[12] = a[10] * b[2] + a[11] * b[7] + a[12] * b[12] + a[13] * b[17];
- res[13] = a[10] * b[3] + a[11] * b[8] + a[12] * b[13] + a[13] * b[18];
- res[14] = a[10] * b[4] + a[11] * b[9] + a[12] * b[14] + a[13] * b[19] + a[14];
- // A
- res[15] = a[15] * b[0] + a[16] * b[5] + a[17] * b[10] + a[18] * b[15];
- res[16] = a[15] * b[1] + a[16] * b[6] + a[17] * b[11] + a[18] * b[16];
- res[17] = a[15] * b[2] + a[16] * b[7] + a[17] * b[12] + a[18] * b[17];
- res[18] = a[15] * b[3] + a[16] * b[8] + a[17] * b[13] + a[18] * b[18];
- res[19] = a[15] * b[4] + a[16] * b[9] + a[17] * b[14] + a[18] * b[19] + a[19];
- return res;
- };
- var getColorMatrixFromColorMatrices = (colorMatrices) => colorMatrices.length
- ? colorMatrices.reduce((previous, current) => dotColorMatrix([...previous], current), colorMatrices.shift())
- : [];
- var roundFraction = (value, fr = 2) => Math.round(value * fr) / fr;
- var getImageRedactionScaleFactor = (imageSize, redactionShapes) => {
- const imageRes = imageSize.width * imageSize.height;
- const maxShapeSize = redactionShapes.reduce((max, shape) => {
- if (shape.width > max.width && shape.height > max.height) {
- max.width = shape.width;
- max.height = shape.height;
- }
- return max;
- }, { width: 0, height: 0 });
- const maxShapeRes = maxShapeSize.width * maxShapeSize.height;
- const fraction = Math.max(0.5, 0.5 + (1 - maxShapeRes / imageRes) / 2);
- return roundFraction(fraction, 5);
- };
- function noop() { }
- const identity = x => x;
- function assign(tar, src) {
- // @ts-ignore
- for (const k in src)
- tar[k] = src[k];
- return tar;
- }
- function run(fn) {
- return fn();
- }
- function blank_object() {
- return Object.create(null);
- }
- function run_all(fns) {
- fns.forEach(run);
- }
- function is_function(thing) {
- return typeof thing === 'function';
- }
- function safe_not_equal(a, b) {
- return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
- }
- function is_empty(obj) {
- return Object.keys(obj).length === 0;
- }
- function subscribe(store, ...callbacks) {
- if (store == null) {
- return noop;
- }
- const unsub = store.subscribe(...callbacks);
- return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
- }
- function get_store_value(store) {
- let value;
- subscribe(store, _ => value = _)();
- return value;
- }
- function component_subscribe(component, store, callback) {
- component.$$.on_destroy.push(subscribe(store, callback));
- }
- function create_slot(definition, ctx, $$scope, fn) {
- if (definition) {
- const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);
- return definition[0](slot_ctx);
- }
- }
- function get_slot_context(definition, ctx, $$scope, fn) {
- return definition[1] && fn
- ? assign($$scope.ctx.slice(), definition[1](fn(ctx)))
- : $$scope.ctx;
- }
- function get_slot_changes(definition, $$scope, dirty, fn) {
- if (definition[2] && fn) {
- const lets = definition[2](fn(dirty));
- if ($$scope.dirty === undefined) {
- return lets;
- }
- if (typeof lets === 'object') {
- const merged = [];
- const len = Math.max($$scope.dirty.length, lets.length);
- for (let i = 0; i < len; i += 1) {
- merged[i] = $$scope.dirty[i] | lets[i];
- }
- return merged;
- }
- return $$scope.dirty | lets;
- }
- return $$scope.dirty;
- }
- function update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) {
- const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);
- if (slot_changes) {
- const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);
- slot.p(slot_context, slot_changes);
- }
- }
- function exclude_internal_props(props) {
- const result = {};
- for (const k in props)
- if (k[0] !== '$')
- result[k] = props[k];
- return result;
- }
- function compute_rest_props(props, keys) {
- const rest = {};
- keys = new Set(keys);
- for (const k in props)
- if (!keys.has(k) && k[0] !== '$')
- rest[k] = props[k];
- return rest;
- }
- function set_store_value(store, ret, value = ret) {
- store.set(value);
- return ret;
- }
- function action_destroyer(action_result) {
- return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;
- }
- const is_client = typeof window !== 'undefined';
- let now = is_client
- ? () => window.performance.now()
- : () => Date.now();
- let raf = is_client ? cb => requestAnimationFrame(cb) : noop;
- const tasks = new Set();
- function run_tasks(now) {
- tasks.forEach(task => {
- if (!task.c(now)) {
- tasks.delete(task);
- task.f();
- }
- });
- if (tasks.size !== 0)
- raf(run_tasks);
- }
- /**
- * Creates a new task that runs on each raf frame
- * until it returns a falsy value or is aborted
- */
- function loop(callback) {
- let task;
- if (tasks.size === 0)
- raf(run_tasks);
- return {
- promise: new Promise(fulfill => {
- tasks.add(task = { c: callback, f: fulfill });
- }),
- abort() {
- tasks.delete(task);
- }
- };
- }
- function append(target, node) {
- target.appendChild(node);
- }
- function insert(target, node, anchor) {
- target.insertBefore(node, anchor || null);
- }
- function detach(node) {
- node.parentNode.removeChild(node);
- }
- function element(name) {
- return document.createElement(name);
- }
- function svg_element(name) {
- return document.createElementNS('http://www.w3.org/2000/svg', name);
- }
- function text(data) {
- return document.createTextNode(data);
- }
- function space() {
- return text(' ');
- }
- function empty() {
- return text('');
- }
- function listen(node, event, handler, options) {
- node.addEventListener(event, handler, options);
- return () => node.removeEventListener(event, handler, options);
- }
- function prevent_default(fn) {
- return function (event) {
- event.preventDefault();
- // @ts-ignore
- return fn.call(this, event);
- };
- }
- function stop_propagation(fn) {
- return function (event) {
- event.stopPropagation();
- // @ts-ignore
- return fn.call(this, event);
- };
- }
- function attr(node, attribute, value) {
- if (value == null)
- node.removeAttribute(attribute);
- else if (node.getAttribute(attribute) !== value)
- node.setAttribute(attribute, value);
- }
- function set_attributes(node, attributes) {
- // @ts-ignore
- const descriptors = Object.getOwnPropertyDescriptors(node.__proto__);
- for (const key in attributes) {
- if (attributes[key] == null) {
- node.removeAttribute(key);
- }
- else if (key === 'style') {
- node.style.cssText = attributes[key];
- }
- else if (key === '__value') {
- node.value = node[key] = attributes[key];
- }
- else if (descriptors[key] && descriptors[key].set) {
- node[key] = attributes[key];
- }
- else {
- attr(node, key, attributes[key]);
- }
- }
- }
- function children(element) {
- return Array.from(element.childNodes);
- }
- function set_data(text, data) {
- data = '' + data;
- if (text.wholeText !== data)
- text.data = data;
- }
- function set_input_value(input, value) {
- input.value = value == null ? '' : value;
- }
- function set_style(node, key, value, important) {
- node.style.setProperty(key, value, important ? 'important' : '');
- }
- function custom_event(type, detail) {
- const e = document.createEvent('CustomEvent');
- e.initCustomEvent(type, false, false, detail);
- return e;
- }
- class HtmlTag {
- constructor(anchor = null) {
- this.a = anchor;
- this.e = this.n = null;
- }
- m(html, target, anchor = null) {
- if (!this.e) {
- this.e = element(target.nodeName);
- this.t = target;
- this.h(html);
- }
- this.i(anchor);
- }
- h(html) {
- this.e.innerHTML = html;
- this.n = Array.from(this.e.childNodes);
- }
- i(anchor) {
- for (let i = 0; i < this.n.length; i += 1) {
- insert(this.t, this.n[i], anchor);
- }
- }
- p(html) {
- this.d();
- this.h(html);
- this.i(this.a);
- }
- d() {
- this.n.forEach(detach);
- }
- }
- const active_docs = new Set();
- let active = 0;
- // https://github.com/darkskyapp/string-hash/blob/master/index.js
- function hash(str) {
- let hash = 5381;
- let i = str.length;
- while (i--)
- hash = ((hash << 5) - hash) ^ str.charCodeAt(i);
- return hash >>> 0;
- }
- function create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {
- const step = 16.666 / duration;
- let keyframes = '{\n';
- for (let p = 0; p <= 1; p += step) {
- const t = a + (b - a) * ease(p);
- keyframes += p * 100 + `%{${fn(t, 1 - t)}}\n`;
- }
- const rule = keyframes + `100% {${fn(b, 1 - b)}}\n}`;
- const name = `__svelte_${hash(rule)}_${uid}`;
- const doc = node.ownerDocument;
- active_docs.add(doc);
- const stylesheet = doc.__svelte_stylesheet || (doc.__svelte_stylesheet = doc.head.appendChild(element('style')).sheet);
- const current_rules = doc.__svelte_rules || (doc.__svelte_rules = {});
- if (!current_rules[name]) {
- current_rules[name] = true;
- stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);
- }
- const animation = node.style.animation || '';
- node.style.animation = `${animation ? `${animation}, ` : ''}${name} ${duration}ms linear ${delay}ms 1 both`;
- active += 1;
- return name;
- }
- function delete_rule(node, name) {
- const previous = (node.style.animation || '').split(', ');
- const next = previous.filter(name
- ? anim => anim.indexOf(name) < 0 // remove specific animation
- : anim => anim.indexOf('__svelte') === -1 // remove all Svelte animations
- );
- const deleted = previous.length - next.length;
- if (deleted) {
- node.style.animation = next.join(', ');
- active -= deleted;
- if (!active)
- clear_rules();
- }
- }
- function clear_rules() {
- raf(() => {
- if (active)
- return;
- active_docs.forEach(doc => {
- const stylesheet = doc.__svelte_stylesheet;
- let i = stylesheet.cssRules.length;
- while (i--)
- stylesheet.deleteRule(i);
- doc.__svelte_rules = {};
- });
- active_docs.clear();
- });
- }
- let current_component;
- function set_current_component(component) {
- current_component = component;
- }
- function get_current_component() {
- if (!current_component)
- throw new Error('Function called outside component initialization');
- return current_component;
- }
- function onMount(fn) {
- get_current_component().$$.on_mount.push(fn);
- }
- function afterUpdate(fn) {
- get_current_component().$$.after_update.push(fn);
- }
- function onDestroy(fn) {
- get_current_component().$$.on_destroy.push(fn);
- }
- function createEventDispatcher() {
- const component = get_current_component();
- return (type, detail) => {
- const callbacks = component.$$.callbacks[type];
- if (callbacks) {
- // TODO are there situations where events could be dispatched
- // in a server (non-DOM) environment?
- const event = custom_event(type, detail);
- callbacks.slice().forEach(fn => {
- fn.call(component, event);
- });
- }
- };
- }
- function setContext(key, context) {
- get_current_component().$$.context.set(key, context);
- }
- function getContext(key) {
- return get_current_component().$$.context.get(key);
- }
- // TODO figure out if we still want to support
- // shorthand events, or if we want to implement
- // a real bubbling mechanism
- function bubble(component, event) {
- const callbacks = component.$$.callbacks[event.type];
- if (callbacks) {
- callbacks.slice().forEach(fn => fn(event));
- }
- }
- const dirty_components = [];
- const binding_callbacks = [];
- const render_callbacks = [];
- const flush_callbacks = [];
- const resolved_promise = Promise.resolve();
- let update_scheduled = false;
- function schedule_update() {
- if (!update_scheduled) {
- update_scheduled = true;
- resolved_promise.then(flush);
- }
- }
- function add_render_callback(fn) {
- render_callbacks.push(fn);
- }
- function add_flush_callback(fn) {
- flush_callbacks.push(fn);
- }
- let flushing = false;
- const seen_callbacks = new Set();
- function flush() {
- if (flushing)
- return;
- flushing = true;
- do {
- // first, call beforeUpdate functions
- // and update components
- for (let i = 0; i < dirty_components.length; i += 1) {
- const component = dirty_components[i];
- set_current_component(component);
- update(component.$$);
- }
- set_current_component(null);
- dirty_components.length = 0;
- while (binding_callbacks.length)
- binding_callbacks.pop()();
- // then, once components are updated, call
- // afterUpdate functions. This may cause
- // subsequent updates...
- for (let i = 0; i < render_callbacks.length; i += 1) {
- const callback = render_callbacks[i];
- if (!seen_callbacks.has(callback)) {
- // ...so guard against infinite loops
- seen_callbacks.add(callback);
- callback();
- }
- }
- render_callbacks.length = 0;
- } while (dirty_components.length);
- while (flush_callbacks.length) {
- flush_callbacks.pop()();
- }
- update_scheduled = false;
- flushing = false;
- seen_callbacks.clear();
- }
- function update($$) {
- if ($$.fragment !== null) {
- $$.update();
- run_all($$.before_update);
- const dirty = $$.dirty;
- $$.dirty = [-1];
- $$.fragment && $$.fragment.p($$.ctx, dirty);
- $$.after_update.forEach(add_render_callback);
- }
- }
- let promise;
- function wait() {
- if (!promise) {
- promise = Promise.resolve();
- promise.then(() => {
- promise = null;
- });
- }
- return promise;
- }
- function dispatch(node, direction, kind) {
- node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));
- }
- const outroing = new Set();
- let outros;
- function group_outros() {
- outros = {
- r: 0,
- c: [],
- p: outros // parent group
- };
- }
- function check_outros() {
- if (!outros.r) {
- run_all(outros.c);
- }
- outros = outros.p;
- }
- function transition_in(block, local) {
- if (block && block.i) {
- outroing.delete(block);
- block.i(local);
- }
- }
- function transition_out(block, local, detach, callback) {
- if (block && block.o) {
- if (outroing.has(block))
- return;
- outroing.add(block);
- outros.c.push(() => {
- outroing.delete(block);
- if (callback) {
- if (detach)
- block.d(1);
- callback();
- }
- });
- block.o(local);
- }
- }
- const null_transition = { duration: 0 };
- function create_bidirectional_transition(node, fn, params, intro) {
- let config = fn(node, params);
- let t = intro ? 0 : 1;
- let running_program = null;
- let pending_program = null;
- let animation_name = null;
- function clear_animation() {
- if (animation_name)
- delete_rule(node, animation_name);
- }
- function init(program, duration) {
- const d = program.b - t;
- duration *= Math.abs(d);
- return {
- a: t,
- b: program.b,
- d,
- duration,
- start: program.start,
- end: program.start + duration,
- group: program.group
- };
- }
- function go(b) {
- const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;
- const program = {
- start: now() + delay,
- b
- };
- if (!b) {
- // @ts-ignore todo: improve typings
- program.group = outros;
- outros.r += 1;
- }
- if (running_program || pending_program) {
- pending_program = program;
- }
- else {
- // if this is an intro, and there's a delay, we need to do
- // an initial tick and/or apply CSS animation immediately
- if (css) {
- clear_animation();
- animation_name = create_rule(node, t, b, duration, delay, easing, css);
- }
- if (b)
- tick(0, 1);
- running_program = init(program, duration);
- add_render_callback(() => dispatch(node, b, 'start'));
- loop(now => {
- if (pending_program && now > pending_program.start) {
- running_program = init(pending_program, duration);
- pending_program = null;
- dispatch(node, running_program.b, 'start');
- if (css) {
- clear_animation();
- animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css);
- }
- }
- if (running_program) {
- if (now >= running_program.end) {
- tick(t = running_program.b, 1 - t);
- dispatch(node, running_program.b, 'end');
- if (!pending_program) {
- // we're done
- if (running_program.b) {
- // intro — we can tidy up immediately
- clear_animation();
- }
- else {
- // outro — needs to be coordinated
- if (!--running_program.group.r)
- run_all(running_program.group.c);
- }
- }
- running_program = null;
- }
- else if (now >= running_program.start) {
- const p = now - running_program.start;
- t = running_program.a + running_program.d * easing(p / running_program.duration);
- tick(t, 1 - t);
- }
- }
- return !!(running_program || pending_program);
- });
- }
- }
- return {
- run(b) {
- if (is_function(config)) {
- wait().then(() => {
- // @ts-ignore
- config = config();
- go(b);
- });
- }
- else {
- go(b);
- }
- },
- end() {
- clear_animation();
- running_program = pending_program = null;
- }
- };
- }
- const globals = (typeof window !== 'undefined'
- ? window
- : typeof globalThis !== 'undefined'
- ? globalThis
- : global);
- function destroy_block(block, lookup) {
- block.d(1);
- lookup.delete(block.key);
- }
- function outro_and_destroy_block(block, lookup) {
- transition_out(block, 1, 1, () => {
- lookup.delete(block.key);
- });
- }
- function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) {
- let o = old_blocks.length;
- let n = list.length;
- let i = o;
- const old_indexes = {};
- while (i--)
- old_indexes[old_blocks[i].key] = i;
- const new_blocks = [];
- const new_lookup = new Map();
- const deltas = new Map();
- i = n;
- while (i--) {
- const child_ctx = get_context(ctx, list, i);
- const key = get_key(child_ctx);
- let block = lookup.get(key);
- if (!block) {
- block = create_each_block(key, child_ctx);
- block.c();
- }
- else if (dynamic) {
- block.p(child_ctx, dirty);
- }
- new_lookup.set(key, new_blocks[i] = block);
- if (key in old_indexes)
- deltas.set(key, Math.abs(i - old_indexes[key]));
- }
- const will_move = new Set();
- const did_move = new Set();
- function insert(block) {
- transition_in(block, 1);
- block.m(node, next);
- lookup.set(block.key, block);
- next = block.first;
- n--;
- }
- while (o && n) {
- const new_block = new_blocks[n - 1];
- const old_block = old_blocks[o - 1];
- const new_key = new_block.key;
- const old_key = old_block.key;
- if (new_block === old_block) {
- // do nothing
- next = new_block.first;
- o--;
- n--;
- }
- else if (!new_lookup.has(old_key)) {
- // remove old block
- destroy(old_block, lookup);
- o--;
- }
- else if (!lookup.has(new_key) || will_move.has(new_key)) {
- insert(new_block);
- }
- else if (did_move.has(old_key)) {
- o--;
- }
- else if (deltas.get(new_key) > deltas.get(old_key)) {
- did_move.add(new_key);
- insert(new_block);
- }
- else {
- will_move.add(old_key);
- o--;
- }
- }
- while (o--) {
- const old_block = old_blocks[o];
- if (!new_lookup.has(old_block.key))
- destroy(old_block, lookup);
- }
- while (n)
- insert(new_blocks[n - 1]);
- return new_blocks;
- }
- function get_spread_update(levels, updates) {
- const update = {};
- const to_null_out = {};
- const accounted_for = { $$scope: 1 };
- let i = levels.length;
- while (i--) {
- const o = levels[i];
- const n = updates[i];
- if (n) {
- for (const key in o) {
- if (!(key in n))
- to_null_out[key] = 1;
- }
- for (const key in n) {
- if (!accounted_for[key]) {
- update[key] = n[key];
- accounted_for[key] = 1;
- }
- }
- levels[i] = n;
- }
- else {
- for (const key in o) {
- accounted_for[key] = 1;
- }
- }
- }
- for (const key in to_null_out) {
- if (!(key in update))
- update[key] = undefined;
- }
- return update;
- }
- function get_spread_object(spread_props) {
- return typeof spread_props === 'object' && spread_props !== null ? spread_props : {};
- }
- function bind(component, name, callback) {
- const index = component.$$.props[name];
- if (index !== undefined) {
- component.$$.bound[index] = callback;
- callback(component.$$.ctx[index]);
- }
- }
- function create_component(block) {
- block && block.c();
- }
- function mount_component(component, target, anchor, customElement) {
- const { fragment, on_mount, on_destroy, after_update } = component.$$;
- fragment && fragment.m(target, anchor);
- if (!customElement) {
- // onMount happens before the initial afterUpdate
- add_render_callback(() => {
- const new_on_destroy = on_mount.map(run).filter(is_function);
- if (on_destroy) {
- on_destroy.push(...new_on_destroy);
- }
- else {
- // Edge case - component was destroyed immediately,
- // most likely as a result of a binding initialising
- run_all(new_on_destroy);
- }
- component.$$.on_mount = [];
- });
- }
- after_update.forEach(add_render_callback);
- }
- function destroy_component(component, detaching) {
- const $$ = component.$$;
- if ($$.fragment !== null) {
- run_all($$.on_destroy);
- $$.fragment && $$.fragment.d(detaching);
- // TODO null out other refs, including component.$$ (but need to
- // preserve final state?)
- $$.on_destroy = $$.fragment = null;
- $$.ctx = [];
- }
- }
- function make_dirty(component, i) {
- if (component.$$.dirty[0] === -1) {
- dirty_components.push(component);
- schedule_update();
- component.$$.dirty.fill(0);
- }
- component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
- }
- function init(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) {
- const parent_component = current_component;
- set_current_component(component);
- const $$ = component.$$ = {
- fragment: null,
- ctx: null,
- // state
- props,
- update: noop,
- not_equal,
- bound: blank_object(),
- // lifecycle
- on_mount: [],
- on_destroy: [],
- on_disconnect: [],
- before_update: [],
- after_update: [],
- context: new Map(parent_component ? parent_component.$$.context : options.context || []),
- // everything else
- callbacks: blank_object(),
- dirty,
- skip_bound: false
- };
- let ready = false;
- $$.ctx = instance
- ? instance(component, options.props || {}, (i, ret, ...rest) => {
- const value = rest.length ? rest[0] : ret;
- if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
- if (!$$.skip_bound && $$.bound[i])
- $$.bound[i](value);
- if (ready)
- make_dirty(component, i);
- }
- return ret;
- })
- : [];
- $$.update();
- ready = true;
- run_all($$.before_update);
- // `false` as a special case of no DOM component
- $$.fragment = create_fragment ? create_fragment($$.ctx) : false;
- if (options.target) {
- if (options.hydrate) {
- const nodes = children(options.target);
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- $$.fragment && $$.fragment.l(nodes);
- nodes.forEach(detach);
- }
- else {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- $$.fragment && $$.fragment.c();
- }
- if (options.intro)
- transition_in(component.$$.fragment);
- mount_component(component, options.target, options.anchor, options.customElement);
- flush();
- }
- set_current_component(parent_component);
- }
- /**
- * Base class for Svelte components. Used when dev=false.
- */
- class SvelteComponent {
- $destroy() {
- destroy_component(this, 1);
- this.$destroy = noop;
- }
- $on(type, callback) {
- const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));
- callbacks.push(callback);
- return () => {
- const index = callbacks.indexOf(callback);
- if (index !== -1)
- callbacks.splice(index, 1);
- };
- }
- $set($$props) {
- if (this.$$set && !is_empty($$props)) {
- this.$$.skip_bound = true;
- this.$$set($$props);
- this.$$.skip_bound = false;
- }
- }
- }
- const subscriber_queue = [];
- /**
- * Creates a `Readable` store that allows reading by subscription.
- * @param value initial value
- * @param {StartStopNotifier}start start and stop notifications for subscriptions
- */
- function readable(value, start) {
- return {
- subscribe: writable(value, start).subscribe
- };
- }
- /**
- * Create a `Writable` store that allows both updating and reading by subscription.
- * @param {*=}value initial value
- * @param {StartStopNotifier=}start start and stop notifications for subscriptions
- */
- function writable(value, start = noop) {
- let stop;
- const subscribers = [];
- function set(new_value) {
- if (safe_not_equal(value, new_value)) {
- value = new_value;
- if (stop) { // store is ready
- const run_queue = !subscriber_queue.length;
- for (let i = 0; i < subscribers.length; i += 1) {
- const s = subscribers[i];
- s[1]();
- subscriber_queue.push(s, value);
- }
- if (run_queue) {
- for (let i = 0; i < subscriber_queue.length; i += 2) {
- subscriber_queue[i][0](subscriber_queue[i + 1]);
- }
- subscriber_queue.length = 0;
- }
- }
- }
- }
- function update(fn) {
- set(fn(value));
- }
- function subscribe(run, invalidate = noop) {
- const subscriber = [run, invalidate];
- subscribers.push(subscriber);
- if (subscribers.length === 1) {
- stop = start(set) || noop;
- }
- run(value);
- return () => {
- const index = subscribers.indexOf(subscriber);
- if (index !== -1) {
- subscribers.splice(index, 1);
- }
- if (subscribers.length === 0) {
- stop();
- stop = null;
- }
- };
- }
- return { set, update, subscribe };
- }
- function derived(stores, fn, initial_value) {
- const single = !Array.isArray(stores);
- const stores_array = single
- ? [stores]
- : stores;
- const auto = fn.length < 2;
- return readable(initial_value, (set) => {
- let inited = false;
- const values = [];
- let pending = 0;
- let cleanup = noop;
- const sync = () => {
- if (pending) {
- return;
- }
- cleanup();
- const result = fn(single ? values[0] : values, set);
- if (auto) {
- set(result);
- }
- else {
- cleanup = is_function(result) ? result : noop;
- }
- };
- const unsubscribers = stores_array.map((store, i) => subscribe(store, (value) => {
- values[i] = value;
- pending &= ~(1 << i);
- if (inited) {
- sync();
- }
- }, () => {
- pending |= (1 << i);
- }));
- inited = true;
- sync();
- return function stop() {
- run_all(unsubscribers);
- cleanup();
- };
- });
- }
- var mergeObjects = (objects) => objects.reduce((prev, curr) => Object.assign(prev, curr), {});
- // @ts-ignore
- const UPDATE_VALUE = (updateValue) => ({ updateValue });
- const DEFAULT_VALUE = (defaultValue) => ({ defaultValue });
- const CUSTOM_STORE = (fn) => ({ store: fn });
- // @ts-ignore
- const DERIVED_STORE = (fn) => ({ store: (defaultValue, stores) => derived(...fn(stores)) });
- const UNIQUE_DERIVED_STORE = (fn) => ({
- store: (defaultValue, stores) => {
- const [selectedStores, update, isEqual = () => false] = fn(stores);
- let isFirst = true;
- let currentValue;
- return derived(selectedStores, (storeValues, set) => {
- update(storeValues, (value) => {
- if (!isFirst && isEqual(currentValue, value))
- return;
- currentValue = value;
- isFirst = false;
- set(value);
- });
- });
- },
- });
- const MAP_STORE = (fn) => ({
- store: (defaultValue, stores) => {
- const [valueMapper, observedStores = {}, sorter = undefined] = fn(stores);
- let storedItems = [];
- let $observedStores = {};
- const mapValue = (item) => valueMapper(item, $observedStores);
- // set default properties for each item
- const setValue = (items) => {
- // was empty, still empty
- if (!storedItems.length && !items.length)
- return;
- // update value
- storedItems = items;
- updateValue();
- };
- const updateValue = () => {
- const mappedItems = storedItems.map(mapValue);
- if (sorter)
- mappedItems.sort(sorter);
- storedItems = [...mappedItems];
- set(mappedItems);
- };
- // TODO: need to at some point unsub from these stores
- Object.entries(observedStores).map(([name, store]) => {
- return store.subscribe((value) => {
- $observedStores[name] = value;
- if (!value)
- return;
- updateValue();
- });
- });
- const { subscribe, set } = writable(defaultValue || []);
- return {
- set: setValue,
- update: (fn) => setValue(fn(storedItems)),
- subscribe,
- };
- },
- });
- const createStore = (accessors, stores, options) => {
- const { store = (defaultValue) => writable(defaultValue), defaultValue = noop$1, // should be a function returning the default value
- updateValue = undefined, } = options;
- // create our private store
- const storeInstance = store(defaultValue(), stores, accessors);
- const { subscribe, update = noop$1 } = storeInstance; // update = noop because not all stores can be updated
- // on update private store
- let unsub;
- const onUpdate = (cb) => {
- let ignoreFirstCallback = true;
- if (unsub)
- unsub();
- unsub = subscribe((value) => {
- // need to ignore first callback because that returns current value
- if (ignoreFirstCallback)
- return (ignoreFirstCallback = false);
- // now we have the newly assigned value
- cb(value);
- unsub();
- unsub = undefined;
- });
- };
- // create the value updater function, needs access to stores so can read all store values
- const updateStoreValue = updateValue ? updateValue(accessors) : passthrough;
- // set and validate value
- storeInstance.set = (nextValue) => update((previousValue) => updateStoreValue(nextValue, previousValue, onUpdate));
- // set default value for external reference
- storeInstance.defaultValue = defaultValue;
- // expose store api
- return storeInstance;
- };
- var createStores = (props) => {
- const stores = {};
- const accessors = {};
- props.forEach(([name, ...options]) => {
- const opts = mergeObjects(options);
- const store = (stores[name] = createStore(accessors, stores, opts));
- const property = {
- get: () => get_store_value(store),
- set: store.set,
- };
- Object.defineProperty(accessors, name, property);
- });
- return {
- stores,
- accessors,
- };
- };
- var props = [
- // io
- ['src'],
- ['imageReader'],
- ['imageWriter'],
- // will process markup items before rendering, used by arrows and frames
- ['shapePreprocessor'],
- // will scramble image data for use with image redaction logic
- ['imageScrambler'],
- // current images
- ['images', DEFAULT_VALUE(() => [])],
- ];
- var capitalizeFirstLetter = (str) => str.charAt(0).toUpperCase() + str.slice(1);
- var defineMethods = (object, api) => {
- Object.keys(api).forEach((name) => {
- const descriptor = isFunction(api[name])
- ? {
- value: api[name],
- writable: false,
- }
- : api[name];
- Object.defineProperty(object, name, descriptor);
- });
- };
- const scalar = 10000;
- var offsetRectToFitPolygon = (rect, poly) => {
- const polyLines = quadLines(poly);
- const offset = vectorCreateEmpty();
- const rectVertexes = rectGetCorners(rect);
- // we can fit it
- rectVertexes.forEach((vertex) => {
- // we update each corner by adding the current offset
- vectorAdd(vertex, offset);
- // test if point lies in polygon, if so, all is fine and we can exit
- if (pointInPoly(vertex, poly))
- return;
- polyLines.forEach((line) => {
- // get angle of edge and draw a ray from the corner perpendicular to the edge
- const a = Math.atan2(line.start.y - line.end.y, line.start.x - line.end.x);
- const x = Math.sin(Math.PI - a) * scalar;
- const y = Math.cos(Math.PI - a) * scalar;
- const ray = vectorCreate(vertex.x + x, vertex.y + y);
- // extend the poly line so even if we overshoot the polygon we hit it
- const lineExtended = lineExtend(lineClone(line), scalar);
- // get the resulting intersection (there's always an intersection)
- const intersection = lineLineIntersection(lineCreate(vertex, ray), lineExtended);
- // no intersection, no need to do anything
- if (!intersection)
- return;
- // update offset to move towards image
- vectorAdd(offset, vectorSubtract(vectorClone(intersection), vertex));
- });
- });
- // test if any vertexes still fall outside of poly, if so, we can't fit the rect
- const rectOffset = rectClone(rect);
- vectorAdd(rectOffset, offset);
- const rectOffsetVertices = rectGetCorners(rectOffset);
- const fits = rectOffsetVertices.every((vertex) => pointInPoly(vertex, poly));
- if (fits) {
- rectUpdateWithRect(rect, rectOffset);
- return true;
- }
- return false;
- };
- var limitCropRectToImage = (rect, poly) => {
- // get crop rect polygon vertexes
- const rectVertexes = rectGetCorners(rect);
- // if we end up here it doesn't fit, we might need to adjust
- const polyLines = quadLines(poly)
- // extend the poly lines a tiny bit so we
- // don't shoot rays between line gaps at corners
- // this caused one intersection to be missing resulting
- // in error while manipulating crop edges
- // (rotate image 90degrees -> drag bottom edge) (2021-04-09)
- .map((line) => lineExtend(line, 5));
- const rectCenterPosition = rectCenter(rect);
- const intersections = [];
- rectVertexes.forEach((rectVertex) => {
- const ray = lineMultiply(lineCreate(vectorClone(rectCenterPosition), vectorClone(rectVertex)), 1000000);
- let intersectionFound = false;
- polyLines.map(lineClone).forEach((line) => {
- const intersection = lineLineIntersection(ray, line);
- if (!intersection || intersectionFound)
- return;
- intersections.push(intersection);
- intersectionFound = true;
- });
- });
- // top left -> bottom right
- const tlbr = vectorDistance(intersections[0], intersections[2]);
- // top right -> bottom left
- const trbl = vectorDistance(intersections[1], intersections[3]);
- // calculate smallest rectangle we can make, use that
- const rectLimitedVertices = tlbr < trbl ? [intersections[0], intersections[2]] : [intersections[1], intersections[3]];
- const rectLimitedToImage = rectCreateFromPoints(rectLimitedVertices);
- // only use our fitted crop rectangle if it's smaller than our current rectangle,
- // this would mean that our current rectangle couldn't be moved to make it fit
- if (rectLimitedToImage.width < rect.width) {
- // need to center on previous rect
- rectUpdateWithRect(rect, rectLimitedToImage);
- return true;
- }
- return false;
- };
- var getImagePolygon = (image, imageRotation, imagePerspective = { x: 0, y: 0 }) => {
- const imageRect = rectCreateFromSize(image);
- const imageCenter = rectCenter(imageRect);
- const imagePoly = rectApplyPerspective(imageRect, imagePerspective, imageCenter).map((imageVertex) => vectorRotate(imageVertex, imageRotation, imageCenter));
- // get image poly bounds, we need this to offset the poly vertices from 0,0
- const imagePolyBounds = rectCreateFromPoints(imagePoly);
- // get image polygon vertexes
- return imagePoly.map((imageVertex) => vectorSubtract(imageVertex, imagePolyBounds));
- };
- var getMaxSizeInRect = (size, rotation = 0, aspectRatio = rectAspectRatio(size)) => {
- let width;
- let height;
- if (rotation !== 0) {
- const innerAngle = Math.atan2(1, aspectRatio);
- const rotationSigned = Math.sign(rotation) * rotation;
- const rotationSignedMod = rotationSigned % Math.PI;
- const rotationSignedModHalf = rotationSigned % HALF_PI;
- // determine if is turned on side
- let hyp;
- let r;
- if (rotationSignedMod > QUART_PI && rotationSignedMod < HALF_PI + QUART_PI) {
- r = rotationSignedModHalf > QUART_PI ? rotationSigned : HALF_PI - rotationSignedModHalf;
- }
- else {
- r = rotationSignedModHalf > QUART_PI ? HALF_PI - rotationSignedModHalf : rotationSigned;
- }
- hyp = Math.min(Math.abs(size.height / Math.sin(innerAngle + r)), Math.abs(size.width / Math.cos(innerAngle - r)));
- width = Math.cos(innerAngle) * hyp;
- height = width / aspectRatio;
- }
- else {
- width = size.width;
- height = width / aspectRatio;
- if (height > size.height) {
- height = size.height;
- width = height * aspectRatio;
- }
- }
- return sizeCreate(width, height);
- };
- var limitRectToImage = (rect, imageSize, imageRotation = 0, imagePerspective = vectorCreateEmpty(), minSize) => {
- // rotation and/or perspective, let's use the "advanced" collision detection method
- if ((isNumber(imageRotation) && imageRotation !== 0) ||
- imagePerspective.x ||
- imagePerspective.y) {
- const inputAspectRatio = rectAspectRatio(rect);
- // test if crop can fit image, if it can, offset the crop so it fits
- const imagePolygon = getImagePolygon(imageSize, imageRotation, imagePerspective);
- const maxSizeInRect = getMaxSizeInRect(imageSize, imageRotation, inputAspectRatio);
- const canFit = rect.width < maxSizeInRect.width && rect.height < maxSizeInRect.height;
- if (!canFit) {
- const dx = rect.width * 0.5 - maxSizeInRect.width * 0.5;
- const dy = rect.height * 0.5 - maxSizeInRect.height * 0.5;
- // adjust crop rect to max size
- if (rect.width > maxSizeInRect.width) {
- rect.width = maxSizeInRect.width;
- rect.x += dx;
- }
- if (rect.height > maxSizeInRect.height) {
- rect.height = maxSizeInRect.height;
- rect.y += dy;
- }
- // test if has exceeded min size, if so we need to limit the size and recalculate the other edge
- /*
- -\
- / ---\
- h2 ---\
- / ---\
- +--------w---------+\
- /| | ---\
- / | | ---\
- / | | ---\
- / | | --
- h1 | | /
- / | | /
- / | | /
- -\ | | /
- ---\ | | /
- --+------------------+ /
- ---\ /
- --\ /
- ---\ /
- ---\ /
- ---\ /
- --
- */
- }
- offsetRectToFitPolygon(rect, imagePolygon);
- const wasLimited = limitCropRectToImage(rect, imagePolygon);
- // this makes sure that after limiting the size, the crop rect is moved to a position that is inside the image
- if (wasLimited)
- offsetRectToFitPolygon(rect, imagePolygon);
- }
- // no rotation, no perspective, use simple bounds method
- else {
- // remember intended aspect ratio so we can try and recreate it
- let intendedAspectRatio = rectAspectRatio(rect);
- // limit to image size first, can never exceed that
- rect.width = Math.min(rect.width, imageSize.width);
- rect.height = Math.min(rect.height, imageSize.height);
- // reposition rect so it's always inside image bounds
- rect.x = Math.max(rect.x, 0);
- if (rect.x + rect.width > imageSize.width) {
- rect.x -= rect.x + rect.width - imageSize.width;
- }
- rect.y = Math.max(rect.y, 0);
- if (rect.y + rect.height > imageSize.height) {
- rect.y -= rect.y + rect.height - imageSize.height;
- }
- // we get the center of the current rect so we can center the contained rect to it
- const intendedCenter = rectCenter(rect);
- // make sure still adheres to aspect ratio
- const containedRect = rectContainRect(rect, intendedAspectRatio);
- containedRect.width = Math.max(minSize.width, containedRect.width);
- containedRect.height = Math.max(minSize.height, containedRect.height);
- containedRect.x = intendedCenter.x - containedRect.width * 0.5;
- containedRect.y = intendedCenter.y - containedRect.height * 0.5;
- rectUpdateWithRect(rect, containedRect);
- }
- };
- var applyCropRectAction = (cropRectPrevious, cropRectNext, imageSize, imageRotation, imagePerspective, cropLimitToImageBounds, cropMinSize, cropMaxSize) => {
- // clone
- const minSize = sizeClone(cropMinSize);
- // set upper bounds to crop max size
- const maxSize = sizeClone(cropMaxSize);
- // limit max size (more important that min size is respected so first limit max size)
- const maxScalar = fixPrecision(Math.max(cropRectNext.width / maxSize.width, cropRectNext.height / maxSize.height));
- const minScalar = fixPrecision(Math.min(cropRectNext.width / minSize.width, cropRectNext.height / minSize.height));
- // clone for resulting crop rect
- const cropRectOut = rectClone(cropRectNext);
- //
- // if exceeds min or max scale correct next crop rectangle to conform to bounds
- //
- if (minScalar < 1 || maxScalar > 1) {
- // center of both previous and next crop rects
- const previousCropRectCenter = rectCenter(cropRectPrevious);
- const nextCropRectCenter = rectCenter(cropRectNext);
- // calculate scales
- const scalar = minScalar < 1 ? minScalar : maxScalar;
- const cx = (nextCropRectCenter.x + previousCropRectCenter.x) / 2;
- const cy = (nextCropRectCenter.y + previousCropRectCenter.y) / 2;
- const cw = cropRectOut.width / scalar;
- const ch = cropRectOut.height / scalar;
- rectUpdate(cropRectOut, cx - cw * 0.5, cy - ch * 0.5, cw, ch);
- }
- // no need to limit to bounds, let's go!
- if (!cropLimitToImageBounds)
- return {
- crop: cropRectOut,
- };
- //
- // make sure the crop is made inside the bounds of the image
- //
- limitRectToImage(cropRectOut, imageSize, imageRotation, imagePerspective, minSize);
- return {
- crop: cropRectOut,
- };
- };
- var getBaseCropRect = (imageSize, transformedCropRect, imageRotation) => {
- const imageRect = rectCreateFromSize(imageSize);
- const imageCenter = rectCenter(imageRect);
- const imageTransformedVertices = rectRotate(imageRect, imageRotation, imageCenter);
- // get the rotated image bounds center (offset isn't relevant as crop is relative to top left image position)
- const imageRotatedBoundsCenter = rectCenter(rectNormalizeOffset(rectCreateFromPoints(imageTransformedVertices)));
- // get the center of the crop inside the rotated image
- const cropCenterInTransformedImage = rectCenter(transformedCropRect);
- // invert the rotation of the crop center around the rotated image center
- const deRotatedCropCenter = vectorRotate(cropCenterInTransformedImage, -imageRotation, imageRotatedBoundsCenter);
- // calculate crop distance from rotated image center
- const cropFromCenterOfTransformedImage = vectorSubtract(deRotatedCropCenter, imageRotatedBoundsCenter);
- // calculate original crop offset (from untransformed image)
- const originalCropCenterOffset = vectorApply(vectorAdd(imageCenter, cropFromCenterOfTransformedImage), fixPrecision);
- return rectCreate(originalCropCenterOffset.x - transformedCropRect.width * 0.5, originalCropCenterOffset.y - transformedCropRect.height * 0.5, transformedCropRect.width, transformedCropRect.height);
- };
- var clamp = (value, min, max) => Math.max(min, Math.min(value, max));
- var applyRotationAction = (imageRotationPrevious, imageRotation, imageRotationRange, cropRect, imageSize, imagePerspective, cropLimitToImageBounds, cropRectOrigin, cropMinSize, cropMaxSize) => {
- // clone
- const minSize = sizeClone(cropMinSize);
- // set upper bounds to crop max size if image is bigger than max size,
- // else if should limit to image bounds use image size as limit
- const maxSize = sizeClone(cropMaxSize);
- if (cropLimitToImageBounds) {
- maxSize.width = Math.min(cropMaxSize.width, imageSize.width);
- maxSize.height = Math.min(cropMaxSize.height, imageSize.height);
- }
- let didAttemptDoubleTurn = false;
- const rotate = (rotationPrevious, rotation) => {
- // get the base crop rect (position of crop rect in untransformed image)
- // if we have the base crop rect we can apply the new rotation to it
- const cropRectBase = getBaseCropRect(imageSize, cropRect, rotationPrevious);
- // calculate transforms based on new rotation and base crop rect
- const imageRect = rectCreateFromSize(imageSize);
- const imageCenter = rectCenter(imageRect);
- const imageTransformedCorners = rectApplyPerspective(imageRect, imagePerspective, imageCenter);
- // need this to correct for perspective centroid displacement
- const perspectiveOffset = vectorSubtract(vectorClone(imageCenter), convexPolyCentroid(imageTransformedCorners));
- // rotate around center of image
- const cropCenter = vectorRotate(rectCenter(cropRectBase), rotation, imageCenter);
- const rotateCropOffset = vectorSubtract(vectorClone(imageCenter), cropCenter);
- // get center of image bounds and move to correct position
- imageTransformedCorners.forEach((imageVertex) => vectorRotate(imageVertex, rotation, imageCenter));
- const imageBoundsRect = rectCreateFromPoints(imageTransformedCorners);
- const imageCentroid = convexPolyCentroid(imageTransformedCorners);
- const cropOffset = vectorAdd(vectorSubtract(vectorSubtract(imageCentroid, rotateCropOffset), imageBoundsRect), perspectiveOffset);
- // create output cropRect
- const cropRectOut = rectCreate(cropOffset.x - cropRectBase.width * 0.5, cropOffset.y - cropRectBase.height * 0.5, cropRectBase.width, cropRectBase.height);
- // if has size target, scale croprect to target size
- if (cropRectOrigin) {
- rectScale(cropRectOut, cropRectOrigin.width / cropRectOut.width);
- }
- // if should limit to image bounds
- if (cropLimitToImageBounds) {
- const imagePoly = getImagePolygon(imageSize, rotation, imagePerspective);
- // offsetRectToFitPolygon(cropRectOut, imagePoly);
- // commenting this fixes poly sliding problem when adjusting rotation
- limitCropRectToImage(cropRectOut, imagePoly);
- }
- //#region if exceeds min or max adjust rotation to conform to bounds
- const minScalar = fixPrecision(Math.min(cropRectOut.width / minSize.width, cropRectOut.height / minSize.height), 8);
- const maxScalar = fixPrecision(Math.max(cropRectOut.width / maxSize.width, cropRectOut.height / maxSize.height), 8);
- if (minScalar < 1 || maxScalar > 1) {
- // determine if is full image turn
- const isTurn = fixPrecision(Math.abs(rotation - rotationPrevious)) === fixPrecision(Math.PI / 2);
- // try another turn if is turning image
- if (isTurn && !didAttemptDoubleTurn) {
- didAttemptDoubleTurn = true;
- return rotate(imageRotationPrevious, imageRotationPrevious + Math.sign(rotation - rotationPrevious) * Math.PI);
- }
- }
- //#endregion
- return {
- rotation,
- crop: rectApply(cropRectOut, (v) => fixPrecision(v, 8)),
- };
- };
- // amount of turns applied, we need this to correctly determine the allowed rotation range
- const imageTurns = Math.sign(imageRotation) * Math.round(Math.abs(imageRotation) / HALF_PI) * HALF_PI;
- const imageRotationClamped = clamp(imageRotation, imageTurns + imageRotationRange[0], imageTurns + imageRotationRange[1]);
- // set new crop position
- return rotate(imageRotationPrevious, imageRotationClamped);
- };
- // @ts-ignore
- const ORDERED_STATE_PROPS = [
- // requirements
- 'cropLimitToImage',
- 'cropMinSize',
- 'cropMaxSize',
- 'cropAspectRatio',
- // selection -> flip -> rotate -> perspective -> crop
- 'flipX',
- 'flipY',
- 'rotation',
- 'crop',
- // 'perspectiveX',
- // 'perspectiveY',
- // effects
- 'colorMatrix',
- 'convolutionMatrix',
- 'gamma',
- 'vignette',
- // 'noise',
- // shapes
- 'redaction',
- 'annotation',
- 'decoration',
- 'frame',
- // other
- 'backgroundColor',
- 'targetSize',
- 'metadata',
- ];
- const clone = (value) => {
- if (isArray(value)) {
- return value.map(clone);
- }
- else if (isObject(value)) {
- return { ...value };
- }
- return value;
- };
- const filterShapeState = (shapes) => shapes.map((shape) => Object.entries(shape).reduce((copy, [key, value]) => {
- if (key.startsWith('_'))
- return copy;
- copy[key] = value;
- return copy;
- }, {}));
- var stateStore = (_, stores, accessors) => {
- const observedStores = ORDERED_STATE_PROPS.map((key) => stores[key]);
- // can only subscribe, setting is done directly through store accessors
- // @ts-ignore
- const { subscribe } = derived(observedStores, (values, set) => {
- // create new state by looping over props in certain order
- const state = ORDERED_STATE_PROPS.reduce((prev, curr, i) => {
- prev[curr] = clone(values[i]);
- return prev;
- }, {});
- // round crop if defined
- state.crop && rectApply(state.crop, Math.round);
- // remove internal state props from decoration and annotation
- state.redaction = state.redaction && filterShapeState(state.redaction);
- state.annotation = state.annotation && filterShapeState(state.annotation);
- state.decoration = state.decoration && filterShapeState(state.decoration);
- // set new state
- set(state);
- });
- const setState = (state) => {
- // requires at least some state to be supplied
- if (!state)
- return;
- // make sure crop origin is reset
- accessors.cropOrigin = undefined;
- // apply new values
- ORDERED_STATE_PROPS
- // remove keys that weren't set
- .filter((key) => hasProp(state, key))
- // apply each key in order
- .forEach((key) => {
- accessors[key] = clone(state[key]);
- });
- };
- return {
- set: setState,
- update: (fn) => setState(fn(null)),
- subscribe,
- };
- };
- var toNumericAspectRatio = (v) => {
- if (!v)
- return undefined;
- if (/:/.test(v)) {
- const [w, h] = v.split(':');
- return w / h;
- }
- return parseFloat(v);
- };
- var arrayEqual = (a, b) => {
- if (a.length !== b.length)
- return false;
- for (let i = 0; i < a.length; i++) {
- if (a[i] !== b[i])
- return false;
- }
- return true;
- };
- var padColorArray = (color = [0, 0, 0, 0], opacity = 1.0) => color.length === 4 ? color : [...color, opacity];
- //
- // constants
- //
- const MIN_ROTATION = -QUART_PI;
- const MAX_ROTATION = QUART_PI;
- //
- // helper methods
- //
- const isCropCentered = (crop, imageSize, imageRotation) => {
- const cropCenter = vectorApply(rectCenter(crop), (v) => fixPrecision(v, 8));
- const imageRect = rectCreateFromSize(imageSize);
- const imageCenter = rectCenter(imageRect);
- const imageRotatedVertices = rectRotate(imageRect, imageRotation, imageCenter);
- const imageBoundsCenter = vectorApply(sizeCenter(rectCreateFromPoints(imageRotatedVertices)), (v) => fixPrecision(v, 8));
- const dx = Math.abs(imageBoundsCenter.x - cropCenter.x);
- const dy = Math.abs(imageBoundsCenter.y - cropCenter.y);
- return dx < 1 && dy < 1;
- };
- const isCropMaxSize = (cropRect, imageSize, rotation) => {
- const maxSize = getMaxSizeInRect(imageSize, rotation, rectAspectRatio(cropRect));
- return sizeEqual(sizeApply(maxSize, Math.round), sizeApply(sizeClone(cropRect), Math.round));
- };
- //
- // updater methods
- //
- const updateCropRect = (props) => (cropNext, cropPrevious = cropNext) => {
- // wait for image to load
- const { loadState, size, cropMinSize, cropMaxSize, cropLimitToImage, cropAspectRatio, rotation, perspective, } = props;
- // image hasn't loaded yet, use supplied crop rect
- if ((!cropNext && !cropPrevious) || !loadState || !loadState.beforeComplete)
- return cropNext;
- // crop previous set, crop next set to undefined, set crop to fit image
- if (!cropNext)
- cropNext = rectCreateFromSize(getMaxSizeInRect(size, rotation, cropAspectRatio || rectAspectRatio(size)));
- // apply the action
- const res = applyCropRectAction(cropPrevious, cropNext, size, rotation, perspective, cropLimitToImage, cropMinSize, cropMaxSize);
- const cropOut = rectApply(res.crop, (v) => fixPrecision(v, 8));
- return cropOut;
- };
- const updateCropAspectRatio = (props) => (aspectRatioNext, aspectRatioPrevious) => {
- const { loadState, crop, size, rotation, cropLimitToImage } = props;
- const aspectRatio = toNumericAspectRatio(aspectRatioNext);
- // no aspect ratio means custom aspect ratio so set to undefined
- if (!aspectRatio)
- return undefined;
- // can't update crop if not defined yet
- if (!crop || !loadState || !loadState.beforeComplete)
- return aspectRatio;
- // calculate difference between aspect ratios, if big difference, re-align in image
- const aspectRatioDist = aspectRatioPrevious
- ? Math.abs(aspectRatioNext - aspectRatioPrevious)
- : 1;
- // if crop centered scale up
- if (isCropCentered(crop, size, rotation) && cropLimitToImage && aspectRatioDist >= 0.1) {
- const imageSize = sizeTurn(sizeClone(size), rotation);
- props.crop = rectApply(rectContainRect(rectCreateFromSize(imageSize), aspectRatioNext), fixPrecision);
- }
- else {
- const cropSize = {
- width: crop.height * aspectRatio,
- height: crop.height,
- };
- const tx = (crop.width - cropSize.width) * 0.5;
- const ty = (crop.height - cropSize.height) * 0.5;
- props.crop = rectApply(rectCreate(crop.x + tx, crop.y + ty, cropSize.width, cropSize.height), fixPrecision);
- }
- return aspectRatio;
- };
- const updateCropLimitToImage = (props) => (limitToImageNext, limitToImagePrevious, onUpdate) => {
- // skip if no crop defined
- const { crop } = props;
- if (!crop)
- return limitToImageNext;
- // if was not limiting previously and now set limiting make sure crop fits bounds
- if (!limitToImagePrevious && limitToImageNext) {
- onUpdate(() => (props.crop = rectClone(props.crop)));
- }
- return limitToImageNext;
- };
- const updateRotation = (props) => (rotationNext, rotationPrevious, onUpdate) => {
- // when image rotation is updated we need to adjust the
- // cropRect offset so rotation happens from cropRect center
- // no change
- if (rotationNext === rotationPrevious)
- return rotationNext;
- // get relevant data from store state
- const { loadState, size, rotationRange, cropMinSize, cropMaxSize, crop, perspective, cropLimitToImage, cropOrigin, } = props;
- // image not ready, exit!
- if (!crop || !loadState || !loadState.beforeComplete)
- return rotationNext;
- // remember if current crop was at max size and centered, if so, resulting crop should also be at max size
- const cropWasAtMaxSize = isCropMaxSize(crop, size, rotationPrevious);
- const cropWasCentered = isCropCentered(crop, size, rotationPrevious);
- // get new state
- const res = applyRotationAction(rotationPrevious, rotationNext, rotationRange, crop, size, perspective, cropLimitToImage, cropOrigin, cropMinSize, cropMaxSize);
- // if is centered, and initial crop was at max size expand crop to max size
- if (cropWasAtMaxSize && cropWasCentered) {
- const rect = getMaxSizeInRect(size, rotationNext, rectAspectRatio(res.crop));
- // move top left corner
- res.crop.x += res.crop.width * 0.5;
- res.crop.y += res.crop.height * 0.5;
- res.crop.x -= rect.width * 0.5;
- res.crop.y -= rect.height * 0.5;
- // update size to max size
- res.crop.width = rect.width;
- res.crop.height = rect.height;
- }
- // return validated rotation value, then, after we assign that value, we update the crop rect
- // we may only call onUpdate if a change was made
- onUpdate(() => {
- props.crop = rectApply(res.crop, (v) => fixPrecision(v, 8));
- });
- // return result rotation (might have been rotated twice to fit crop rectangle)
- return res.rotation;
- };
- // updates the range of valid rotation input
- const updateRotationRange = (imageSize, imageIsRotatedSideways, cropMinSize, cropSize, cropLimitToImage) => {
- if (!cropLimitToImage)
- return [MIN_ROTATION, MAX_ROTATION];
- /*
- - 'a' is angle between diagonal and image height
- - 'b' is angle between diagonal and crop height
- - 'c' is angle between diagonal and image width
- - resulting range is then a - b
- +----------/\------------------------+
- | / \ \ |
- | / \ \ |
- | / \ \ |
- | \ \ \ |
- | \ \ \ |
- | \ \ \ |
- | \ \ / |
- | \ \ / |
- | \ \ / |
- | \\a/b |
- +---------------------\--------------+
- */
- const scalar = Math.max(cropMinSize.width / cropSize.width, cropMinSize.height / cropSize.height);
- const minSize = sizeCreate(cropSize.width * scalar, cropSize.height * scalar);
- // the hypotenus is the length of the diagonal of the min crop size
- const requiredSpace = sizeHypotenuse(minSize);
- // minimum space available in horizontal / vertical direction
- const availableSpace = Math.min(imageSize.width, imageSize.height);
- // if there's enough space available, we can return the max range
- if (requiredSpace < availableSpace)
- return [MIN_ROTATION, MAX_ROTATION];
- // if the image is turned we need to swap the width and height
- const imageWidth = imageIsRotatedSideways ? imageSize.height : imageSize.width;
- const imageHeight = imageIsRotatedSideways ? imageSize.width : imageSize.height;
- // subtracting the angle between the hypotenuse and the crop itself
- const a = Math.acos(minSize.height / requiredSpace);
- const b = Math.acos(imageHeight / requiredSpace);
- const c = Math.asin(imageWidth / requiredSpace);
- const rangeHorizontal = a - b;
- const rangeVertical = c - a;
- // range is not a number, it means we can rotate as much as we want
- if (Number.isNaN(rangeHorizontal) && Number.isNaN(rangeVertical))
- return [MIN_ROTATION, MAX_ROTATION];
- // get minimum range
- const range = Number.isNaN(rangeHorizontal)
- ? rangeVertical
- : Number.isNaN(rangeVertical)
- ? rangeHorizontal
- : Math.min(rangeHorizontal, rangeVertical);
- // if not, limit range to min and max rotation
- const rangeMin = Math.max(-range, MIN_ROTATION);
- const rangeMax = Math.min(range, MAX_ROTATION);
- return [rangeMin, rangeMax];
- };
- // updates the range of valid crop rectangle input
- const updateCropRange = (imageSize, rotation, cropAspectRatio, cropMinSize, cropMaxSize, cropLimitToImage) => {
- // ! rotation doesn't affect min size, only max size
- // set lower bounds to crop min size
- const minSize = sizeClone(cropMinSize);
- // set upper bounds to crop max size
- const maxSize = sizeClone(cropMaxSize);
- // now we got basic bounds, let's see if we should limit to the image bounds, else we done
- if (!cropLimitToImage)
- return [minSize, maxSize];
- return [minSize, sizeApply(getMaxSizeInRect(imageSize, rotation, cropAspectRatio), Math.round)];
- };
- const formatShape = (shape, options) => {
- const { context, props } = options;
- // only auto-format once
- if (!shape._isFormatted) {
- shape = shapeFormat(shape);
- shape._isFormatted = true;
- Object.assign(shape, props);
- }
- // we need to make sure shape is still correctly positioned relative to parent context
- // draft cannot be relative
- // if context changed
- // if has left top right or bottom
- if (!shape._isDraft &&
- shapeHasRelativeSize(shape) &&
- (!shape._context || !rectEqual(context, shape._context))) {
- shape = shapeComputeRect(shape, context);
- shape._context = { ...context };
- }
- return shape;
- };
- const updateFrame = () => (frameShapeNext) => {
- if (!frameShapeNext)
- return;
- const shape = {
- frameStyle: undefined,
- x: 0,
- y: 0,
- width: '100%',
- height: '100%',
- disableStyle: ['backgroundColor', 'strokeColor', 'strokeWidth'],
- };
- if (isString(frameShapeNext)) {
- shape.frameStyle = frameShapeNext;
- }
- else {
- Object.assign(shape, frameShapeNext);
- }
- return shape;
- };
- var imageProps = [
- // image info received from read
- ['file'],
- ['size'],
- // loading and processing state
- ['loadState'],
- ['processState'],
- // derived info
- [
- 'aspectRatio',
- DERIVED_STORE(({ size }) => [
- size,
- ($size) => ($size ? rectAspectRatio($size) : undefined),
- ]),
- ],
- // image modifications
- ['perspectiveX', DEFAULT_VALUE(() => 0)],
- ['perspectiveY', DEFAULT_VALUE(() => 0)],
- [
- 'perspective',
- DERIVED_STORE(({ perspectiveX, perspectiveY }) => [
- [perspectiveX, perspectiveY],
- ([x, y]) => ({ x, y }),
- ]),
- ],
- ['rotation', DEFAULT_VALUE(() => 0), UPDATE_VALUE(updateRotation)],
- ['flipX', DEFAULT_VALUE(() => false)],
- ['flipY', DEFAULT_VALUE(() => false)],
- ['flip', DERIVED_STORE(({ flipX, flipY }) => [[flipX, flipY], ([x, y]) => ({ x, y })])],
- [
- 'isRotatedSideways',
- UNIQUE_DERIVED_STORE(({ rotation }) => [
- [rotation],
- ([$rotation], set) => set(isRotatedSideways($rotation)),
- (prevValue, nextValue) => prevValue !== nextValue,
- ]),
- ],
- ['crop', UPDATE_VALUE(updateCropRect)],
- ['cropAspectRatio', UPDATE_VALUE(updateCropAspectRatio)],
- ['cropOrigin'],
- ['cropMinSize', DEFAULT_VALUE(() => ({ width: 1, height: 1 }))],
- ['cropMaxSize', DEFAULT_VALUE(() => ({ width: 32768, height: 32768 }))],
- ['cropLimitToImage', DEFAULT_VALUE(() => true), UPDATE_VALUE(updateCropLimitToImage)],
- [
- 'cropSize',
- UNIQUE_DERIVED_STORE(({ crop }) => [
- [crop],
- ([$crop], set) => {
- if (!$crop)
- return;
- set(sizeCreate($crop.width, $crop.height));
- },
- // if is same as previous size, don't trigger update (happens when updating only the crop offset)
- (prevValue, nextValue) => sizeEqual(prevValue, nextValue),
- ]),
- ],
- [
- 'cropRectAspectRatio',
- DERIVED_STORE(({ cropSize }) => [
- [cropSize],
- ([$cropSize], set) => {
- if (!$cropSize)
- return;
- set(fixPrecision(rectAspectRatio($cropSize), 5));
- },
- ]),
- ],
- [
- 'cropRange',
- UNIQUE_DERIVED_STORE(({ size, rotation, cropRectAspectRatio, cropMinSize, cropMaxSize, cropLimitToImage, }) => [
- [size, rotation, cropRectAspectRatio, cropMinSize, cropMaxSize, cropLimitToImage],
- ([$size, $rotation, $cropRectAspectRatio, $cropMinSize, $cropMaxSize, $cropLimitToImage,], set) => {
- // wait for image size
- if (!$size)
- return;
- const range = updateCropRange($size, $rotation, $cropRectAspectRatio, $cropMinSize, $cropMaxSize, $cropLimitToImage);
- set(range);
- },
- // if is same range as previous range, don't trigger update
- (prevRange, nextRange) => arrayEqual(prevRange, nextRange),
- ]),
- ],
- [
- 'rotationRange',
- UNIQUE_DERIVED_STORE(({ size, isRotatedSideways, cropMinSize, cropSize, cropLimitToImage }) => [
- [size, isRotatedSideways, cropMinSize, cropSize, cropLimitToImage],
- ([$size, $isRotatedSideways, $cropMinSize, $cropSize, $cropLimitToImage], set) => {
- // wait for image size
- if (!$size || !$cropSize)
- return;
- const range = updateRotationRange($size, $isRotatedSideways, $cropMinSize, $cropSize, $cropLimitToImage);
- set(range);
- },
- // if is same range as previous range, don't trigger update
- (prevRange, nextRange) => arrayEqual(prevRange, nextRange),
- ]),
- ],
- // canvas
- ['backgroundColor', UPDATE_VALUE(() => (color) => padColorArray(color))],
- // size
- ['targetSize'],
- // effects
- ['colorMatrix'],
- ['convolutionMatrix'],
- ['gamma'],
- ['noise'],
- ['vignette'],
- // redaction lives in image space
- ['redaction', MAP_STORE(({ size }) => [formatShape, { context: size }])],
- // annotation lives in image space
- ['annotation', MAP_STORE(({ size }) => [formatShape, { context: size }])],
- // decoration lives in crop space
- ['decoration', MAP_STORE(({ crop }) => [formatShape, { context: crop }])],
- // frame to render on top of the image (or outside)
- ['frame', UPDATE_VALUE(updateFrame)],
- // custom metadata
- ['metadata'],
- // state of image, used to restore a previous state or request the current state
- ['state', CUSTOM_STORE(stateStore)],
- ];
- var process = async (value, chainTasks, chainOptions = {}, processOptions) => {
- // options relevant to the process method itself
- const { ontaskstart, ontaskprogress, ontaskend, token } = processOptions;
- // has been cancelled
- let cancelled = false;
- // set cancel handler method
- token.cancel = () => {
- // cancel called from outside of the process method
- cancelled = true;
- };
- // step through chain
- for (const [index, task] of chainTasks.entries()) {
- // exit when cancelled
- if (cancelled)
- return;
- // get the task function and the id so we can notify the callee of the task that is being started
- const [fn, id] = task;
- // start task
- ontaskstart(index, id);
- try {
- value = await fn(value, { ...chainOptions }, (event) => ontaskprogress(index, id, event));
- }
- catch (err) {
- // stop processing more items in the chain
- cancelled = true;
- // pass error back to parent
- throw err;
- }
- ontaskend(index, id);
- }
- return value;
- };
- // TODO: find better location for minSize / file load validation
- var createImageCore = ({ minSize = { width: 1, height: 1 } } = {}) => {
- // create default store
- const { stores, accessors } = createStores(imageProps);
- // pub/sub
- const { pub, sub } = pubsub();
- // processing handler
- const createProcessingHandler = (stateProp, eventKey) => {
- const getStore = () => accessors[stateProp] || {};
- const setStore = (obj) => (accessors[stateProp] = {
- ...getStore(),
- ...obj,
- timeStamp: Date.now(),
- });
- const hasError = () => getStore().error;
- const handleError = (error) => {
- if (hasError())
- return;
- setStore({
- error: error,
- });
- pub(`${eventKey}error`, { ...getStore() });
- };
- return {
- start() {
- pub(`${eventKey}start`);
- },
- onabort() {
- setStore({
- abort: true,
- });
- pub(`${eventKey}abort`, { ...getStore() });
- },
- ontaskstart(index, id) {
- if (hasError())
- return;
- setStore({
- index,
- task: id,
- taskProgress: undefined,
- taskLengthComputable: undefined,
- });
- pub(`${eventKey}taskstart`, { ...getStore() });
- },
- ontaskprogress(index, id, event) {
- if (hasError())
- return;
- setStore({
- index,
- task: id,
- taskProgress: event.loaded / event.total,
- taskLengthComputable: event.lengthComputable,
- });
- pub(`${eventKey}taskprogress`, { ...getStore() });
- pub(`${eventKey}progress`, { ...getStore() });
- },
- ontaskend(index, id) {
- if (hasError())
- return;
- setStore({
- index,
- task: id,
- });
- pub(`${eventKey}taskend`, { ...getStore() });
- },
- ontaskerror(error) {
- handleError(error);
- },
- error(error) {
- handleError(error);
- },
- beforeComplete(data) {
- if (hasError())
- return;
- setStore({ beforeComplete: true });
- pub(`before${eventKey}`, data);
- },
- complete(data) {
- if (hasError())
- return;
- setStore({ complete: true });
- pub(eventKey, data);
- },
- };
- };
- //#region read image
- const read = (src, { reader }) => {
- // exit if no reader supplied
- if (!reader)
- return;
- // reset file data to undefined as we're loading a new image
- Object.assign(accessors, {
- file: undefined,
- size: undefined,
- loadState: undefined,
- });
- // our cancel token so we can abort load if needed, cancel will be set by process
- let imageReadToken = { cancel: noop$1 };
- let imageReadCancelled = false;
- const imageReadHandler = createProcessingHandler('loadState', 'load');
- const processOptions = {
- token: imageReadToken,
- ...imageReadHandler,
- };
- const readerState = {
- src,
- size: undefined,
- dest: undefined,
- };
- const readerOptions = {};
- // wait a tick before starting image read so the read can be cancelled in loadstart
- Promise.resolve().then(async () => {
- try {
- imageReadHandler.start();
- if (imageReadCancelled)
- return imageReadHandler.onabort();
- const output = (await process(readerState, reader, readerOptions, processOptions));
- // was cancelled
- if (imageReadCancelled)
- return imageReadHandler.onabort();
- // get shortcuts for validation
- const { size, dest } = output || {};
- // if we don't have a size
- if (!size || !size.width || !size.height)
- throw new EditorError('Image size missing', 'IMAGE_SIZE_MISSING', output);
- // size of image is too small
- if (size.width < minSize.width || size.height < minSize.height)
- throw new EditorError('Image too small', 'IMAGE_TOO_SMALL', {
- ...output,
- minWidth: minSize.width,
- minHeight: minSize.height,
- });
- // update internal data
- Object.assign(accessors, {
- size: size,
- file: dest,
- });
- // before load complete
- imageReadHandler.beforeComplete(output);
- // done loading image
- imageReadHandler.complete(output);
- }
- catch (err) {
- imageReadHandler.error(err);
- }
- finally {
- imageReadToken = undefined;
- }
- });
- // call to abort load
- return () => {
- imageReadCancelled = true;
- imageReadToken && imageReadToken.cancel();
- imageReadHandler.onabort();
- };
- };
- //#endregion
- //#region write image
- const write = (writer, options) => {
- // not ready to start processing
- if (!accessors.loadState.complete)
- return;
- // reset process state to undefined
- accessors.processState = undefined;
- const imageWriteHandler = createProcessingHandler('processState', 'process');
- const writerState = {
- src: accessors.file,
- imageState: accessors.state,
- dest: undefined,
- };
- // willProcessImageState
- if (!writer) {
- imageWriteHandler.start();
- imageWriteHandler.complete(writerState);
- return;
- }
- // we need this token to be a blet to cancel the processing operation
- let imageWriteToken = { cancel: noop$1 };
- let imageWriteCancelled = false;
- const writerOptions = options;
- const processOptions = {
- token: imageWriteToken,
- ...imageWriteHandler,
- };
- // wait a tick before starting image write so the write can be cancelled in processtart
- Promise.resolve().then(async () => {
- try {
- imageWriteHandler.start();
- if (imageWriteCancelled)
- return imageWriteHandler.onabort();
- const output = (await process(writerState, writer, writerOptions, processOptions));
- imageWriteHandler.complete(output);
- }
- catch (err) {
- imageWriteHandler.error(err);
- }
- finally {
- imageWriteToken = undefined;
- }
- });
- // call to abort processing
- return () => {
- imageWriteCancelled = true;
- imageWriteToken && imageWriteToken.cancel();
- };
- };
- //#endregion
- //#region api
- defineMethods(accessors, {
- read,
- write,
- on: sub,
- });
- //#endregion
- // expose store API
- return {
- accessors,
- stores,
- };
- };
- // @ts-ignore
- const editorEventsToBubble = [
- 'loadstart',
- 'loadabort',
- 'loaderror',
- 'loadprogress',
- 'load',
- 'processstart',
- 'processabort',
- 'processerror',
- 'processprogress',
- 'process',
- ];
- const imagePrivateProps = [
- 'flip',
- 'cropOrigin',
- 'isRotatedSideways',
- 'perspective',
- 'perspectiveX',
- 'perspectiveY',
- 'cropRange',
- ];
- const editorPrivateProps = ['images'];
- const imagePublicProps = imageProps
- .map(([prop]) => prop)
- .filter((prop) => !imagePrivateProps.includes(prop));
- const getImagePropGroupedName = (prop) => `image${capitalizeFirstLetter(prop)}`;
- const getEditorProps$1 = () => {
- const imageProperties = imagePublicProps.map(getImagePropGroupedName);
- const editorProperties = props
- .map(([prop]) => prop)
- .filter((prop) => !editorPrivateProps.includes(prop));
- return imageProperties.concat(editorProperties);
- };
- const isImageSource = (src) => isString(src) || isBinary(src) || isElement(src);
- const isImageState = (obj) => hasProp(obj, 'crop');
- var createImageEditor = () => {
- // create default stores
- const { stores, accessors } = createStores(props);
- // set up pub/sub for the app layer
- const { sub, pub } = pubsub();
- const bubble = (name) => (value) => pub(name, value);
- // helper method
- const getImageObjSafe = () => (accessors.images ? accessors.images[0] : {});
- // initialImageProps is the list of transforms to apply when the image loads
- let initialImageProps = {};
- // create shortcuts to image props : `crop` -> `imageCrop`
- imagePublicProps.forEach((prop) => {
- Object.defineProperty(accessors, getImagePropGroupedName(prop), {
- get: () => {
- // no image, can't get
- const image = getImageObjSafe();
- if (!image)
- return;
- // return from image state
- return image.accessors[prop];
- },
- set: (value) => {
- // always use as initial prop when loading a new image without reset
- initialImageProps[getImagePropGroupedName(prop)] = value;
- // no image, we can't update
- const image = getImageObjSafe();
- if (!image)
- return;
- // update the image immidiately
- image.accessors[prop] = value;
- },
- });
- });
- // internal helper method to get active image
- const getImage = () => accessors.images && accessors.images[0];
- // handling loading an image if a src is set
- const unsubSrc = stores.src.subscribe((src) => {
- // no image set, means clear active image
- if (!src)
- return (accessors.images = []);
- // exit here if we don't have an imageReader we'll wait for an imageReader to be defined
- if (!accessors.imageReader)
- return;
- // reset initial image props if an image is already loaded, so props applied to previous image aren't applied to the new one
- if (accessors.images.length)
- initialImageProps = {};
- // load image in src prop
- loadSrc(src);
- });
- const unsubReader = stores.imageReader.subscribe((reader) => {
- // can't do anything without an image reader
- if (!reader)
- return;
- // an image has already been loaded no need to load images that were set earlier
- if (accessors.images.length)
- return;
- // no image to load, we'll wait for images to be set to the `src` prop
- if (!accessors.src)
- return;
- // src is waiting to be loaded so let's pick it up,
- loadSrc(accessors.src);
- });
- const loadSrc = (src) => {
- // push it back a tick so we know initialImageProps are set
- Promise.resolve()
- .then(() => {
- // load with initial props
- return loadImage(src, initialImageProps);
- })
- .catch(() => {
- // fail silently, any errors are handled with 'loaderror' event
- });
- };
- //#endregion
- //#region public method (note that these are also called from UI, name of method is name of dispatched event in UI)
- const applyImageOptionsOrState = (image, options) => {
- // test if options is image state, if so, apply and exit
- if (isImageState(options)) {
- accessors.imageState = options;
- return;
- }
- // create an initial crop rect if no crop supplied
- if (!options.imageCrop) {
- const imageSize = image.accessors.size;
- const imageRotation = options.imageRotation || 0;
- const cropRect = rectCreateFromSize(sizeRotate(sizeClone(imageSize), imageRotation));
- const aspectRatio = options.imageCropAspectRatio ||
- (options.imageCropLimitToImage
- ? rectAspectRatio(imageSize) // use image size if should limit to image
- : rectAspectRatio(cropRect)); // use rotated crop rect bounds if no limit
- const crop = rectContainRect(cropRect, aspectRatio);
- // center the image in the crop rectangle
- if (!options.imageCropLimitToImage) {
- crop.x = (imageSize.width - crop.width) / 2;
- crop.y = (imageSize.height - crop.height) / 2;
- }
- options.imageCrop = crop;
- }
- // we need to apply these props in the correct order
- ['imageCropLimitToImage', 'imageCrop', 'imageCropAspectRatio', 'imageRotation']
- .filter((prop) => hasProp(options, prop))
- .forEach((prop) => {
- // assign to `image`
- accessors[prop] = options[prop];
- // remove from normalizedOptions so it's not set twice
- delete options[prop];
- });
- // don't set the above options for a second time
- const { imageCropLimitToImage, imageCrop, imageCropAspectRatio, imageRotation, ...remainingOptions } = options;
- // trigger setState
- Object.assign(accessors, remainingOptions);
- };
- // load image, resolve when image is loaded
- let imageLoadAbort;
- const loadImage = (src, options = {}) => new Promise((resolve, reject) => {
- // get current image
- let image = getImage();
- // determine min defined image size (is crop min size)
- const cropLimitedToImage = !(options.cropLimitToImage === false || options.imageCropLimitToImage === false);
- const cropMinSize = options.cropMinSize || options.imageCropMinSize;
- const minImageSize = cropLimitedToImage
- ? cropMinSize
- : image && image.accessors.cropMinSize;
- // if already has image, remove existing image
- if (image)
- removeImage();
- // access image props and stores
- image = createImageCore({ minSize: minImageSize });
- editorEventsToBubble.map((event) => image.accessors.on(event, bubble(event)));
- // done, clean up listeners
- const fin = () => {
- // reset initial props (as now applied)
- initialImageProps = {};
- unsubs.forEach((unsub) => unsub());
- };
- const unsubs = [];
- unsubs.push(image.accessors.on('loaderror', (error) => {
- fin();
- reject(error);
- }));
- unsubs.push(image.accessors.on('loadabort', () => {
- fin();
- reject({ name: 'AbortError' });
- }));
- unsubs.push(image.accessors.on('load', (output) => {
- imageLoadAbort = undefined;
- fin();
- resolve(output);
- }));
- unsubs.push(image.accessors.on('beforeload', () => applyImageOptionsOrState(image, options)));
- // set new image
- accessors.images = [image];
- // assign passed options to editor accessors, we ignore 'src'
- if (options.imageReader)
- accessors.imageReader = options.imageReader;
- if (options.imageWriter)
- accessors.imageWriter = options.imageWriter;
- // start reading image
- imageLoadAbort = image.accessors.read(src, { reader: accessors.imageReader });
- });
- // start processing a loaded image, resolve when image is processed
- let imageProcessAbort;
- const processImage = (src, options) => new Promise(async (resolve, reject) => {
- // if src supplied, first load src, then process
- if (isImageSource(src)) {
- await loadImage(src, options);
- }
- // if first argument is not `src` but is set it's an options object, so we'll update the options before generating the image
- else if (src) {
- if (isImageState(src)) {
- accessors.imageState = src;
- }
- else {
- Object.assign(accessors, src);
- }
- }
- // get current active image
- const image = getImage();
- // needs image for processing
- if (!image)
- return reject('no image');
- // done, clean up listeners
- const fin = () => {
- imageProcessAbort = undefined;
- unsubs.forEach((unsub) => unsub());
- };
- const unsubs = [];
- unsubs.push(image.accessors.on('processerror', (error) => {
- fin();
- reject(error);
- }));
- unsubs.push(image.accessors.on('processabort', () => {
- fin();
- reject({ name: 'AbortError' });
- }));
- unsubs.push(image.accessors.on('process', (output) => {
- fin();
- resolve(output);
- }));
- imageProcessAbort = image.accessors.write(accessors.imageWriter, {
- shapePreprocessor: accessors.shapePreprocessor || passthrough,
- imageScrambler: accessors.imageScrambler,
- });
- });
- const abortProcessImage = () => {
- const image = getImage();
- if (!image)
- return;
- if (imageProcessAbort)
- imageProcessAbort();
- image.accessors.processState = undefined;
- };
- // used internally (triggered by 'x' button when error loading image in UI)
- const abortLoadImage = () => {
- if (imageLoadAbort)
- imageLoadAbort();
- accessors.images = [];
- };
- // edit image, loads an image and resolve when image is processed
- const editImage = (src, options) => new Promise((resolve, reject) => {
- loadImage(src, options)
- .then(() => {
- // access image props and stores
- const { images } = accessors;
- const image = images[0];
- // done, clean up listeners
- const done = () => {
- unsubReject();
- unsubResolve();
- };
- const unsubReject = image.accessors.on('processerror', (error) => {
- done();
- reject(error);
- });
- const unsubResolve = image.accessors.on('process', (output) => {
- done();
- resolve(output);
- });
- })
- .catch(reject);
- });
- const removeImage = () => {
- // no images, nothing to remove
- const image = getImage();
- if (!image)
- return;
- // try to abort image load
- if (imageLoadAbort)
- imageLoadAbort();
- image.accessors.loadState = undefined;
- // clear images
- accessors.images = [];
- };
- //#endregion
- Object.defineProperty(accessors, 'stores', {
- get: () => stores,
- });
- //#region API
- defineMethods(accessors, {
- on: sub,
- loadImage,
- abortLoadImage,
- editImage,
- removeImage,
- processImage,
- abortProcessImage,
- destroy: () => {
- unsubSrc();
- unsubReader();
- },
- });
- return accessors;
- //#endregion
- };
- const processImage = (src, options) => {
- const { processImage } = createImageEditor();
- return processImage(src, options);
- };
- var getCanvasMemoryLimit = () => {
- if (!isSafari$1())
- return Infinity;
- const isSafari15 = /15_/.test(navigator.userAgent);
- if (isIOS()) {
- // limit resolution a little bit further to prevent drawing issues
- if (isSafari15)
- return 3840 * 3840;
- // old iOS can deal with 4096 * 4096 without issues
- return 4096 * 4096;
- }
- return isSafari15 ? 4096 * 4096 : Infinity;
- };
- // custom method to draw images
- const canvasDrawImage = async (ctx, image, srcRect, destRect) => {
- // get resized image
- const { dest } = await processImage(image, {
- imageReader: createDefaultImageReader$1(),
- imageWriter: createDefaultImageWriter$1({
- format: 'canvas',
- targetSize: {
- ...destRect,
- upscale: true,
- },
- }),
- imageCrop: srcRect,
- });
- // draw processed image
- ctx.drawImage(dest, destRect.x, destRect.y, destRect.width, destRect.height);
- // release image canvas to free up memory
- releaseCanvas(dest);
- };
- // connect function in process chain
- const connect = (fn, getter = (...args) => args, setter) => async (state, options, onprogress) => {
- // will hold function result
- // at this point we don't know if the length of this task can be computed
- onprogress(createProgressEvent(0, false));
- // try to run the function
- let progressUpdated = false;
- const res = await fn(...getter(state, options, (event) => {
- progressUpdated = true;
- onprogress(event);
- }));
- // a setter isn't required
- setter && setter(state, res);
- // if progress was updated, we expect the connected function to fire the 1/1 event, else we fire it here
- if (!progressUpdated)
- onprogress(createProgressEvent(1, false));
- return state;
- };
- //
- // Reader/Writer Presets
- //
- const AnyToFile = ({ srcProp = 'src', destProp = 'dest' } = {}) => [
- connect(srcToFile, (state, options, onprogress) => [state[srcProp], onprogress], (state, file) => (state[destProp] = file)),
- 'any-to-file',
- ];
- const BlobReadImageSize = ({ srcProp = 'src', destProp = 'size' } = {}) => [
- connect(getImageSize, (state, options) => [state[srcProp]], (state, size) => (state[destProp] = size)),
- 'read-image-size',
- ];
- const ImageSizeMatchOrientation = ({ srcSize = 'size', srcOrientation = 'orientation', destSize = 'size', } = {}) => [
- connect(orientImageSize, (state) => [state[srcSize], state[srcOrientation]], (state, size) => (state[destSize] = size)),
- 'image-size-match-orientation',
- ];
- const BlobReadImageHead = ({ srcProp = 'src', destProp = 'head' } = {}) => [
- connect((blob, slice) => (isJPEG(blob) ? blobReadSection(blob, slice) : undefined),
- // 64 * 1024 should be plenty to find extract header
- // Exif metadata are restricted in size to 64 kB in JPEG images because
- // according to the specification this information must be contained within a single JPEG APP1 segment.
- (state) => [state[srcProp], [0, 64 * 2048], onprogress], (state, head) => (state[destProp] = head)),
- 'read-image-head',
- ];
- const ImageHeadReadExifOrientationTag = ({ srcProp = 'head', destProp = 'orientation', } = {}) => [
- connect(arrayBufferImageExif, (state) => [state[srcProp], ORIENTATION_TAG], (state, orientation = 1) => (state[destProp] = orientation)),
- 'read-exif-orientation-tag',
- ];
- const ImageHeadClearExifOrientationTag = ({ srcProp = 'head' } = {}) => [
- connect(arrayBufferImageExif, (state) => [state[srcProp], ORIENTATION_TAG, 1]),
- 'clear-exif-orientation-tag',
- ];
- const ApplyCanvasScalar = ({ srcImageSize = 'size', srcCanvasSize = 'imageData', srcImageState = 'imageState', destImageSize = 'size', destScalar = 'scalar', } = {}) => [
- connect((naturalSize, canvasSize, imageState) => {
- // calculate canvas scalar
- const scalar = Math.min(canvasSize.width / naturalSize.width, canvasSize.height / naturalSize.height);
- // done because not scaling
- if (scalar !== 1) {
- const { crop, annotation, decoration } = imageState;
- // origin to scale to
- const origin = vectorCreateEmpty();
- // scale select.crop
- if (crop)
- imageState.crop = rectScale(crop, scalar, origin);
- // scale annotation
- const translate = vectorCreateEmpty();
- imageState.annotation = annotation.map((shape) => shapeComputeTransform(shape, translate, scalar));
- // scale decoration
- imageState.decoration = decoration.map((shape) => shapeComputeTransform(shape, translate, scalar));
- }
- return [scalar, sizeCreateFromAny(canvasSize)];
- }, (state) => [state[srcImageSize], state[srcCanvasSize], state[srcImageState]], (state, [scalar, imageSize]) => {
- state[destScalar] = scalar;
- state[destImageSize] = imageSize;
- }),
- 'calculate-canvas-scalar',
- ];
- const BlobToImageData = ({ srcProp = 'src', destProp = 'imageData', canvasMemoryLimit = undefined, }) => [
- connect(blobToImageData, (state) => [state[srcProp], canvasMemoryLimit], (state, imageData) => (state[destProp] = imageData)),
- 'blob-to-image-data',
- ];
- const ImageDataMatchOrientation = ({ srcImageData = 'imageData', srcOrientation = 'orientation', } = {}) => [
- connect(orientImageData, (state) => [state[srcImageData], state[srcOrientation]], (state, imageData) => (state.imageData = imageData)),
- 'image-data-match-orientation',
- ];
- const ImageDataFill = ({ srcImageData = 'imageData', srcImageState = 'imageState' } = {}) => [
- connect(fillImageData, (state) => [
- state[srcImageData],
- { backgroundColor: state[srcImageState].backgroundColor },
- ], (state, imageData) => (state.imageData = imageData)),
- 'image-data-fill',
- ];
- const ImageDataCrop = ({ srcImageData = 'imageData', srcImageState = 'imageState' } = {}) => [
- connect(cropImageData, (state) => [
- state[srcImageData],
- {
- crop: state[srcImageState].crop,
- rotation: state[srcImageState].rotation,
- flipX: state[srcImageState].flipX,
- flipY: state[srcImageState].flipY,
- },
- ], (state, imageData) => (state.imageData = imageData)),
- 'image-data-crop',
- ];
- const hasTargetSize = (imageState) => !!((imageState.targetSize && imageState.targetSize.width) ||
- (imageState.targetSize && imageState.targetSize.height));
- const ImageDataResize = ({ resize = {
- width: undefined,
- height: undefined,
- fit: undefined,
- upscale: undefined,
- }, srcProp = 'imageData', srcImageState = 'imageState', destImageScaledSize = 'imageScaledSize', }) => [
- connect(resizeImageData, (state) => [
- state[srcProp],
- {
- width: Math.min(resize.width || Number.MAX_SAFE_INTEGER, (state[srcImageState].targetSize && state[srcImageState].targetSize.width) ||
- Number.MAX_SAFE_INTEGER),
- height: Math.min(resize.height || Number.MAX_SAFE_INTEGER, (state[srcImageState].targetSize && state[srcImageState].targetSize.height) ||
- Number.MAX_SAFE_INTEGER),
- fit: resize.fit || 'contain',
- upscale: hasTargetSize(state[srcImageState]) ? true : resize.upscale || false,
- },
- ], (state, imageData) => {
- if (!sizeEqual(state.imageData, imageData))
- state[destImageScaledSize] = sizeCreateFromAny(imageData);
- state.imageData = imageData;
- }),
- 'image-data-resize',
- ];
- const ImageDataFilter = ({ srcImageData = 'imageData', srcImageState = 'imageState', destImageData = 'imageData', } = {}) => [
- connect(filterImageData, (state) => {
- const { colorMatrix } = state[srcImageState];
- const colorMatrices = colorMatrix &&
- Object.keys(colorMatrix)
- .map((name) => colorMatrix[name])
- .filter(Boolean);
- return [
- state[srcImageData],
- {
- colorMatrix: colorMatrices && getColorMatrixFromColorMatrices(colorMatrices),
- convolutionMatrix: state[srcImageState].convolutionMatrix,
- gamma: state[srcImageState].gamma,
- noise: state[srcImageState].noise,
- vignette: state[srcImageState].vignette,
- },
- ];
- }, (state, imageData) => (state[destImageData] = imageData)),
- 'image-data-filter',
- ];
- const createImageContextDrawingTransform = (state, { srcSize, srcImageState, destImageScaledSize }) => (ctx) => {
- const imageSize = state[srcSize];
- const { crop = rectCreateFromSize(imageSize), rotation = 0, flipX, flipY } = state[srcImageState];
- const rotatedRect = getImageTransformedRect(imageSize, rotation);
- const rotatedSize = {
- width: rotatedRect.width,
- height: rotatedRect.height,
- };
- // calculate image scalar so we can scale annotations accordingly
- const scaledSize = state[destImageScaledSize];
- const scalar = scaledSize
- ? Math.min(scaledSize.width / crop.width, scaledSize.height / crop.height)
- : 1;
- // calculate center
- const dx = imageSize.width * 0.5 - rotatedSize.width * 0.5;
- const dy = imageSize.height * 0.5 - rotatedSize.height * 0.5;
- const center = sizeCenter(imageSize);
- // image scalar
- ctx.scale(scalar, scalar);
- // offset
- ctx.translate(-dx, -dy);
- ctx.translate(-crop.x, -crop.y);
- // rotation
- ctx.translate(center.x, center.y);
- ctx.rotate(rotation);
- ctx.translate(-center.x, -center.y);
- // flipping
- ctx.scale(flipX ? -1 : 1, flipY ? -1 : 1);
- ctx.translate(flipX ? -imageSize.width : 0, flipY ? -imageSize.height : 0);
- // annotations are clipped clip to image
- ctx.rect(0, 0, imageSize.width, imageSize.height);
- ctx.clip();
- };
- const ImageDataRedact = ({ srcImageData = 'imageData', srcImageState = 'imageState', destImageData = 'imageData', destScalar = 'scalar', } = {}) => [
- connect(async (imageData, imageScrambler, imageBackgroundColor, shapes, scalar) => {
- // skip!
- if (!imageScrambler)
- return imageData;
- // create scrambled texture version
- let scrambledCanvas;
- try {
- const options = {
- dataSizeScalar: getImageRedactionScaleFactor(imageData, shapes),
- };
- if (imageBackgroundColor && imageBackgroundColor[3] > 0) {
- options.backgroundColor = [...imageBackgroundColor];
- }
- scrambledCanvas = await imageScrambler(imageData, options);
- }
- catch (err) {
- }
- // create drawing context
- const canvas = h('canvas');
- canvas.width = imageData.width;
- canvas.height = imageData.height;
- const ctx = canvas.getContext('2d');
- ctx.putImageData(imageData, 0, 0);
- // set up a clip path so we only draw scrambled image within path
- const path = new Path2D();
- shapes.forEach((shape) => {
- const rect = rectCreate(shape.x, shape.y, shape.width, shape.height);
- rectMultiply(rect, scalar);
- const corners = rectRotate(rectClone(rect), shape.rotation);
- const poly = new Path2D();
- corners.forEach((corner, i) => {
- if (i === 0)
- return poly.moveTo(corner.x, corner.y);
- poly.lineTo(corner.x, corner.y);
- });
- path.addPath(poly);
- });
- ctx.clip(path, 'nonzero');
- ctx.imageSmoothingEnabled = false;
- ctx.drawImage(scrambledCanvas, 0, 0, canvas.width, canvas.height);
- releaseCanvas(scrambledCanvas);
- // done
- const imageDataOut = ctx.getImageData(0, 0, canvas.width, canvas.height);
- // clean up memory usage
- releaseCanvas(canvas);
- return imageDataOut;
- }, (state, { imageScrambler }) => [
- state[srcImageData],
- imageScrambler,
- state[srcImageState].backgroundColor,
- state[srcImageState].redaction,
- state[destScalar],
- ], (state, imageData) => (state[destImageData] = imageData)),
- 'image-data-annotate',
- ];
- const ImageDataAnnotate = ({ srcImageData = 'imageData', srcSize = 'size', srcImageState = 'imageState', destImageData = 'imageData', destImageScaledSize = 'imageScaledSize', } = {}) => [
- connect(drawImageData, (state, { shapePreprocessor }) => [
- state[srcImageData],
- {
- shapes: state[srcImageState].annotation,
- context: state[srcSize],
- transform: createImageContextDrawingTransform(state, {
- srcSize,
- srcImageState,
- destImageScaledSize,
- }),
- drawImage: canvasDrawImage,
- preprocessShape: (shape) => shapePreprocessor(shape, { isPreview: false }),
- },
- ], (state, imageData) => (state[destImageData] = imageData)),
- 'image-data-annotate',
- ];
- const ImageDataDecorate = ({ srcImageData = 'imageData', srcImageState = 'imageState', destImageData = 'imageData', destImageScaledSize = 'imageScaledSize', } = {}) => [
- connect(drawImageData, (state, { shapePreprocessor }) => [
- state[srcImageData],
- {
- shapes: state[srcImageState].decoration,
- context: state[srcImageState].crop,
- transform: (ctx) => {
- // calculate image scalar so we can scale decoration accordingly
- const { crop } = state.imageState;
- const scaledSize = state[destImageScaledSize];
- const scalar = scaledSize
- ? Math.min(scaledSize.width / crop.width, scaledSize.height / crop.height)
- : 1;
- ctx.scale(scalar, scalar);
- },
- drawImage: canvasDrawImage,
- preprocessShape: (shape) => shapePreprocessor(shape, { isPreview: false }),
- },
- ], (state, imageData) => (state[destImageData] = imageData)),
- 'image-data-decorate',
- ];
- const ImageDataFrame = ({ srcImageData = 'imageData', srcImageState = 'imageState', destImageData = 'imageData', destImageScaledSize = 'imageScaledSize', } = {}) => [
- connect(drawImageData, (state, { shapePreprocessor }) => {
- const frame = state[srcImageState].frame;
- if (!frame)
- return [state[srcImageData]];
- const context = { ...state[srcImageState].crop };
- const bounds = shapesBounds(shapesFromCompositShape(frame, context, shapePreprocessor), context);
- context.x = Math.abs(bounds.left);
- context.y = Math.abs(bounds.top);
- context.width += Math.abs(bounds.left) + Math.abs(bounds.right);
- context.height += Math.abs(bounds.top) + Math.abs(bounds.bottom);
- const { crop } = state.imageState;
- const scaledSize = state[destImageScaledSize];
- const scalar = scaledSize
- ? Math.min(scaledSize.width / crop.width, scaledSize.height / crop.height)
- : 1;
- rectMultiply(context, scalar);
- // use floor because we can't fill up half pixels
- context.x = Math.floor(context.x);
- context.y = Math.floor(context.y);
- context.width = Math.floor(context.width);
- context.height = Math.floor(context.height);
- return [
- state[srcImageData],
- {
- shapes: [frame],
- contextBounds: context,
- transform: (ctx) => {
- ctx.translate(context.x, context.y);
- },
- drawImage: canvasDrawImage,
- preprocessShape: (shape) => shapePreprocessor(shape, { isPreview: false }),
- },
- ];
- }, (state, imageData) => (state[destImageData] = imageData)),
- 'image-data-frame',
- ];
- const ImageDataToBlob = ({ mimeType = undefined, quality = undefined, srcImageData = 'imageData', srcFile = 'src', destBlob = 'blob', } = {}) => [
- connect(imageDataToBlob, (state) => [
- state[srcImageData],
- mimeType || getMimeTypeFromFilename(state[srcFile].name) || state[srcFile].type,
- quality,
- ], (state, blob) => (state[destBlob] = blob)),
- 'image-data-to-blob',
- ];
- const ImageDataToCanvas = ({ srcImageData = 'imageData', srcOrientation = 'orientation', destCanvas = 'dest', } = {}) => [
- connect(imageDataToCanvas, (state) => [state[srcImageData], state[srcOrientation]], (state, canvas) => (state[destCanvas] = canvas)),
- 'image-data-to-canvas',
- ];
- const writeImageHead = async (blob, head) => {
- if (!isJPEG(blob) || !head)
- return blob;
- // get exif section
- const view = new DataView(head);
- const markers = dataViewGetApplicationMarkers(view);
- if (!markers || !markers.exif)
- return blob;
- const { exif } = markers;
- // from byte 0 to end of exif header
- const exifBuffer = head.slice(0, exif.offset + exif.size + 2);
- return blobWriteSection(blob,
- // insert head buffer into blob
- exifBuffer,
- // current blob doesn't have exif header (as outputted by canvas), so we insert ours in
- // (jpeg header 2) + (jfif size 16) + (app1 header 2)
- [20]);
- };
- const BlobWriteImageHead = (srcBlob = 'blob', srcHead = 'head', destBlob = 'blob') => [
- connect(writeImageHead, (state) => [state[srcBlob], state[srcHead]], (state, blob) => (state[destBlob] = blob)),
- 'blob-write-image-head',
- ];
- const BlobToFile = ({ renameFile = undefined, srcBlob = 'blob', srcFile = 'src', destFile = 'dest', defaultFilename = undefined, } = {}) => [
- connect(blobToFile, (state) => [
- state[srcBlob],
- renameFile
- ? renameFile(state[srcFile])
- : state[srcFile].name ||
- `${defaultFilename}.${getExtensionFromMimeType(state[srcBlob].type)}`,
- ], (state, file) => (state[destFile] = file)),
- 'blob-to-file',
- ];
- const Store = ({ url = './', dataset = (state) => [
- ['dest', state.dest, state.dest.name],
- ['imageState', state.imageState],
- ], destStore = 'store', }) => [
- connect(
- // upload function
- async (dataset, onprogress) => await post(url, dataset, { onprogress }),
- // get state values
- (state, options, onprogress) => [dataset(state), onprogress],
- // set state values
- (state, xhr) => (state[destStore] = xhr) // logs XHR request returned by `post`
- ),
- 'store',
- ];
- const PropFilter = (allowlist) => [
- connect((state) => {
- // if no allowlist suppleid or is empty array we don't filter
- if (!allowlist || !allowlist.length)
- return state;
- // else we only allow the props defined in the list and delete non matching props
- Object.keys(state).forEach((key) => {
- if (allowlist.includes(key))
- return;
- delete state[key];
- });
- return state;
- }),
- 'prop-filter',
- ];
- // Generic image reader, suitable for most use cases
- const createDefaultImageReader$1 = (options = {}) => {
- const { orientImage = true, outputProps = ['src', 'dest', 'size'], preprocessImageFile, } = options;
- return [
- // can read most source files and turn them into blobs
- AnyToFile(),
- // TODO: test if supported mime/type
- // called when file created, can be used to read unrecognized files
- preprocessImageFile && [
- connect(preprocessImageFile, (state, options, onprogress) => [
- state.dest,
- options,
- onprogress,
- ], (state, file) => (state.dest = file)),
- 'preprocess-image-file',
- ],
- // quickly read size (only reads first part of image)
- BlobReadImageSize({ srcProp: 'dest' }),
- // fix image orientation
- orientImage && BlobReadImageHead({ srcProp: 'dest' }),
- orientImage && ImageHeadReadExifOrientationTag(),
- orientImage && ImageSizeMatchOrientation(),
- // remove unwanted props
- PropFilter(outputProps),
- ].filter(Boolean);
- };
- const createDefaultImageWriter$1 = (options = {}) => {
- const { canvasMemoryLimit = getCanvasMemoryLimit(), orientImage = true, copyImageHead = true, mimeType = undefined, quality = undefined, renameFile = undefined, targetSize = undefined, store = undefined, format = 'file', outputProps = ['src', 'dest', 'imageState', 'store'], preprocessImageSource, preprocessImageState, postprocessImageData, postprocessImageBlob, } = options;
- return [
- // allow preprocessing of image blob, should return a new blob, for example to automatically make image background transparent
- preprocessImageSource && [
- connect(preprocessImageSource, (state, options, onprogress) => [
- state.src,
- options,
- onprogress,
- ], (state, src) => (state.src = src)),
- 'preprocess-image-source',
- ],
- // get orientation info (if is jpeg)
- (orientImage || copyImageHead) && BlobReadImageHead(),
- orientImage && ImageHeadReadExifOrientationTag(),
- // get image size
- BlobReadImageSize(),
- // allow preproccesing of image state for example to replace placeholders
- preprocessImageState && [
- connect(preprocessImageState, (state, options, onprogress) => [
- state.imageState,
- options,
- onprogress,
- ], (state, imageState) => (state.imageState = imageState)),
- 'preprocess-image-state',
- ],
- // get image data
- BlobToImageData({ canvasMemoryLimit }),
- // fix image orientation
- orientImage && ImageSizeMatchOrientation(),
- orientImage && ImageDataMatchOrientation(),
- // apply canvas scalar to data
- ApplyCanvasScalar(),
- // apply image state
- ImageDataRedact(),
- ImageDataCrop(),
- ImageDataResize({ resize: targetSize }),
- ImageDataFilter(),
- ImageDataFill(),
- ImageDataAnnotate(),
- ImageDataDecorate(),
- ImageDataFrame(),
- // run post processing on image data, for example to apply circular crop
- postprocessImageData && [
- connect(postprocessImageData, (state, options, onprogress) => [
- state.imageData,
- options,
- onprogress,
- ], (state, imageData) => (state.imageData = imageData)),
- 'postprocess-image-data',
- ],
- // convert to correct output format
- format === 'file'
- ? ImageDataToBlob({ mimeType, quality })
- : format === 'canvas'
- ? ImageDataToCanvas()
- : [
- (state) => {
- state.dest = state.imageData;
- return state;
- },
- ],
- // we overwite the exif orientation tag so the image is oriented correctly
- format === 'file' && orientImage && ImageHeadClearExifOrientationTag(),
- // we write the new image head to the target blob
- format === 'file' && copyImageHead && BlobWriteImageHead(),
- // allow converting the blob to a different format
- postprocessImageBlob && [
- connect(postprocessImageBlob, ({ blob, imageData, src }, options, onprogress) => [
- { blob, imageData, src },
- options,
- onprogress,
- ], (state, blob) => (state.blob = blob)),
- 'postprocess-image-file',
- ],
- // turn the image blob into a file, will also rename the file
- format === 'file' && BlobToFile({ defaultFilename: 'image', renameFile }),
- // upload or process data if is a file
- format === 'file'
- ? // used for file output formats
- store &&
- (isString(store)
- ? // a basic store to post to
- Store({ url: store })
- : // see if is fully custom or store config
- isFunction(store)
- ? // fully custom store function
- [store, 'store']
- : // a store configuration object
- Store(store))
- : // used for imageData and canvas output formats
- isFunction(store) && [store, 'store'],
- // remove unwanted props
- PropFilter(outputProps),
- ].filter(Boolean);
- };
- var scrambleEffect = (options, done) => {
- const { imageData, amount = 1 } = options;
- const intensity = Math.round(Math.max(1, amount) * 2);
- const range = Math.round(intensity * 0.5);
- const inputWidth = imageData.width;
- const inputHeight = imageData.height;
- const outputData = new Uint8ClampedArray(inputWidth * inputHeight * 4);
- const inputData = imageData.data;
- let randomData;
- let i = 0, x, y, r;
- let xoffset = 0;
- let yoffset = 0;
- let index;
- const l = inputWidth * inputHeight * 4 - 4;
- for (y = 0; y < inputHeight; y++) {
- randomData = crypto.getRandomValues(new Uint8ClampedArray(inputHeight));
- for (x = 0; x < inputWidth; x++) {
- r = randomData[y] / 255;
- xoffset = 0;
- yoffset = 0;
- if (r < 0.5) {
- xoffset = (-range + Math.round(Math.random() * intensity)) * 4;
- }
- if (r > 0.5) {
- yoffset = (-range + Math.round(Math.random() * intensity)) * (inputWidth * 4);
- }
- // limit to image data
- index = Math.min(Math.max(0, i + xoffset + yoffset), l);
- outputData[i] = inputData[index];
- outputData[i + 1] = inputData[index + 1];
- outputData[i + 2] = inputData[index + 2];
- outputData[i + 3] = inputData[index + 3];
- i += 4;
- }
- }
- done(null, {
- data: outputData,
- width: imageData.width,
- height: imageData.height,
- });
- };
- // basic blur covolution matrix
- const BLUR_MATRIX = [0.0625, 0.125, 0.0625, 0.125, 0.25, 0.125, 0.0625, 0.125, 0.0625];
- var imageDataScramble = async (inputData, options = {}) => {
- if (!inputData)
- return;
- const { width, height } = inputData;
- const { dataSize = 96, dataSizeScalar = 1, scrambleAmount = 4, blurAmount = 6, outputFormat = 'canvas', backgroundColor = [0, 0, 0], } = options;
- const size = Math.round(dataSize * dataSizeScalar);
- const scalar = Math.min(size / width, size / height);
- const outputWidth = Math.floor(width * scalar);
- const outputHeight = Math.floor(height * scalar);
- // draw low res preview, add margin so blur isn't transparent
- const scaledOutputCanvas = (h('canvas', { width: outputWidth, height: outputHeight }));
- const ctx = scaledOutputCanvas.getContext('2d');
- // fill background on transparent images
- backgroundColor.length = 3; // prevent transparent colors
- ctx.fillStyle = colorArrayToRGBA(backgroundColor);
- ctx.fillRect(0, 0, outputWidth, outputHeight);
- if (isImageData(inputData)) {
- // temporarily draw to canvas so we can draw image data to scaled context
- const transferCanvas = h('canvas', { width, height });
- transferCanvas.getContext('2d').putImageData(inputData, 0, 0);
- // draw to scaled context
- ctx.drawImage(transferCanvas, 0, 0, outputWidth, outputHeight);
- // release memory
- releaseCanvas(transferCanvas);
- }
- else {
- // bitmap data
- ctx.drawImage(inputData, 0, 0, outputWidth, outputHeight);
- }
- // get scaled image data for scrambling
- const imageData = ctx.getImageData(0, 0, outputWidth, outputHeight);
- // filters to apply
- const filters = [];
- // add scramble filter
- if (scrambleAmount > 0)
- filters.push([scrambleEffect, { amount: scrambleAmount }]);
- // add blur filters
- if (blurAmount > 0)
- for (let i = 0; i < blurAmount; i++) {
- filters.push([convolutionEffect, { matrix: BLUR_MATRIX }]);
- }
- let imageDataScrambled;
- if (filters.length) {
- // builds effect chain
- const chain = (transforms, i) => `(err, imageData) => {
- (${transforms[i][0].toString()})(Object.assign({ imageData: imageData }, filterInstructions[${i}]),
- ${transforms[i + 1] ? chain(transforms, i + 1) : 'done'})
- }`;
- const filterChain = `function (options, done) {
- const filterInstructions = options.filterInstructions;
- const imageData = options.imageData;
- (${chain(filters, 0)})(null, imageData)
- }`;
- // scramble image data in separate thread
- const imageDataObjectScrambled = await thread(filterChain, [
- {
- imageData: imageData,
- filterInstructions: filters.map((t) => t[1]),
- },
- ], [imageData.data.buffer]);
- imageDataScrambled = imageDataObjectToImageData(imageDataObjectScrambled);
- }
- else {
- imageDataScrambled = imageData;
- }
- if (outputFormat === 'canvas') {
- // put back scrambled data
- ctx.putImageData(imageDataScrambled, 0, 0);
- // return canvas
- return scaledOutputCanvas;
- }
- return imageDataScrambled;
- };
- var getComponentExportedProps = (Component) => {
- const descriptors = Object.getOwnPropertyDescriptors(Component.prototype);
- return Object.keys(descriptors).filter((key) => !!descriptors[key]['get']);
- };
- function circOut(t) {
- return Math.sqrt(1 - --t * t);
- }
- function is_date(obj) {
- return Object.prototype.toString.call(obj) === '[object Date]';
- }
- function get_interpolator(a, b) {
- if (a === b || a !== a)
- return () => a;
- const type = typeof a;
- if (type !== typeof b || Array.isArray(a) !== Array.isArray(b)) {
- throw new Error('Cannot interpolate values of different type');
- }
- if (Array.isArray(a)) {
- const arr = b.map((bi, i) => {
- return get_interpolator(a[i], bi);
- });
- return t => arr.map(fn => fn(t));
- }
- if (type === 'object') {
- if (!a || !b)
- throw new Error('Object cannot be null');
- if (is_date(a) && is_date(b)) {
- a = a.getTime();
- b = b.getTime();
- const delta = b - a;
- return t => new Date(a + t * delta);
- }
- const keys = Object.keys(b);
- const interpolators = {};
- keys.forEach(key => {
- interpolators[key] = get_interpolator(a[key], b[key]);
- });
- return t => {
- const result = {};
- keys.forEach(key => {
- result[key] = interpolators[key](t);
- });
- return result;
- };
- }
- if (type === 'number') {
- const delta = b - a;
- return t => a + t * delta;
- }
- throw new Error(`Cannot interpolate ${type} values`);
- }
- function tweened(value, defaults = {}) {
- const store = writable(value);
- let task;
- let target_value = value;
- function set(new_value, opts) {
- if (value == null) {
- store.set(value = new_value);
- return Promise.resolve();
- }
- target_value = new_value;
- let previous_task = task;
- let started = false;
- let { delay = 0, duration = 400, easing = identity, interpolate = get_interpolator } = assign(assign({}, defaults), opts);
- if (duration === 0) {
- if (previous_task) {
- previous_task.abort();
- previous_task = null;
- }
- store.set(value = target_value);
- return Promise.resolve();
- }
- const start = now() + delay;
- let fn;
- task = loop(now => {
- if (now < start)
- return true;
- if (!started) {
- fn = interpolate(value, new_value);
- if (typeof duration === 'function')
- duration = duration(value, new_value);
- started = true;
- }
- if (previous_task) {
- previous_task.abort();
- previous_task = null;
- }
- const elapsed = now - start;
- if (elapsed > duration) {
- store.set(value = new_value);
- return false;
- }
- // @ts-ignore
- store.set(value = fn(easing(elapsed / duration)));
- return true;
- });
- return task.promise;
- }
- return {
- set,
- update: (fn, opts) => set(fn(target_value, value), opts),
- subscribe: store.subscribe
- };
- }
- // @ts-ignore
- function tick_spring(ctx, last_value, current_value, target_value) {
- if (typeof current_value === 'number') {
- // @ts-ignore
- const delta = target_value - current_value;
- // @ts-ignore
- const velocity = (current_value - last_value) / (ctx.dt || 1 / 60); // guard div by 0
- const spring = ctx.opts.stiffness * delta;
- const damper = ctx.opts.damping * velocity;
- const acceleration = (spring - damper) * ctx.inv_mass;
- const d = (velocity + acceleration) * ctx.dt;
- if (Math.abs(d) < ctx.opts.precision && Math.abs(delta) < ctx.opts.precision) {
- return target_value; // settled
- }
- else {
- ctx.settled = false; // signal loop to keep ticking
- // @ts-ignore
- return current_value + d;
- }
- }
- else if (isArray(current_value)) {
- // @ts-ignore
- return current_value.map((_, i) => tick_spring(ctx, last_value[i], current_value[i], target_value[i]));
- }
- else if (typeof current_value === 'object') {
- const next_value = {};
- // @ts-ignore
- for (const k in current_value) {
- // @ts-ignore
- next_value[k] = tick_spring(ctx, last_value[k], current_value[k], target_value[k]);
- }
- // @ts-ignore
- return next_value;
- }
- else {
- throw new Error(`Cannot spring ${typeof current_value} values`);
- }
- }
- // export interface Spring {
- // set: (new_value: any, opts?: SpringUpdateOpts) => Promise<void>;
- // update: (fn: Function, opts?: SpringUpdateOpts) => Promise<void>;
- // subscribe: Function;
- // precision: number;
- // damping: number;
- // stiffness: number;
- // }
- function spring(value, opts = {}) {
- const store = writable(value);
- const { stiffness = 0.15, damping = 0.8, precision = 0.01 } = opts;
- let last_time;
- let task;
- let current_token;
- let last_value = value;
- let target_value = value;
- let inv_mass = 1;
- let inv_mass_recovery_rate = 0;
- let cancel_task = false;
- function set(new_value, opts = {}) {
- target_value = new_value;
- const token = (current_token = {});
- if (value == null || opts.hard || (spring.stiffness >= 1 && spring.damping >= 1)) {
- cancel_task = true; // cancel any running animation
- last_time = null;
- last_value = new_value;
- store.set((value = target_value));
- return Promise.resolve();
- }
- else if (opts.soft) {
- const rate = opts.soft === true ? 0.5 : +opts.soft;
- inv_mass_recovery_rate = 1 / (rate * 60);
- inv_mass = 0; // infinite mass, unaffected by spring forces
- }
- if (!task) {
- last_time = null;
- cancel_task = false;
- const ctx = {
- inv_mass: undefined,
- opts: spring,
- settled: true,
- dt: undefined,
- };
- task = loop((now) => {
- if (last_time === null)
- last_time = now;
- if (cancel_task) {
- cancel_task = false;
- task = null;
- return false;
- }
- inv_mass = Math.min(inv_mass + inv_mass_recovery_rate, 1);
- // altered so doesn't create a new object
- ctx.inv_mass = inv_mass;
- ctx.opts = spring;
- ctx.settled = true; // tick_spring may signal false
- ctx.dt = ((now - last_time) * 60) / 1000;
- const next_value = tick_spring(ctx, last_value, value, target_value);
- last_time = now;
- last_value = value;
- store.set((value = next_value));
- if (ctx.settled)
- task = null;
- return !ctx.settled;
- });
- }
- return new Promise((fulfil) => {
- task.promise.then(() => {
- if (token === current_token)
- fulfil();
- });
- });
- }
- const spring = {
- set,
- update: (fn, opts) => set(fn(target_value, value), opts),
- subscribe: store.subscribe,
- stiffness,
- damping,
- precision,
- };
- return spring;
- }
- var prefersReducedMotion = readable(false, set => {
- const mql = window.matchMedia('(prefers-reduced-motion:reduce)');
- set(mql.matches);
- mql.onchange = () => set(mql.matches);
- });
- var hasResizeObserver = () => 'ResizeObserver' in window;
- //
- const rectNext = rectCreateEmpty();
- const updateNodeRect = (node, x, y, width, height) => {
- if (!node.rect)
- node.rect = rectCreateEmpty();
- const rect = node.rect;
- rectUpdate(rectNext, x, y, width, height);
- if (rectEqual(rect, rectNext))
- return;
- rectUpdateWithRect(rect, rectNext);
- node.dispatchEvent(new CustomEvent('measure', { detail: rect }));
- };
- // measures the element
- const r = Math.round;
- const measureViewRect = (node) => {
- const clientRect = node.getBoundingClientRect();
- updateNodeRect(node, r(clientRect.x), r(clientRect.y), r(clientRect.width), r(clientRect.height));
- };
- const measureOffset = (node) => updateNodeRect(node, node.offsetLeft, node.offsetTop, node.offsetWidth, node.offsetHeight);
- // holds all the elements to measure using requestAnimationFrame
- const elements = [];
- // draw loop
- let frame = null;
- function tick() {
- if (!elements.length) {
- frame = null;
- return;
- }
- elements.forEach((node) => node.measure(node));
- frame = requestAnimationFrame(tick);
- }
- let observer; // ResizeObserver API not known by TypeScript
- var measurable = (node, options = {}) => {
- const { observePosition = false, observeViewRect = false, once = false, disabled = false, } = options;
- // exit
- if (disabled)
- return;
- // use resize observe if available
- if (hasResizeObserver() && !observePosition && !observeViewRect) {
- // we only create one observer, it will observe all registered elements
- if (!observer) {
- // @ts-ignore: [2020-02-20] ResizeObserver API not known by TypeScript
- observer = new ResizeObserver((entries) => {
- // @ts-ignore
- entries.forEach((entry) => measureOffset(entry.target));
- });
- }
- // start observing this node
- observer.observe(node);
- // measure our node for the first time
- measureOffset(node);
- // if should only measure once, remove now
- if (once)
- observer.unobserve(node);
- // and we done, need to return a clean up method for when our node is destroyed
- return {
- destroy() {
- // already unobserved this node
- if (once)
- return;
- observer.unobserve(node);
- // TODO: test if all nodes have been removed, if so, remove observer
- },
- };
- }
- // set measure function
- node.measure = observeViewRect ? measureViewRect : measureOffset;
- // add so the element is measured
- elements.push(node);
- // start measuring on next frame, we set up a single measure loop,
- // the loop will check if there's still elements that need to be measured,
- // else it will stop running
- if (!frame)
- frame = requestAnimationFrame(tick);
- // measure this element now
- node.measure(node);
- // remove method
- return {
- destroy() {
- const index = elements.indexOf(node);
- elements.splice(index, 1);
- },
- };
- };
- var focusvisible = (element) => {
- let isKeyboardInteraction = false;
- const handlePointerdown = () => {
- isKeyboardInteraction = false;
- };
- const handleKeydown = () => {
- isKeyboardInteraction = true;
- };
- const handleKeyup = () => {
- isKeyboardInteraction = false;
- };
- const handleFocus = (e) => {
- if (!isKeyboardInteraction)
- return;
- e.target.dataset.focusVisible = '';
- };
- const handleBlur = (e) => {
- delete e.target.dataset.focusVisible;
- };
- const map = {
- pointerdown: handlePointerdown,
- keydown: handleKeydown,
- keyup: handleKeyup,
- focus: handleFocus,
- blur: handleBlur,
- };
- Object.keys(map).forEach((event) => element.addEventListener(event, map[event], true));
- return {
- destroy() {
- Object.keys(map).forEach((event) => element.removeEventListener(event, map[event], true));
- },
- };
- };
- const getResourceFromItem = async (item) => new Promise((resolve) => {
- if (item.kind === 'file')
- return resolve(item.getAsFile());
- item.getAsString(resolve);
- });
- const getResourcesFromEvent = (e) => new Promise((resolve, reject) => {
- const { items } = e.dataTransfer;
- if (!items)
- return resolve([]);
- Promise.all(Array.from(items).map(getResourceFromItem))
- .then((res) => {
- resolve(res.filter((item) => (isBinary(item) && isImage(item)) || /^http/.test(item)));
- })
- .catch(reject);
- });
- var dropable = (node, options = {}) => {
- const handleDragOver = (e) => {
- // need to be prevent default to allow drop
- e.preventDefault();
- };
- const handleDrop = async (e) => {
- e.preventDefault();
- e.stopPropagation(); // prevents parents from catching this drop
- try {
- const resources = await getResourcesFromEvent(e);
- node.dispatchEvent(new CustomEvent('dropfiles', {
- detail: {
- event: e,
- resources,
- },
- ...options,
- }));
- }
- catch (err) {
- // silent, wasn't able to catch
- }
- };
- node.addEventListener('drop', handleDrop);
- node.addEventListener('dragover', handleDragOver);
- // remove method
- return {
- destroy() {
- node.removeEventListener('drop', handleDrop);
- node.removeEventListener('dragover', handleDragOver);
- },
- };
- };
- let result$6 = null;
- var supportsWebGL2 = () => {
- if (result$6 === null) {
- if ('WebGL2RenderingContext' in window) {
- let canvas;
- try {
- canvas = h('canvas');
- result$6 = !!canvas.getContext('webgl2');
- }
- catch (err) {
- result$6 = false;
- }
- canvas && releaseCanvas(canvas);
- }
- else {
- result$6 = false;
- }
- }
- return result$6;
- };
- var getWebGLContext = (canvas, attrs) => {
- if (supportsWebGL2())
- return canvas.getContext('webgl2', attrs);
- return (canvas.getContext('webgl', attrs) ||
- canvas.getContext('experimental-webgl', attrs));
- };
- let result$5 = null;
- var isSoftwareRendering = () => {
- if (result$5 === null) {
- if (isBrowser()) {
- const canvas = h('canvas');
- result$5 = !getWebGLContext(canvas, {
- failIfMajorPerformanceCaveat: true,
- });
- releaseCanvas(canvas);
- }
- else {
- result$5 = false;
- }
- }
- return result$5;
- };
- var isPowerOf2 = (value) => (value & (value - 1)) === 0;
- var stringReplace = (str, entries = {}, prefix = '', postfix = '') => {
- return Object.keys(entries)
- .filter((key) => !isObject(entries[key]))
- .reduce((prev, curr) => {
- return prev.replace(new RegExp(prefix + curr + postfix), entries[curr]);
- }, str);
- };
- var SHADER_FRAG_HEAD = "#version 300 es\nprecision highp float;\n\nout vec4 fragColor;"; // eslint-disable-line
- var SHADER_FRAG_INIT = "\nfloat a=1.0;vec4 fillColor=uColor;vec4 textureColor=texture(uTexture,vTexCoord);textureColor*=(1.0-step(1.0,vTexCoord.y))*step(0.0,vTexCoord.y)*(1.0-step(1.0,vTexCoord.x))*step(0.0,vTexCoord.x);"; // eslint-disable-line
- var SHADER_FRAG_MASK = "\nuniform float uMaskFeather[8];uniform float uMaskBounds[4];uniform float uMaskOpacity;float mask(float x,float y,float bounds[4],float opacity){return 1.0-(1.0-(smoothstep(bounds[3],bounds[3]+1.0,x)*(1.0-smoothstep(bounds[1]-1.0,bounds[1],x))*(1.0-step(bounds[0],y))*step(bounds[2],y)))*(1.0-opacity);}"; // eslint-disable-line
- var SHADER_FRAG_MASK_APPLY = "\nfloat m=mask(gl_FragCoord.x,gl_FragCoord.y,uMaskBounds,uMaskOpacity);"; // eslint-disable-line
- var SHADER_FRAG_MASK_FEATHER_APPLY = "\nfloat leftFeatherOpacity=step(uMaskFeather[1],gl_FragCoord.x)*uMaskFeather[0]+((1.0-uMaskFeather[0])*smoothstep(uMaskFeather[1],uMaskFeather[3],gl_FragCoord.x));float rightFeatherOpacity=(1.0-step(uMaskFeather[7],gl_FragCoord.x))*uMaskFeather[4]+((1.0-uMaskFeather[4])*smoothstep(uMaskFeather[7],uMaskFeather[5],gl_FragCoord.x));a*=leftFeatherOpacity*rightFeatherOpacity;"; // eslint-disable-line
- var SHADER_FRAG_RECT_AA = "\nvec2 scaledPoint=vec2(vRectCoord.x*uSize.x,vRectCoord.y*uSize.y);a*=smoothstep(0.0,1.0,uSize.x-scaledPoint.x);a*=smoothstep(0.0,1.0,uSize.y-scaledPoint.y);a*=smoothstep(0.0,1.0,scaledPoint.x);a*=smoothstep(0.0,1.0,scaledPoint.y);"; // eslint-disable-line
- var SHADER_FRAG_CORNER_RADIUS = "\nvec2 s=(uSize-2.0)*.5;vec2 r=(vRectCoord*uSize);vec2 p=r-(uSize*.5);float cornerRadius=uCornerRadius[0];bool left=r.x<s.x;bool top=r.y<s.x;if(!left&&top){cornerRadius=uCornerRadius[1];}if(!left&&!top){cornerRadius=uCornerRadius[3];}if(left&&!top){cornerRadius=uCornerRadius[2];}a*=1.0-clamp(length(max(abs(p)-(s-cornerRadius),0.0))-cornerRadius,0.0,1.0);"; // eslint-disable-line
- var SHADER_FRAG_SHAPE_BLEND_COLOR = "\nif(m<=0.0)discard;fillColor.a*=a;fillColor.rgb*=fillColor.a;fillColor.rgb*=m;fillColor.rgb+=(1.0-m)*(uCanvasColor.rgb*fillColor.a);textureColor*=uTextureOpacity;textureColor.a*=a;textureColor.rgb*=m*a;textureColor.rgb+=(1.0-m)*(uCanvasColor.rgb*textureColor.a);fragColor=textureColor+(fillColor*(1.0-textureColor.a));"; // eslint-disable-line
- var SHADER_FRAG_TEXTURE_COLORIZE = "\nif(uTextureColor.a!=0.0&&textureColor.a>0.0){vec3 colorFlattened=textureColor.rgb/textureColor.a;if(colorFlattened.r>.999999&&colorFlattened.g==0.0&&colorFlattened.b>.999999){textureColor.rgb=uTextureColor.rgb*textureColor.a;}textureColor*=uTextureColor.a;}"; // eslint-disable-line
- var SHADER_VERT_HEAD = "#version 300 es\n\nin vec4 aPosition;uniform mat4 uMatrix;"; // eslint-disable-line
- var SHADER_VERT_MULTIPLY_MATRUX = "\ngl_Position=uMatrix*vec4(aPosition.x,aPosition.y,0,1);"; // eslint-disable-line
- var SHADER_VERT_TEXTURE = "\nin vec2 aTexCoord;out vec2 vTexCoord;"; // eslint-disable-line
- const SHADER_VERT_SNIPPETS = {
- head: SHADER_VERT_HEAD,
- text: SHADER_VERT_TEXTURE,
- matrix: SHADER_VERT_MULTIPLY_MATRUX,
- };
- const SHADER_FRAG_SNIPPETS = {
- head: SHADER_FRAG_HEAD,
- mask: SHADER_FRAG_MASK,
- init: SHADER_FRAG_INIT,
- colorize: SHADER_FRAG_TEXTURE_COLORIZE,
- maskapply: SHADER_FRAG_MASK_APPLY,
- maskfeatherapply: SHADER_FRAG_MASK_FEATHER_APPLY,
- edgeaa: SHADER_FRAG_RECT_AA,
- cornerradius: SHADER_FRAG_CORNER_RADIUS,
- fragcolor: SHADER_FRAG_SHAPE_BLEND_COLOR,
- };
- const transpileShader = (gl, src, type) => {
- src = stringReplace(src, type === gl.VERTEX_SHADER ? SHADER_VERT_SNIPPETS : SHADER_FRAG_SNIPPETS, '##').trim();
- // ready if supports webgl
- if (supportsWebGL2())
- return src;
- src = src.replace(/#version.+/gm, '').trim();
- src = src.replace(/^\/\/\#/gm, '#');
- if (type === gl.VERTEX_SHADER) {
- src = src.replace(/in /gm, 'attribute ').replace(/out /g, 'varying ');
- }
- if (type === gl.FRAGMENT_SHADER) {
- src = src
- .replace(/in /gm, 'varying ')
- .replace(/out.*?;/gm, '')
- .replace(/texture\(/g, 'texture2D(')
- .replace(/fragColor/g, 'gl_FragColor');
- }
- return `${src}`;
- };
- const compileShader = (gl, src, type) => {
- const shader = gl.createShader(type);
- const transpiledSrc = transpileShader(gl, src, type);
- gl.shaderSource(shader, transpiledSrc);
- gl.compileShader(shader);
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- console.error(gl.getShaderInfoLog(shader));
- }
- return shader;
- };
- const createShader = (gl, vertexShader, fragmentShader, attribs, uniforms) => {
- const program = gl.createProgram();
- gl.attachShader(program, compileShader(gl, vertexShader, gl.VERTEX_SHADER));
- gl.attachShader(program, compileShader(gl, fragmentShader, gl.FRAGMENT_SHADER));
- gl.linkProgram(program);
- const locations = {};
- attribs.forEach((name) => {
- locations[name] = gl.getAttribLocation(program, name);
- });
- uniforms.forEach((name) => {
- locations[name] = gl.getUniformLocation(program, name);
- });
- return {
- program,
- locations,
- };
- };
- const canMipMap = (source) => {
- if (supportsWebGL2())
- return true;
- return isPowerOf2(source.width) && isPowerOf2(source.height);
- };
- const applyTextureProperties = (gl, source, options) => {
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, canMipMap(source) ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, options.filter // === 'nearest' ? gl.NEAREST : gl.LINEAR
- );
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- if (canMipMap(source))
- gl.generateMipmap(gl.TEXTURE_2D);
- };
- const updateTexture = (gl, texture, source, options) => {
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
- applyTextureProperties(gl, source, options);
- gl.bindTexture(gl.TEXTURE_2D, null);
- return texture;
- };
- const applyOpacity = (color, opacity = 1) => color
- ? [color[0], color[1], color[2], isNumber(color[3]) ? opacity * color[3] : opacity]
- : [0, 0, 0, 0];
- const mat4Create = () => {
- const mat = new Float32Array(16);
- mat[0] = 1;
- mat[5] = 1;
- mat[10] = 1;
- mat[15] = 1;
- return mat;
- };
- const mat4Perspective = (mat, fovy, aspect, near, far) => {
- const f = 1.0 / Math.tan(fovy / 2);
- const nf = 1 / (near - far);
- mat[0] = f / aspect;
- mat[1] = 0;
- mat[2] = 0;
- mat[3] = 0;
- mat[4] = 0;
- mat[5] = f;
- mat[6] = 0;
- mat[7] = 0;
- mat[8] = 0;
- mat[9] = 0;
- mat[10] = (far + near) * nf;
- mat[11] = -1;
- mat[12] = 0;
- mat[13] = 0;
- mat[14] = 2 * far * near * nf;
- mat[15] = 0;
- };
- const mat4Ortho = (mat, left, right, bottom, top, near, far) => {
- const lr = 1 / (left - right);
- const bt = 1 / (bottom - top);
- const nf = 1 / (near - far);
- mat[0] = -2 * lr;
- mat[1] = 0;
- mat[2] = 0;
- mat[3] = 0;
- mat[4] = 0;
- mat[5] = -2 * bt;
- mat[6] = 0;
- mat[7] = 0;
- mat[8] = 0;
- mat[9] = 0;
- mat[10] = 2 * nf;
- mat[11] = 0;
- mat[12] = (left + right) * lr;
- mat[13] = (top + bottom) * bt;
- mat[14] = (far + near) * nf;
- mat[15] = 1;
- };
- const mat4Translate = (mat, x, y, z) => {
- mat[12] = mat[0] * x + mat[4] * y + mat[8] * z + mat[12];
- mat[13] = mat[1] * x + mat[5] * y + mat[9] * z + mat[13];
- mat[14] = mat[2] * x + mat[6] * y + mat[10] * z + mat[14];
- mat[15] = mat[3] * x + mat[7] * y + mat[11] * z + mat[15];
- };
- const mat4Scale = (mat, s) => {
- mat[0] = mat[0] * s;
- mat[1] = mat[1] * s;
- mat[2] = mat[2] * s;
- mat[3] = mat[3] * s;
- mat[4] = mat[4] * s;
- mat[5] = mat[5] * s;
- mat[6] = mat[6] * s;
- mat[7] = mat[7] * s;
- mat[8] = mat[8] * s;
- mat[9] = mat[9] * s;
- mat[10] = mat[10] * s;
- mat[11] = mat[11] * s;
- };
- const mat4ScaleX = (mat, s) => {
- mat[0] = mat[0] * s;
- mat[1] = mat[1] * s;
- mat[2] = mat[2] * s;
- mat[3] = mat[3] * s;
- };
- const mat4ScaleY = (mat, s) => {
- mat[4] = mat[4] * s;
- mat[5] = mat[5] * s;
- mat[6] = mat[6] * s;
- mat[7] = mat[7] * s;
- };
- const mat4RotateX = (mat, rad) => {
- const s = Math.sin(rad);
- const c = Math.cos(rad);
- const a10 = mat[4];
- const a11 = mat[5];
- const a12 = mat[6];
- const a13 = mat[7];
- const a20 = mat[8];
- const a21 = mat[9];
- const a22 = mat[10];
- const a23 = mat[11];
- mat[4] = a10 * c + a20 * s;
- mat[5] = a11 * c + a21 * s;
- mat[6] = a12 * c + a22 * s;
- mat[7] = a13 * c + a23 * s;
- mat[8] = a20 * c - a10 * s;
- mat[9] = a21 * c - a11 * s;
- mat[10] = a22 * c - a12 * s;
- mat[11] = a23 * c - a13 * s;
- };
- const mat4RotateY = (mat, rad) => {
- const s = Math.sin(rad);
- const c = Math.cos(rad);
- const a00 = mat[0];
- const a01 = mat[1];
- const a02 = mat[2];
- const a03 = mat[3];
- const a20 = mat[8];
- const a21 = mat[9];
- const a22 = mat[10];
- const a23 = mat[11];
- mat[0] = a00 * c - a20 * s;
- mat[1] = a01 * c - a21 * s;
- mat[2] = a02 * c - a22 * s;
- mat[3] = a03 * c - a23 * s;
- mat[8] = a00 * s + a20 * c;
- mat[9] = a01 * s + a21 * c;
- mat[10] = a02 * s + a22 * c;
- mat[11] = a03 * s + a23 * c;
- };
- const mat4RotateZ = (mat, rad) => {
- const s = Math.sin(rad);
- const c = Math.cos(rad);
- const a00 = mat[0];
- const a01 = mat[1];
- const a02 = mat[2];
- const a03 = mat[3];
- const a10 = mat[4];
- const a11 = mat[5];
- const a12 = mat[6];
- const a13 = mat[7];
- mat[0] = a00 * c + a10 * s;
- mat[1] = a01 * c + a11 * s;
- mat[2] = a02 * c + a12 * s;
- mat[3] = a03 * c + a13 * s;
- mat[4] = a10 * c - a00 * s;
- mat[5] = a11 * c - a01 * s;
- mat[6] = a12 * c - a02 * s;
- mat[7] = a13 * c - a03 * s;
- };
- var degToRad = (degrees) => degrees * Math.PI / 180;
- var imageFragmentShader = "\n##head\nin vec2 vTexCoord;uniform sampler2D uTexture;uniform sampler2D uTextureMarkup;uniform sampler2D uTextureBlend;uniform vec2 uTextureSize;uniform float uOpacity;uniform vec4 uFillColor;uniform vec4 uOverlayColor;uniform mat4 uColorMatrix;uniform vec4 uColorOffset;uniform float uClarityKernel[9];uniform float uClarityKernelWeight;uniform float uColorGamma;uniform float uColorVignette;uniform float uMaskClip;uniform float uMaskOpacity;uniform float uMaskBounds[4];uniform float uMaskCornerRadius[4];uniform float uMaskFeather[8];vec4 applyGamma(vec4 c,float g){c.r=pow(c.r,g);c.g=pow(c.g,g);c.b=pow(c.b,g);return c;}vec4 applyColorMatrix(vec4 c,mat4 m,vec4 o){vec4 cM=(c*m)+o;cM*=cM.a;return cM;}vec4 applyConvolutionMatrix(vec4 c,float k0,float k1,float k2,float k3,float k4,float k5,float k6,float k7,float k8,float w){vec2 pixel=vec2(1)/uTextureSize;vec4 colorSum=texture(uTexture,vTexCoord-pixel)*k0+texture(uTexture,vTexCoord+pixel*vec2(0.0,-1.0))*k1+texture(uTexture,vTexCoord+pixel*vec2(1.0,-1.0))*k2+texture(uTexture,vTexCoord+pixel*vec2(-1.0,0.0))*k3+texture(uTexture,vTexCoord)*k4+texture(uTexture,vTexCoord+pixel*vec2(1.0,0.0))*k5+texture(uTexture,vTexCoord+pixel*vec2(-1.0,1.0))*k6+texture(uTexture,vTexCoord+pixel*vec2(0.0,1.0))*k7+texture(uTexture,vTexCoord+pixel)*k8;vec4 color=vec4((colorSum/w).rgb,c.a);color.rgb=clamp(color.rgb,0.0,1.0);return color;}vec4 applyVignette(vec4 c,vec2 pos,vec2 center,float v){float d=distance(pos,center)/length(center);float f=1.0-(d*abs(v));if(v>0.0){c.rgb*=f;}else if(v<0.0){c.rgb+=(1.0-f)*(1.0-c.rgb);}return c;}vec4 blendPremultipliedAlpha(vec4 back,vec4 front){return front+(back*(1.0-front.a));}void main(){float x=gl_FragCoord.x;float y=gl_FragCoord.y;float a=1.0;float maskTop=uMaskBounds[0];float maskRight=uMaskBounds[1];float maskBottom=uMaskBounds[2];float maskLeft=uMaskBounds[3];float leftFeatherOpacity=step(uMaskFeather[1],x)*uMaskFeather[0]+((1.0-uMaskFeather[0])*smoothstep(uMaskFeather[1],uMaskFeather[3],x));float rightFeatherOpacity=(1.0-step(uMaskFeather[7],x))*uMaskFeather[4]+((1.0-uMaskFeather[4])*smoothstep(uMaskFeather[7],uMaskFeather[5],x));a*=leftFeatherOpacity*rightFeatherOpacity;float overlayColorAlpha=(smoothstep(maskLeft,maskLeft+1.0,x)*(1.0-smoothstep(maskRight-1.0,maskRight,x))*(1.0-step(maskTop,y))*step(maskBottom,y));if(uOverlayColor.a==0.0){a*=overlayColorAlpha;}vec2 offset=vec2(maskLeft,maskBottom);vec2 size=vec2(maskRight-maskLeft,maskTop-maskBottom)*.5;vec2 center=offset.xy+size.xy;int pixelX=int(step(center.x,x));int pixelY=int(step(y,center.y));float cornerRadius=0.0;if(pixelX==0&&pixelY==0)cornerRadius=uMaskCornerRadius[0];if(pixelX==1&&pixelY==0)cornerRadius=uMaskCornerRadius[1];if(pixelX==0&&pixelY==1)cornerRadius=uMaskCornerRadius[2];if(pixelX==1&&pixelY==1)cornerRadius=uMaskCornerRadius[3];float cornerOffset=sign(cornerRadius)*length(max(abs(gl_FragCoord.xy-size-offset)-size+cornerRadius,0.0))-cornerRadius;float cornerOpacity=1.0-smoothstep(0.0,1.0,cornerOffset);a*=cornerOpacity;vec2 scaledPoint=vec2(vTexCoord.x*uTextureSize.x,vTexCoord.y*uTextureSize.y);a*=smoothstep(0.0,1.0,uTextureSize.x-scaledPoint.x);a*=smoothstep(0.0,1.0,uTextureSize.y-scaledPoint.y);a*=smoothstep(0.0,1.0,scaledPoint.x);a*=smoothstep(0.0,1.0,scaledPoint.y);vec4 color=texture(uTexture,vTexCoord);color=blendPremultipliedAlpha(color,texture(uTextureBlend,vTexCoord));if(uClarityKernelWeight!=-1.0){color=applyConvolutionMatrix(color,uClarityKernel[0],uClarityKernel[1],uClarityKernel[2],uClarityKernel[3],uClarityKernel[4],uClarityKernel[5],uClarityKernel[6],uClarityKernel[7],uClarityKernel[8],uClarityKernelWeight);}color=applyGamma(color,uColorGamma);color=applyColorMatrix(color,uColorMatrix,uColorOffset);color=blendPremultipliedAlpha(uFillColor,color);color*=a;if(uColorVignette!=0.0){vec2 pos=gl_FragCoord.xy-offset;color=applyVignette(color,pos,center-offset,uColorVignette);}color=blendPremultipliedAlpha(color,texture(uTextureMarkup,vTexCoord));vec4 overlayColor=uOverlayColor*(1.0-overlayColorAlpha);overlayColor.rgb*=overlayColor.a;color=blendPremultipliedAlpha(color,overlayColor);if(uOverlayColor.a>0.0&&color.a<1.0&&uFillColor.a>0.0){color=blendPremultipliedAlpha(uFillColor,overlayColor);}color*=uOpacity;fragColor=color;}"; // eslint-disable-line
- var imageVertexShader = "\n##head\n##text\nvoid main(){vTexCoord=aTexCoord;gl_Position=uMatrix*aPosition;}"; // eslint-disable-line
- var pathVertexShader = "#version 300 es\n\nin vec4 aPosition;in vec2 aNormal;in float aMiter;out vec2 vNormal;out float vMiter;out float vWidth;uniform float uWidth;uniform mat4 uMatrix;void main(){vMiter=aMiter;vNormal=aNormal;vWidth=(uWidth*.5)+1.0;gl_Position=uMatrix*vec4(aPosition.x+(aNormal.x*vWidth*aMiter),aPosition.y+(aNormal.y*vWidth*aMiter),0,1);}"; // eslint-disable-line
- var pathFragmentShader = "\n##head\n##mask\nin vec2 vNormal;in float vMiter;in float vWidth;uniform float uWidth;uniform vec4 uColor;uniform vec4 uCanvasColor;void main(){vec4 fillColor=uColor;float m=mask(gl_FragCoord.x,gl_FragCoord.y,uMaskBounds,uMaskOpacity);if(m<=0.0)discard;fillColor.a*=clamp(smoothstep(vWidth-.5,vWidth-1.0,abs(vMiter)*vWidth),0.0,1.0);fillColor.rgb*=fillColor.a;fillColor.rgb*=m;fillColor.rgb+=(1.0-m)*(uCanvasColor.rgb*fillColor.a);fragColor=fillColor;}"; // eslint-disable-line
- var rectVertexShader = "\n##head\n##text\nin vec2 aRectCoord;out vec2 vRectCoord;void main(){vTexCoord=aTexCoord;vRectCoord=aRectCoord;\n##matrix\n}"; // eslint-disable-line
- var rectFragmentShader = "\n##head\n##mask\nin vec2 vTexCoord;in vec2 vRectCoord;uniform sampler2D uTexture;uniform vec4 uTextureColor;uniform float uTextureOpacity;uniform vec4 uColor;uniform float uCornerRadius[4];uniform vec2 uSize;uniform vec2 uPosition;uniform vec4 uCanvasColor;uniform int uInverted;void main(){\n##init\n##colorize\n##edgeaa\n##cornerradius\n##maskfeatherapply\nif(uInverted==1)a=1.0-a;\n##maskapply\n##fragcolor\n}"; // eslint-disable-line
- var ellipseVertexShader = "\n##head\n##text\nout vec2 vTexCoordDouble;void main(){vTexCoordDouble=vec2(aTexCoord.x*2.0-1.0,aTexCoord.y*2.0-1.0);vTexCoord=aTexCoord;\n##matrix\n}"; // eslint-disable-line
- var ellipseFragmentShader = "\n##head\n##mask\nin vec2 vTexCoord;in vec2 vTexCoordDouble;uniform sampler2D uTexture;uniform float uTextureOpacity;uniform vec2 uRadius;uniform vec4 uColor;uniform int uInverted;uniform vec4 uCanvasColor;void main(){\n##init\nfloat ar=uRadius.x/uRadius.y;vec2 rAA=vec2(uRadius.x-1.0,uRadius.y-(1.0/ar));vec2 scaledPointSq=vec2((vTexCoordDouble.x*uRadius.x)*(vTexCoordDouble.x*uRadius.x),(vTexCoordDouble.y*uRadius.y)*(vTexCoordDouble.y*uRadius.y));float p=(scaledPointSq.x/(uRadius.x*uRadius.x))+(scaledPointSq.y/(uRadius.y*uRadius.y));float pAA=(scaledPointSq.x/(rAA.x*rAA.x))+(scaledPointSq.y/(rAA.y*rAA.y));a=smoothstep(1.0,p/pAA,p);if(uInverted==1)a=1.0-a;\n##maskapply\n##fragcolor\n}"; // eslint-disable-line
- var triangleVertexShader = "\n##head\nvoid main(){\n##matrix\n}"; // eslint-disable-line
- var triangleFragmentShader = "\n##head\n##mask\nuniform vec4 uColor;uniform vec4 uCanvasColor;void main(){vec4 fillColor=uColor;\n##maskapply\nfillColor.rgb*=fillColor.a;fillColor.rgb*=m;fillColor.rgb+=(1.0-m)*(uCanvasColor.rgb*fillColor.a);fragColor=fillColor;}"; // eslint-disable-line
- const createPathSegment = (vertices, index, a, b, c) => {
- const ab = vectorNormalize(vectorCreate(b.x - a.x, b.y - a.y));
- const bc = vectorNormalize(vectorCreate(c.x - b.x, c.y - b.y));
- const tangent = vectorNormalize(vectorCreate(ab.x + bc.x, ab.y + bc.y));
- const miter = vectorCreate(-tangent.y, tangent.x);
- const normal = vectorCreate(-ab.y, ab.x);
- // limit miter length (TEMP fix to prevent spikes, should eventually add caps)
- const miterLength = Math.min(1 / vectorDot(miter, normal), 5);
- vertices[index] = b.x;
- vertices[index + 1] = b.y;
- vertices[index + 2] = miter.x * miterLength;
- vertices[index + 3] = miter.y * miterLength;
- vertices[index + 4] = -1;
- vertices[index + 5] = b.x;
- vertices[index + 6] = b.y;
- vertices[index + 7] = miter.x * miterLength;
- vertices[index + 8] = miter.y * miterLength;
- vertices[index + 9] = 1;
- };
- const createPathVertices = (points, close) => {
- let a, b, c, i = 0;
- const l = points.length;
- const stride = 10;
- const vertices = new Float32Array((close ? l + 1 : l) * stride);
- const first = points[0];
- const last = points[l - 1];
- for (i = 0; i < l; i++) {
- a = points[i - 1];
- b = points[i];
- c = points[i + 1];
- // if previous point not available use inverse vector to next point
- if (!a)
- a = close ? last : vectorCreate(b.x + (b.x - c.x), b.y + (b.y - c.y));
- // if next point not available use inverse vector from previous point
- if (!c)
- c = close ? first : vectorCreate(b.x + (b.x - a.x), b.y + (b.y - a.y));
- createPathSegment(vertices, i * stride, a, b, c);
- }
- if (close)
- createPathSegment(vertices, l * stride, last, first, points[1]);
- return vertices;
- };
- const rectPointsToVertices = (points) => {
- // [tl, tr, br, bl]
- // B D
- // | \ |
- // A C
- const vertices = new Float32Array(8);
- vertices[0] = points[3].x;
- vertices[1] = points[3].y;
- vertices[2] = points[0].x;
- vertices[3] = points[0].y;
- vertices[4] = points[2].x;
- vertices[5] = points[2].y;
- vertices[6] = points[1].x;
- vertices[7] = points[1].y;
- return vertices;
- };
- const trianglePointToVertices = (points) => {
- const vertices = new Float32Array(6);
- vertices[0] = points[0].x;
- vertices[1] = points[0].y;
- vertices[2] = points[1].x;
- vertices[3] = points[1].y;
- vertices[4] = points[2].x;
- vertices[5] = points[2].y;
- return vertices;
- };
- const createRectPoints = (rect, rotation = 0, flipX, flipY) => {
- const corners = rectGetCorners(rect);
- const cx = rect.x + rect.width * 0.5;
- const cy = rect.y + rect.height * 0.5;
- if (flipX || flipY)
- vectorsFlip(corners, flipX, flipY, cx, cy);
- if (rotation !== 0)
- vectorsRotate(corners, rotation, cx, cy);
- return corners;
- };
- const createEllipseOutline = (x, y, width, height, rotation, flipX, flipY) => {
- const rx = Math.abs(width) * 0.5;
- const ry = Math.abs(height) * 0.5;
- const size = Math.abs(width) + Math.abs(height);
- const precision = Math.max(20, Math.round(size / 6));
- return ellipseToPolygon(vectorCreate(x + rx, y + ry), rx, ry, rotation, flipX, flipY, precision);
- };
- const createRectOutline = (x, y, width, height, rotation, cornerRadius, flipX, flipY) => {
- const points = [];
- if (cornerRadius.every((v) => v === 0)) {
- points.push(vectorCreate(x, y), // top left corner
- vectorCreate(x + width, y), // top right corner
- vectorCreate(x + width, y + height), // bottom right corner
- vectorCreate(x, y + height) // bottom left corner
- );
- }
- else {
- const [tl, tr, bl, br] = cornerRadius;
- const l = x;
- const r = x + width;
- const t = y;
- const b = y + height;
- // start at end of top left corner
- points.push(vectorCreate(l + tl, t));
- pushRectCornerPoints(points, r - tr, t + tr, tr, -1);
- // move to bottom right corner
- points.push(vectorCreate(r, t + tr));
- pushRectCornerPoints(points, r - br, b - br, br, 0);
- // move to bottom left corner
- points.push(vectorCreate(r - br, b));
- pushRectCornerPoints(points, l + bl, b - bl, bl, 1);
- // move to top left corner
- points.push(vectorCreate(l, b - bl));
- pushRectCornerPoints(points, l + tl, t + tl, tl, 2);
- }
- if (flipX || flipY)
- vectorsFlip(points, flipX, flipY, x + width * 0.5, y + height * 0.5);
- if (rotation)
- vectorsRotate(points, rotation, x + width * 0.5, y + height * 0.5);
- return points;
- };
- const pushRectCornerPoints = (points, x, y, radius, offset) => {
- const precision = Math.min(20, Math.max(4, Math.round(radius / 2)));
- let p = 0;
- let s = 0;
- let rx = 0;
- let ry = 0;
- let i = 0;
- for (; i < precision; i++) {
- p = i / precision;
- s = offset * HALF_PI + p * HALF_PI;
- rx = radius * Math.cos(s);
- ry = radius * Math.sin(s);
- points.push(vectorCreate(x + rx, y + ry));
- }
- };
- let limit = null;
- var getWebGLTextureSizeLimit = () => {
- if (limit !== null)
- return limit;
- const canvas = h('canvas');
- const gl = getWebGLContext(canvas);
- limit = gl ? gl.getParameter(gl.MAX_TEXTURE_SIZE) : undefined;
- releaseCanvas(canvas);
- return limit;
- };
- // prettier-ignore
- // B D
- // | \ |
- // A C
- const RECT_UV = new Float32Array([
- 0.0, 1.0,
- 0.0, 0.0,
- 1.0, 1.0,
- 1.0, 0.0,
- ]);
- const CLARITY_IDENTITY = [0, 0, 0, 0, 1, 0, 0, 0, 0];
- const COLOR_MATRIX_IDENTITY$1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
- const TEXTURE_TRANSPARENT_INDEX = 0;
- const TEXTURE_PREVIEW_BLEND_INDEX = 1;
- const TEXTURE_PREVIEW_MARKUP_INDEX = 2;
- const TEXTURE_PREVIEW_INDEX = 3;
- const TEXTURE_SHAPE_INDEX = 4;
- const COLOR_TRANSPARENT = [0, 0, 0, 0];
- const NO_CORNERS = [0, 0, 0, 0];
- const calculateBackgroundUVMap = (width, height, backgroundSize, backgroundPosition, viewPixelDensity) => {
- if (!backgroundSize || !backgroundPosition)
- return RECT_UV;
- const x = backgroundPosition.x / backgroundSize.width;
- const y = backgroundPosition.y / backgroundSize.height;
- let w = width / backgroundSize.width / viewPixelDensity;
- let h = height / backgroundSize.height / viewPixelDensity;
- w -= x;
- h -= y;
- // prettier-ignore
- // B D
- // | \ |
- // A C
- // bottom left
- const ax = -x;
- const ay = h;
- // top left
- const bx = -x;
- const by = -y;
- // bottom right
- const cx = w;
- const cy = h;
- // top right
- const dx = w;
- const dy = -y;
- return new Float32Array([
- ax,
- ay,
- bx,
- by,
- cx,
- cy,
- dx,
- dy,
- ]);
- };
- const limitCornerRadius = (r, size) => {
- return Math.floor(clamp(r, 0, Math.min((size.width - 1) * 0.5, (size.height - 1) * 0.5)));
- };
- var createWebGLCanvas = (canvas) => {
- const viewSize = { width: 0, height: 0 };
- const viewSizeVisual = { width: 0, height: 0 };
- const textureSizeLimit = getWebGLTextureSizeLimit() || 1024;
- let viewAspectRatio;
- let viewPixelDensity;
- const markupMatrixCanvas = mat4Create();
- const markupMatrixFrameBuffer = mat4Create();
- let markupMatrix;
- let maskTop;
- let maskRight;
- let maskBottom;
- let maskLeft;
- let maskOpacity;
- let maskBounds;
- let IMAGE_MASK_FEATHER; // updated when viewport is resized
- let RECT_MASK_FEATHER;
- let CANVAS_COLOR_R = 0;
- let CANVAS_COLOR_G = 0;
- let CANVAS_COLOR_B = 0;
- const indexTextureMap = new Map([]);
- // resize view
- const resize = (width, height, pixelDensity) => {
- // density
- viewPixelDensity = pixelDensity;
- // visual size
- viewSizeVisual.width = width;
- viewSizeVisual.height = height;
- // size
- viewSize.width = width * viewPixelDensity;
- viewSize.height = height * viewPixelDensity;
- // calculate the aspect ratio, we use this to determine quad size
- viewAspectRatio = getAspectRatio(viewSize.width, viewSize.height);
- // sync dimensions with image data
- canvas.width = viewSize.width;
- canvas.height = viewSize.height;
- // update canvas markup matrix
- mat4Ortho(markupMatrixCanvas, 0, viewSize.width, viewSize.height, 0, -1, 1);
- IMAGE_MASK_FEATHER = [1, 0, 1, 0, 1, viewSizeVisual.width, 1, viewSizeVisual.width];
- };
- // fov is fixed
- const FOV = degToRad(30);
- const FOV_TAN_HALF = Math.tan(FOV / 2);
- // get gl drawing context
- const gl = getWebGLContext(canvas, {
- antialias: false,
- alpha: false,
- premultipliedAlpha: true,
- });
- // no drawing context received, exit
- if (!gl)
- return;
- // enable derivatives
- gl.getExtension('OES_standard_derivatives');
- // toggle gl settings
- gl.disable(gl.DEPTH_TEST);
- // set blend mode, we need it for alpha blending
- gl.enable(gl.BLEND);
- /*
- https://webglfundamentals.org/webgl/lessons/webgl-and-alpha.html
- most if not all Canvas 2D implementations work with pre-multiplied alpha.
- That means when you transfer them to WebGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL
- is false WebGL will convert them back to un-premultipiled.
- With pre-multiplied alpha on, [1, .5, .5, 0] does not exist, it's always [0, 0, 0, 0]
- */
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
- // something to look into:
- // gl.UNPACK_COLORSPACE_CONVERSION_WEBGL
- const transparentTexture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, transparentTexture);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, // width
- 1, // height
- 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(COLOR_TRANSPARENT) // transparent background
- );
- indexTextureMap.set(TEXTURE_TRANSPARENT_INDEX, transparentTexture);
- // create image markup texture and framebuffer
- const imageMarkupTexture = gl.createTexture();
- indexTextureMap.set(TEXTURE_PREVIEW_MARKUP_INDEX, imageMarkupTexture);
- const markupFramebuffer = gl.createFramebuffer();
- // create image blend texture and framebuffer
- const imageBlendTexture = gl.createTexture();
- indexTextureMap.set(TEXTURE_PREVIEW_BLEND_INDEX, imageBlendTexture);
- const blendFramebuffer = gl.createFramebuffer();
- // color mask not set (this needs to run otherwise Firefox 93+ renders incorrectly)
- gl.colorMask(true, true, true, true);
- gl.clearColor(0, 0, 0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- // #region image
- // create default pixel drawing program, supports what we need
- const imageShader = createShader(gl, imageVertexShader, imageFragmentShader, ['aPosition', 'aTexCoord'], [
- 'uMatrix',
- 'uTexture',
- 'uTextureBlend',
- 'uTextureMarkup',
- 'uTextureSize',
- 'uColorGamma',
- 'uColorVignette',
- 'uColorOffset',
- 'uColorMatrix',
- 'uClarityKernel',
- 'uClarityKernelWeight',
- 'uOpacity',
- 'uMaskOpacity',
- 'uMaskBounds',
- 'uMaskCornerRadius',
- 'uMaskFeather',
- 'uFillColor',
- 'uOverlayColor',
- ]);
- // create image buffers
- const imagePositionsBuffer = gl.createBuffer();
- const texturePositionsBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, texturePositionsBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, RECT_UV, gl.STATIC_DRAW);
- const drawImage = (texture, textureSize, originX, originY, translateX, translateY, rotateX, rotateY, rotateZ, scale, colorMatrix = COLOR_MATRIX_IDENTITY$1, opacity = 1, clarity, gamma = 1, vignette = 0, maskFeather = IMAGE_MASK_FEATHER, maskCornerRadius = NO_CORNERS, imageBackgroundColor = COLOR_TRANSPARENT, imageOverlayColor = COLOR_TRANSPARENT, enableMarkup = false, enableBlend = false) => {
- // update image texture
- const imageWidth = textureSize.width * viewPixelDensity;
- const imageHeight = textureSize.height * viewPixelDensity;
- const l = imageWidth * -0.5;
- const t = imageHeight * 0.5;
- const r = imageWidth * 0.5;
- const b = imageHeight * -0.5;
- // prettier-ignore
- // B D
- // | \ |
- // A C
- const imagePositions = new Float32Array([
- l, b, 0,
- l, t, 0,
- r, b, 0,
- r, t, 0,
- ]);
- gl.bindBuffer(gl.ARRAY_BUFFER, imagePositionsBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, imagePositions, gl.STATIC_DRAW);
- // move image backwards so it's presented in actual pixel size
- const viewZ = // 1. we calculate the z offset required to have the
-
- // image height match the view height
- /* /|
- / |
- / | height / 2
- / |
- f / 2 /__z_|
- \ |
- \ |
- \ |
- \ |
- \|
- */
- (textureSize.height / 2 / FOV_TAN_HALF) *
- // 2. we want to render the image at the actual height, viewsize / height gets us results in a 1:1 presentation
- (viewSize.height / textureSize.height) *
- // 3. z has to be negative, therefor multiply by -1
- -1;
- // convert to pixel density
- translateX *= viewPixelDensity;
- translateY *= viewPixelDensity;
- originX *= viewPixelDensity;
- originY *= viewPixelDensity;
- // get shader params
- const { program, locations } = imageShader;
- // apply
- const matrix = mat4Create();
- mat4Perspective(matrix, FOV, viewAspectRatio, 1, -viewZ * 2);
- // move image
- mat4Translate(matrix, translateX, -translateY, viewZ);
- // set rotation origin in view
- mat4Translate(matrix, originX, -originY, 0);
- // rotate image
- mat4RotateZ(matrix, -rotateZ);
- // resize
- mat4Scale(matrix, scale);
- // reset rotation origin
- mat4Translate(matrix, -originX, originY, 0);
- // flip
- mat4RotateY(matrix, rotateY);
- mat4RotateX(matrix, rotateX);
- //
- // tell context to draw preview
- //
- gl.useProgram(program);
- gl.enableVertexAttribArray(locations.aPosition);
- gl.enableVertexAttribArray(locations.aTexCoord);
- // set up texture
- gl.uniform1i(locations.uTexture, TEXTURE_PREVIEW_INDEX);
- gl.uniform2f(locations.uTextureSize, textureSize.width, textureSize.height);
- gl.activeTexture(gl.TEXTURE0 + TEXTURE_PREVIEW_INDEX);
- gl.bindTexture(gl.TEXTURE_2D, texture);
- // set up blend texture
- const blendTextureIndex = enableBlend
- ? TEXTURE_PREVIEW_BLEND_INDEX
- : TEXTURE_TRANSPARENT_INDEX;
- const blendTexture = indexTextureMap.get(blendTextureIndex);
- gl.uniform1i(locations.uTextureBlend, blendTextureIndex);
- gl.activeTexture(gl.TEXTURE0 + blendTextureIndex);
- gl.bindTexture(gl.TEXTURE_2D, blendTexture);
- // set up markup texture
- const markupTextureIndex = enableMarkup
- ? TEXTURE_PREVIEW_MARKUP_INDEX
- : TEXTURE_TRANSPARENT_INDEX;
- const markupTexture = indexTextureMap.get(markupTextureIndex);
- gl.uniform1i(locations.uTextureMarkup, markupTextureIndex);
- gl.activeTexture(gl.TEXTURE0 + markupTextureIndex);
- gl.bindTexture(gl.TEXTURE_2D, markupTexture);
- // set up buffers
- gl.bindBuffer(gl.ARRAY_BUFFER, imagePositionsBuffer);
- gl.vertexAttribPointer(locations.aPosition, 3, gl.FLOAT, false, 0, 0);
- gl.bindBuffer(gl.ARRAY_BUFFER, texturePositionsBuffer);
- gl.vertexAttribPointer(locations.aTexCoord, 2, gl.FLOAT, false, 0, 0);
- // update matrix
- gl.uniformMatrix4fv(locations.uMatrix, false, matrix);
- // overlay color
- gl.uniform4fv(locations.uOverlayColor, imageOverlayColor);
- gl.uniform4fv(locations.uFillColor, imageBackgroundColor);
- // convolution
- let clarityWeight;
- if (!clarity || arrayEqual(clarity, CLARITY_IDENTITY)) {
- clarity = CLARITY_IDENTITY;
- clarityWeight = -1;
- }
- else {
- clarityWeight = clarity.reduce((prev, curr) => prev + curr, 0);
- clarityWeight = clarityWeight <= 0 ? 1 : clarityWeight;
- }
- gl.uniform1fv(locations.uClarityKernel, clarity);
- gl.uniform1f(locations.uClarityKernelWeight, clarityWeight);
- gl.uniform1f(locations.uColorGamma, 1.0 / gamma);
- gl.uniform1f(locations.uColorVignette, vignette);
- // set color matrix values
- gl.uniform4f(locations.uColorOffset, colorMatrix[4], colorMatrix[9], colorMatrix[14], colorMatrix[19]);
- gl.uniformMatrix4fv(locations.uColorMatrix, false, [
- colorMatrix[0],
- colorMatrix[1],
- colorMatrix[2],
- colorMatrix[3],
- colorMatrix[5],
- colorMatrix[6],
- colorMatrix[7],
- colorMatrix[8],
- colorMatrix[10],
- colorMatrix[11],
- colorMatrix[12],
- colorMatrix[13],
- colorMatrix[15],
- colorMatrix[16],
- colorMatrix[17],
- colorMatrix[18],
- ]);
- // opacity level
- gl.uniform1f(locations.uOpacity, opacity);
- // mask
- gl.uniform1f(locations.uMaskOpacity, maskOpacity);
- gl.uniform1fv(locations.uMaskBounds, maskBounds);
- gl.uniform1fv(locations.uMaskCornerRadius, maskCornerRadius.map((v) => v * viewPixelDensity));
- gl.uniform1fv(locations.uMaskFeather, maskFeather.map((v, i) => (i % 2 === 0 ? v : v * viewPixelDensity)));
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- gl.disableVertexAttribArray(locations.aPosition);
- gl.disableVertexAttribArray(locations.aTexCoord);
- };
- //#endregion
- // #region path
- const pathShader = createShader(gl, pathVertexShader, pathFragmentShader, ['aPosition', 'aNormal', 'aMiter'], ['uColor', 'uCanvasColor', 'uMatrix', 'uWidth', 'uMaskBounds', 'uMaskOpacity']);
- const pathBuffer = gl.createBuffer();
- const strokePath = (points, width, color, close = false) => {
- const { program, locations } = pathShader;
- gl.useProgram(program);
- gl.enableVertexAttribArray(locations.aPosition);
- gl.enableVertexAttribArray(locations.aNormal);
- gl.enableVertexAttribArray(locations.aMiter);
- const vertices = createPathVertices(points, close);
- const stride = Float32Array.BYTES_PER_ELEMENT * 5;
- const normalOffset = Float32Array.BYTES_PER_ELEMENT * 2; // at position 2
- const miterOffset = Float32Array.BYTES_PER_ELEMENT * 4; // at position 4
- gl.uniform1f(locations.uWidth, width); // add 1 so we can feather the edges
- gl.uniform4fv(locations.uColor, color);
- gl.uniformMatrix4fv(locations.uMatrix, false, markupMatrix);
- gl.uniform4f(locations.uCanvasColor, CANVAS_COLOR_R, CANVAS_COLOR_G, CANVAS_COLOR_B, 1);
- gl.uniform1fv(locations.uMaskBounds, maskBounds);
- gl.uniform1f(locations.uMaskOpacity, maskOpacity);
- gl.bindBuffer(gl.ARRAY_BUFFER, pathBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
- gl.vertexAttribPointer(locations.aPosition, 2, gl.FLOAT, false, stride, 0);
- gl.vertexAttribPointer(locations.aNormal, 2, gl.FLOAT, false, stride, normalOffset);
- gl.vertexAttribPointer(locations.aMiter, 1, gl.FLOAT, false, stride, miterOffset);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / 5);
- gl.disableVertexAttribArray(locations.aPosition);
- gl.disableVertexAttribArray(locations.aNormal);
- gl.disableVertexAttribArray(locations.aMiter);
- };
- //#endregion
- // #region triangle
- const triangleShader = createShader(gl, triangleVertexShader, triangleFragmentShader, ['aPosition'], ['uColor', 'uCanvasColor', 'uMatrix', 'uMaskBounds', 'uMaskOpacity']);
- const triangleBuffer = gl.createBuffer();
- const fillTriangle = (vertices, backgroundColor) => {
- const { program, locations } = triangleShader;
- gl.useProgram(program);
- gl.enableVertexAttribArray(locations.aPosition);
- gl.uniform4fv(locations.uColor, backgroundColor);
- gl.uniformMatrix4fv(locations.uMatrix, false, markupMatrix);
- gl.uniform1fv(locations.uMaskBounds, maskBounds);
- gl.uniform1f(locations.uMaskOpacity, maskOpacity);
- gl.uniform4f(locations.uCanvasColor, CANVAS_COLOR_R, CANVAS_COLOR_G, CANVAS_COLOR_B, 1);
- gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
- gl.vertexAttribPointer(locations.aPosition, 2, gl.FLOAT, false, 0, 0);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / 2);
- gl.disableVertexAttribArray(locations.aPosition);
- return vertices;
- };
- //#endregion
- // #region rect
- const rectShaderAttributes = ['aPosition', 'aTexCoord', 'aRectCoord'];
- const rectShaderUniforms = [
- 'uTexture',
- 'uColor',
- 'uMatrix',
- 'uCanvasColor',
- 'uTextureColor',
- 'uTextureOpacity',
- 'uPosition',
- 'uSize',
- 'uMaskBounds',
- 'uMaskOpacity',
- 'uMaskFeather',
- 'uCornerRadius',
- 'uInverted',
- ];
- const rectShader = createShader(gl, rectVertexShader, rectFragmentShader, rectShaderAttributes, rectShaderUniforms);
- const rectBuffer = gl.createBuffer();
- const rectTextureBuffer = gl.createBuffer();
- const rectCornerBuffer = gl.createBuffer();
- const fillRect = (vertices, width, height, cornerRadius, backgroundColor, backgroundImage = transparentTexture, opacity = 1.0, colorFilter = COLOR_TRANSPARENT, uv = RECT_UV, maskFeather = RECT_MASK_FEATHER, inverted) => {
- const { program, locations } = rectShader;
- gl.useProgram(program);
- gl.enableVertexAttribArray(locations.aPosition);
- gl.enableVertexAttribArray(locations.aTexCoord);
- gl.enableVertexAttribArray(locations.aRectCoord);
- gl.uniform4fv(locations.uColor, backgroundColor);
- gl.uniform2fv(locations.uSize, [width, height]);
- gl.uniform2fv(locations.uPosition, [vertices[2], vertices[3]]);
- gl.uniform1i(locations.uInverted, inverted ? 1 : 0);
- gl.uniform1fv(locations.uCornerRadius, cornerRadius);
- gl.uniform4f(locations.uCanvasColor, CANVAS_COLOR_R, CANVAS_COLOR_G, CANVAS_COLOR_B, 1);
- // mask
- gl.uniform1fv(locations.uMaskFeather, maskFeather.map((v, i) => (i % 2 === 0 ? v : v * viewPixelDensity)));
- gl.uniform1fv(locations.uMaskBounds, maskBounds);
- gl.uniform1f(locations.uMaskOpacity, maskOpacity);
- gl.uniformMatrix4fv(locations.uMatrix, false, markupMatrix);
- gl.uniform1i(locations.uTexture, TEXTURE_SHAPE_INDEX);
- gl.uniform4fv(locations.uTextureColor, colorFilter);
- gl.uniform1f(locations.uTextureOpacity, opacity);
- gl.activeTexture(gl.TEXTURE0 + TEXTURE_SHAPE_INDEX);
- gl.bindTexture(gl.TEXTURE_2D, backgroundImage);
- gl.bindBuffer(gl.ARRAY_BUFFER, rectTextureBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, uv, gl.STATIC_DRAW);
- gl.vertexAttribPointer(locations.aTexCoord, 2, gl.FLOAT, false, 0, 0);
- // we use these coordinates combined with the size of the rect to interpolate and alias edges
- gl.bindBuffer(gl.ARRAY_BUFFER, rectCornerBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, RECT_UV, gl.STATIC_DRAW);
- gl.vertexAttribPointer(locations.aRectCoord, 2, gl.FLOAT, false, 0, 0);
- gl.bindBuffer(gl.ARRAY_BUFFER, rectBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
- gl.vertexAttribPointer(locations.aPosition, 2, gl.FLOAT, false, 0, 0);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / 2);
- gl.disableVertexAttribArray(locations.aPosition);
- gl.disableVertexAttribArray(locations.aTexCoord);
- gl.disableVertexAttribArray(locations.aRectCoord);
- return vertices;
- };
- //#endregion
- // #region ellipse
- const ellipseShader = createShader(gl, ellipseVertexShader, ellipseFragmentShader, ['aPosition', 'aTexCoord'], [
- 'uTexture',
- 'uTextureOpacity',
- 'uColor',
- 'uCanvasColor',
- 'uMatrix',
- 'uRadius',
- 'uInverted',
- 'uMaskBounds',
- 'uMaskOpacity',
- ]);
- const ellipseBuffer = gl.createBuffer();
- const ellipseTextureBuffer = gl.createBuffer();
- const fillEllipse = (vertices, width, height, backgroundColor, backgroundImage = transparentTexture, uv = RECT_UV, opacity = 1.0, inverted = false) => {
- const { program, locations } = ellipseShader;
- gl.useProgram(program);
- gl.enableVertexAttribArray(locations.aPosition);
- gl.enableVertexAttribArray(locations.aTexCoord);
- gl.uniformMatrix4fv(locations.uMatrix, false, markupMatrix);
- gl.uniform2fv(locations.uRadius, [width * 0.5, height * 0.5]);
- gl.uniform1i(locations.uInverted, inverted ? 1 : 0);
- gl.uniform4fv(locations.uColor, backgroundColor);
- gl.uniform4f(locations.uCanvasColor, CANVAS_COLOR_R, CANVAS_COLOR_G, CANVAS_COLOR_B, 1);
- gl.uniform1fv(locations.uMaskBounds, maskBounds);
- gl.uniform1f(locations.uMaskOpacity, maskOpacity);
- gl.uniform1i(locations.uTexture, TEXTURE_SHAPE_INDEX);
- gl.uniform1f(locations.uTextureOpacity, opacity);
- gl.activeTexture(gl.TEXTURE0 + TEXTURE_SHAPE_INDEX);
- gl.bindTexture(gl.TEXTURE_2D, backgroundImage);
- gl.bindBuffer(gl.ARRAY_BUFFER, ellipseTextureBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, uv, gl.STATIC_DRAW);
- gl.vertexAttribPointer(locations.aTexCoord, 2, gl.FLOAT, false, 0, 0);
- gl.bindBuffer(gl.ARRAY_BUFFER, ellipseBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
- gl.vertexAttribPointer(locations.aPosition, 2, gl.FLOAT, false, 0, 0);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / 2);
- gl.disableVertexAttribArray(locations.aPosition);
- gl.disableVertexAttribArray(locations.aTexCoord);
- };
- //#endregion
- //
- // draw calls
- //
- const drawPath = (points, strokeWidth, strokeColor, strokeClose, opacity) => {
- // is no line
- if (points.length < 2)
- return;
- strokePath(points.map((p) => ({
- x: p.x * viewPixelDensity,
- y: p.y * viewPixelDensity,
- })), strokeWidth * viewPixelDensity, applyOpacity(strokeColor, opacity), strokeClose);
- };
- const drawTriangle = (points, rotation = 0, flipX = false, flipY = false, backgroundColor, opacity) => {
- if (!backgroundColor)
- return;
- const clonedPoints = points.map((p) => ({
- x: p.x * viewPixelDensity,
- y: p.y * viewPixelDensity,
- }));
- const center = convexPolyCentroid(clonedPoints);
- if (flipX || flipY)
- vectorsFlip(clonedPoints, flipX, flipY, center.x, center.y);
- vectorsRotate(clonedPoints, rotation, center.x, center.y);
- const vertices = trianglePointToVertices(clonedPoints);
- fillTriangle(vertices, applyOpacity(backgroundColor, opacity));
- };
- const drawRect = (rect, rotation = 0, flipX = false, flipY = false, cornerRadius, backgroundColor, backgroundImage, backgroundSize = undefined, backgroundPosition = undefined, backgroundUVMap = undefined, strokeWidth, strokeColor, opacity, maskFeather = undefined, colorize, inverted) => {
- // clone first
- const rectOut = rectMultiply(rectClone(rect), viewPixelDensity);
- // has radius, doesn't matter for coordinates
- const cornerRadiusOut = cornerRadius
- .map((r) => limitCornerRadius(r || 0, rect))
- .map((r) => r * viewPixelDensity);
- // should fill
- if (backgroundColor || backgroundImage) {
- // adjust for edge anti-aliasing, if we don't do this the
- // visible rectangle will be 1 pixel smaller than the actual rectangle
- const rectFill = rectClone(rectOut);
- rectFill.x -= 0.5;
- rectFill.y -= 0.5;
- rectFill.width += 1;
- rectFill.height += 1;
- const points = createRectPoints(rectFill, rotation, flipX, flipY);
- const vertices = rectPointsToVertices(points);
- let color;
- if (colorize) {
- color = applyOpacity(colorize);
- // as 0 transparancy is used to test if the colorize filter should be applied we set it to 0.001
- if (color[3] === 0)
- color[3] = 0.001;
- }
- fillRect(vertices, rectFill.width, rectFill.height, cornerRadiusOut, applyOpacity(backgroundColor, opacity), backgroundImage, opacity, color, backgroundUVMap
- ? new Float32Array(backgroundUVMap)
- : calculateBackgroundUVMap(rectFill.width, rectFill.height, backgroundSize, backgroundPosition, viewPixelDensity), maskFeather, inverted);
- }
- // should draw outline
- if (strokeWidth) {
- // fixes issue where stroke would render weirdly
- strokeWidth = Math.min(strokeWidth, rectOut.width, rectOut.height);
- strokePath(
- // rect out is already multiplied by pixel density
- createRectOutline(rectOut.x, rectOut.y, rectOut.width, rectOut.height, rotation, cornerRadiusOut, flipX, flipY), strokeWidth * viewPixelDensity, applyOpacity(strokeColor, opacity), true);
- }
- };
- const drawEllipse = (center, rx, ry, rotation, flipX, flipY, backgroundColor, backgroundImage, backgroundSize = undefined, backgroundPosition = undefined, backgroundUVMap = undefined, strokeWidth, strokeColor, opacity, inverted) => {
- const rectOut = rectMultiply(rectCreate(center.x - rx, center.y - ry, rx * 2, ry * 2), viewPixelDensity);
- if (backgroundColor || backgroundImage) {
- // adjust for edge anti-aliasing, if we don't do this the
- // visible rectangle will be 1 pixel smaller than the actual rectangle
- const rectFill = rectClone(rectOut);
- rectFill.x -= 0.5;
- rectFill.y -= 0.5;
- rectFill.width += 1.0;
- rectFill.height += 1.0;
- const points = createRectPoints(rectFill, rotation, flipX, flipY);
- const vertices = rectPointsToVertices(points);
- fillEllipse(vertices, rectFill.width, rectFill.height, applyOpacity(backgroundColor, opacity), backgroundImage, backgroundUVMap
- ? new Float32Array(backgroundUVMap)
- : calculateBackgroundUVMap(rectFill.width, rectFill.height, backgroundSize, backgroundPosition, viewPixelDensity), opacity, inverted);
- }
- if (strokeWidth)
- strokePath(
- // rect out is already multiplied by pixeldensity
- createEllipseOutline(rectOut.x, rectOut.y, rectOut.width, rectOut.height, rotation, flipX, flipY), strokeWidth * viewPixelDensity, applyOpacity(strokeColor, opacity), true);
- };
- //#endregion
- const glTextures = new Map();
- // let currentMarkupFrameBufferSize = { width: 0, height: 0 };
- const imageFramebufferSize = {};
- imageFramebufferSize[TEXTURE_PREVIEW_MARKUP_INDEX] = { width: 0, height: 0 };
- imageFramebufferSize[TEXTURE_PREVIEW_BLEND_INDEX] = { width: 0, height: 0 };
- const drawToImageFramebuffer = (index, buffer, imageSize) => {
- const textureScalar = Math.min(textureSizeLimit / imageSize.width, textureSizeLimit / imageSize.height, 1);
- const textureWidth = Math.floor(textureScalar * imageSize.width);
- const textureHeight = Math.floor(textureScalar * imageSize.height);
- if (!sizeEqual(imageSize, imageFramebufferSize[index])) {
- // update preview markup texture
- gl.bindTexture(gl.TEXTURE_2D, indexTextureMap.get(index));
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, textureWidth, textureHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
- // set the filtering, we don't need mips
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.bindFramebuffer(gl.FRAMEBUFFER, buffer);
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, indexTextureMap.get(index), 0);
- // remember so we know when to update the framebuffer
- imageFramebufferSize[index] = imageSize;
- }
- else {
- gl.bindFramebuffer(gl.FRAMEBUFFER, buffer);
- }
- // switch transformMatrix
- const w = imageSize.width * viewPixelDensity;
- const h = imageSize.height * viewPixelDensity;
- mat4Ortho(markupMatrixFrameBuffer, 0, w, h, 0, -1, 1);
- mat4Translate(markupMatrixFrameBuffer, 0, h, 0);
- mat4ScaleX(markupMatrixFrameBuffer, 1);
- mat4ScaleY(markupMatrixFrameBuffer, -1);
- markupMatrix = markupMatrixFrameBuffer;
- // framebuffer lives in image space
- gl.viewport(0, 0, textureWidth, textureHeight);
- // always transparent
- gl.colorMask(true, true, true, true);
- gl.clearColor(0, 0, 0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- // update rect mask
- RECT_MASK_FEATHER = [
- 1,
- 0,
- 1,
- 0,
- 1,
- Math.max(viewSize.width, imageSize.width),
- 1,
- Math.max(viewSize.width, imageSize.width),
- ];
- };
- return {
- // draw api
- drawPath,
- drawTriangle,
- drawRect,
- drawEllipse,
- drawImage,
- // texture filters
- textureFilterNearest: gl.NEAREST,
- textureFilterLinear: gl.LINEAR,
- //#region texture management
- textureCreate: () => {
- return gl.createTexture();
- },
- textureUpdate: (texture, source, options) => {
- glTextures.set(texture, source);
- return updateTexture(gl, texture, source, options);
- },
- textureSize: (texture) => {
- return sizeCreateFromAny(glTextures.get(texture));
- },
- textureDelete: (texture) => {
- const source = glTextures.get(texture);
- if (source instanceof HTMLCanvasElement && !source.dataset.retain)
- releaseCanvas(source);
- glTextures.delete(texture);
- gl.deleteTexture(texture);
- },
- //#endregion
- setCanvasColor(color) {
- CANVAS_COLOR_R = color[0];
- CANVAS_COLOR_G = color[1];
- CANVAS_COLOR_B = color[2];
- },
- drawToCanvas() {
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- // switch transformMatrix
- markupMatrix = markupMatrixCanvas;
- // tell webgl about the viewport
- gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
- // black (or other color depending on background)
- gl.colorMask(true, true, true, false);
- gl.clearColor(CANVAS_COLOR_R, CANVAS_COLOR_G, CANVAS_COLOR_B, 1);
- // gl.clearColor(0.25, 0.25, 0.25, 1); // for debugging
- gl.clear(gl.COLOR_BUFFER_BIT);
- // update rect mask
- RECT_MASK_FEATHER = [1, 0, 1, 0, 1, viewSize.width, 1, viewSize.width];
- },
- drawToImageBlendBuffer(imageSize) {
- drawToImageFramebuffer(TEXTURE_PREVIEW_BLEND_INDEX, blendFramebuffer, imageSize);
- },
- drawToImageOverlayBuffer(imageSize) {
- drawToImageFramebuffer(TEXTURE_PREVIEW_MARKUP_INDEX, markupFramebuffer, imageSize);
- },
- // set mask
- enableMask(rect, opacity) {
- const maskX = rect.x * viewPixelDensity;
- const maskY = rect.y * viewPixelDensity;
- const maskWidth = rect.width * viewPixelDensity;
- const maskHeight = rect.height * viewPixelDensity;
- maskLeft = maskX;
- maskRight = maskLeft + maskWidth;
- maskTop = viewSize.height - maskY;
- maskBottom = viewSize.height - (maskY + maskHeight);
- maskOpacity = 1.0 - opacity;
- maskBounds = [maskTop, maskRight, maskBottom, maskLeft];
- },
- disableMask() {
- maskLeft = 0;
- maskRight = viewSize.width;
- maskTop = viewSize.height;
- maskBottom = 0;
- maskOpacity = 1;
- maskBounds = [maskTop, maskRight, maskBottom, maskLeft];
- },
- // canvas
- resize,
- release() {
- canvas.width = 1;
- canvas.height = 1;
- },
- };
- };
- var isImageBitmap = (obj) => 'close' in obj;
- /* src/core/ui/components/Canvas.svelte generated by Svelte v3.37.0 */
- function create_fragment$M(ctx) {
- let div;
- let canvas_1;
- let mounted;
- let dispose;
- return {
- c() {
- div = element("div");
- canvas_1 = element("canvas");
- attr(div, "class", "PinturaCanvas");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- append(div, canvas_1);
- /*canvas_1_binding*/ ctx[24](canvas_1);
- if (!mounted) {
- dispose = [
- listen(canvas_1, "measure", /*measure_handler*/ ctx[25]),
- action_destroyer(measurable.call(null, canvas_1))
- ];
- mounted = true;
- }
- },
- p: noop,
- i: noop,
- o: noop,
- d(detaching) {
- if (detaching) detach(div);
- /*canvas_1_binding*/ ctx[24](null);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function instance$M($$self, $$props, $$invalidate) {
- let canDraw;
- let drawUpdate;
- let $background;
- let $maskOpacityStore;
- let $mask;
- let $imageOverlayColor;
- let $maskFrameOpacityStore;
- const blendWithCanvasBackground = (back, front) => {
- const [bR, bG, bB] = back;
- const [fR, fG, fB, fA] = front;
- return [fR * fA + bR * (1 - fA), fG * fA + bG * (1 - fA), fB * fA + bB * (1 - fA), 1];
- };
- // used to dispatch the 'measure' event
- const dispatch = createEventDispatcher();
- let { animate } = $$props;
- let { maskRect } = $$props;
- let { maskOpacity = 1 } = $$props;
- let { maskFrameOpacity = 0.95 } = $$props;
- let { pixelRatio = 1 } = $$props;
- let { backgroundColor } = $$props;
- let { willRender = passthrough } = $$props;
- let { loadImageData = passthrough } = $$props;
- let { images = [] } = $$props;
- let { interfaceImages = [] } = $$props;
- // internal props
- let canvas;
- let canvasGL = null;
- let width = null;
- let height = null;
- //
- // springyness for main preview
- //
- const updateSpring = (spring, value) => spring.set(value, { hard: !animate });
- const SPRING_PROPS = { precision: 0.0001 };
- const SPRING_PROPS_FRACTION = { precision: SPRING_PROPS.precision * 0.01 };
- // Editor UI
- const background = tweened(undefined, { duration: 250 });
- component_subscribe($$self, background, value => $$invalidate(20, $background = value));
- const maskOpacityStore = spring(1, SPRING_PROPS_FRACTION);
- component_subscribe($$self, maskOpacityStore, value => $$invalidate(21, $maskOpacityStore = value));
- const maskFrameOpacityStore = spring(1, SPRING_PROPS_FRACTION);
- component_subscribe($$self, maskFrameOpacityStore, value => $$invalidate(30, $maskFrameOpacityStore = value));
- const mask = writable();
- component_subscribe($$self, mask, value => $$invalidate(28, $mask = value));
- const imageOverlayColor = writable();
- component_subscribe($$self, imageOverlayColor, value => $$invalidate(29, $imageOverlayColor = value));
- //#region texture loading and binding
- const TEXT_TEXTURE_MEASURE_CONTEXT = createSimpleContext();
- const Textures = new Map([]);
- const getImageTexture = (image, imageRendering) => {
- // no texture yet for this source
- if (!Textures.has(image)) {
- // is in loading state when is same as source
- Textures.set(image, image);
- // get texture filter mode
- const filter = imageRendering === "pixelated"
- ? canvasGL.textureFilterNearest
- : canvasGL.textureFilterLinear;
- // already loaded
- if (!isString(image) && (isImageBitmap(image) || isImageData(image) || isCanvas(image))) {
- // create texture
- const texture = canvasGL.textureCreate();
- // udpate texture in gl canvas
- canvasGL.textureUpdate(texture, image, { filter });
- // update state we now have a texture
- Textures.set(image, texture);
- } else // need to load the image
- {
- loadImageData(image).then(data => {
- // create texture
- const texture = canvasGL.textureCreate();
- // udpate texture in gl canvas
- canvasGL.textureUpdate(texture, data, { filter });
- // update state we now have a texture
- Textures.set(image, texture);
- // need to redraw because texture is now available
- requestAnimationFrame(drawUpdate);
- }).catch(err => {
- console.error(err);
- });
- }
- }
- return Textures.get(image);
- };
- const getTextTexture = shape => {
- let { text, textAlign, fontFamily, fontSize, fontWeight, fontVariant, fontStyle, lineHeight, width } = shape;
- // we need this context to correctly wrap text
- updateTextContext(TEXT_TEXTURE_MEASURE_CONTEXT, {
- fontSize,
- fontFamily,
- fontWeight,
- fontVariant,
- fontStyle,
- textAlign
- });
- // wrap the text
- const textString = width
- ? wrapText(TEXT_TEXTURE_MEASURE_CONTEXT, text, width)
- : text;
- // create UID for this texture so we can cache it and fetch it later on
- const textUID = shapeTextUID({ ...shape, text: textString });
- // get texture unit assigned to this specific text shape
- if (!Textures.has(textUID)) {
- // TODO: Create power of 2 texture and update texture instead of delete -> replace
- // we need to create a new texture
- const ctx = createSimpleContext();
- updateTextContext(ctx, {
- fontSize,
- fontFamily,
- fontWeight,
- fontVariant,
- fontStyle,
- textAlign
- });
- // calculate canvas height
- resizeContextToFitText(ctx, textString, {
- fontSize,
- fontFamily,
- fontWeight,
- fontVariant,
- fontStyle,
- textAlign,
- lineHeight
- });
- const contextMinWidth = ctx.canvas.width;
- // scale context to account for italic styles
- ctx.canvas.width += textPadding;
- // context resized, we now need to re-apply style
- updateTextContext(ctx, {
- fontSize,
- fontFamily,
- fontWeight,
- fontVariant,
- fontStyle,
- textAlign,
- color: [1, 0, 1], // color we'll replace in the shader
-
- });
- // if so, draw text and update texture
- drawText$1(ctx, textString, {
- fontSize,
- textAlign,
- lineHeight,
- lineWidth: contextMinWidth
- });
- Textures.set(textUID, canvasGL.textureUpdate(canvasGL.textureCreate(), ctx.canvas, { filter: canvasGL.textureFilterLinear }));
- }
- return Textures.get(textUID);
- };
- const getShapeTexture = shape => {
- let texture;
- // let's create textures for backgrounds and texts
- if (shape.backgroundImage) {
- texture = getImageTexture(shape.backgroundImage, shape.backgroundImageRendering);
- } else if (isString(shape.text)) {
- if (shape.width && shape.width < 1 || shape.height && shape.height < 1) return undefined;
- texture = getTextTexture(shape);
- }
- return texture;
- };
- const isTexture = texture => texture instanceof WebGLTexture;
- const releaseUnusedTextures = usedTextures => {
- Textures.forEach((registeredTexture, key) => {
- const isUsed = !!usedTextures.find(usedTexture => usedTexture === registeredTexture);
- // stil used, no need to release
- if (isUsed) return;
- // remove this texture
- Textures.delete(key);
- canvasGL.textureDelete(registeredTexture);
- });
- };
- //#endregion
- //#region drawing
- const drawImageHelper = ({ data, size, origin, translation, rotation, scale, colorMatrix, opacity, convolutionMatrix, gamma, vignette, maskFeather, maskCornerRadius, backgroundColor, overlayColor, enableShapes, enableBlend }) => {
- // calculate opaque backgroundColor if backgroundColor is transparent and visible
- if (backgroundColor && backgroundColor[3] < 1 && backgroundColor[3] > 0) {
- backgroundColor = blendWithCanvasBackground($background, backgroundColor);
- }
- // gets texture to use for this image
- const texture = getImageTexture(data);
- // draw the image
- canvasGL.drawImage(texture, size, origin.x, origin.y, translation.x, translation.y, rotation.x, rotation.y, rotation.z, scale, colorMatrix, clamp(opacity, 0, 1), convolutionMatrix, gamma, vignette, maskFeather, maskCornerRadius, backgroundColor, overlayColor, enableShapes, enableBlend);
- return texture;
- };
- const backgroundCornersToUVMap = ([tl, tr, br, bl]) => {
- // tl, tr, br, bl -> bl, tl, br, tr
- // prettier-ignore
- // B D
- // | \ |
- // A C
- return [bl.x, bl.y, tl.x, tl.y, br.x, br.y, tr.x, tr.y];
- };
- const drawShapes = (shapes = []) => {
- return shapes.map(shape => {
- // only show texture if shape is finished loading
- let shapeTexture = !shape._isLoading && getShapeTexture(shape);
- // get the webgl texture
- let texture = isTexture(shapeTexture) ? shapeTexture : undefined;
- if (isArray(shape.points)) {
- // is triangle
- if (shape.points.length === 3 && shape.backgroundColor) {
- canvasGL.drawTriangle(shape.points, shape.rotation, shape.flipX, shape.flipY, shape.backgroundColor, shape.strokeWidth, shape.strokeColor, shape.opacity);
- } else // is normal path
- {
- canvasGL.drawPath(shape.points, shape.strokeWidth, shape.strokeColor, shape.pathClose, shape.opacity);
- }
- } else // is ellipse
- if (isNumber(shape.rx) && isNumber(shape.ry)) {
- let backgroundSize;
- let backgroundPosition;
- canvasGL.drawEllipse(shape, shape.rx, shape.ry, shape.rotation, shape.flipX, shape.flipY, shape.backgroundColor, texture, backgroundSize, backgroundPosition, shape.backgroundCorners && backgroundCornersToUVMap(shape.backgroundCorners), shape.strokeWidth, shape.strokeColor, shape.opacity, shape.inverted);
- } else // is rect
- if (isString(shape.text) && texture || shape.width) {
- const textureSize = texture && canvasGL.textureSize(texture);
- let colorize = undefined;
- let shapeRect;
- let shapeCornerRadius = [
- shape.cornerRadius,
- shape.cornerRadius,
- shape.cornerRadius,
- shape.cornerRadius
- ];
- if (shape.width) {
- shapeRect = shape;
- } else {
- shapeRect = { x: shape.x, y: shape.y, ...textureSize };
- }
- let backgroundSize;
- let backgroundPosition;
- if (textureSize) {
- // background should be scaled
- if (shape.backgroundImage && shape.backgroundSize) {
- // always respect texture aspect ratio
- const textureAspectRatio = getAspectRatio(textureSize.width, textureSize.height);
- // adjust position of background
- if (shape.backgroundSize === "contain") {
- const rect = rectContainRect(shape, textureAspectRatio, shapeRect);
- backgroundSize = sizeCreateFromRect(rect);
- backgroundPosition = vectorCreate((shape.width - backgroundSize.width) * 0.5, (shape.height - backgroundSize.height) * 0.5);
- } else if (shape.backgroundSize === "cover") {
- const rect = rectCoverRect(shape, textureAspectRatio, shapeRect);
- backgroundSize = sizeCreateFromRect(rect);
- backgroundPosition = vectorCreate(rect.x, rect.y);
- backgroundPosition = vectorCreate((shape.width - backgroundSize.width) * 0.5, (shape.height - backgroundSize.height) * 0.5);
- } else {
- backgroundSize = shape.backgroundSize;
- backgroundPosition = shape.backgroundPosition;
- }
- } else // is text, "background" should be texture size and be positioned based on alignment
- if (shape.text && shape.width) {
- // position texture based on text alignment
- backgroundSize = textureSize;
- backgroundPosition = vectorCreate(0, 0);
- // auto height
- if (!shape.height) shape.height = textureSize.height;
- // textPadding so text doesn't clip on left and right edges
- shape.x -= textPadding;
- shape.width += textPadding * 2;
- if (shape.textAlign === "left") {
- backgroundPosition.x = textPadding;
- }
- if (shape.textAlign === "center") {
- backgroundPosition.x = textPadding * 0.5 + (shape.width - textureSize.width) * 0.5;
- }
- if (shape.textAlign === "right") {
- backgroundPosition.x = shape.width - textureSize.width;
- }
- } else if (shape.text) {
- backgroundPosition = vectorCreate(0, 0);
- backgroundSize = {
- width: shapeRect.width,
- height: shapeRect.height
- };
- // texture is slightly larger because of text padding, need to compensate for this in single line mode
- shapeRect.width -= textPadding;
- }
- if (shape.text) colorize = shape.color;
- }
- canvasGL.drawRect(shapeRect, shape.rotation, shape.flipX, shape.flipY, shapeCornerRadius, shape.backgroundColor, texture, backgroundSize, backgroundPosition, shape.backgroundCorners && backgroundCornersToUVMap(shape.backgroundCorners), shape.strokeWidth, shape.strokeColor, shape.opacity, undefined, colorize, shape.inverted);
- }
- return shapeTexture;
- }).filter(Boolean);
- };
- // redraws state
- const usedTextures = [];
- const redraw = () => {
- // reset array of textures used in this draw call
- usedTextures.length = 0;
- // get top image shortcut
- const imagesTop = images[0];
- // allow dev to inject more shapes
- const { blendShapes, annotationShapes, interfaceShapes, decorationShapes, frameShapes } = willRender({
- // top image state shortcut
- opacity: imagesTop.opacity,
- rotation: imagesTop.rotation,
- scale: imagesTop.scale,
- // active images
- images,
- // canvas size
- size: sizeCreate(width, height),
- // canvas background
- backgroundColor: [...$background]
- });
- const canvasBackgroundColor = [...$background];
- const imagesMask = $mask;
- const imagesMaskOpacity = clamp($maskOpacityStore, 0, 1);
- const imagesOverlayColor = $imageOverlayColor;
- const imagesSize = imagesTop.size;
- const imagesBackgroundColor = imagesTop.backgroundColor;
- // no need to draw to blend framebuffer if no redactions
- const hasBlendShapes = blendShapes.length > 0;
- // no need to draw to markup framebuffer if no annotations
- const hasAnnotations = annotationShapes.length > 0;
- // if image has background color
- const hasImageBackgroundColor = imagesBackgroundColor[3] > 0;
- // if the overlay is transparent so we can see the canvas
- const hasTransparentOverlay = imagesMaskOpacity < 1;
- // set canvas background color to image background color if is defined
- if (hasTransparentOverlay && hasImageBackgroundColor) {
- const backR = canvasBackgroundColor[0];
- const backG = canvasBackgroundColor[1];
- const backB = canvasBackgroundColor[2];
- const frontA = 1 - imagesMaskOpacity;
- const frontR = imagesBackgroundColor[0] * frontA;
- const frontG = imagesBackgroundColor[1] * frontA;
- const frontB = imagesBackgroundColor[2] * frontA;
- const fA = 1 - frontA;
- canvasBackgroundColor[0] = frontR + backR * fA;
- canvasBackgroundColor[1] = frontG + backG * fA;
- canvasBackgroundColor[2] = frontB + backB * fA;
- canvasBackgroundColor[3] = 1;
- }
- canvasGL.setCanvasColor(canvasBackgroundColor);
- // if has blend shapes draw blend shapes to framebuffer
- // TODO: only run this if blend shapes have changed
- if (hasBlendShapes) {
- canvasGL.disableMask();
- canvasGL.drawToImageBlendBuffer(imagesSize);
- usedTextures.push(...drawShapes(blendShapes));
- }
- // if has annotations draw annotation shapes to framebuffer
- // TODO: only run this if annotations have changed
- if (hasAnnotations) {
- canvasGL.disableMask();
- canvasGL.drawToImageOverlayBuffer(imagesSize);
- usedTextures.push(...drawShapes(annotationShapes));
- }
- // switch to canvas drawing for other elements
- canvasGL.drawToCanvas();
- canvasGL.enableMask(imagesMask, imagesMaskOpacity);
- // draw a colored rectangle behind main preview image
- if (hasImageBackgroundColor) {
- canvasGL.drawRect(imagesMask, 0, false, false, [0, 0, 0, 0], blendWithCanvasBackground($background, imagesBackgroundColor));
- }
- usedTextures.push(...[...images].reverse().map(image => {
- return drawImageHelper({
- ...image,
- // enable drawing markup if defined
- enableShapes: hasAnnotations,
- // enable drawing redactions if defined
- enableBlend: hasBlendShapes,
- // mask and overlay positions
- mask: imagesMask,
- maskOpacity: imagesMaskOpacity,
- overlayColor: imagesOverlayColor
- });
- }));
- // TODO: move vignette here (draw with colorized circular gradient texture instead of in shader)
- // draw decorations shapes relative to crop
- canvasGL.enableMask(imagesMask, 1);
- usedTextures.push(...drawShapes(decorationShapes));
- // draw frames
- if (frameShapes.length) {
- const shapesInside = frameShapes.filter(shape => !shape.expandsCanvas);
- const shapesOutside = frameShapes.filter(shape => shape.expandsCanvas);
- if (shapesInside.length) {
- usedTextures.push(...drawShapes(shapesInside));
- }
- if (shapesOutside.length) {
- // the half pixel helps mask the outside shapes at the correct position
- canvasGL.enableMask(
- {
- x: imagesMask.x + 0.5,
- y: imagesMask.y + 0.5,
- width: imagesMask.width - 1,
- height: imagesMask.height - 1
- },
- $maskFrameOpacityStore
- );
- usedTextures.push(...drawShapes(shapesOutside));
- }
- }
- // crop mask not used for interface
- canvasGL.disableMask();
- // frames rendered on the outside
- // draw custom interface shapes
- usedTextures.push(...drawShapes(interfaceShapes));
- interfaceImages.forEach(image => {
- canvasGL.enableMask(image.mask, image.maskOpacity);
- // draw background fill
- if (image.backgroundColor) {
- canvasGL.drawRect(image.mask, 0, false, false, image.maskCornerRadius, image.backgroundColor, undefined, undefined, undefined, undefined, undefined, image.opacity, image.maskFeather);
- }
- // draw image
- drawImageHelper({
- ...image,
- // update translation to apply `offset` from top left
- translation: {
- x: image.translation.x + image.offset.x - width * 0.5,
- y: image.translation.y + image.offset.y - height * 0.5
- }
- });
- });
- canvasGL.disableMask();
- // determine which textures can be dropped
- releaseUnusedTextures(usedTextures);
- };
- //#endregion
- //#region set up
- // throttled redrawer
- let lastDraw = Date.now();
- const redrawThrottled = () => {
- const now = Date.now();
- const dist = now - lastDraw;
- if (dist < 48) return;
- lastDraw = now;
- redraw();
- };
- // returns the render function to use for this browser context
- const selectFittingRenderFunction = () => isSoftwareRendering() ? redrawThrottled : redraw;
- // after DOM has been altered, redraw to canvas
- afterUpdate(() => drawUpdate());
- // hook up canvas to WebGL drawer
- onMount(() => $$invalidate(19, canvasGL = createWebGLCanvas(canvas)));
- // clean up canvas
- onDestroy(() => {
- // if canvas wasn't created we don't need to release it
- if (!canvasGL) return;
- // done drawing
- canvasGL.release();
- // force release canvas for Safari
- releaseCanvas(TEXT_TEXTURE_MEASURE_CONTEXT.canvas);
- });
- function canvas_1_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- canvas = $$value;
- $$invalidate(2, canvas);
- });
- }
- const measure_handler = e => {
- $$invalidate(0, width = e.detail.width);
- $$invalidate(1, height = e.detail.height);
- dispatch("measure", { width, height });
- };
- $$self.$$set = $$props => {
- if ("animate" in $$props) $$invalidate(9, animate = $$props.animate);
- if ("maskRect" in $$props) $$invalidate(10, maskRect = $$props.maskRect);
- if ("maskOpacity" in $$props) $$invalidate(11, maskOpacity = $$props.maskOpacity);
- if ("maskFrameOpacity" in $$props) $$invalidate(12, maskFrameOpacity = $$props.maskFrameOpacity);
- if ("pixelRatio" in $$props) $$invalidate(13, pixelRatio = $$props.pixelRatio);
- if ("backgroundColor" in $$props) $$invalidate(14, backgroundColor = $$props.backgroundColor);
- if ("willRender" in $$props) $$invalidate(15, willRender = $$props.willRender);
- if ("loadImageData" in $$props) $$invalidate(16, loadImageData = $$props.loadImageData);
- if ("images" in $$props) $$invalidate(17, images = $$props.images);
- if ("interfaceImages" in $$props) $$invalidate(18, interfaceImages = $$props.interfaceImages);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*backgroundColor*/ 16384) {
- backgroundColor && updateSpring(background, backgroundColor);
- }
- if ($$self.$$.dirty[0] & /*maskOpacity*/ 2048) {
- updateSpring(maskOpacityStore, isNumber(maskOpacity) ? maskOpacity : 1);
- }
- if ($$self.$$.dirty[0] & /*maskFrameOpacity*/ 4096) {
- updateSpring(maskFrameOpacityStore, isNumber(maskFrameOpacity) ? maskFrameOpacity : 1);
- }
- if ($$self.$$.dirty[0] & /*maskRect*/ 1024) {
- maskRect && mask.set(maskRect);
- }
- if ($$self.$$.dirty[0] & /*$background, $maskOpacityStore*/ 3145728) {
- $background && imageOverlayColor.set([
- $background[0],
- $background[1],
- $background[2],
- clamp($maskOpacityStore, 0, 1)
- ]);
- }
- if ($$self.$$.dirty[0] & /*canvasGL, width, height, images*/ 655363) {
- // can draw view
- $$invalidate(23, canDraw = !!(canvasGL && width && height && images.length));
- }
- if ($$self.$$.dirty[0] & /*width, height, canvasGL, pixelRatio*/ 532483) {
- // observe width and height changes and resize the canvas proportionally
- width && height && canvasGL && canvasGL.resize(width, height, pixelRatio);
- }
- if ($$self.$$.dirty[0] & /*canDraw*/ 8388608) {
- // switch to draw method when can draw
- $$invalidate(22, drawUpdate = canDraw ? selectFittingRenderFunction() : noop$1);
- }
- if ($$self.$$.dirty[0] & /*canDraw, drawUpdate*/ 12582912) {
- // if can draw state is updated and we have a draw update function, time to redraw
- canDraw && drawUpdate && drawUpdate();
- }
- };
- return [
- width,
- height,
- canvas,
- dispatch,
- background,
- maskOpacityStore,
- maskFrameOpacityStore,
- mask,
- imageOverlayColor,
- animate,
- maskRect,
- maskOpacity,
- maskFrameOpacity,
- pixelRatio,
- backgroundColor,
- willRender,
- loadImageData,
- images,
- interfaceImages,
- canvasGL,
- $background,
- $maskOpacityStore,
- drawUpdate,
- canDraw,
- canvas_1_binding,
- measure_handler
- ];
- }
- class Canvas extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$M,
- create_fragment$M,
- safe_not_equal,
- {
- animate: 9,
- maskRect: 10,
- maskOpacity: 11,
- maskFrameOpacity: 12,
- pixelRatio: 13,
- backgroundColor: 14,
- willRender: 15,
- loadImageData: 16,
- images: 17,
- interfaceImages: 18
- },
- [-1, -1]
- );
- }
- }
- var arrayJoin = (arr, filter = Boolean, str = ' ') => arr.filter(filter).join(str);
- /* src/core/ui/components/TabList.svelte generated by Svelte v3.37.0 */
- function get_each_context$9(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[17] = list[i];
- return child_ctx;
- }
- const get_default_slot_changes$1 = dirty => ({ tab: dirty & /*tabNodes*/ 4 });
- const get_default_slot_context$1 = ctx => ({ tab: /*tab*/ ctx[17] });
- // (52:0) {#if shouldRender}
- function create_if_block$e(ctx) {
- let ul;
- let each_blocks = [];
- let each_1_lookup = new Map();
- let ul_class_value;
- let current;
- let each_value = /*tabNodes*/ ctx[2];
- const get_key = ctx => /*tab*/ ctx[17].id;
- for (let i = 0; i < each_value.length; i += 1) {
- let child_ctx = get_each_context$9(ctx, each_value, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block$9(key, child_ctx));
- }
- return {
- c() {
- ul = element("ul");
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- attr(ul, "class", ul_class_value = arrayJoin(["PinturaTabList", /*klass*/ ctx[0]]));
- attr(ul, "role", "tablist");
- attr(ul, "data-layout", /*layout*/ ctx[1]);
- },
- m(target, anchor) {
- insert(target, ul, anchor);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].m(ul, null);
- }
- /*ul_binding*/ ctx[14](ul);
- current = true;
- },
- p(ctx, dirty) {
- if (dirty & /*tabNodes, handleKeyTab, handleClickTab, $$scope*/ 1124) {
- each_value = /*tabNodes*/ ctx[2];
- group_outros();
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, ul, outro_and_destroy_block, create_each_block$9, null, get_each_context$9);
- check_outros();
- }
- if (!current || dirty & /*klass*/ 1 && ul_class_value !== (ul_class_value = arrayJoin(["PinturaTabList", /*klass*/ ctx[0]]))) {
- attr(ul, "class", ul_class_value);
- }
- if (!current || dirty & /*layout*/ 2) {
- attr(ul, "data-layout", /*layout*/ ctx[1]);
- }
- },
- i(local) {
- if (current) return;
- for (let i = 0; i < each_value.length; i += 1) {
- transition_in(each_blocks[i]);
- }
- current = true;
- },
- o(local) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- transition_out(each_blocks[i]);
- }
- current = false;
- },
- d(detaching) {
- if (detaching) detach(ul);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d();
- }
- /*ul_binding*/ ctx[14](null);
- }
- };
- }
- // (59:8) {#each tabNodes as tab (tab.id)}
- function create_each_block$9(key_1, ctx) {
- let li;
- let button;
- let button_disabled_value;
- let t;
- let li_aria_controls_value;
- let li_id_value;
- let li_aria_selected_value;
- let current;
- let mounted;
- let dispose;
- const default_slot_template = /*#slots*/ ctx[11].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[10], get_default_slot_context$1);
- function keydown_handler(...args) {
- return /*keydown_handler*/ ctx[12](/*tab*/ ctx[17], ...args);
- }
- function click_handler(...args) {
- return /*click_handler*/ ctx[13](/*tab*/ ctx[17], ...args);
- }
- return {
- key: key_1,
- first: null,
- c() {
- li = element("li");
- button = element("button");
- if (default_slot) default_slot.c();
- t = space();
- button.disabled = button_disabled_value = /*tab*/ ctx[17].disabled;
- attr(li, "role", "tab");
- attr(li, "aria-controls", li_aria_controls_value = /*tab*/ ctx[17].href.substr(1));
- attr(li, "id", li_id_value = /*tab*/ ctx[17].tabId);
- attr(li, "aria-selected", li_aria_selected_value = /*tab*/ ctx[17].selected);
- this.first = li;
- },
- m(target, anchor) {
- insert(target, li, anchor);
- append(li, button);
- if (default_slot) {
- default_slot.m(button, null);
- }
- append(li, t);
- current = true;
- if (!mounted) {
- dispose = [
- listen(button, "keydown", keydown_handler),
- listen(button, "click", click_handler)
- ];
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope, tabNodes*/ 1028) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[10], dirty, get_default_slot_changes$1, get_default_slot_context$1);
- }
- }
- if (!current || dirty & /*tabNodes*/ 4 && button_disabled_value !== (button_disabled_value = /*tab*/ ctx[17].disabled)) {
- button.disabled = button_disabled_value;
- }
- if (!current || dirty & /*tabNodes*/ 4 && li_aria_controls_value !== (li_aria_controls_value = /*tab*/ ctx[17].href.substr(1))) {
- attr(li, "aria-controls", li_aria_controls_value);
- }
- if (!current || dirty & /*tabNodes*/ 4 && li_id_value !== (li_id_value = /*tab*/ ctx[17].tabId)) {
- attr(li, "id", li_id_value);
- }
- if (!current || dirty & /*tabNodes*/ 4 && li_aria_selected_value !== (li_aria_selected_value = /*tab*/ ctx[17].selected)) {
- attr(li, "aria-selected", li_aria_selected_value);
- }
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(li);
- if (default_slot) default_slot.d(detaching);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function create_fragment$L(ctx) {
- let if_block_anchor;
- let current;
- let if_block = /*shouldRender*/ ctx[4] && create_if_block$e(ctx);
- return {
- c() {
- if (if_block) if_block.c();
- if_block_anchor = empty();
- },
- m(target, anchor) {
- if (if_block) if_block.m(target, anchor);
- insert(target, if_block_anchor, anchor);
- current = true;
- },
- p(ctx, [dirty]) {
- if (/*shouldRender*/ ctx[4]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty & /*shouldRender*/ 16) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block$e(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(if_block_anchor.parentNode, if_block_anchor);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (if_block) if_block.d(detaching);
- if (detaching) detach(if_block_anchor);
- }
- };
- }
- function instance$L($$self, $$props, $$invalidate) {
- let tabNodes;
- let shouldRender;
- let { $$slots: slots = {}, $$scope } = $$props;
- let root;
- let { class: klass = undefined } = $$props;
- let { name } = $$props;
- let { selected } = $$props;
- let { tabs = [] } = $$props;
- let { layout = undefined } = $$props;
- const dispatch = createEventDispatcher();
- const focusTab = index => {
- const tab = root.querySelectorAll("[role=\"tab\"] button")[index];
- if (!tab) return;
- tab.focus();
- };
- const handleClickTab = (e, id) => {
- e.preventDefault();
- e.stopPropagation();
- dispatch("select", id);
- };
- const handleKeyTab = ({ key }, id) => {
- if (!(/arrow/i).test(key)) return;
- const index = tabs.findIndex(tab => tab.id === id);
- // next
- if ((/right|down/i).test(key)) return focusTab(index < tabs.length - 1 ? index + 1 : 0);
- // prev
- if ((/left|up/i).test(key)) return focusTab(index > 0 ? index - 1 : tabs.length - 1);
- };
- const keydown_handler = (tab, e) => handleKeyTab(e, tab.id);
- const click_handler = (tab, e) => handleClickTab(e, tab.id);
- function ul_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- root = $$value;
- $$invalidate(3, root);
- });
- }
- $$self.$$set = $$props => {
- if ("class" in $$props) $$invalidate(0, klass = $$props.class);
- if ("name" in $$props) $$invalidate(7, name = $$props.name);
- if ("selected" in $$props) $$invalidate(8, selected = $$props.selected);
- if ("tabs" in $$props) $$invalidate(9, tabs = $$props.tabs);
- if ("layout" in $$props) $$invalidate(1, layout = $$props.layout);
- if ("$$scope" in $$props) $$invalidate(10, $$scope = $$props.$$scope);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*tabs, selected, name*/ 896) {
- $$invalidate(2, tabNodes = tabs.map(tab => {
- const isActive = tab.id === selected;
- return {
- ...tab,
- tabId: `tab-${name}-${tab.id}`,
- href: `#panel-${name}-${tab.id}`,
- selected: isActive
- };
- }));
- }
- if ($$self.$$.dirty & /*tabNodes*/ 4) {
- $$invalidate(4, shouldRender = tabNodes.length > 1);
- }
- };
- return [
- klass,
- layout,
- tabNodes,
- root,
- shouldRender,
- handleClickTab,
- handleKeyTab,
- name,
- selected,
- tabs,
- $$scope,
- slots,
- keydown_handler,
- click_handler,
- ul_binding
- ];
- }
- class TabList extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$L, create_fragment$L, safe_not_equal, {
- class: 0,
- name: 7,
- selected: 8,
- tabs: 9,
- layout: 1
- });
- }
- }
- /* src/core/ui/components/TabPanels.svelte generated by Svelte v3.37.0 */
- const get_default_slot_changes_1 = dirty => ({ panel: dirty & /*panelNodes*/ 16 });
- const get_default_slot_context_1 = ctx => ({
- panel: /*panelNodes*/ ctx[4][0].id,
- panelIsActive: true
- });
- function get_each_context$8(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[14] = list[i].id;
- child_ctx[15] = list[i].draw;
- child_ctx[16] = list[i].panelId;
- child_ctx[17] = list[i].tabindex;
- child_ctx[18] = list[i].labelledBy;
- child_ctx[19] = list[i].hidden;
- child_ctx[3] = list[i].visible;
- return child_ctx;
- }
- const get_default_slot_changes = dirty => ({
- panel: dirty & /*panelNodes*/ 16,
- panelIsActive: dirty & /*panelNodes*/ 16
- });
- const get_default_slot_context = ctx => ({
- panel: /*id*/ ctx[14],
- panelIsActive: !/*hidden*/ ctx[19]
- });
- // (56:0) {:else}
- function create_else_block$5(ctx) {
- let div1;
- let div0;
- let div0_class_value;
- let current;
- let mounted;
- let dispose;
- const default_slot_template = /*#slots*/ ctx[11].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[10], get_default_slot_context_1);
- return {
- c() {
- div1 = element("div");
- div0 = element("div");
- if (default_slot) default_slot.c();
- attr(div0, "class", div0_class_value = arrayJoin([/*panelClass*/ ctx[1]]));
- attr(div1, "class", /*klass*/ ctx[0]);
- attr(div1, "style", /*style*/ ctx[2]);
- },
- m(target, anchor) {
- insert(target, div1, anchor);
- append(div1, div0);
- if (default_slot) {
- default_slot.m(div0, null);
- }
- current = true;
- if (!mounted) {
- dispose = [
- listen(div1, "measure", /*measure_handler_1*/ ctx[13]),
- action_destroyer(measurable.call(null, div1))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope, panelNodes*/ 1040) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[10], dirty, get_default_slot_changes_1, get_default_slot_context_1);
- }
- }
- if (!current || dirty & /*panelClass*/ 2 && div0_class_value !== (div0_class_value = arrayJoin([/*panelClass*/ ctx[1]]))) {
- attr(div0, "class", div0_class_value);
- }
- if (!current || dirty & /*klass*/ 1) {
- attr(div1, "class", /*klass*/ ctx[0]);
- }
- if (!current || dirty & /*style*/ 4) {
- attr(div1, "style", /*style*/ ctx[2]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div1);
- if (default_slot) default_slot.d(detaching);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- // (35:0) {#if shouldRender}
- function create_if_block$d(ctx) {
- let div;
- let each_blocks = [];
- let each_1_lookup = new Map();
- let div_class_value;
- let current;
- let mounted;
- let dispose;
- let each_value = /*panelNodes*/ ctx[4];
- const get_key = ctx => /*id*/ ctx[14];
- for (let i = 0; i < each_value.length; i += 1) {
- let child_ctx = get_each_context$8(ctx, each_value, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block$8(key, child_ctx));
- }
- return {
- c() {
- div = element("div");
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- attr(div, "class", div_class_value = arrayJoin(["PinturaTabPanels", /*klass*/ ctx[0]]));
- attr(div, "style", /*style*/ ctx[2]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].m(div, null);
- }
- current = true;
- if (!mounted) {
- dispose = [
- listen(div, "measure", /*measure_handler*/ ctx[12]),
- action_destroyer(measurable.call(null, div, { observePosition: true }))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- if (dirty & /*arrayJoin, panelClass, panelNodes, $$scope*/ 1042) {
- each_value = /*panelNodes*/ ctx[4];
- group_outros();
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, div, outro_and_destroy_block, create_each_block$8, null, get_each_context$8);
- check_outros();
- }
- if (!current || dirty & /*klass*/ 1 && div_class_value !== (div_class_value = arrayJoin(["PinturaTabPanels", /*klass*/ ctx[0]]))) {
- attr(div, "class", div_class_value);
- }
- if (!current || dirty & /*style*/ 4) {
- attr(div, "style", /*style*/ ctx[2]);
- }
- },
- i(local) {
- if (current) return;
- for (let i = 0; i < each_value.length; i += 1) {
- transition_in(each_blocks[i]);
- }
- current = true;
- },
- o(local) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- transition_out(each_blocks[i]);
- }
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d();
- }
- mounted = false;
- run_all(dispose);
- }
- };
- }
- // (52:16) {#if draw}
- function create_if_block_1$e(ctx) {
- let current;
- const default_slot_template = /*#slots*/ ctx[11].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[10], get_default_slot_context);
- return {
- c() {
- if (default_slot) default_slot.c();
- },
- m(target, anchor) {
- if (default_slot) {
- default_slot.m(target, anchor);
- }
- current = true;
- },
- p(ctx, dirty) {
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope, panelNodes*/ 1040) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[10], dirty, get_default_slot_changes, get_default_slot_context);
- }
- }
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (default_slot) default_slot.d(detaching);
- }
- };
- }
- // (43:8) {#each panelNodes as { id, draw, panelId, tabindex, labelledBy, hidden, visible }
- function create_each_block$8(key_1, ctx) {
- let div;
- let t;
- let div_class_value;
- let div_hidden_value;
- let div_id_value;
- let div_tabindex_value;
- let div_aria_labelledby_value;
- let div_data_inert_value;
- let current;
- let if_block = /*draw*/ ctx[15] && create_if_block_1$e(ctx);
- return {
- key: key_1,
- first: null,
- c() {
- div = element("div");
- if (if_block) if_block.c();
- t = space();
- attr(div, "class", div_class_value = arrayJoin(["PinturaTabPanel", /*panelClass*/ ctx[1]]));
- div.hidden = div_hidden_value = /*hidden*/ ctx[19];
- attr(div, "id", div_id_value = /*panelId*/ ctx[16]);
- attr(div, "tabindex", div_tabindex_value = /*tabindex*/ ctx[17]);
- attr(div, "aria-labelledby", div_aria_labelledby_value = /*labelledBy*/ ctx[18]);
- attr(div, "data-inert", div_data_inert_value = !/*visible*/ ctx[3]);
- this.first = div;
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (if_block) if_block.m(div, null);
- append(div, t);
- current = true;
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- if (/*draw*/ ctx[15]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty & /*panelNodes*/ 16) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block_1$e(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(div, t);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- if (!current || dirty & /*panelClass*/ 2 && div_class_value !== (div_class_value = arrayJoin(["PinturaTabPanel", /*panelClass*/ ctx[1]]))) {
- attr(div, "class", div_class_value);
- }
- if (!current || dirty & /*panelNodes*/ 16 && div_hidden_value !== (div_hidden_value = /*hidden*/ ctx[19])) {
- div.hidden = div_hidden_value;
- }
- if (!current || dirty & /*panelNodes*/ 16 && div_id_value !== (div_id_value = /*panelId*/ ctx[16])) {
- attr(div, "id", div_id_value);
- }
- if (!current || dirty & /*panelNodes*/ 16 && div_tabindex_value !== (div_tabindex_value = /*tabindex*/ ctx[17])) {
- attr(div, "tabindex", div_tabindex_value);
- }
- if (!current || dirty & /*panelNodes*/ 16 && div_aria_labelledby_value !== (div_aria_labelledby_value = /*labelledBy*/ ctx[18])) {
- attr(div, "aria-labelledby", div_aria_labelledby_value);
- }
- if (!current || dirty & /*panelNodes*/ 16 && div_data_inert_value !== (div_data_inert_value = !/*visible*/ ctx[3])) {
- attr(div, "data-inert", div_data_inert_value);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (if_block) if_block.d();
- }
- };
- }
- function create_fragment$K(ctx) {
- let current_block_type_index;
- let if_block;
- let if_block_anchor;
- let current;
- const if_block_creators = [create_if_block$d, create_else_block$5];
- const if_blocks = [];
- function select_block_type(ctx, dirty) {
- if (/*shouldRender*/ ctx[5]) return 0;
- return 1;
- }
- current_block_type_index = select_block_type(ctx);
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- return {
- c() {
- if_block.c();
- if_block_anchor = empty();
- },
- m(target, anchor) {
- if_blocks[current_block_type_index].m(target, anchor);
- insert(target, if_block_anchor, anchor);
- current = true;
- },
- p(ctx, [dirty]) {
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type(ctx);
- if (current_block_type_index === previous_block_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- } else {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- if_block = if_blocks[current_block_type_index];
- if (!if_block) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block.c();
- } else {
- if_block.p(ctx, dirty);
- }
- transition_in(if_block, 1);
- if_block.m(if_block_anchor.parentNode, if_block_anchor);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if_blocks[current_block_type_index].d(detaching);
- if (detaching) detach(if_block_anchor);
- }
- };
- }
- function instance$K($$self, $$props, $$invalidate) {
- let panelNodes;
- let shouldRender;
- let { $$slots: slots = {}, $$scope } = $$props;
- let { class: klass = undefined } = $$props;
- let { name } = $$props;
- let { selected } = $$props;
- let { visible = undefined } = $$props;
- let { panelClass = undefined } = $$props;
- let { panels = [] } = $$props;
- let { style = undefined } = $$props;
- const drawCache = {};
- function measure_handler(event) {
- bubble($$self, event);
- }
- function measure_handler_1(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("class" in $$props) $$invalidate(0, klass = $$props.class);
- if ("name" in $$props) $$invalidate(6, name = $$props.name);
- if ("selected" in $$props) $$invalidate(7, selected = $$props.selected);
- if ("visible" in $$props) $$invalidate(3, visible = $$props.visible);
- if ("panelClass" in $$props) $$invalidate(1, panelClass = $$props.panelClass);
- if ("panels" in $$props) $$invalidate(8, panels = $$props.panels);
- if ("style" in $$props) $$invalidate(2, style = $$props.style);
- if ("$$scope" in $$props) $$invalidate(10, $$scope = $$props.$$scope);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*panels, selected, visible, name, drawCache*/ 968) {
- $$invalidate(4, panelNodes = panels.map(id => {
- const isActive = id === selected;
- const isVisible = visible ? visible.indexOf(id) !== -1 : true;
- // remember that this tab was active so we keep drawing it even when it's inactive
- if (isActive) $$invalidate(9, drawCache[id] = true, drawCache);
- return {
- id,
- panelId: `panel-${name}-${id}`,
- labelledBy: `tab-${name}-${id}`,
- hidden: !isActive,
- visible: isVisible,
- tabindex: isActive ? 0 : -1,
- draw: isActive || drawCache[id]
- };
- }));
- }
- if ($$self.$$.dirty & /*panelNodes*/ 16) {
- $$invalidate(5, shouldRender = panelNodes.length > 1);
- }
- };
- return [
- klass,
- panelClass,
- style,
- visible,
- panelNodes,
- shouldRender,
- name,
- selected,
- panels,
- drawCache,
- $$scope,
- slots,
- measure_handler,
- measure_handler_1
- ];
- }
- class TabPanels extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$K, create_fragment$K, safe_not_equal, {
- class: 0,
- name: 6,
- selected: 7,
- visible: 3,
- panelClass: 1,
- panels: 8,
- style: 2
- });
- }
- }
- /* src/core/ui/components/Panel.svelte generated by Svelte v3.37.0 */
- function create_fragment$J(ctx) {
- let div;
- let switch_instance;
- let updating_name;
- let div_class_value;
- let current;
- const switch_instance_spread_levels = [/*componentProps*/ ctx[7]];
- function switch_instance_name_binding(value) {
- /*switch_instance_name_binding*/ ctx[19](value);
- }
- var switch_value = /*componentView*/ ctx[11];
- function switch_props(ctx) {
- let switch_instance_props = {};
- for (let i = 0; i < switch_instance_spread_levels.length; i += 1) {
- switch_instance_props = assign(switch_instance_props, switch_instance_spread_levels[i]);
- }
- if (/*panelName*/ ctx[5] !== void 0) {
- switch_instance_props.name = /*panelName*/ ctx[5];
- }
- return { props: switch_instance_props };
- }
- if (switch_value) {
- switch_instance = new switch_value(switch_props(ctx));
- binding_callbacks.push(() => bind(switch_instance, "name", switch_instance_name_binding));
- /*switch_instance_binding*/ ctx[20](switch_instance);
- switch_instance.$on("measure", /*measure_handler*/ ctx[21]);
- }
- return {
- c() {
- div = element("div");
- if (switch_instance) create_component(switch_instance.$$.fragment);
- attr(div, "data-util", /*panelName*/ ctx[5]);
- attr(div, "class", div_class_value = arrayJoin(["PinturaPanel", /*klass*/ ctx[2]]));
- attr(div, "style", /*style*/ ctx[6]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (switch_instance) {
- mount_component(switch_instance, div, null);
- }
- current = true;
- },
- p(ctx, [dirty]) {
- const switch_instance_changes = (dirty & /*componentProps*/ 128)
- ? get_spread_update(switch_instance_spread_levels, [get_spread_object(/*componentProps*/ ctx[7])])
- : {};
- if (!updating_name && dirty & /*panelName*/ 32) {
- updating_name = true;
- switch_instance_changes.name = /*panelName*/ ctx[5];
- add_flush_callback(() => updating_name = false);
- }
- if (switch_value !== (switch_value = /*componentView*/ ctx[11])) {
- if (switch_instance) {
- group_outros();
- const old_component = switch_instance;
- transition_out(old_component.$$.fragment, 1, 0, () => {
- destroy_component(old_component, 1);
- });
- check_outros();
- }
- if (switch_value) {
- switch_instance = new switch_value(switch_props(ctx));
- binding_callbacks.push(() => bind(switch_instance, "name", switch_instance_name_binding));
- /*switch_instance_binding*/ ctx[20](switch_instance);
- switch_instance.$on("measure", /*measure_handler*/ ctx[21]);
- create_component(switch_instance.$$.fragment);
- transition_in(switch_instance.$$.fragment, 1);
- mount_component(switch_instance, div, null);
- } else {
- switch_instance = null;
- }
- } else if (switch_value) {
- switch_instance.$set(switch_instance_changes);
- }
- if (!current || dirty & /*panelName*/ 32) {
- attr(div, "data-util", /*panelName*/ ctx[5]);
- }
- if (!current || dirty & /*klass*/ 4 && div_class_value !== (div_class_value = arrayJoin(["PinturaPanel", /*klass*/ ctx[2]]))) {
- attr(div, "class", div_class_value);
- }
- if (!current || dirty & /*style*/ 64) {
- attr(div, "style", /*style*/ ctx[6]);
- }
- },
- i(local) {
- if (current) return;
- if (switch_instance) transition_in(switch_instance.$$.fragment, local);
- current = true;
- },
- o(local) {
- if (switch_instance) transition_out(switch_instance.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- /*switch_instance_binding*/ ctx[20](null);
- if (switch_instance) destroy_component(switch_instance);
- }
- };
- }
- function instance$J($$self, $$props, $$invalidate) {
- let style;
- let componentProps;
- let $opacityClamped;
- let $isActivePrivateStore;
- const dispatch = createEventDispatcher();
- let { isActive = true } = $$props;
- let { isAnimated = true } = $$props;
- let { stores } = $$props;
- let { content } = $$props;
- let { component } = $$props;
- let { locale } = $$props;
- let { class: klass = undefined } = $$props;
- // we remember the view rect in this variable
- let rect;
- const opacity = spring(0);
- const opacityClamped = derived(opacity, $opacity => clamp($opacity, 0, 1));
- component_subscribe($$self, opacityClamped, value => $$invalidate(18, $opacityClamped = value));
- // throw hide / show events
- let isHidden = !isActive;
- // create active store so can be used in derived stores
- const isActivePrivateStore = writable(isActive);
- component_subscribe($$self, isActivePrivateStore, value => $$invalidate(22, $isActivePrivateStore = value));
- const stateProps = {
- isActive: derived(isActivePrivateStore, $isActivePrivateStore => $isActivePrivateStore),
- isActiveFraction: derived(opacityClamped, $opacityClamped => $opacityClamped),
- isVisible: derived(opacityClamped, $opacityClamped => $opacityClamped > 0)
- };
- // build the component props
- const componentView = content.view;
- const componentExportedProps = getComponentExportedProps(componentView);
- const componentComputedProps = Object.keys(content.props || {}).reduce(
- (computedProps, key) => {
- if (!componentExportedProps.includes(key)) return computedProps;
- computedProps[key] = content.props[key];
- return computedProps;
- },
- {}
- );
- const componentComputedStateProps = Object.keys(stateProps).reduce(
- (computedStateProps, key) => {
- if (!componentExportedProps.includes(key)) return computedStateProps;
- computedStateProps[key] = stateProps[key];
- return computedStateProps;
- },
- {}
- );
- // class used on panel element
- let panelName;
- // we use the `hasBeenMounted` bool to block rect updates until the entire panel is ready
- let hasBeenMounted = false;
- onMount(() => {
- $$invalidate(4, hasBeenMounted = true);
- });
- function switch_instance_name_binding(value) {
- panelName = value;
- $$invalidate(5, panelName);
- }
- function switch_instance_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- component = $$value;
- $$invalidate(0, component);
- });
- }
- const measure_handler = e => {
- if (!hasBeenMounted || !isActive) return;
- $$invalidate(3, rect = e.detail);
- dispatch("measure", { ...rect });
- };
- $$self.$$set = $$props => {
- if ("isActive" in $$props) $$invalidate(1, isActive = $$props.isActive);
- if ("isAnimated" in $$props) $$invalidate(12, isAnimated = $$props.isAnimated);
- if ("stores" in $$props) $$invalidate(13, stores = $$props.stores);
- if ("content" in $$props) $$invalidate(14, content = $$props.content);
- if ("component" in $$props) $$invalidate(0, component = $$props.component);
- if ("locale" in $$props) $$invalidate(15, locale = $$props.locale);
- if ("class" in $$props) $$invalidate(2, klass = $$props.class);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*rect, isActive, component*/ 11) {
- // when the view rect changes and the panel is in active state or became active, dispatch measure event
- if (rect && isActive && component) dispatch("measure", rect);
- }
- if ($$self.$$.dirty & /*isActive, isAnimated*/ 4098) {
- opacity.set(isActive ? 1 : 0, { hard: !isAnimated });
- }
- if ($$self.$$.dirty & /*$opacityClamped, isHidden*/ 393216) {
- if ($opacityClamped <= 0 && !isHidden) {
- $$invalidate(17, isHidden = true);
- } else if ($opacityClamped > 0 && isHidden) {
- $$invalidate(17, isHidden = false);
- }
- }
- if ($$self.$$.dirty & /*hasBeenMounted, isHidden*/ 131088) {
- hasBeenMounted && dispatch(isHidden ? "hide" : "show");
- }
- if ($$self.$$.dirty & /*$opacityClamped*/ 262144) {
- dispatch("fade", $opacityClamped);
- }
- if ($$self.$$.dirty & /*$opacityClamped*/ 262144) {
- // only set opacity prop if is below 0
- $$invalidate(6, style = $opacityClamped < 1
- ? `opacity: ${$opacityClamped}`
- : undefined);
- }
- if ($$self.$$.dirty & /*isActive*/ 2) {
- set_store_value(isActivePrivateStore, $isActivePrivateStore = isActive, $isActivePrivateStore);
- }
- if ($$self.$$.dirty & /*stores, locale*/ 40960) {
- $$invalidate(7, componentProps = {
- ...componentComputedProps,
- ...componentComputedStateProps,
- stores,
- locale
- });
- }
- };
- return [
- component,
- isActive,
- klass,
- rect,
- hasBeenMounted,
- panelName,
- style,
- componentProps,
- dispatch,
- opacityClamped,
- isActivePrivateStore,
- componentView,
- isAnimated,
- stores,
- content,
- locale,
- opacity,
- isHidden,
- $opacityClamped,
- switch_instance_name_binding,
- switch_instance_binding,
- measure_handler
- ];
- }
- class Panel extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$J, create_fragment$J, safe_not_equal, {
- isActive: 1,
- isAnimated: 12,
- stores: 13,
- content: 14,
- component: 0,
- locale: 15,
- class: 2,
- opacity: 16
- });
- }
- get opacity() {
- return this.$$.ctx[16];
- }
- }
- /* src/core/ui/components/Icon.svelte generated by Svelte v3.37.0 */
- function create_fragment$I(ctx) {
- let svg;
- let svg_viewBox_value;
- let current;
- const default_slot_template = /*#slots*/ ctx[5].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[4], null);
- return {
- c() {
- svg = svg_element("svg");
- if (default_slot) default_slot.c();
- attr(svg, "class", /*klass*/ ctx[3]);
- attr(svg, "style", /*style*/ ctx[2]);
- attr(svg, "width", /*width*/ ctx[0]);
- attr(svg, "height", /*height*/ ctx[1]);
- attr(svg, "viewBox", svg_viewBox_value = "0 0 " + /*width*/ ctx[0] + "\n " + /*height*/ ctx[1]);
- attr(svg, "xmlns", "http://www.w3.org/2000/svg");
- attr(svg, "aria-hidden", "true");
- attr(svg, "focusable", "false");
- attr(svg, "stroke-linecap", "round");
- attr(svg, "stroke-linejoin", "round");
- },
- m(target, anchor) {
- insert(target, svg, anchor);
- if (default_slot) {
- default_slot.m(svg, null);
- }
- current = true;
- },
- p(ctx, [dirty]) {
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope*/ 16) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[4], dirty, null, null);
- }
- }
- if (!current || dirty & /*klass*/ 8) {
- attr(svg, "class", /*klass*/ ctx[3]);
- }
- if (!current || dirty & /*style*/ 4) {
- attr(svg, "style", /*style*/ ctx[2]);
- }
- if (!current || dirty & /*width*/ 1) {
- attr(svg, "width", /*width*/ ctx[0]);
- }
- if (!current || dirty & /*height*/ 2) {
- attr(svg, "height", /*height*/ ctx[1]);
- }
- if (!current || dirty & /*width, height*/ 3 && svg_viewBox_value !== (svg_viewBox_value = "0 0 " + /*width*/ ctx[0] + "\n " + /*height*/ ctx[1])) {
- attr(svg, "viewBox", svg_viewBox_value);
- }
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(svg);
- if (default_slot) default_slot.d(detaching);
- }
- };
- }
- function instance$I($$self, $$props, $$invalidate) {
- let { $$slots: slots = {}, $$scope } = $$props;
- let { width = 24 } = $$props;
- let { height = 24 } = $$props;
- let { style = undefined } = $$props;
- let { class: klass = undefined } = $$props;
- $$self.$$set = $$props => {
- if ("width" in $$props) $$invalidate(0, width = $$props.width);
- if ("height" in $$props) $$invalidate(1, height = $$props.height);
- if ("style" in $$props) $$invalidate(2, style = $$props.style);
- if ("class" in $$props) $$invalidate(3, klass = $$props.class);
- if ("$$scope" in $$props) $$invalidate(4, $$scope = $$props.$$scope);
- };
- return [width, height, style, klass, $$scope, slots];
- }
- class Icon extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$I, create_fragment$I, safe_not_equal, { width: 0, height: 1, style: 2, class: 3 });
- }
- }
- var isEventTarget = (e, element) => element === e.target || element.contains(e.target);
- /* src/core/ui/components/Button.svelte generated by Svelte v3.37.0 */
- function create_if_block_1$d(ctx) {
- let icon_1;
- let current;
- icon_1 = new Icon({
- props: {
- class: "PinturaButtonIcon",
- $$slots: { default: [create_default_slot$h] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(icon_1.$$.fragment);
- },
- m(target, anchor) {
- mount_component(icon_1, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const icon_1_changes = {};
- if (dirty & /*$$scope, icon*/ 1048578) {
- icon_1_changes.$$scope = { dirty, ctx };
- }
- icon_1.$set(icon_1_changes);
- },
- i(local) {
- if (current) return;
- transition_in(icon_1.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon_1.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(icon_1, detaching);
- }
- };
- }
- // (44:16) <Icon class="PinturaButtonIcon">
- function create_default_slot$h(ctx) {
- let g;
- return {
- c() {
- g = svg_element("g");
- },
- m(target, anchor) {
- insert(target, g, anchor);
- g.innerHTML = /*icon*/ ctx[1];
- },
- p(ctx, dirty) {
- if (dirty & /*icon*/ 2) g.innerHTML = /*icon*/ ctx[1]; },
- d(detaching) {
- if (detaching) detach(g);
- }
- };
- }
- // (50:12) {#if label}
- function create_if_block$c(ctx) {
- let span;
- let t;
- return {
- c() {
- span = element("span");
- t = text(/*label*/ ctx[0]);
- attr(span, "class", /*elLabelClass*/ ctx[11]);
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- },
- p(ctx, dirty) {
- if (dirty & /*label*/ 1) set_data(t, /*label*/ ctx[0]);
- if (dirty & /*elLabelClass*/ 2048) {
- attr(span, "class", /*elLabelClass*/ ctx[11]);
- }
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- // (41:10)
- function fallback_block$2(ctx) {
- let span;
- let t;
- let current;
- let if_block0 = /*icon*/ ctx[1] && create_if_block_1$d(ctx);
- let if_block1 = /*label*/ ctx[0] && create_if_block$c(ctx);
- return {
- c() {
- span = element("span");
- if (if_block0) if_block0.c();
- t = space();
- if (if_block1) if_block1.c();
- attr(span, "class", /*elButtonInnerClass*/ ctx[9]);
- },
- m(target, anchor) {
- insert(target, span, anchor);
- if (if_block0) if_block0.m(span, null);
- append(span, t);
- if (if_block1) if_block1.m(span, null);
- current = true;
- },
- p(ctx, dirty) {
- if (/*icon*/ ctx[1]) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty & /*icon*/ 2) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_1$d(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(span, t);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (/*label*/ ctx[0]) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- } else {
- if_block1 = create_if_block$c(ctx);
- if_block1.c();
- if_block1.m(span, null);
- }
- } else if (if_block1) {
- if_block1.d(1);
- if_block1 = null;
- }
- if (!current || dirty & /*elButtonInnerClass*/ 512) {
- attr(span, "class", /*elButtonInnerClass*/ ctx[9]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(span);
- if (if_block0) if_block0.d();
- if (if_block1) if_block1.d();
- }
- };
- }
- function create_fragment$H(ctx) {
- let button;
- let current;
- let mounted;
- let dispose;
- const default_slot_template = /*#slots*/ ctx[18].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[20], null);
- const default_slot_or_fallback = default_slot || fallback_block$2(ctx);
- return {
- c() {
- button = element("button");
- if (default_slot_or_fallback) default_slot_or_fallback.c();
- attr(button, "type", /*type*/ ctx[4]);
- attr(button, "style", /*style*/ ctx[2]);
- button.disabled = /*disabled*/ ctx[3];
- attr(button, "class", /*elButtonClass*/ ctx[10]);
- attr(button, "title", /*label*/ ctx[0]);
- },
- m(target, anchor) {
- insert(target, button, anchor);
- if (default_slot_or_fallback) {
- default_slot_or_fallback.m(button, null);
- }
- /*button_binding*/ ctx[19](button);
- current = true;
- if (!mounted) {
- dispose = [
- listen(button, "keydown", function () {
- if (is_function(/*onkeydown*/ ctx[6])) /*onkeydown*/ ctx[6].apply(this, arguments);
- }),
- listen(button, "click", function () {
- if (is_function(/*onclick*/ ctx[5])) /*onclick*/ ctx[5].apply(this, arguments);
- }),
- action_destroyer(/*action*/ ctx[7].call(null, button))
- ];
- mounted = true;
- }
- },
- p(new_ctx, [dirty]) {
- ctx = new_ctx;
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope*/ 1048576) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[20], dirty, null, null);
- }
- } else {
- if (default_slot_or_fallback && default_slot_or_fallback.p && dirty & /*elButtonInnerClass, elLabelClass, label, icon*/ 2563) {
- default_slot_or_fallback.p(ctx, dirty);
- }
- }
- if (!current || dirty & /*type*/ 16) {
- attr(button, "type", /*type*/ ctx[4]);
- }
- if (!current || dirty & /*style*/ 4) {
- attr(button, "style", /*style*/ ctx[2]);
- }
- if (!current || dirty & /*disabled*/ 8) {
- button.disabled = /*disabled*/ ctx[3];
- }
- if (!current || dirty & /*elButtonClass*/ 1024) {
- attr(button, "class", /*elButtonClass*/ ctx[10]);
- }
- if (!current || dirty & /*label*/ 1) {
- attr(button, "title", /*label*/ ctx[0]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(default_slot_or_fallback, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot_or_fallback, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(button);
- if (default_slot_or_fallback) default_slot_or_fallback.d(detaching);
- /*button_binding*/ ctx[19](null);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function instance$H($$self, $$props, $$invalidate) {
- let elButtonInnerClass;
- let elButtonClass;
- let elLabelClass;
- let { $$slots: slots = {}, $$scope } = $$props;
- let { class: klass = undefined } = $$props;
- let { label = undefined } = $$props;
- let { labelClass = undefined } = $$props;
- let { innerClass = undefined } = $$props;
- let { hideLabel = false } = $$props;
- let { icon = undefined } = $$props;
- let { style = undefined } = $$props;
- let { disabled = undefined } = $$props;
- let { type = "button" } = $$props;
- let { onclick = undefined } = $$props;
- let { onkeydown = undefined } = $$props;
- let { action = () => {
-
- } } = $$props;
- let root;
- const isEventTarget$1 = e => isEventTarget(e, root);
- const getElement = () => root;
- function button_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- root = $$value;
- $$invalidate(8, root);
- });
- }
- $$self.$$set = $$props => {
- if ("class" in $$props) $$invalidate(12, klass = $$props.class);
- if ("label" in $$props) $$invalidate(0, label = $$props.label);
- if ("labelClass" in $$props) $$invalidate(13, labelClass = $$props.labelClass);
- if ("innerClass" in $$props) $$invalidate(14, innerClass = $$props.innerClass);
- if ("hideLabel" in $$props) $$invalidate(15, hideLabel = $$props.hideLabel);
- if ("icon" in $$props) $$invalidate(1, icon = $$props.icon);
- if ("style" in $$props) $$invalidate(2, style = $$props.style);
- if ("disabled" in $$props) $$invalidate(3, disabled = $$props.disabled);
- if ("type" in $$props) $$invalidate(4, type = $$props.type);
- if ("onclick" in $$props) $$invalidate(5, onclick = $$props.onclick);
- if ("onkeydown" in $$props) $$invalidate(6, onkeydown = $$props.onkeydown);
- if ("action" in $$props) $$invalidate(7, action = $$props.action);
- if ("$$scope" in $$props) $$invalidate(20, $$scope = $$props.$$scope);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*innerClass*/ 16384) {
- $$invalidate(9, elButtonInnerClass = arrayJoin(["PinturaButtonInner", innerClass]));
- }
- if ($$self.$$.dirty & /*hideLabel, klass*/ 36864) {
- $$invalidate(10, elButtonClass = arrayJoin(["PinturaButton", hideLabel && "PinturaButtonIconOnly", klass]));
- }
- if ($$self.$$.dirty & /*hideLabel, labelClass*/ 40960) {
- $$invalidate(11, elLabelClass = arrayJoin([hideLabel ? "implicit" : "PinturaButtonLabel", labelClass]));
- }
- };
- return [
- label,
- icon,
- style,
- disabled,
- type,
- onclick,
- onkeydown,
- action,
- root,
- elButtonInnerClass,
- elButtonClass,
- elLabelClass,
- klass,
- labelClass,
- innerClass,
- hideLabel,
- isEventTarget$1,
- getElement,
- slots,
- button_binding,
- $$scope
- ];
- }
- class Button extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$H, create_fragment$H, safe_not_equal, {
- class: 12,
- label: 0,
- labelClass: 13,
- innerClass: 14,
- hideLabel: 15,
- icon: 1,
- style: 2,
- disabled: 3,
- type: 4,
- onclick: 5,
- onkeydown: 6,
- action: 7,
- isEventTarget: 16,
- getElement: 17
- });
- }
- get isEventTarget() {
- return this.$$.ctx[16];
- }
- get getElement() {
- return this.$$.ctx[17];
- }
- }
- var arrayRemove = (array, predicate) => {
- const index = array.findIndex(predicate);
- if (index >= 0)
- return array.splice(index, 1);
- return undefined;
- };
- // svelte
- // constants
- const INERTIA_THRESHOLD = 0.25; // when force of velocity exceeds this value we drift
- const INERTIA_DISTANCE_MULTIPLIER = 50;
- const INERTIA_DURATION_MULTIPLIER = 80;
- const TAP_DURATION_MAX = 300;
- const TAP_DISTANCE_MAX = 64;
- const DOUBLE_TAP_DURATION_MAX = 700;
- const DOUBLE_TAP_DISTANCE_MAX = 128;
- const isContextMenuAction = (e) => isNumber(e.button) && e.button !== 0;
- var interactable = (node, options = {}) => {
- // set defaults
- const { inertia = false, matchTarget = false, pinch = false, getEventPosition = (e) => vectorCreate(e.clientX, e.clientY), } = options;
- //
- // helpers
- //
- function dispatch(type, detail) {
- node.dispatchEvent(new CustomEvent(type, { detail }));
- }
- function resetInertia() {
- if (inertiaTweenUnsubscribe)
- inertiaTweenUnsubscribe();
- inertiaTweenUnsubscribe = undefined;
- }
- //#region pointer registry
- const pointers = [];
- const addPointer = (e) => {
- const pointer = {
- timeStamp: e.timeStamp,
- timeStampInitial: e.timeStamp,
- position: getEventPosition(e),
- origin: getEventPosition(e),
- velocity: vectorCreateEmpty(),
- translation: vectorCreateEmpty(),
- interactionState: undefined,
- event: e,
- };
- pointers.push(pointer);
- pointer.interactionState = getInteractionState(pointers);
- };
- const removePointer = (e) => {
- const pointer = arrayRemove(pointers, (pointer) => pointer.event.pointerId === e.pointerId);
- if (pointer)
- return pointer[0];
- };
- const getPointerIndex = (e) => pointers.findIndex((pointer) => pointer.event.pointerId === e.pointerId);
- const flattenPointerOrigin = (pointer) => {
- pointer.origin.x = pointer.position.x;
- pointer.origin.y = pointer.position.y;
- pointer.translation.x = 0;
- pointer.translation.y = 0;
- };
- const updatePointer = (e) => {
- const pointer = getPointer(e);
- if (!pointer)
- return;
- const { timeStamp } = e;
- // position
- const eventPosition = getEventPosition(e);
- // duration between previous interaction and new interaction, an interaction duration cannot be faster than 1 millisecond
- const interactionDuration = Math.max(1, timeStamp - pointer.timeStamp);
- // calculate velocity
- pointer.velocity.x = (eventPosition.x - pointer.position.x) / interactionDuration;
- pointer.velocity.y = (eventPosition.y - pointer.position.y) / interactionDuration;
- // update the translation
- pointer.translation.x = eventPosition.x - pointer.origin.x;
- pointer.translation.y = eventPosition.y - pointer.origin.y;
- // set new state
- pointer.timeStamp = timeStamp;
- pointer.position.x = eventPosition.x;
- pointer.position.y = eventPosition.y;
- pointer.event = e;
- };
- const getPointer = (e) => {
- const i = getPointerIndex(e);
- if (i < 0)
- return;
- return pointers[i];
- };
- const isSingleTouching = () => pointers.length === 1;
- const isMultiTouching = () => pointers.length === 2;
- const getDistance = (pointers, position) => {
- const distanceTotal = pointers.reduce((prev, curr) => {
- prev += vectorDistance(position, curr.position);
- return prev;
- }, 0);
- return distanceTotal / pointers.length;
- };
- const getInteractionState = (pointers) => {
- const center = vectorCenter(pointers.map((pointer) => pointer.position));
- const distance = getDistance(pointers, center);
- return {
- center,
- distance,
- velocity: vectorCenter(pointers.map((pointer) => pointer.velocity)),
- translation: vectorCenter(pointers.map((pointer) => pointer.translation)),
- };
- };
- //#endregion
- let inertiaTween;
- let inertiaTweenUnsubscribe;
- let pinchOffsetDistance;
- let currentTranslation;
- let currentScale;
- let isGesture;
- let lastTapTimeStamp = 0;
- let lastTapPosition = undefined;
- // start handling interactions
- node.addEventListener('pointerdown', handlePointerdown);
- function handlePointerdown(e) {
- // ignore more than two pointers for now
- if (isMultiTouching())
- return;
- // not interested in context menu
- if (isContextMenuAction(e))
- return;
- // target should equal node, if it doesn't user might have clicked one of the nodes children
- if (matchTarget && e.target !== node)
- return;
- // stop any previous inertia tweens
- resetInertia();
- // register this pointer
- addPointer(e);
- // if is first pointer we need to init the drag gesture
- if (isSingleTouching()) {
- // handle pointer events
- document.documentElement.addEventListener('pointermove', handlePointermove);
- document.documentElement.addEventListener('pointerup', handlePointerup);
- document.documentElement.addEventListener('pointercancel', handlePointerup);
- // clear vars
- isGesture = false;
- currentScale = 1;
- currentTranslation = vectorCreateEmpty();
- pinchOffsetDistance = undefined;
- dispatch('interactionstart', {
- origin: vectorClone(getPointer(e).origin),
- });
- }
- else if (pinch) {
- isGesture = true;
- pinchOffsetDistance = vectorDistance(pointers[0].position, pointers[1].position);
- currentTranslation.x += pointers[0].translation.x;
- currentTranslation.y += pointers[0].translation.y;
- flattenPointerOrigin(pointers[0]);
- }
- }
- //
- // pointer move can only be a primary event (other pointers are not handled)
- //
- let moveLast = Date.now();
- function handlePointermove(e) {
- // prevent selection of text (Safari)
- e.preventDefault();
- // update pointer state
- updatePointer(e);
- let translation = vectorClone(pointers[0].translation);
- let scalar = currentScale;
- if (pinch && isMultiTouching()) {
- // current pinch distance
- const pinchCurrentDistance = vectorDistance(pointers[0].position, pointers[1].position);
- // to find out scalar we calculate the difference between the pinch offset and the new pinch
- const pinchScalar = pinchCurrentDistance / pinchOffsetDistance;
- // add to existing scalar
- scalar *= pinchScalar;
- // current offset
- vectorAdd(translation, pointers[1].translation);
- }
- translation.x += currentTranslation.x;
- translation.y += currentTranslation.y;
- // skip update event if last interaction was less than 16 ms ago
- const now = Date.now();
- const dist = now - moveLast;
- if (dist < 16)
- return;
- moveLast = now;
- dispatch('interactionupdate', {
- translation,
- scalar: pinch ? scalar : undefined,
- });
- }
- //
- // pointer up can only be a primary event (other pointers are not handled)
- //
- function handlePointerup(e) {
- // test if is my pointer that was released, as we're listining on document it could be other pointers
- if (!getPointer(e))
- return;
- // remove pointer from active pointers array
- const removedPointer = removePointer(e);
- // store current size
- if (pinch && isSingleTouching()) {
- // calculate current scale
- const pinchCurrentDistance = vectorDistance(pointers[0].position, removedPointer.position);
- currentScale *= pinchCurrentDistance / pinchOffsetDistance;
- currentTranslation.x += pointers[0].translation.x + removedPointer.translation.x;
- currentTranslation.y += pointers[0].translation.y + removedPointer.translation.y;
- flattenPointerOrigin(pointers[0]);
- }
- // check if this was a tap
- let isTap = false;
- let isDoubleTap = false;
- if (!isGesture && removedPointer) {
- const interactionEnd = performance.now();
- const interactionDuration = interactionEnd - removedPointer.timeStampInitial;
- const interactionDistanceSquared = vectorDistanceSquared(removedPointer.translation);
- isTap =
- interactionDistanceSquared < TAP_DISTANCE_MAX &&
- interactionDuration < TAP_DURATION_MAX;
- isDoubleTap = !!(lastTapPosition &&
- isTap &&
- interactionEnd - lastTapTimeStamp < DOUBLE_TAP_DURATION_MAX &&
- vectorDistanceSquared(lastTapPosition, removedPointer.position) <
- DOUBLE_TAP_DISTANCE_MAX);
- if (isTap) {
- lastTapPosition = vectorClone(removedPointer.position);
- lastTapTimeStamp = interactionEnd;
- }
- }
- // we wait till last multi-touch interaction is finished, all pointers need to be de-registered before proceeding
- if (pointers.length > 0)
- return;
- // stop listening
- document.documentElement.removeEventListener('pointermove', handlePointermove);
- document.documentElement.removeEventListener('pointerup', handlePointerup);
- document.documentElement.removeEventListener('pointercancel', handlePointerup);
- const translation = vectorClone(removedPointer.translation);
- const velocity = vectorClone(removedPointer.velocity);
- // allows cancelling inertia from release handler
- let inertiaPrevented = false;
- // user has released interaction
- dispatch('interactionrelease', {
- isTap,
- isDoubleTap,
- translation,
- scalar: currentScale,
- preventInertia: () => (inertiaPrevented = true),
- });
- // stop intantly if not a lot of force applied
- const force = vectorDistance(velocity);
- if (inertiaPrevented || !inertia || force < INERTIA_THRESHOLD) {
- return handleEnd(translation, { isTap, isDoubleTap });
- }
- // drift
- inertiaTween = tweened(vectorClone(translation), {
- easing: circOut,
- duration: force * INERTIA_DURATION_MULTIPLIER,
- });
- inertiaTween
- .set({
- x: translation.x + velocity.x * INERTIA_DISTANCE_MULTIPLIER,
- y: translation.y + velocity.y * INERTIA_DISTANCE_MULTIPLIER,
- })
- .then(() => {
- // if has unsubscribed (tween was reset)
- if (!inertiaTweenUnsubscribe)
- return;
- // go!
- handleEnd(get_store_value(inertiaTween), { isTap, isDoubleTap });
- });
- inertiaTweenUnsubscribe = inertiaTween.subscribe(handleInertiaUpdate);
- }
- function handleInertiaUpdate(inertiaTranslation) {
- // if is same as previous position, ignore
- if (!inertiaTranslation)
- return; // || vectorEqual(inertiaTranslation, translation)) return;
- // this will handle drift interactions
- dispatch('interactionupdate', {
- translation: inertiaTranslation,
- scalar: pinch ? currentScale : undefined,
- });
- }
- function handleEnd(translation, tapState) {
- resetInertia();
- dispatch('interactionend', {
- ...tapState,
- translation,
- scalar: pinch ? currentScale : undefined,
- });
- }
- return {
- destroy() {
- resetInertia();
- node.removeEventListener('pointerdown', handlePointerdown);
- },
- };
- };
- var nudgeable = (element, options = {}) => {
- // if added as action on non focusable element you should add tabindex=0 attribute
- const { direction = undefined, shiftMultiplier = 10, bubbles = false, stopKeydownPropagation = true, } = options;
- const isHorizontalDirection = direction === 'horizontal';
- const isVerticalDirection = direction === 'vertical';
- const handleKeydown = (e) => {
- const { key } = e;
- const isShift = e.shiftKey;
- const isVerticalAction = /up|down/i.test(key);
- const isHorizontalAction = /left|right/i.test(key);
- // no directional key
- if (!isHorizontalAction && !isVerticalAction)
- return;
- // is horizontal but up or down pressed
- if (isHorizontalDirection && isVerticalAction)
- return;
- // is vertical but left or right pressed
- if (isVerticalDirection && isHorizontalAction)
- return;
- // if holding shift move by a factor 10
- const multiplier = isShift ? shiftMultiplier : 1;
- if (stopKeydownPropagation)
- e.stopPropagation();
- element.dispatchEvent(new CustomEvent('nudge', {
- bubbles,
- detail: vectorCreate((/left/i.test(key) ? -1 : /right/i.test(key) ? 1 : 0) * multiplier, (/up/i.test(key) ? -1 : /down/i.test(key) ? 1 : 0) * multiplier),
- }));
- };
- element.addEventListener('keydown', handleKeydown);
- return {
- destroy() {
- element.removeEventListener('keydown', handleKeydown);
- },
- };
- };
- function elastify(translation, dist) {
- return dist * Math.sign(translation) * Math.log10(1 + Math.abs(translation) / dist);
- }
- const elastifyRects = (a, b, dist) => {
- if (!b)
- return rectClone(a);
- const left = a.x + elastify(b.x - a.x, dist);
- const right = a.x + a.width + elastify(b.x + b.width - (a.x + a.width), dist);
- const top = a.y + elastify(b.y - a.y, dist);
- const bottom = a.y + a.height + elastify(b.y + b.height - (a.y + a.height), dist);
- return {
- x: left,
- y: top,
- width: right - left,
- height: bottom - top,
- };
- };
- var unitToPixels = (value, element) => {
- if (!value)
- return;
- if (/em/.test(value))
- return parseInt(value, 10) * 16;
- if (/px/.test(value))
- return parseInt(value, 10);
- };
- var getWheelDelta = (e) => {
- let d = e.detail || 0;
- // @ts-ignore
- const { deltaX, deltaY, wheelDelta, wheelDeltaX, wheelDeltaY } = e;
- // "detect" x axis interaction for MacOS trackpad
- if (isNumber(wheelDeltaX) && Math.abs(wheelDeltaX) > Math.abs(wheelDeltaY)) {
- // blink & webkit
- d = wheelDeltaX / -120;
- }
- else if (isNumber(deltaX) && Math.abs(deltaX) > Math.abs(deltaY)) {
- // quantum
- d = deltaX / 20;
- }
- // @ts-ignore
- else if (wheelDelta || wheelDeltaY) {
- // blink & webkit
- d = (wheelDelta || wheelDeltaY) / -120;
- }
- if (!d) {
- // quantum
- d = deltaY / 20;
- }
- return d;
- };
- /* src/core/ui/components/Scrollable.svelte generated by Svelte v3.37.0 */
- function create_fragment$G(ctx) {
- let div1;
- let div0;
- let div1_class_value;
- let nudgeable_action;
- let current;
- let mounted;
- let dispose;
- const default_slot_template = /*#slots*/ ctx[37].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[36], null);
- return {
- c() {
- div1 = element("div");
- div0 = element("div");
- if (default_slot) default_slot.c();
- attr(div0, "style", /*childStyle*/ ctx[6]);
- attr(div1, "class", div1_class_value = arrayJoin(["PinturaScrollable", /*klass*/ ctx[0]]));
- attr(div1, "style", /*overflowStyle*/ ctx[4]);
- attr(div1, "data-direction", /*scrollDirection*/ ctx[1]);
- attr(div1, "data-state", /*containerState*/ ctx[5]);
- },
- m(target, anchor) {
- insert(target, div1, anchor);
- append(div1, div0);
- if (default_slot) {
- default_slot.m(div0, null);
- }
- /*div1_binding*/ ctx[39](div1);
- current = true;
- if (!mounted) {
- dispose = [
- listen(div0, "interactionstart", /*handleDragStart*/ ctx[9]),
- listen(div0, "interactionupdate", /*handleDragMove*/ ctx[11]),
- listen(div0, "interactionend", /*handleDragEnd*/ ctx[12]),
- listen(div0, "interactionrelease", /*handleDragRelease*/ ctx[10]),
- action_destroyer(interactable.call(null, div0, { inertia: true })),
- listen(div0, "measure", /*measure_handler*/ ctx[38]),
- action_destroyer(measurable.call(null, div0)),
- listen(div1, "wheel", /*handleWheel*/ ctx[14], { passive: false }),
- listen(div1, "scroll", /*handleScroll*/ ctx[16]),
- listen(div1, "focusin", /*handleFocus*/ ctx[15]),
- listen(div1, "nudge", /*handleNudge*/ ctx[17]),
- listen(div1, "measure", /*handleResizeScrollContainer*/ ctx[13]),
- action_destroyer(measurable.call(null, div1, { observePosition: true })),
- action_destroyer(nudgeable_action = nudgeable.call(null, div1, {
- direction: /*scrollDirection*/ ctx[1] === "x"
- ? "horizontal"
- : "vertical",
- stopKeydownPropagation: false
- }))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- if (default_slot) {
- if (default_slot.p && dirty[1] & /*$$scope*/ 32) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[36], dirty, null, null);
- }
- }
- if (!current || dirty[0] & /*childStyle*/ 64) {
- attr(div0, "style", /*childStyle*/ ctx[6]);
- }
- if (!current || dirty[0] & /*klass*/ 1 && div1_class_value !== (div1_class_value = arrayJoin(["PinturaScrollable", /*klass*/ ctx[0]]))) {
- attr(div1, "class", div1_class_value);
- }
- if (!current || dirty[0] & /*overflowStyle*/ 16) {
- attr(div1, "style", /*overflowStyle*/ ctx[4]);
- }
- if (!current || dirty[0] & /*scrollDirection*/ 2) {
- attr(div1, "data-direction", /*scrollDirection*/ ctx[1]);
- }
- if (!current || dirty[0] & /*containerState*/ 32) {
- attr(div1, "data-state", /*containerState*/ ctx[5]);
- }
- if (nudgeable_action && is_function(nudgeable_action.update) && dirty[0] & /*scrollDirection*/ 2) nudgeable_action.update.call(null, {
- direction: /*scrollDirection*/ ctx[1] === "x"
- ? "horizontal"
- : "vertical",
- stopKeydownPropagation: false
- });
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div1);
- if (default_slot) default_slot.d(detaching);
- /*div1_binding*/ ctx[39](null);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function instance$G($$self, $$props, $$invalidate) {
- let size;
- let axis;
- let containerStyle;
- let containerFeatherSize;
- let overflows;
- let containerState;
- let childStyle;
- let $scrollOffset;
- let $keysPressedStore;
- let { $$slots: slots = {}, $$scope } = $$props;
- const dispatch = createEventDispatcher();
- const keysPressedStore = getContext("keysPressed");
- component_subscribe($$self, keysPressedStore, value => $$invalidate(46, $keysPressedStore = value));
- let scrollState = "idle";
- let scrollOrigin;
- let scrollRect;
- let scrollContainerRect;
- let scrollReleased;
- let scrollOffset = spring(0);
- component_subscribe($$self, scrollOffset, value => $$invalidate(34, $scrollOffset = value));
- let { class: klass = undefined } = $$props;
- let { scrollBlockInteractionDist = 5 } = $$props;
- let { scrollStep = 10 } = $$props; // the distance multiplier for each mouse scroll interaction (delta)
- let { scrollFocusMargin = 64 } = $$props; // the margin used around elements to decided where to move the focus so elements are positioned into view with some spacing around them, this allows peaking at next/previous elements
- let { scrollDirection = "x" } = $$props;
- let { scrollAutoCancel = false } = $$props;
- let { elasticity = 0 } = $$props;
- let { onscroll = noop$1 } = $$props;
- let { maskFeatherSize = undefined } = $$props;
- let { maskFeatherStartOpacity = undefined } = $$props;
- let { maskFeatherEndOpacity = undefined } = $$props;
- let { scroll = undefined } = $$props;
- // logic
- let container;
- let overflowStyle = "";
- // is scroll in reset state
- let scrollAtRest = true;
- // triggers onscroll callback
- scrollOffset.subscribe(value => {
- const pos = vectorCreateEmpty();
- pos[scrollDirection] = value;
- onscroll(pos);
- });
- const limitOffsetToContainer = offset => Math.max(Math.min(0, offset), scrollContainerRect[size] - scrollRect[size]);
- let scrollFirstMove;
- let scrollCancelled;
- let scrollTranslationPrev;
- const isHorizontalTranslation = translation => {
- const velocity = vectorApply(vectorCreate(translation.x - scrollTranslationPrev.x, translation.y - scrollTranslationPrev.y), Math.abs);
- scrollTranslationPrev = vectorClone(translation);
- const speed = vectorDistanceSquared(velocity);
- const diff = velocity.x - velocity.y;
- return !(speed > 1 && diff < -0.5);
- };
- const handleDragStart = () => {
- // not overflowing so no need to handle
- if (!overflows) return;
- scrollCancelled = false;
- scrollFirstMove = true;
- scrollTranslationPrev = vectorCreate(0, 0);
- scrollReleased = false;
- $$invalidate(28, scrollState = "idle");
- scrollOrigin = get_store_value(scrollOffset);
- };
- const handleDragRelease = ({ detail }) => {
- if (!overflows) return;
- scrollReleased = true;
- $$invalidate(28, scrollState = "idle");
- };
- const handleDragMove = ({ detail }) => {
- if (!overflows) return;
- if (scrollCancelled) return;
- // fixes problem with single move event fired when clicking
- if (scrollFirstMove) {
- scrollFirstMove = false;
- if (vectorDistanceSquared(detail.translation) < 0.1) return;
- }
- if (scrollAutoCancel && scrollDirection === "x" && !isHorizontalTranslation(detail.translation)) {
- scrollCancelled = true;
- return;
- }
- setScrollOffset(scrollOrigin + detail.translation[scrollDirection], { elastic: true });
- };
- const handleDragEnd = ({ detail }) => {
- if (!overflows) return;
- if (scrollCancelled) return;
- const offset = scrollOrigin + detail.translation[scrollDirection];
- const offsetLimited = limitOffsetToContainer(offset);
- scrollAtRest = false;
- scrollOffset.set(offsetLimited).then(res => {
- if (!scrollReleased) return;
- scrollAtRest = true;
- });
- };
- const handleResizeScrollContainer = ({ detail }) => {
- $$invalidate(29, scrollContainerRect = detail);
- dispatch("measure", {
- x: detail.x,
- y: detail.y,
- width: detail.width,
- height: detail.height
- });
- };
- const setScrollOffset = (offset, options = {}) => {
- const { elastic = false, animate = false } = options;
- // prevents clicks on child elements if the container is being scrolled
- if (Math.abs(offset) > scrollBlockInteractionDist && scrollState === "idle" && !scrollReleased) {
- $$invalidate(28, scrollState = "scrolling");
- }
- const offsetLimited = limitOffsetToContainer(offset);
- const offsetVisual = elastic && elasticity && !scrollReleased
- ? offsetLimited + elastify(offset - offsetLimited, elasticity)
- : offsetLimited;
- let snapToPosition = true;
- if (animate) {
- snapToPosition = false;
- } else if (!scrollAtRest) {
- snapToPosition = !scrollReleased;
- }
- scrollAtRest = false;
- scrollOffset.set(offsetVisual, { hard: snapToPosition }).then(res => {
- if (!scrollReleased) return;
- scrollAtRest = true;
- });
- };
- const handleWheel = e => {
- // don't do anything if isn't overflowing
- if (!overflows) return;
- // scroll down -> move to right/down
- // scroll up -> move to left/up
- // don't run default actions, prevent other actions from running
- e.preventDefault();
- e.stopPropagation();
- // apply wheel delta to offset
- const delta = getWheelDelta(e);
- const offset = get_store_value(scrollOffset);
- setScrollOffset(offset + delta * scrollStep, { animate: true });
- };
- const handleFocus = e => {
- // don't do anything if isn't overflowing
- if (!overflows) return;
- // ignore this handler if is dragging
- if (!scrollReleased && !$keysPressedStore.length) return;
- let target = e.target;
- // when a target is marked as implicit we use its parent elemetn
- if (e.target.classList.contains("implicit")) target = target.parentNode;
- // get bounds
- const start = target[scrollDirection === "x" ? "offsetLeft" : "offsetTop"]; //.offsetLeft;
- const space = target[scrollDirection === "x" ? "offsetWidth" : "offsetHeight"]; //.offsetWidth;
- const end = start + space;
- // we need to know the current offset of the scroll so we can determine if the target is in view
- const currentScrollOffset = get_store_value(scrollOffset);
- // the margin around elements to keep in mind when focussing items
- const margin = scrollFocusMargin + maskFeatherSize;
- if (currentScrollOffset + start < margin) {
- setScrollOffset(-start + margin);
- } else if (currentScrollOffset + end > scrollContainerRect[size] - margin) {
- setScrollOffset(scrollContainerRect[size] - end - margin, { animate: true });
- }
- };
- const handleScroll = () => {
- // the scroll handler corrects auto browser scroll,
- // is triggered when browser tries to focus an
- // element outside of the scrollcontiner
- $$invalidate(3, container[scrollDirection === "x" ? "scrollLeft" : "scrollTop"] = 0, container);
- };
- const handleNudge = ({ detail }) => {
- const delta = -2 * detail[scrollDirection];
- const offset = get_store_value(scrollOffset);
- setScrollOffset(offset + delta * scrollStep, { animate: true });
- };
- const measure_handler = e => $$invalidate(2, scrollRect = e.detail);
- function div1_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- container = $$value;
- $$invalidate(3, container);
- });
- }
- $$self.$$set = $$props => {
- if ("class" in $$props) $$invalidate(0, klass = $$props.class);
- if ("scrollBlockInteractionDist" in $$props) $$invalidate(21, scrollBlockInteractionDist = $$props.scrollBlockInteractionDist);
- if ("scrollStep" in $$props) $$invalidate(22, scrollStep = $$props.scrollStep);
- if ("scrollFocusMargin" in $$props) $$invalidate(23, scrollFocusMargin = $$props.scrollFocusMargin);
- if ("scrollDirection" in $$props) $$invalidate(1, scrollDirection = $$props.scrollDirection);
- if ("scrollAutoCancel" in $$props) $$invalidate(24, scrollAutoCancel = $$props.scrollAutoCancel);
- if ("elasticity" in $$props) $$invalidate(25, elasticity = $$props.elasticity);
- if ("onscroll" in $$props) $$invalidate(26, onscroll = $$props.onscroll);
- if ("maskFeatherSize" in $$props) $$invalidate(20, maskFeatherSize = $$props.maskFeatherSize);
- if ("maskFeatherStartOpacity" in $$props) $$invalidate(18, maskFeatherStartOpacity = $$props.maskFeatherStartOpacity);
- if ("maskFeatherEndOpacity" in $$props) $$invalidate(19, maskFeatherEndOpacity = $$props.maskFeatherEndOpacity);
- if ("scroll" in $$props) $$invalidate(27, scroll = $$props.scroll);
- if ("$$scope" in $$props) $$invalidate(36, $$scope = $$props.$$scope);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*scrollDirection*/ 2) {
- $$invalidate(30, size = scrollDirection === "x" ? "width" : "height");
- }
- if ($$self.$$.dirty[0] & /*scrollDirection*/ 2) {
- $$invalidate(31, axis = scrollDirection.toUpperCase());
- }
- if ($$self.$$.dirty[0] & /*container*/ 8) {
- $$invalidate(32, containerStyle = container && getComputedStyle(container));
- }
- if ($$self.$$.dirty[0] & /*container*/ 8 | $$self.$$.dirty[1] & /*containerStyle*/ 2) {
- $$invalidate(33, containerFeatherSize = containerStyle && unitToPixels(containerStyle.getPropertyValue("--scrollable-feather-size")));
- }
- if ($$self.$$.dirty[0] & /*scrollContainerRect, scrollRect, size, maskFeatherStartOpacity, maskFeatherEndOpacity*/ 1611399172 | $$self.$$.dirty[1] & /*$scrollOffset, containerFeatherSize*/ 12) {
- if ($scrollOffset != null && scrollContainerRect && containerFeatherSize != null && scrollRect) {
- const startOffset = -1 * $scrollOffset / containerFeatherSize;
- const endOffset = -(scrollContainerRect[size] - scrollRect[size] - $scrollOffset) / containerFeatherSize;
- $$invalidate(18, maskFeatherStartOpacity = clamp(1 - startOffset, 0, 1));
- $$invalidate(19, maskFeatherEndOpacity = clamp(1 - endOffset, 0, 1));
- $$invalidate(20, maskFeatherSize = containerFeatherSize);
- $$invalidate(4, overflowStyle = `--scrollable-feather-start-opacity: ${maskFeatherStartOpacity};--scrollable-feather-end-opacity: ${maskFeatherEndOpacity}`);
- }
- }
- if ($$self.$$.dirty[0] & /*container, scroll*/ 134217736) {
- // update scroll position
- if (container && scroll !== undefined) {
- if (isNumber(scroll)) setScrollOffset(scroll); else setScrollOffset(scroll.scrollOffset, scroll);
- }
- }
- if ($$self.$$.dirty[0] & /*scrollContainerRect, scrollRect, size*/ 1610612740) {
- $$invalidate(35, overflows = scrollContainerRect && scrollRect
- ? scrollRect[size] > scrollContainerRect[size]
- : undefined);
- }
- if ($$self.$$.dirty[0] & /*scrollState*/ 268435456 | $$self.$$.dirty[1] & /*overflows*/ 16) {
- $$invalidate(5, containerState = arrayJoin([scrollState, overflows ? "overflows" : undefined]));
- }
- if ($$self.$$.dirty[1] & /*overflows, axis, $scrollOffset*/ 25) {
- $$invalidate(6, childStyle = overflows
- ? `transform: translate${axis}(${$scrollOffset}px)`
- : undefined);
- }
- };
- return [
- klass,
- scrollDirection,
- scrollRect,
- container,
- overflowStyle,
- containerState,
- childStyle,
- keysPressedStore,
- scrollOffset,
- handleDragStart,
- handleDragRelease,
- handleDragMove,
- handleDragEnd,
- handleResizeScrollContainer,
- handleWheel,
- handleFocus,
- handleScroll,
- handleNudge,
- maskFeatherStartOpacity,
- maskFeatherEndOpacity,
- maskFeatherSize,
- scrollBlockInteractionDist,
- scrollStep,
- scrollFocusMargin,
- scrollAutoCancel,
- elasticity,
- onscroll,
- scroll,
- scrollState,
- scrollContainerRect,
- size,
- axis,
- containerStyle,
- containerFeatherSize,
- $scrollOffset,
- overflows,
- $$scope,
- slots,
- measure_handler,
- div1_binding
- ];
- }
- class Scrollable extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$G,
- create_fragment$G,
- safe_not_equal,
- {
- class: 0,
- scrollBlockInteractionDist: 21,
- scrollStep: 22,
- scrollFocusMargin: 23,
- scrollDirection: 1,
- scrollAutoCancel: 24,
- elasticity: 25,
- onscroll: 26,
- maskFeatherSize: 20,
- maskFeatherStartOpacity: 18,
- maskFeatherEndOpacity: 19,
- scroll: 27
- },
- [-1, -1]
- );
- }
- }
- function fade$1(node, { delay = 0, duration = 400, easing = identity } = {}) {
- const o = +getComputedStyle(node).opacity;
- return {
- delay,
- duration,
- easing,
- css: t => `opacity: ${t * o}`
- };
- }
- /* src/core/ui/components/StatusMessage.svelte generated by Svelte v3.37.0 */
- function create_fragment$F(ctx) {
- let span;
- let t;
- let span_transition;
- let current;
- let mounted;
- let dispose;
- return {
- c() {
- span = element("span");
- t = text(/*text*/ ctx[0]);
- attr(span, "class", "PinturaStatusMessage");
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- current = true;
- if (!mounted) {
- dispose = [
- listen(span, "measure", function () {
- if (is_function(/*onmeasure*/ ctx[1])) /*onmeasure*/ ctx[1].apply(this, arguments);
- }),
- action_destroyer(measurable.call(null, span))
- ];
- mounted = true;
- }
- },
- p(new_ctx, [dirty]) {
- ctx = new_ctx;
- if (!current || dirty & /*text*/ 1) set_data(t, /*text*/ ctx[0]);
- },
- i(local) {
- if (current) return;
- add_render_callback(() => {
- if (!span_transition) span_transition = create_bidirectional_transition(span, fade$1, {}, true);
- span_transition.run(1);
- });
- current = true;
- },
- o(local) {
- if (!span_transition) span_transition = create_bidirectional_transition(span, fade$1, {}, false);
- span_transition.run(0);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(span);
- if (detaching && span_transition) span_transition.end();
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function instance$F($$self, $$props, $$invalidate) {
- let { text } = $$props;
- let { onmeasure = noop$1 } = $$props;
- $$self.$$set = $$props => {
- if ("text" in $$props) $$invalidate(0, text = $$props.text);
- if ("onmeasure" in $$props) $$invalidate(1, onmeasure = $$props.onmeasure);
- };
- return [text, onmeasure];
- }
- class StatusMessage extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$F, create_fragment$F, safe_not_equal, { text: 0, onmeasure: 1 });
- }
- }
- /* src/core/ui/components/ProgressIndicator.svelte generated by Svelte v3.37.0 */
- function create_fragment$E(ctx) {
- let span1;
- let svg;
- let g;
- let circle0;
- let circle1;
- let t0;
- let span0;
- let t1;
- return {
- c() {
- span1 = element("span");
- svg = svg_element("svg");
- g = svg_element("g");
- circle0 = svg_element("circle");
- circle1 = svg_element("circle");
- t0 = space();
- span0 = element("span");
- t1 = text(/*formattedValue*/ ctx[0]);
- attr(circle0, "class", "PinturaProgressIndicatorBar");
- attr(circle0, "r", "8.5");
- attr(circle0, "cx", "10");
- attr(circle0, "cy", "10");
- attr(circle0, "stroke-linecap", "round");
- attr(circle0, "opacity", ".25");
- attr(circle1, "class", "PinturaProgressIndicatorFill");
- attr(circle1, "r", "8.5");
- attr(circle1, "stroke-dasharray", /*circleValue*/ ctx[1]);
- attr(circle1, "cx", "10");
- attr(circle1, "cy", "10");
- attr(circle1, "transform", "rotate(-90) translate(-20)");
- attr(g, "fill", "none");
- attr(g, "stroke", "currentColor");
- attr(g, "stroke-width", "2.5");
- attr(g, "stroke-linecap", "round");
- attr(g, "opacity", /*circleOpacity*/ ctx[2]);
- attr(svg, "width", "20");
- attr(svg, "height", "20");
- attr(svg, "viewBox", "0 0 20 20");
- attr(svg, "xmlns", "http://www.w3.org/2000/svg");
- attr(svg, "aria-hidden", "true");
- attr(svg, "focusable", "false");
- attr(span0, "class", "implicit");
- attr(span1, "class", "PinturaProgressIndicator");
- attr(span1, "data-status", /*status*/ ctx[3]);
- },
- m(target, anchor) {
- insert(target, span1, anchor);
- append(span1, svg);
- append(svg, g);
- append(g, circle0);
- append(g, circle1);
- append(span1, t0);
- append(span1, span0);
- append(span0, t1);
- },
- p(ctx, [dirty]) {
- if (dirty & /*circleValue*/ 2) {
- attr(circle1, "stroke-dasharray", /*circleValue*/ ctx[1]);
- }
- if (dirty & /*circleOpacity*/ 4) {
- attr(g, "opacity", /*circleOpacity*/ ctx[2]);
- }
- if (dirty & /*formattedValue*/ 1) set_data(t1, /*formattedValue*/ ctx[0]);
- if (dirty & /*status*/ 8) {
- attr(span1, "data-status", /*status*/ ctx[3]);
- }
- },
- i: noop,
- o: noop,
- d(detaching) {
- if (detaching) detach(span1);
- }
- };
- }
- function instance$E($$self, $$props, $$invalidate) {
- let formattedValue;
- let circleValue;
- let circleOpacity;
- let status;
- let $animatedProgressClamped;
- const dispatch = createEventDispatcher();
- let { progress } = $$props;
- let { min = 0 } = $$props;
- let { max = 100 } = $$props;
- let { labelBusy = "Busy" } = $$props;
- const animatedValue = spring(0, { precision: 0.01 });
- const animatedProgressClamped = derived([animatedValue], $animatedValue => clamp($animatedValue, min, max));
- component_subscribe($$self, animatedProgressClamped, value => $$invalidate(9, $animatedProgressClamped = value));
- animatedProgressClamped.subscribe(value => {
- if (progress === 1 && Math.round(value) >= 100) dispatch("complete");
- });
- $$self.$$set = $$props => {
- if ("progress" in $$props) $$invalidate(5, progress = $$props.progress);
- if ("min" in $$props) $$invalidate(6, min = $$props.min);
- if ("max" in $$props) $$invalidate(7, max = $$props.max);
- if ("labelBusy" in $$props) $$invalidate(8, labelBusy = $$props.labelBusy);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*progress*/ 32) {
- progress && progress !== Infinity && animatedValue.set(progress * 100);
- }
- if ($$self.$$.dirty & /*progress, labelBusy, $animatedProgressClamped*/ 800) {
- $$invalidate(0, formattedValue = progress === Infinity
- ? labelBusy
- : `${Math.round($animatedProgressClamped)}%`);
- }
- if ($$self.$$.dirty & /*progress, $animatedProgressClamped*/ 544) {
- $$invalidate(1, circleValue = progress === Infinity
- ? "26.5 53"
- : `${$animatedProgressClamped / 100 * 53} 53`);
- }
- if ($$self.$$.dirty & /*progress, $animatedProgressClamped*/ 544) {
- $$invalidate(2, circleOpacity = Math.min(1, progress === Infinity
- ? 1
- : $animatedProgressClamped / 10));
- }
- if ($$self.$$.dirty & /*progress*/ 32) {
- $$invalidate(3, status = progress === Infinity ? "busy" : "loading");
- }
- };
- return [
- formattedValue,
- circleValue,
- circleOpacity,
- status,
- animatedProgressClamped,
- progress,
- min,
- max,
- labelBusy,
- $animatedProgressClamped
- ];
- }
- class ProgressIndicator extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$E, create_fragment$E, safe_not_equal, {
- progress: 5,
- min: 6,
- max: 7,
- labelBusy: 8
- });
- }
- }
- /* src/core/ui/components/StatusAside.svelte generated by Svelte v3.37.0 */
- function create_fragment$D(ctx) {
- let span;
- let span_class_value;
- let current;
- const default_slot_template = /*#slots*/ ctx[5].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[4], null);
- return {
- c() {
- span = element("span");
- if (default_slot) default_slot.c();
- attr(span, "class", span_class_value = `PinturaStatusAside ${/*klass*/ ctx[0]}`);
- attr(span, "style", /*style*/ ctx[1]);
- },
- m(target, anchor) {
- insert(target, span, anchor);
- if (default_slot) {
- default_slot.m(span, null);
- }
- current = true;
- },
- p(ctx, [dirty]) {
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope*/ 16) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[4], dirty, null, null);
- }
- }
- if (!current || dirty & /*klass*/ 1 && span_class_value !== (span_class_value = `PinturaStatusAside ${/*klass*/ ctx[0]}`)) {
- attr(span, "class", span_class_value);
- }
- if (!current || dirty & /*style*/ 2) {
- attr(span, "style", /*style*/ ctx[1]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(span);
- if (default_slot) default_slot.d(detaching);
- }
- };
- }
- function instance$D($$self, $$props, $$invalidate) {
- let style;
- let { $$slots: slots = {}, $$scope } = $$props;
- let { offset = 0 } = $$props;
- let { opacity = 0 } = $$props;
- let { class: klass = undefined } = $$props;
- $$self.$$set = $$props => {
- if ("offset" in $$props) $$invalidate(2, offset = $$props.offset);
- if ("opacity" in $$props) $$invalidate(3, opacity = $$props.opacity);
- if ("class" in $$props) $$invalidate(0, klass = $$props.class);
- if ("$$scope" in $$props) $$invalidate(4, $$scope = $$props.$$scope);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*offset, opacity*/ 12) {
- $$invalidate(1, style = `transform:translateX(${offset}px);opacity:${opacity}`);
- }
- };
- return [klass, style, offset, opacity, $$scope, slots];
- }
- class StatusAside extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$D, create_fragment$D, safe_not_equal, { offset: 2, opacity: 3, class: 0 });
- }
- }
- /* src/core/ui/components/Tag.svelte generated by Svelte v3.37.0 */
- function create_if_block_2$9(ctx) {
- let label;
- let label_for_value;
- let current;
- const default_slot_template = /*#slots*/ ctx[3].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[2], null);
- let label_levels = [{ for: label_for_value = "_" }, /*attributes*/ ctx[1]];
- let label_data = {};
- for (let i = 0; i < label_levels.length; i += 1) {
- label_data = assign(label_data, label_levels[i]);
- }
- return {
- c() {
- label = element("label");
- if (default_slot) default_slot.c();
- set_attributes(label, label_data);
- },
- m(target, anchor) {
- insert(target, label, anchor);
- if (default_slot) {
- default_slot.m(label, null);
- }
- current = true;
- },
- p(ctx, dirty) {
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope*/ 4) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[2], dirty, null, null);
- }
- }
- set_attributes(label, label_data = get_spread_update(label_levels, [
- { for: label_for_value },
- dirty & /*attributes*/ 2 && /*attributes*/ ctx[1]
- ]));
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(label);
- if (default_slot) default_slot.d(detaching);
- }
- };
- }
- // (12:26)
- function create_if_block_1$c(ctx) {
- let div;
- let current;
- const default_slot_template = /*#slots*/ ctx[3].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[2], null);
- let div_levels = [/*attributes*/ ctx[1]];
- let div_data = {};
- for (let i = 0; i < div_levels.length; i += 1) {
- div_data = assign(div_data, div_levels[i]);
- }
- return {
- c() {
- div = element("div");
- if (default_slot) default_slot.c();
- set_attributes(div, div_data);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (default_slot) {
- default_slot.m(div, null);
- }
- current = true;
- },
- p(ctx, dirty) {
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope*/ 4) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[2], dirty, null, null);
- }
- }
- set_attributes(div, div_data = get_spread_update(div_levels, [dirty & /*attributes*/ 2 && /*attributes*/ ctx[1]]));
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (default_slot) default_slot.d(detaching);
- }
- };
- }
- // (8:0) {#if name === 'div'}
- function create_if_block$b(ctx) {
- let div;
- let current;
- const default_slot_template = /*#slots*/ ctx[3].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[2], null);
- let div_levels = [/*attributes*/ ctx[1]];
- let div_data = {};
- for (let i = 0; i < div_levels.length; i += 1) {
- div_data = assign(div_data, div_levels[i]);
- }
- return {
- c() {
- div = element("div");
- if (default_slot) default_slot.c();
- set_attributes(div, div_data);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (default_slot) {
- default_slot.m(div, null);
- }
- current = true;
- },
- p(ctx, dirty) {
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope*/ 4) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[2], dirty, null, null);
- }
- }
- set_attributes(div, div_data = get_spread_update(div_levels, [dirty & /*attributes*/ 2 && /*attributes*/ ctx[1]]));
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (default_slot) default_slot.d(detaching);
- }
- };
- }
- function create_fragment$C(ctx) {
- let current_block_type_index;
- let if_block;
- let if_block_anchor;
- let current;
- const if_block_creators = [create_if_block$b, create_if_block_1$c, create_if_block_2$9];
- const if_blocks = [];
- function select_block_type(ctx, dirty) {
- if (/*name*/ ctx[0] === "div") return 0;
- if (/*name*/ ctx[0] === "span") return 1;
- if (/*name*/ ctx[0] === "label") return 2;
- return -1;
- }
- if (~(current_block_type_index = select_block_type(ctx))) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- }
- return {
- c() {
- if (if_block) if_block.c();
- if_block_anchor = empty();
- },
- m(target, anchor) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].m(target, anchor);
- }
- insert(target, if_block_anchor, anchor);
- current = true;
- },
- p(ctx, [dirty]) {
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type(ctx);
- if (current_block_type_index === previous_block_index) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- }
- } else {
- if (if_block) {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- }
- if (~current_block_type_index) {
- if_block = if_blocks[current_block_type_index];
- if (!if_block) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block.c();
- } else {
- if_block.p(ctx, dirty);
- }
- transition_in(if_block, 1);
- if_block.m(if_block_anchor.parentNode, if_block_anchor);
- } else {
- if_block = null;
- }
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].d(detaching);
- }
- if (detaching) detach(if_block_anchor);
- }
- };
- }
- function instance$C($$self, $$props, $$invalidate) {
- let { $$slots: slots = {}, $$scope } = $$props;
- let { name = "div" } = $$props;
- let { attributes = {} } = $$props;
- $$self.$$set = $$props => {
- if ("name" in $$props) $$invalidate(0, name = $$props.name);
- if ("attributes" in $$props) $$invalidate(1, attributes = $$props.attributes);
- if ("$$scope" in $$props) $$invalidate(2, $$scope = $$props.$$scope);
- };
- return [name, attributes, $$scope, slots];
- }
- class Tag extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$C, create_fragment$C, safe_not_equal, { name: 0, attributes: 1 });
- }
- }
- var getDevicePixelRatio = () => (isBrowser() && window.devicePixelRatio) || 1;
- // if this is a non retina display snap to pixel
- let fn = null;
- var snapToPixel = (v) => {
- if (fn === null)
- fn = getDevicePixelRatio() === 1 ? (v) => Math.round(v) : (v) => v;
- return fn(v);
- };
- /* src/core/ui/components/Details.svelte generated by Svelte v3.37.0 */
- const get_details_slot_changes = dirty => ({});
- const get_details_slot_context = ctx => ({});
- const get_label_slot_changes = dirty => ({});
- const get_label_slot_context = ctx => ({});
- // (177:0) <Button bind:this={buttonComponent} class={arrayJoin(['PinturaDetailsButton', buttonClass])} onkeydown={handleButtonKeydown} onclick={handleClick} >
- function create_default_slot$g(ctx) {
- let current;
- const label_slot_template = /*#slots*/ ctx[35].label;
- const label_slot = create_slot(label_slot_template, ctx, /*$$scope*/ ctx[39], get_label_slot_context);
- return {
- c() {
- if (label_slot) label_slot.c();
- },
- m(target, anchor) {
- if (label_slot) {
- label_slot.m(target, anchor);
- }
- current = true;
- },
- p(ctx, dirty) {
- if (label_slot) {
- if (label_slot.p && dirty[1] & /*$$scope*/ 256) {
- update_slot(label_slot, label_slot_template, ctx, /*$$scope*/ ctx[39], dirty, get_label_slot_changes, get_label_slot_context);
- }
- }
- },
- i(local) {
- if (current) return;
- transition_in(label_slot, local);
- current = true;
- },
- o(local) {
- transition_out(label_slot, local);
- current = false;
- },
- d(detaching) {
- if (label_slot) label_slot.d(detaching);
- }
- };
- }
- // (186:0) {#if isVisible}
- function create_if_block_1$b(ctx) {
- let div;
- let t;
- let span;
- let div_class_value;
- let current;
- let mounted;
- let dispose;
- const details_slot_template = /*#slots*/ ctx[35].details;
- const details_slot = create_slot(details_slot_template, ctx, /*$$scope*/ ctx[39], get_details_slot_context);
- return {
- c() {
- div = element("div");
- if (details_slot) details_slot.c();
- t = space();
- span = element("span");
- attr(span, "class", "PinturaDetailsPanelTip");
- attr(span, "style", /*tipStyle*/ ctx[7]);
- attr(div, "class", div_class_value = arrayJoin(["PinturaDetailsPanel", /*panelClass*/ ctx[1]]));
- attr(div, "tabindex", "-1");
- attr(div, "style", /*style*/ ctx[6]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (details_slot) {
- details_slot.m(div, null);
- }
- append(div, t);
- append(div, span);
- /*div_binding*/ ctx[37](div);
- current = true;
- if (!mounted) {
- dispose = [
- listen(div, "keydown", /*handlePanelKeydown*/ ctx[17]),
- listen(div, "measure", /*measure_handler*/ ctx[38]),
- action_destroyer(measurable.call(null, div))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- if (details_slot) {
- if (details_slot.p && dirty[1] & /*$$scope*/ 256) {
- update_slot(details_slot, details_slot_template, ctx, /*$$scope*/ ctx[39], dirty, get_details_slot_changes, get_details_slot_context);
- }
- }
- if (!current || dirty[0] & /*tipStyle*/ 128) {
- attr(span, "style", /*tipStyle*/ ctx[7]);
- }
- if (!current || dirty[0] & /*panelClass*/ 2 && div_class_value !== (div_class_value = arrayJoin(["PinturaDetailsPanel", /*panelClass*/ ctx[1]]))) {
- attr(div, "class", div_class_value);
- }
- if (!current || dirty[0] & /*style*/ 64) {
- attr(div, "style", /*style*/ ctx[6]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(details_slot, local);
- current = true;
- },
- o(local) {
- transition_out(details_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (details_slot) details_slot.d(detaching);
- /*div_binding*/ ctx[37](null);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function create_fragment$B(ctx) {
- let t0;
- let button;
- let t1;
- let t2;
- let if_block1_anchor;
- let current;
- let mounted;
- let dispose;
- let button_props = {
- class: arrayJoin(["PinturaDetailsButton", /*buttonClass*/ ctx[0]]),
- onkeydown: /*handleButtonKeydown*/ ctx[16],
- onclick: /*handleClick*/ ctx[15],
- $$slots: { default: [create_default_slot$g] },
- $$scope: { ctx }
- };
- button = new Button({ props: button_props });
- /*button_binding*/ ctx[36](button);
- let if_block0 = /*isVisible*/ ctx[5] && create_if_block_1$b(ctx);
- let if_block1 = false ;
- return {
- c() {
- t0 = space();
- create_component(button.$$.fragment);
- t1 = space();
- if (if_block0) if_block0.c();
- t2 = space();
- if_block1_anchor = empty();
- },
- m(target, anchor) {
- insert(target, t0, anchor);
- mount_component(button, target, anchor);
- insert(target, t1, anchor);
- if (if_block0) if_block0.m(target, anchor);
- insert(target, t2, anchor);
- insert(target, if_block1_anchor, anchor);
- current = true;
- if (!mounted) {
- dispose = [
- listen(document.body, "pointerdown", function () {
- if (is_function(/*handleDown*/ ctx[8])) /*handleDown*/ ctx[8].apply(this, arguments);
- }),
- listen(document.body, "pointerup", function () {
- if (is_function(/*handleUp*/ ctx[9])) /*handleUp*/ ctx[9].apply(this, arguments);
- })
- ];
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- const button_changes = {};
- if (dirty[0] & /*buttonClass*/ 1) button_changes.class = arrayJoin(["PinturaDetailsButton", /*buttonClass*/ ctx[0]]);
- if (dirty[1] & /*$$scope*/ 256) {
- button_changes.$$scope = { dirty, ctx };
- }
- button.$set(button_changes);
- if (/*isVisible*/ ctx[5]) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty[0] & /*isVisible*/ 32) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_1$b(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(t2.parentNode, t2);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(button.$$.fragment, local);
- transition_in(if_block0);
- transition_in(if_block1);
- current = true;
- },
- o(local) {
- transition_out(button.$$.fragment, local);
- transition_out(if_block0);
- transition_out(if_block1);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(t0);
- /*button_binding*/ ctx[36](null);
- destroy_component(button, detaching);
- if (detaching) detach(t1);
- if (if_block0) if_block0.d(detaching);
- if (detaching) detach(t2);
- if (detaching) detach(if_block1_anchor);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- let panelMargin = 12;
- function instance$B($$self, $$props, $$invalidate) {
- let buttonElement;
- let offsetProgress;
- let isVisible;
- let isAnimating;
- let transform;
- let style;
- let tipScale;
- let tipOpacity;
- let tipStyle;
- let handleDown;
- let handleUp;
- let $offset;
- let $portalRootRect;
- let $position;
- let $opacity;
- let $portal;
- let { $$slots: slots = {}, $$scope } = $$props;
- let { buttonClass = undefined } = $$props;
- let { panelClass = undefined } = $$props;
- let { isActive = false } = $$props;
- let { onshow = ({ panel }) => panel.focus() } = $$props;
- const portal = getContext("rootPortal");
- component_subscribe($$self, portal, value => $$invalidate(34, $portal = value));
- const portalRootRect = getContext("rootRect");
- component_subscribe($$self, portalRootRect, value => $$invalidate(27, $portalRootRect = value));
- let panelSize;
- let buttonComponent;
- let buttonRect;
- let dir = vectorCreateEmpty();
- let opacity = spring(0);
- component_subscribe($$self, opacity, value => $$invalidate(29, $opacity = value));
- let shift = vectorCreateEmpty();
- const position = writable({ x: 0, y: 0 });
- component_subscribe($$self, position, value => $$invalidate(28, $position = value));
- const offset = spring(-5, {
- stiffness: 0.1,
- damping: 0.35,
- precision: 0.001
- });
- component_subscribe($$self, offset, value => $$invalidate(26, $offset = value));
- const isTargetSelf = e => isEventTarget(e, $portal) || buttonComponent.isEventTarget(e);
- let downOutsidePanel = false;
- // move detail panel to portal
- let detailPanel;
- let trigger;
- // test keydown press to open
- const handleClick = e => {
- if (!isActive) $$invalidate(20, buttonRect = buttonElement.getBoundingClientRect());
- $$invalidate(24, trigger = e);
- $$invalidate(18, isActive = !isActive);
- };
- const handleButtonKeydown = e => {
- if (!(/down/i).test(e.key)) return;
- $$invalidate(18, isActive = true);
- $$invalidate(24, trigger = e);
- };
- const handlePanelKeydown = e => {
- if (!(/esc/i).test(e.key)) return;
- $$invalidate(18, isActive = false);
- buttonElement.focus();
- };
- // clean up panel if it was appended to a portal
- onDestroy(() => {
- if (!$portal || !detailPanel || detailPanel.parentNode) return;
- $portal.removeChild(detailPanel);
- });
- function button_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- buttonComponent = $$value;
- $$invalidate(3, buttonComponent);
- });
- }
- function div_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- detailPanel = $$value;
- $$invalidate(4, detailPanel);
- });
- }
- const measure_handler = e => $$invalidate(2, panelSize = sizeCreateFromAny(e.detail));
- $$self.$$set = $$props => {
- if ("buttonClass" in $$props) $$invalidate(0, buttonClass = $$props.buttonClass);
- if ("panelClass" in $$props) $$invalidate(1, panelClass = $$props.panelClass);
- if ("isActive" in $$props) $$invalidate(18, isActive = $$props.isActive);
- if ("onshow" in $$props) $$invalidate(19, onshow = $$props.onshow);
- if ("$$scope" in $$props) $$invalidate(39, $$scope = $$props.$$scope);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*buttonComponent*/ 8) {
- buttonElement = buttonComponent && buttonComponent.getElement();
- }
- if ($$self.$$.dirty[0] & /*isActive, downOutsidePanel*/ 8650752) {
- $$invalidate(9, handleUp = isActive
- ? e => {
- if (!downOutsidePanel) return;
- $$invalidate(23, downOutsidePanel = false);
- if (isTargetSelf(e)) return;
- $$invalidate(18, isActive = false);
- }
- : undefined);
- }
- if ($$self.$$.dirty[0] & /*isActive*/ 262144) {
- opacity.set(isActive ? 1 : 0);
- }
- if ($$self.$$.dirty[0] & /*isActive*/ 262144) {
- offset.set(isActive ? 0 : -5);
- }
- if ($$self.$$.dirty[0] & /*$offset*/ 67108864) {
- $$invalidate(25, offsetProgress = 1 - $offset / -5);
- }
- if ($$self.$$.dirty[0] & /*$portalRootRect, panelSize, buttonRect*/ 135266308) {
- if ($portalRootRect && panelSize && buttonRect) {
- // as a starting point we'll align panel to center of button and position below
- let x = buttonRect.x - $portalRootRect.x + buttonRect.width * 0.5 - panelSize.width * 0.5;
- let y = buttonRect.y - $portalRootRect.y + buttonRect.height;
- const parentLeft = panelMargin;
- const parentTop = panelMargin;
- const parentRight = $portalRootRect.width - panelMargin;
- const parentBottom = $portalRootRect.height - panelMargin;
- const panelLeft = x;
- const panelTop = y;
- const panelRight = panelLeft + panelSize.width;
- const panelBottom = panelTop + panelSize.height;
- // move to right
- if (panelLeft < parentLeft) {
- $$invalidate(22, shift.x = panelLeft - parentLeft, shift);
- x = parentLeft;
- }
- // move to left
- if (panelRight > parentRight) {
- $$invalidate(22, shift.x = panelRight - parentRight, shift);
- x = parentRight - panelSize.width;
- }
- if (panelBottom > parentBottom) {
- // doesn't fit vertically, push up
- $$invalidate(21, dir.y = -1, dir);
- const positionedAboveButtonY = y - panelSize.height - buttonRect.height;
- const panelFitsAboveButton = parentTop < positionedAboveButtonY;
- if (panelFitsAboveButton) {
- $$invalidate(22, shift.y = 0, shift);
- y -= panelSize.height + buttonRect.height;
- } else {
- // overlap with button
- $$invalidate(22, shift.y = y - (panelBottom - parentBottom), shift);
- y -= panelBottom - parentBottom;
- }
- } else {
- // all is fine
- $$invalidate(21, dir.y = 1, dir);
- }
- set_store_value(position, $position = vectorApply(vectorCreate(x, y), snapToPixel), $position);
- }
- }
- if ($$self.$$.dirty[0] & /*$opacity*/ 536870912) {
- $$invalidate(5, isVisible = $opacity > 0);
- }
- if ($$self.$$.dirty[0] & /*$opacity*/ 536870912) {
- $$invalidate(30, isAnimating = $opacity < 1);
- }
- if ($$self.$$.dirty[0] & /*$position, dir, $offset*/ 337641472) {
- $$invalidate(31, transform = `translateX(${$position.x + dir.x * panelMargin}px) translateY(${$position.y + dir.y * panelMargin + dir.y * $offset}px)`);
- }
- if ($$self.$$.dirty[0] & /*isAnimating, $opacity*/ 1610612736 | $$self.$$.dirty[1] & /*transform*/ 1) {
- $$invalidate(6, style = isAnimating
- ? `opacity: ${$opacity}; pointer-events: ${$opacity < 1 ? "none" : "all"}; transform: ${transform};`
- : `transform: ${transform}`);
- }
- if ($$self.$$.dirty[0] & /*offsetProgress*/ 33554432) {
- $$invalidate(32, tipScale = 0.5 + offsetProgress * 0.5);
- }
- if ($$self.$$.dirty[0] & /*offsetProgress*/ 33554432) {
- $$invalidate(33, tipOpacity = offsetProgress);
- }
- if ($$self.$$.dirty[0] & /*$position, panelSize, dir, shift*/ 274726916 | $$self.$$.dirty[1] & /*tipOpacity, tipScale*/ 6) {
- $$invalidate(7, tipStyle = $position && panelSize && `opacity:${tipOpacity};transform:scaleX(${tipScale})rotate(45deg);top:${dir.y < 0 ? shift.y + panelSize.height : 0}px;left:${shift.x + panelSize.width * 0.5}px`);
- }
- if ($$self.$$.dirty[0] & /*isActive*/ 262144) {
- $$invalidate(8, handleDown = isActive
- ? e => {
- if (isTargetSelf(e)) return;
- $$invalidate(23, downOutsidePanel = true);
- }
- : undefined);
- }
- if ($$self.$$.dirty[0] & /*isVisible, detailPanel*/ 48 | $$self.$$.dirty[1] & /*$portal*/ 8) {
- if (isVisible && $portal && detailPanel && detailPanel.parentNode !== $portal) $portal.appendChild(detailPanel);
- }
- if ($$self.$$.dirty[0] & /*isActive*/ 262144) {
- if (!isActive) $$invalidate(24, trigger = undefined);
- }
- if ($$self.$$.dirty[0] & /*isVisible, detailPanel, onshow, trigger*/ 17301552) {
- if (isVisible && detailPanel) onshow({ e: trigger, panel: detailPanel });
- }
- };
- return [
- buttonClass,
- panelClass,
- panelSize,
- buttonComponent,
- detailPanel,
- isVisible,
- style,
- tipStyle,
- handleDown,
- handleUp,
- portal,
- portalRootRect,
- opacity,
- position,
- offset,
- handleClick,
- handleButtonKeydown,
- handlePanelKeydown,
- isActive,
- onshow,
- buttonRect,
- dir,
- shift,
- downOutsidePanel,
- trigger,
- offsetProgress,
- $offset,
- $portalRootRect,
- $position,
- $opacity,
- isAnimating,
- transform,
- tipScale,
- tipOpacity,
- $portal,
- slots,
- button_binding,
- div_binding,
- measure_handler,
- $$scope
- ];
- }
- class Details extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$B,
- create_fragment$B,
- safe_not_equal,
- {
- buttonClass: 0,
- panelClass: 1,
- isActive: 18,
- onshow: 19
- },
- [-1, -1]
- );
- }
- }
- /* src/core/ui/components/RadioItem.svelte generated by Svelte v3.37.0 */
- function create_fragment$A(ctx) {
- let li;
- let input;
- let t;
- let label_1;
- let li_class_value;
- let current;
- let mounted;
- let dispose;
- const default_slot_template = /*#slots*/ ctx[14].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[13], null);
- return {
- c() {
- li = element("li");
- input = element("input");
- t = space();
- label_1 = element("label");
- if (default_slot) default_slot.c();
- attr(input, "type", "radio");
- attr(input, "class", "implicit");
- attr(input, "id", /*inputId*/ ctx[6]);
- attr(input, "name", /*name*/ ctx[0]);
- input.value = /*value*/ ctx[3];
- input.disabled = /*disabled*/ ctx[5];
- input.checked = /*checked*/ ctx[4];
- attr(label_1, "for", /*inputId*/ ctx[6]);
- attr(label_1, "title", /*label*/ ctx[2]);
- attr(li, "class", li_class_value = arrayJoin(["PinturaRadioGroupOption", /*klass*/ ctx[1]]));
- attr(li, "data-disabled", /*disabled*/ ctx[5]);
- attr(li, "data-selected", /*checked*/ ctx[4]);
- },
- m(target, anchor) {
- insert(target, li, anchor);
- append(li, input);
- append(li, t);
- append(li, label_1);
- if (default_slot) {
- default_slot.m(label_1, null);
- }
- current = true;
- if (!mounted) {
- dispose = [
- listen(input, "change", stop_propagation(/*change_handler*/ ctx[15])),
- listen(input, "keydown", /*handleKeydown*/ ctx[8]),
- listen(input, "click", /*handleClick*/ ctx[9])
- ];
- mounted = true;
- }
- },
- p(ctx, [dirty]) {
- if (!current || dirty & /*inputId*/ 64) {
- attr(input, "id", /*inputId*/ ctx[6]);
- }
- if (!current || dirty & /*name*/ 1) {
- attr(input, "name", /*name*/ ctx[0]);
- }
- if (!current || dirty & /*value*/ 8) {
- input.value = /*value*/ ctx[3];
- }
- if (!current || dirty & /*disabled*/ 32) {
- input.disabled = /*disabled*/ ctx[5];
- }
- if (!current || dirty & /*checked*/ 16) {
- input.checked = /*checked*/ ctx[4];
- }
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope*/ 8192) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[13], dirty, null, null);
- }
- }
- if (!current || dirty & /*inputId*/ 64) {
- attr(label_1, "for", /*inputId*/ ctx[6]);
- }
- if (!current || dirty & /*label*/ 4) {
- attr(label_1, "title", /*label*/ ctx[2]);
- }
- if (!current || dirty & /*klass*/ 2 && li_class_value !== (li_class_value = arrayJoin(["PinturaRadioGroupOption", /*klass*/ ctx[1]]))) {
- attr(li, "class", li_class_value);
- }
- if (!current || dirty & /*disabled*/ 32) {
- attr(li, "data-disabled", /*disabled*/ ctx[5]);
- }
- if (!current || dirty & /*checked*/ 16) {
- attr(li, "data-selected", /*checked*/ ctx[4]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(li);
- if (default_slot) default_slot.d(detaching);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function instance$A($$self, $$props, $$invalidate) {
- let inputId;
- let $keysPressedStored;
- let { $$slots: slots = {}, $$scope } = $$props;
- let { name } = $$props;
- let { class: klass = undefined } = $$props;
- let { label } = $$props;
- let { id } = $$props;
- let { value } = $$props;
- let { checked } = $$props;
- let { onkeydown } = $$props;
- let { onclick } = $$props;
- let { disabled = false } = $$props;
- const keysPressedStored = getContext("keysPressed");
- component_subscribe($$self, keysPressedStored, value => $$invalidate(16, $keysPressedStored = value));
- const handleKeydown = e => {
- onkeydown(e);
- };
- const handleClick = e => {
- if ($keysPressedStored.length) return;
- onclick(e);
- };
- function change_handler(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("name" in $$props) $$invalidate(0, name = $$props.name);
- if ("class" in $$props) $$invalidate(1, klass = $$props.class);
- if ("label" in $$props) $$invalidate(2, label = $$props.label);
- if ("id" in $$props) $$invalidate(10, id = $$props.id);
- if ("value" in $$props) $$invalidate(3, value = $$props.value);
- if ("checked" in $$props) $$invalidate(4, checked = $$props.checked);
- if ("onkeydown" in $$props) $$invalidate(11, onkeydown = $$props.onkeydown);
- if ("onclick" in $$props) $$invalidate(12, onclick = $$props.onclick);
- if ("disabled" in $$props) $$invalidate(5, disabled = $$props.disabled);
- if ("$$scope" in $$props) $$invalidate(13, $$scope = $$props.$$scope);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*name, id*/ 1025) {
- $$invalidate(6, inputId = `${name}-${id}`);
- }
- };
- return [
- name,
- klass,
- label,
- value,
- checked,
- disabled,
- inputId,
- keysPressedStored,
- handleKeydown,
- handleClick,
- id,
- onkeydown,
- onclick,
- $$scope,
- slots,
- change_handler
- ];
- }
- class RadioItem extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$A, create_fragment$A, safe_not_equal, {
- name: 0,
- class: 1,
- label: 2,
- id: 10,
- value: 3,
- checked: 4,
- onkeydown: 11,
- onclick: 12,
- disabled: 5
- });
- }
- }
- var flattenOptions = (options = []) => options.reduce((prev, current) => {
- const isGroup = isArray(current) ? isArray(current[1]) : !!current.options;
- if (isGroup) {
- return prev.concat(isArray(current) ? current[1] : current.options);
- }
- prev.push(current);
- return prev;
- }, []);
- const mapOption = (option, index, optionMapper) => {
- let mappedOption;
- if (isArray(option)) {
- mappedOption = {
- id: index,
- value: option[0],
- label: option[1],
- ...(option[2] || {}),
- };
- }
- else {
- mappedOption = option;
- mappedOption.id = mappedOption.id != null ? mappedOption.id : index;
- }
- return optionMapper ? optionMapper(mappedOption) : mappedOption;
- };
- var mapOptions = (options = [], optionMapper) => {
- let index = 0;
- return options.map((option) => {
- index++;
- if (isArray(option)) {
- // is either [label, options] or [value, label]
- if (isArray(option[1])) {
- return {
- id: index,
- label: option[0],
- options: option[1].map((option) => mapOption(option, ++index, optionMapper)),
- };
- }
- return mapOption(option, index, optionMapper);
- }
- else {
- // is either { id?, label, options } or { id?, value, label }
- if (option.options) {
- return {
- id: option.id || index,
- label: option.label,
- options: option.options.map((option) => mapOption(option, ++index, optionMapper)),
- };
- }
- return mapOption(option, index, optionMapper);
- }
- });
- };
- var opop = (fn, ...args) => fn && fn(...args);
- var localize = (prop, locale, params) => isFunction(prop) ? prop(locale, params) : prop;
- const localizeOptions = (options, locale) => options.map(([value, label, props]) => {
- if (isArray(label)) {
- return [localize(value, locale), localizeOptions(label, locale)];
- }
- else {
- const res = [value, localize(label, locale)];
- if (props) {
- let obj = { ...props };
- if (props.icon)
- obj.icon = localize(props.icon, locale);
- res.push(obj);
- }
- return res;
- }
- });
- var localizeOptions$1 = (options, locale) => localizeOptions(options, locale);
- var isConfirmKey = (key) => /enter| /i.test(key);
- /* src/core/ui/components/RadioGroup.svelte generated by Svelte v3.37.0 */
- function get_each_context$7(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[26] = list[i];
- return child_ctx;
- }
- const get_option_slot_changes_1 = dirty => ({ option: dirty & /*mappedOptions*/ 2048 });
- const get_option_slot_context_1 = ctx => ({ option: /*option*/ ctx[26] });
- function get_each_context_1(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[26] = list[i];
- return child_ctx;
- }
- const get_option_slot_changes = dirty => ({ option: dirty & /*mappedOptions*/ 2048 });
- const get_option_slot_context = ctx => ({ option: /*option*/ ctx[26] });
- const get_group_slot_changes = dirty => ({ option: dirty & /*mappedOptions*/ 2048 });
- const get_group_slot_context = ctx => ({ option: /*option*/ ctx[26] });
- // (71:0) {#if localizedOptions.length}
- function create_if_block_1$a(ctx) {
- let fieldset;
- let t;
- let ul;
- let each_blocks = [];
- let each_1_lookup = new Map();
- let fieldset_class_value;
- let current;
- let if_block = /*label*/ ctx[1] && create_if_block_7$1(ctx);
- let each_value = /*mappedOptions*/ ctx[11];
- const get_key = ctx => /*option*/ ctx[26].id;
- for (let i = 0; i < each_value.length; i += 1) {
- let child_ctx = get_each_context$7(ctx, each_value, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block$7(key, child_ctx));
- }
- return {
- c() {
- fieldset = element("fieldset");
- if (if_block) if_block.c();
- t = space();
- ul = element("ul");
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- attr(ul, "class", "PinturaRadioGroupOptions");
- attr(fieldset, "class", fieldset_class_value = arrayJoin(["PinturaRadioGroup", /*klass*/ ctx[3]]));
- attr(fieldset, "data-layout", /*layout*/ ctx[5]);
- attr(fieldset, "title", /*title*/ ctx[7]);
- },
- m(target, anchor) {
- insert(target, fieldset, anchor);
- if (if_block) if_block.m(fieldset, null);
- append(fieldset, t);
- append(fieldset, ul);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].m(ul, null);
- }
- current = true;
- },
- p(ctx, dirty) {
- if (/*label*/ ctx[1]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- } else {
- if_block = create_if_block_7$1(ctx);
- if_block.c();
- if_block.m(fieldset, t);
- }
- } else if (if_block) {
- if_block.d(1);
- if_block = null;
- }
- if (dirty & /*arrayJoin, optionGroupClass, mappedOptions, name, optionClass, getOptionIndex, selectedIndex, handleRadioKeydown, handleRadioClick, optionLabelClass, $$scope*/ 8420177) {
- each_value = /*mappedOptions*/ ctx[11];
- group_outros();
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, ul, outro_and_destroy_block, create_each_block$7, null, get_each_context$7);
- check_outros();
- }
- if (!current || dirty & /*klass*/ 8 && fieldset_class_value !== (fieldset_class_value = arrayJoin(["PinturaRadioGroup", /*klass*/ ctx[3]]))) {
- attr(fieldset, "class", fieldset_class_value);
- }
- if (!current || dirty & /*layout*/ 32) {
- attr(fieldset, "data-layout", /*layout*/ ctx[5]);
- }
- if (!current || dirty & /*title*/ 128) {
- attr(fieldset, "title", /*title*/ ctx[7]);
- }
- },
- i(local) {
- if (current) return;
- for (let i = 0; i < each_value.length; i += 1) {
- transition_in(each_blocks[i]);
- }
- current = true;
- },
- o(local) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- transition_out(each_blocks[i]);
- }
- current = false;
- },
- d(detaching) {
- if (detaching) detach(fieldset);
- if (if_block) if_block.d();
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d();
- }
- }
- };
- }
- // (73:8) {#if label}
- function create_if_block_7$1(ctx) {
- let legend;
- let t;
- let legend_class_value;
- return {
- c() {
- legend = element("legend");
- t = text(/*label*/ ctx[1]);
- attr(legend, "class", legend_class_value = /*hideLabel*/ ctx[2] && "implicit");
- },
- m(target, anchor) {
- insert(target, legend, anchor);
- append(legend, t);
- },
- p(ctx, dirty) {
- if (dirty & /*label*/ 2) set_data(t, /*label*/ ctx[1]);
- if (dirty & /*hideLabel*/ 4 && legend_class_value !== (legend_class_value = /*hideLabel*/ ctx[2] && "implicit")) {
- attr(legend, "class", legend_class_value);
- }
- },
- d(detaching) {
- if (detaching) detach(legend);
- }
- };
- }
- // (108:16) {:else}
- function create_else_block$4(ctx) {
- let radioitem;
- let current;
- radioitem = new RadioItem({
- props: {
- name: /*name*/ ctx[4],
- label: /*option*/ ctx[26].label,
- id: /*option*/ ctx[26].id,
- value: /*option*/ ctx[26].value,
- disabled: /*option*/ ctx[26].disabled,
- class: /*optionClass*/ ctx[8],
- checked: /*getOptionIndex*/ ctx[12](/*option*/ ctx[26]) === /*selectedIndex*/ ctx[0],
- onkeydown: /*handleRadioKeydown*/ ctx[13](/*option*/ ctx[26]),
- onclick: /*handleRadioClick*/ ctx[14](/*option*/ ctx[26]),
- $$slots: { default: [create_default_slot_2$4] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(radioitem.$$.fragment);
- },
- m(target, anchor) {
- mount_component(radioitem, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const radioitem_changes = {};
- if (dirty & /*name*/ 16) radioitem_changes.name = /*name*/ ctx[4];
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.label = /*option*/ ctx[26].label;
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.id = /*option*/ ctx[26].id;
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.value = /*option*/ ctx[26].value;
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.disabled = /*option*/ ctx[26].disabled;
- if (dirty & /*optionClass*/ 256) radioitem_changes.class = /*optionClass*/ ctx[8];
- if (dirty & /*mappedOptions, selectedIndex*/ 2049) radioitem_changes.checked = /*getOptionIndex*/ ctx[12](/*option*/ ctx[26]) === /*selectedIndex*/ ctx[0];
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.onkeydown = /*handleRadioKeydown*/ ctx[13](/*option*/ ctx[26]);
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.onclick = /*handleRadioClick*/ ctx[14](/*option*/ ctx[26]);
- if (dirty & /*$$scope, optionLabelClass, mappedOptions*/ 8390720) {
- radioitem_changes.$$scope = { dirty, ctx };
- }
- radioitem.$set(radioitem_changes);
- },
- i(local) {
- if (current) return;
- transition_in(radioitem.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(radioitem.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(radioitem, detaching);
- }
- };
- }
- // (78:16) {#if option.options}
- function create_if_block_2$8(ctx) {
- let li;
- let t0;
- let ul;
- let each_blocks = [];
- let each_1_lookup = new Map();
- let t1;
- let li_class_value;
- let current;
- const group_slot_template = /*#slots*/ ctx[22].group;
- const group_slot = create_slot(group_slot_template, ctx, /*$$scope*/ ctx[23], get_group_slot_context);
- const group_slot_or_fallback = group_slot || fallback_block_1(ctx);
- let each_value_1 = /*option*/ ctx[26].options;
- const get_key = ctx => /*option*/ ctx[26].id;
- for (let i = 0; i < each_value_1.length; i += 1) {
- let child_ctx = get_each_context_1(ctx, each_value_1, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block_1(key, child_ctx));
- }
- return {
- c() {
- li = element("li");
- if (group_slot_or_fallback) group_slot_or_fallback.c();
- t0 = space();
- ul = element("ul");
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- t1 = space();
- attr(ul, "class", "PinturaRadioGroupOptions");
- attr(li, "class", li_class_value = arrayJoin(["PinturaRadioGroupOptionGroup", /*optionGroupClass*/ ctx[9]]));
- },
- m(target, anchor) {
- insert(target, li, anchor);
- if (group_slot_or_fallback) {
- group_slot_or_fallback.m(li, null);
- }
- append(li, t0);
- append(li, ul);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].m(ul, null);
- }
- append(li, t1);
- current = true;
- },
- p(ctx, dirty) {
- if (group_slot) {
- if (group_slot.p && dirty & /*$$scope, mappedOptions*/ 8390656) {
- update_slot(group_slot, group_slot_template, ctx, /*$$scope*/ ctx[23], dirty, get_group_slot_changes, get_group_slot_context);
- }
- } else {
- if (group_slot_or_fallback && group_slot_or_fallback.p && dirty & /*mappedOptions*/ 2048) {
- group_slot_or_fallback.p(ctx, dirty);
- }
- }
- if (dirty & /*name, mappedOptions, optionClass, getOptionIndex, selectedIndex, handleRadioKeydown, handleRadioClick, optionLabelClass, $$scope*/ 8419665) {
- each_value_1 = /*option*/ ctx[26].options;
- group_outros();
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value_1, each_1_lookup, ul, outro_and_destroy_block, create_each_block_1, null, get_each_context_1);
- check_outros();
- }
- if (!current || dirty & /*optionGroupClass*/ 512 && li_class_value !== (li_class_value = arrayJoin(["PinturaRadioGroupOptionGroup", /*optionGroupClass*/ ctx[9]]))) {
- attr(li, "class", li_class_value);
- }
- },
- i(local) {
- if (current) return;
- transition_in(group_slot_or_fallback, local);
- for (let i = 0; i < each_value_1.length; i += 1) {
- transition_in(each_blocks[i]);
- }
- current = true;
- },
- o(local) {
- transition_out(group_slot_or_fallback, local);
- for (let i = 0; i < each_blocks.length; i += 1) {
- transition_out(each_blocks[i]);
- }
- current = false;
- },
- d(detaching) {
- if (detaching) detach(li);
- if (group_slot_or_fallback) group_slot_or_fallback.d(detaching);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d();
- }
- }
- };
- }
- // (120:28) {#if option.icon}
- function create_if_block_6$2(ctx) {
- let icon;
- let current;
- icon = new Icon({
- props: {
- $$slots: { default: [create_default_slot_3$2] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(icon.$$.fragment);
- },
- m(target, anchor) {
- mount_component(icon, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const icon_changes = {};
- if (dirty & /*$$scope, mappedOptions*/ 8390656) {
- icon_changes.$$scope = { dirty, ctx };
- }
- icon.$set(icon_changes);
- },
- i(local) {
- if (current) return;
- transition_in(icon.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(icon, detaching);
- }
- };
- }
- // (121:32) <Icon>
- function create_default_slot_3$2(ctx) {
- let g;
- let raw_value = /*option*/ ctx[26].icon + "";
- return {
- c() {
- g = svg_element("g");
- },
- m(target, anchor) {
- insert(target, g, anchor);
- g.innerHTML = raw_value;
- },
- p(ctx, dirty) {
- if (dirty & /*mappedOptions*/ 2048 && raw_value !== (raw_value = /*option*/ ctx[26].icon + "")) g.innerHTML = raw_value; },
- d(detaching) {
- if (detaching) detach(g);
- }
- };
- }
- // (123:28) {#if !option.hideLabel}
- function create_if_block_5$4(ctx) {
- let span;
- let t_value = /*option*/ ctx[26].label + "";
- let t;
- return {
- c() {
- span = element("span");
- t = text(t_value);
- attr(span, "class", /*optionLabelClass*/ ctx[6]);
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- },
- p(ctx, dirty) {
- if (dirty & /*mappedOptions*/ 2048 && t_value !== (t_value = /*option*/ ctx[26].label + "")) set_data(t, t_value);
- if (dirty & /*optionLabelClass*/ 64) {
- attr(span, "class", /*optionLabelClass*/ ctx[6]);
- }
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- // (119:54)
- function fallback_block_2(ctx) {
- let t0;
- let t1;
- let current;
- let if_block0 = /*option*/ ctx[26].icon && create_if_block_6$2(ctx);
- let if_block1 = !/*option*/ ctx[26].hideLabel && create_if_block_5$4(ctx);
- return {
- c() {
- if (if_block0) if_block0.c();
- t0 = space();
- if (if_block1) if_block1.c();
- t1 = space();
- },
- m(target, anchor) {
- if (if_block0) if_block0.m(target, anchor);
- insert(target, t0, anchor);
- if (if_block1) if_block1.m(target, anchor);
- insert(target, t1, anchor);
- current = true;
- },
- p(ctx, dirty) {
- if (/*option*/ ctx[26].icon) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty & /*mappedOptions*/ 2048) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_6$2(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(t0.parentNode, t0);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (!/*option*/ ctx[26].hideLabel) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- } else {
- if_block1 = create_if_block_5$4(ctx);
- if_block1.c();
- if_block1.m(t1.parentNode, t1);
- }
- } else if (if_block1) {
- if_block1.d(1);
- if_block1 = null;
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- current = false;
- },
- d(detaching) {
- if (if_block0) if_block0.d(detaching);
- if (detaching) detach(t0);
- if (if_block1) if_block1.d(detaching);
- if (detaching) detach(t1);
- }
- };
- }
- // (109:20) <RadioItem {name} label={option.label} id={option.id} value={option.value} disabled={option.disabled} class={optionClass} checked={getOptionIndex(option) === selectedIndex} onkeydown={handleRadioKeydown(option)} onclick={handleRadioClick(option)} >
- function create_default_slot_2$4(ctx) {
- let current;
- const option_slot_template = /*#slots*/ ctx[22].option;
- const option_slot = create_slot(option_slot_template, ctx, /*$$scope*/ ctx[23], get_option_slot_context_1);
- const option_slot_or_fallback = option_slot || fallback_block_2(ctx);
- return {
- c() {
- if (option_slot_or_fallback) option_slot_or_fallback.c();
- },
- m(target, anchor) {
- if (option_slot_or_fallback) {
- option_slot_or_fallback.m(target, anchor);
- }
- current = true;
- },
- p(ctx, dirty) {
- if (option_slot) {
- if (option_slot.p && dirty & /*$$scope, mappedOptions*/ 8390656) {
- update_slot(option_slot, option_slot_template, ctx, /*$$scope*/ ctx[23], dirty, get_option_slot_changes_1, get_option_slot_context_1);
- }
- } else {
- if (option_slot_or_fallback && option_slot_or_fallback.p && dirty & /*optionLabelClass, mappedOptions*/ 2112) {
- option_slot_or_fallback.p(ctx, dirty);
- }
- }
- },
- i(local) {
- if (current) return;
- transition_in(option_slot_or_fallback, local);
- current = true;
- },
- o(local) {
- transition_out(option_slot_or_fallback, local);
- current = false;
- },
- d(detaching) {
- if (option_slot_or_fallback) option_slot_or_fallback.d(detaching);
- }
- };
- }
- // (81:29) <span class="PinturaRadioGroupOptionGroupLabel">
- function fallback_block_1(ctx) {
- let span;
- let t_value = /*option*/ ctx[26].label + "";
- let t;
- return {
- c() {
- span = element("span");
- t = text(t_value);
- attr(span, "class", "PinturaRadioGroupOptionGroupLabel");
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- },
- p(ctx, dirty) {
- if (dirty & /*mappedOptions*/ 2048 && t_value !== (t_value = /*option*/ ctx[26].label + "")) set_data(t, t_value);
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- // (97:40) {#if option.icon}
- function create_if_block_4$5(ctx) {
- let icon;
- let current;
- icon = new Icon({
- props: {
- $$slots: { default: [create_default_slot_1$7] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(icon.$$.fragment);
- },
- m(target, anchor) {
- mount_component(icon, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const icon_changes = {};
- if (dirty & /*$$scope, mappedOptions*/ 8390656) {
- icon_changes.$$scope = { dirty, ctx };
- }
- icon.$set(icon_changes);
- },
- i(local) {
- if (current) return;
- transition_in(icon.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(icon, detaching);
- }
- };
- }
- // (98:44) <Icon>
- function create_default_slot_1$7(ctx) {
- let g;
- let raw_value = /*option*/ ctx[26].icon + "";
- return {
- c() {
- g = svg_element("g");
- },
- m(target, anchor) {
- insert(target, g, anchor);
- g.innerHTML = raw_value;
- },
- p(ctx, dirty) {
- if (dirty & /*mappedOptions*/ 2048 && raw_value !== (raw_value = /*option*/ ctx[26].icon + "")) g.innerHTML = raw_value; },
- d(detaching) {
- if (detaching) detach(g);
- }
- };
- }
- // (100:40) {#if !option.hideLabel}
- function create_if_block_3$6(ctx) {
- let span;
- let t_value = /*option*/ ctx[26].label + "";
- let t;
- return {
- c() {
- span = element("span");
- t = text(t_value);
- attr(span, "class", /*optionLabelClass*/ ctx[6]);
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- },
- p(ctx, dirty) {
- if (dirty & /*mappedOptions*/ 2048 && t_value !== (t_value = /*option*/ ctx[26].label + "")) set_data(t, t_value);
- if (dirty & /*optionLabelClass*/ 64) {
- attr(span, "class", /*optionLabelClass*/ ctx[6]);
- }
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- // (96:66)
- function fallback_block$1(ctx) {
- let t0;
- let t1;
- let current;
- let if_block0 = /*option*/ ctx[26].icon && create_if_block_4$5(ctx);
- let if_block1 = !/*option*/ ctx[26].hideLabel && create_if_block_3$6(ctx);
- return {
- c() {
- if (if_block0) if_block0.c();
- t0 = space();
- if (if_block1) if_block1.c();
- t1 = space();
- },
- m(target, anchor) {
- if (if_block0) if_block0.m(target, anchor);
- insert(target, t0, anchor);
- if (if_block1) if_block1.m(target, anchor);
- insert(target, t1, anchor);
- current = true;
- },
- p(ctx, dirty) {
- if (/*option*/ ctx[26].icon) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty & /*mappedOptions*/ 2048) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_4$5(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(t0.parentNode, t0);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (!/*option*/ ctx[26].hideLabel) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- } else {
- if_block1 = create_if_block_3$6(ctx);
- if_block1.c();
- if_block1.m(t1.parentNode, t1);
- }
- } else if (if_block1) {
- if_block1.d(1);
- if_block1 = null;
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- current = false;
- },
- d(detaching) {
- if (if_block0) if_block0.d(detaching);
- if (detaching) detach(t0);
- if (if_block1) if_block1.d(detaching);
- if (detaching) detach(t1);
- }
- };
- }
- // (86:32) <RadioItem {name} label={option.label} id={option.id} value={option.value} disabled={option.disabled} class={optionClass} checked={getOptionIndex(option) === selectedIndex} onkeydown={handleRadioKeydown(option)} onclick={handleRadioClick(option)} >
- function create_default_slot$f(ctx) {
- let current;
- const option_slot_template = /*#slots*/ ctx[22].option;
- const option_slot = create_slot(option_slot_template, ctx, /*$$scope*/ ctx[23], get_option_slot_context);
- const option_slot_or_fallback = option_slot || fallback_block$1(ctx);
- return {
- c() {
- if (option_slot_or_fallback) option_slot_or_fallback.c();
- },
- m(target, anchor) {
- if (option_slot_or_fallback) {
- option_slot_or_fallback.m(target, anchor);
- }
- current = true;
- },
- p(ctx, dirty) {
- if (option_slot) {
- if (option_slot.p && dirty & /*$$scope, mappedOptions*/ 8390656) {
- update_slot(option_slot, option_slot_template, ctx, /*$$scope*/ ctx[23], dirty, get_option_slot_changes, get_option_slot_context);
- }
- } else {
- if (option_slot_or_fallback && option_slot_or_fallback.p && dirty & /*optionLabelClass, mappedOptions*/ 2112) {
- option_slot_or_fallback.p(ctx, dirty);
- }
- }
- },
- i(local) {
- if (current) return;
- transition_in(option_slot_or_fallback, local);
- current = true;
- },
- o(local) {
- transition_out(option_slot_or_fallback, local);
- current = false;
- },
- d(detaching) {
- if (option_slot_or_fallback) option_slot_or_fallback.d(detaching);
- }
- };
- }
- // (85:28) {#each option.options as option (option.id)}
- function create_each_block_1(key_1, ctx) {
- let first;
- let radioitem;
- let current;
- radioitem = new RadioItem({
- props: {
- name: /*name*/ ctx[4],
- label: /*option*/ ctx[26].label,
- id: /*option*/ ctx[26].id,
- value: /*option*/ ctx[26].value,
- disabled: /*option*/ ctx[26].disabled,
- class: /*optionClass*/ ctx[8],
- checked: /*getOptionIndex*/ ctx[12](/*option*/ ctx[26]) === /*selectedIndex*/ ctx[0],
- onkeydown: /*handleRadioKeydown*/ ctx[13](/*option*/ ctx[26]),
- onclick: /*handleRadioClick*/ ctx[14](/*option*/ ctx[26]),
- $$slots: { default: [create_default_slot$f] },
- $$scope: { ctx }
- }
- });
- return {
- key: key_1,
- first: null,
- c() {
- first = empty();
- create_component(radioitem.$$.fragment);
- this.first = first;
- },
- m(target, anchor) {
- insert(target, first, anchor);
- mount_component(radioitem, target, anchor);
- current = true;
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- const radioitem_changes = {};
- if (dirty & /*name*/ 16) radioitem_changes.name = /*name*/ ctx[4];
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.label = /*option*/ ctx[26].label;
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.id = /*option*/ ctx[26].id;
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.value = /*option*/ ctx[26].value;
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.disabled = /*option*/ ctx[26].disabled;
- if (dirty & /*optionClass*/ 256) radioitem_changes.class = /*optionClass*/ ctx[8];
- if (dirty & /*mappedOptions, selectedIndex*/ 2049) radioitem_changes.checked = /*getOptionIndex*/ ctx[12](/*option*/ ctx[26]) === /*selectedIndex*/ ctx[0];
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.onkeydown = /*handleRadioKeydown*/ ctx[13](/*option*/ ctx[26]);
- if (dirty & /*mappedOptions*/ 2048) radioitem_changes.onclick = /*handleRadioClick*/ ctx[14](/*option*/ ctx[26]);
- if (dirty & /*$$scope, optionLabelClass, mappedOptions*/ 8390720) {
- radioitem_changes.$$scope = { dirty, ctx };
- }
- radioitem.$set(radioitem_changes);
- },
- i(local) {
- if (current) return;
- transition_in(radioitem.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(radioitem.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(first);
- destroy_component(radioitem, detaching);
- }
- };
- }
- // (77:12) {#each mappedOptions as option (option.id)}
- function create_each_block$7(key_1, ctx) {
- let first;
- let current_block_type_index;
- let if_block;
- let if_block_anchor;
- let current;
- const if_block_creators = [create_if_block_2$8, create_else_block$4];
- const if_blocks = [];
- function select_block_type(ctx, dirty) {
- if (/*option*/ ctx[26].options) return 0;
- return 1;
- }
- current_block_type_index = select_block_type(ctx);
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- return {
- key: key_1,
- first: null,
- c() {
- first = empty();
- if_block.c();
- if_block_anchor = empty();
- this.first = first;
- },
- m(target, anchor) {
- insert(target, first, anchor);
- if_blocks[current_block_type_index].m(target, anchor);
- insert(target, if_block_anchor, anchor);
- current = true;
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type(ctx);
- if (current_block_type_index === previous_block_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- } else {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- if_block = if_blocks[current_block_type_index];
- if (!if_block) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block.c();
- } else {
- if_block.p(ctx, dirty);
- }
- transition_in(if_block, 1);
- if_block.m(if_block_anchor.parentNode, if_block_anchor);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(first);
- if_blocks[current_block_type_index].d(detaching);
- if (detaching) detach(if_block_anchor);
- }
- };
- }
- function create_fragment$z(ctx) {
- let t;
- let if_block1_anchor;
- let current;
- let if_block0 = /*localizedOptions*/ ctx[10].length && create_if_block_1$a(ctx);
- let if_block1 = false ;
- return {
- c() {
- if (if_block0) if_block0.c();
- t = space();
- if_block1_anchor = empty();
- },
- m(target, anchor) {
- if (if_block0) if_block0.m(target, anchor);
- insert(target, t, anchor);
- insert(target, if_block1_anchor, anchor);
- current = true;
- },
- p(ctx, [dirty]) {
- if (/*localizedOptions*/ ctx[10].length) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty & /*localizedOptions*/ 1024) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_1$a(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(t.parentNode, t);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- transition_in(if_block1);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- transition_out(if_block1);
- current = false;
- },
- d(detaching) {
- if (if_block0) if_block0.d(detaching);
- if (detaching) detach(t);
- if (detaching) detach(if_block1_anchor);
- }
- };
- }
- function instance$z($$self, $$props, $$invalidate) {
- let localizedOptions;
- let mappedOptions;
- let flattenedOptions;
- let { $$slots: slots = {}, $$scope } = $$props;
- const dispatch = createEventDispatcher();
- let { label = undefined } = $$props;
- let { hideLabel = true } = $$props;
- let { class: klass = undefined } = $$props;
- let { name = `radio-group-${getUniqueId()}` } = $$props;
- let { selectedIndex = -1 } = $$props;
- let { options = [] } = $$props;
- let { onchange = undefined } = $$props;
- let { layout = undefined } = $$props;
- let { optionMapper = undefined } = $$props;
- let { optionFilter = undefined } = $$props;
- let { value = undefined } = $$props;
- let { optionLabelClass = undefined } = $$props;
- let { title = undefined } = $$props;
- let { locale = undefined } = $$props;
- let { optionClass = undefined } = $$props;
- let { optionGroupClass = undefined } = $$props;
- const getOptionIndex = option => flattenedOptions.findIndex(flattenedOption => flattenedOption.id === option.id);
- const changeSelection = (option, e) => {
- $$invalidate(0, selectedIndex = getOptionIndex(option));
- const payload = { index: selectedIndex, ...option };
- opop(onchange, payload, e);
- dispatch("change", payload);
- };
- const handleRadioKeydown = option => e => {
- // is confirm key ([enter] or [space])
- if (!isConfirmKey(e.key)) return;
- changeSelection(option, e);
- };
- const handleRadioClick = option => e => {
- changeSelection(option, e);
- };
- $$self.$$set = $$props => {
- if ("label" in $$props) $$invalidate(1, label = $$props.label);
- if ("hideLabel" in $$props) $$invalidate(2, hideLabel = $$props.hideLabel);
- if ("class" in $$props) $$invalidate(3, klass = $$props.class);
- if ("name" in $$props) $$invalidate(4, name = $$props.name);
- if ("selectedIndex" in $$props) $$invalidate(0, selectedIndex = $$props.selectedIndex);
- if ("options" in $$props) $$invalidate(15, options = $$props.options);
- if ("onchange" in $$props) $$invalidate(16, onchange = $$props.onchange);
- if ("layout" in $$props) $$invalidate(5, layout = $$props.layout);
- if ("optionMapper" in $$props) $$invalidate(17, optionMapper = $$props.optionMapper);
- if ("optionFilter" in $$props) $$invalidate(18, optionFilter = $$props.optionFilter);
- if ("value" in $$props) $$invalidate(19, value = $$props.value);
- if ("optionLabelClass" in $$props) $$invalidate(6, optionLabelClass = $$props.optionLabelClass);
- if ("title" in $$props) $$invalidate(7, title = $$props.title);
- if ("locale" in $$props) $$invalidate(20, locale = $$props.locale);
- if ("optionClass" in $$props) $$invalidate(8, optionClass = $$props.optionClass);
- if ("optionGroupClass" in $$props) $$invalidate(9, optionGroupClass = $$props.optionGroupClass);
- if ("$$scope" in $$props) $$invalidate(23, $$scope = $$props.$$scope);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*optionFilter, options, locale*/ 1343488) {
- $$invalidate(10, localizedOptions = localizeOptions$1(optionFilter ? options.filter(optionFilter) : options, locale));
- }
- if ($$self.$$.dirty & /*localizedOptions, optionMapper*/ 132096) {
- $$invalidate(11, mappedOptions = mapOptions(localizedOptions, optionMapper));
- }
- if ($$self.$$.dirty & /*mappedOptions*/ 2048) {
- $$invalidate(21, flattenedOptions = flattenOptions(mappedOptions));
- }
- if ($$self.$$.dirty & /*value, selectedIndex, flattenedOptions*/ 2621441) {
- // can optionally pass value to have radio button group try to auto-select the right option
- if (value && selectedIndex < 0) {
- $$invalidate(0, selectedIndex = flattenedOptions.findIndex(option => option.value === value));
- }
- }
- };
- return [
- selectedIndex,
- label,
- hideLabel,
- klass,
- name,
- layout,
- optionLabelClass,
- title,
- optionClass,
- optionGroupClass,
- localizedOptions,
- mappedOptions,
- getOptionIndex,
- handleRadioKeydown,
- handleRadioClick,
- options,
- onchange,
- optionMapper,
- optionFilter,
- value,
- locale,
- flattenedOptions,
- slots,
- $$scope
- ];
- }
- class RadioGroup extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$z, create_fragment$z, safe_not_equal, {
- label: 1,
- hideLabel: 2,
- class: 3,
- name: 4,
- selectedIndex: 0,
- options: 15,
- onchange: 16,
- layout: 5,
- optionMapper: 17,
- optionFilter: 18,
- value: 19,
- optionLabelClass: 6,
- title: 7,
- locale: 20,
- optionClass: 8,
- optionGroupClass: 9
- });
- }
- }
- var isDeepEqual = (a, b) => {
- if (Array.isArray(a) && Array.isArray(b))
- return arrayEqual(a, b);
- return a === b;
- };
- /* src/core/ui/components/Dropdown.svelte generated by Svelte v3.37.0 */
- function create_if_block_1$9(ctx) {
- let icon_1;
- let current;
- icon_1 = new Icon({
- props: {
- class: "PinturaButtonIcon",
- $$slots: { default: [create_default_slot_1$6] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(icon_1.$$.fragment);
- },
- m(target, anchor) {
- mount_component(icon_1, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const icon_1_changes = {};
- if (dirty & /*$$scope, icon*/ 536870976) {
- icon_1_changes.$$scope = { dirty, ctx };
- }
- icon_1.$set(icon_1_changes);
- },
- i(local) {
- if (current) return;
- transition_in(icon_1.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon_1.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(icon_1, detaching);
- }
- };
- }
- // (95:12) <Icon class="PinturaButtonIcon">
- function create_default_slot_1$6(ctx) {
- let g;
- return {
- c() {
- g = svg_element("g");
- },
- m(target, anchor) {
- insert(target, g, anchor);
- g.innerHTML = /*icon*/ ctx[6];
- },
- p(ctx, dirty) {
- if (dirty & /*icon*/ 64) g.innerHTML = /*icon*/ ctx[6]; },
- d(detaching) {
- if (detaching) detach(g);
- }
- };
- }
- // (89:4)
- function create_label_slot$2(ctx) {
- let span1;
- let t0;
- let span0;
- let t1_value = (/*label*/ ctx[2] || /*selectedLabel*/ ctx[18]) + "";
- let t1;
- let span0_class_value;
- let span1_title_value;
- let span1_class_value;
- let current;
- let if_block = /*icon*/ ctx[6] && create_if_block_1$9(ctx);
- return {
- c() {
- span1 = element("span");
- if (if_block) if_block.c();
- t0 = space();
- span0 = element("span");
- t1 = text(t1_value);
- attr(span0, "class", span0_class_value = arrayJoin([
- "PinturaButtonLabel",
- /*labelClass*/ ctx[3],
- /*hideLabel*/ ctx[5] && "implicit"
- ]));
- attr(span1, "slot", "label");
- attr(span1, "title", span1_title_value = localize(/*title*/ ctx[1], /*locale*/ ctx[15]));
- attr(span1, "class", span1_class_value = arrayJoin(["PinturaButtonInner", /*innerClass*/ ctx[4]]));
- },
- m(target, anchor) {
- insert(target, span1, anchor);
- if (if_block) if_block.m(span1, null);
- append(span1, t0);
- append(span1, span0);
- append(span0, t1);
- current = true;
- },
- p(ctx, dirty) {
- if (/*icon*/ ctx[6]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty & /*icon*/ 64) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block_1$9(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(span1, t0);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- if ((!current || dirty & /*label, selectedLabel*/ 262148) && t1_value !== (t1_value = (/*label*/ ctx[2] || /*selectedLabel*/ ctx[18]) + "")) set_data(t1, t1_value);
- if (!current || dirty & /*labelClass, hideLabel*/ 40 && span0_class_value !== (span0_class_value = arrayJoin([
- "PinturaButtonLabel",
- /*labelClass*/ ctx[3],
- /*hideLabel*/ ctx[5] && "implicit"
- ]))) {
- attr(span0, "class", span0_class_value);
- }
- if (!current || dirty & /*title, locale*/ 32770 && span1_title_value !== (span1_title_value = localize(/*title*/ ctx[1], /*locale*/ ctx[15]))) {
- attr(span1, "title", span1_title_value);
- }
- if (!current || dirty & /*innerClass*/ 16 && span1_class_value !== (span1_class_value = arrayJoin(["PinturaButtonInner", /*innerClass*/ ctx[4]]))) {
- attr(span1, "class", span1_class_value);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(span1);
- if (if_block) if_block.d();
- }
- };
- }
- // (116:12)
- function create_group_slot$1(ctx) {
- let span;
- let t_value = /*option*/ ctx[28].label + "";
- let t;
- return {
- c() {
- span = element("span");
- t = text(t_value);
- attr(span, "slot", "group");
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- },
- p(ctx, dirty) {
- if (dirty & /*option*/ 268435456 && t_value !== (t_value = /*option*/ ctx[28].label + "")) set_data(t, t_value);
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- // (118:16) {#if option.icon}
- function create_if_block$a(ctx) {
- let icon_1;
- let current;
- icon_1 = new Icon({
- props: {
- style: isFunction(/*optionIconStyle*/ ctx[13])
- ? /*optionIconStyle*/ ctx[13](/*option*/ ctx[28].value)
- : /*optionIconStyle*/ ctx[13],
- $$slots: { default: [create_default_slot$e] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(icon_1.$$.fragment);
- },
- m(target, anchor) {
- mount_component(icon_1, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const icon_1_changes = {};
- if (dirty & /*optionIconStyle, option*/ 268443648) icon_1_changes.style = isFunction(/*optionIconStyle*/ ctx[13])
- ? /*optionIconStyle*/ ctx[13](/*option*/ ctx[28].value)
- : /*optionIconStyle*/ ctx[13];
- if (dirty & /*$$scope, option*/ 805306368) {
- icon_1_changes.$$scope = { dirty, ctx };
- }
- icon_1.$set(icon_1_changes);
- },
- i(local) {
- if (current) return;
- transition_in(icon_1.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon_1.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(icon_1, detaching);
- }
- };
- }
- // (119:20) <Icon style={isFunction(optionIconStyle) ? optionIconStyle(option.value) : optionIconStyle}>
- function create_default_slot$e(ctx) {
- let g;
- let raw_value = /*option*/ ctx[28].icon + "";
- return {
- c() {
- g = svg_element("g");
- },
- m(target, anchor) {
- insert(target, g, anchor);
- g.innerHTML = raw_value;
- },
- p(ctx, dirty) {
- if (dirty & /*option*/ 268435456 && raw_value !== (raw_value = /*option*/ ctx[28].icon + "")) g.innerHTML = raw_value; },
- d(detaching) {
- if (detaching) detach(g);
- }
- };
- }
- // (117:12)
- function create_option_slot$4(ctx) {
- let span1;
- let t0;
- let span0;
- let t1_value = /*option*/ ctx[28].label + "";
- let t1;
- let span0_style_value;
- let span0_class_value;
- let current;
- let if_block = /*option*/ ctx[28].icon && create_if_block$a(ctx);
- return {
- c() {
- span1 = element("span");
- if (if_block) if_block.c();
- t0 = space();
- span0 = element("span");
- t1 = text(t1_value);
- attr(span0, "style", span0_style_value = isFunction(/*optionLabelStyle*/ ctx[14])
- ? /*optionLabelStyle*/ ctx[14](/*option*/ ctx[28].value)
- : /*optionLabelStyle*/ ctx[14]);
- attr(span0, "class", span0_class_value = arrayJoin(["PinturaDropdownOptionLabel", /*optionLabelClass*/ ctx[10]]));
- attr(span1, "slot", "option");
- },
- m(target, anchor) {
- insert(target, span1, anchor);
- if (if_block) if_block.m(span1, null);
- append(span1, t0);
- append(span1, span0);
- append(span0, t1);
- current = true;
- },
- p(ctx, dirty) {
- if (/*option*/ ctx[28].icon) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty & /*option*/ 268435456) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block$a(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(span1, t0);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- if ((!current || dirty & /*option*/ 268435456) && t1_value !== (t1_value = /*option*/ ctx[28].label + "")) set_data(t1, t1_value);
- if (!current || dirty & /*optionLabelStyle, option*/ 268451840 && span0_style_value !== (span0_style_value = isFunction(/*optionLabelStyle*/ ctx[14])
- ? /*optionLabelStyle*/ ctx[14](/*option*/ ctx[28].value)
- : /*optionLabelStyle*/ ctx[14])) {
- attr(span0, "style", span0_style_value);
- }
- if (!current || dirty & /*optionLabelClass*/ 1024 && span0_class_value !== (span0_class_value = arrayJoin(["PinturaDropdownOptionLabel", /*optionLabelClass*/ ctx[10]]))) {
- attr(span0, "class", span0_class_value);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(span1);
- if (if_block) if_block.d();
- }
- };
- }
- // (102:4)
- function create_details_slot$2(ctx) {
- let div;
- let radiogroup;
- let current;
- let mounted;
- let dispose;
- radiogroup = new RadioGroup({
- props: {
- name: /*name*/ ctx[7],
- value: /*value*/ ctx[9],
- selectedIndex: /*selectedIndex*/ ctx[8],
- optionFilter: /*optionFilter*/ ctx[11],
- optionMapper: /*optionMapper*/ ctx[12],
- optionLabelClass: arrayJoin(["PinturaDropdownOptionLabel", /*optionLabelClass*/ ctx[10]]),
- optionGroupClass: "PinturaDropdownOptionGroup",
- optionClass: "PinturaDropdownOption",
- options: /*localizedOptions*/ ctx[16],
- onchange: /*handleSelect*/ ctx[19],
- $$slots: {
- option: [
- create_option_slot$4,
- ({ option }) => ({ 28: option }),
- ({ option }) => option ? 268435456 : 0
- ],
- group: [
- create_group_slot$1,
- ({ option }) => ({ 28: option }),
- ({ option }) => option ? 268435456 : 0
- ]
- },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- div = element("div");
- create_component(radiogroup.$$.fragment);
- attr(div, "class", "PinturaDropdownPanel");
- attr(div, "slot", "details");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(radiogroup, div, null);
- current = true;
- if (!mounted) {
- dispose = listen(div, "keydown", /*handleKeydown*/ ctx[21]);
- mounted = true;
- }
- },
- p(ctx, dirty) {
- const radiogroup_changes = {};
- if (dirty & /*name*/ 128) radiogroup_changes.name = /*name*/ ctx[7];
- if (dirty & /*value*/ 512) radiogroup_changes.value = /*value*/ ctx[9];
- if (dirty & /*selectedIndex*/ 256) radiogroup_changes.selectedIndex = /*selectedIndex*/ ctx[8];
- if (dirty & /*optionFilter*/ 2048) radiogroup_changes.optionFilter = /*optionFilter*/ ctx[11];
- if (dirty & /*optionMapper*/ 4096) radiogroup_changes.optionMapper = /*optionMapper*/ ctx[12];
- if (dirty & /*optionLabelClass*/ 1024) radiogroup_changes.optionLabelClass = arrayJoin(["PinturaDropdownOptionLabel", /*optionLabelClass*/ ctx[10]]);
- if (dirty & /*localizedOptions*/ 65536) radiogroup_changes.options = /*localizedOptions*/ ctx[16];
- if (dirty & /*$$scope, optionLabelStyle, option, optionLabelClass, optionIconStyle*/ 805331968) {
- radiogroup_changes.$$scope = { dirty, ctx };
- }
- radiogroup.$set(radiogroup_changes);
- },
- i(local) {
- if (current) return;
- transition_in(radiogroup.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(radiogroup.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(radiogroup);
- mounted = false;
- dispose();
- }
- };
- }
- function create_fragment$y(ctx) {
- let details;
- let updating_isActive;
- let current;
- function details_isActive_binding(value) {
- /*details_isActive_binding*/ ctx[26](value);
- }
- let details_props = {
- onshow: /*handleShowPanel*/ ctx[20],
- buttonClass: arrayJoin([
- "PinturaDropdownButton",
- /*klass*/ ctx[0],
- /*hideLabel*/ ctx[5] && "PinturaDropdownIconOnly"
- ]),
- $$slots: {
- details: [create_details_slot$2],
- label: [create_label_slot$2]
- },
- $$scope: { ctx }
- };
- if (/*dropdownVisible*/ ctx[17] !== void 0) {
- details_props.isActive = /*dropdownVisible*/ ctx[17];
- }
- details = new Details({ props: details_props });
- binding_callbacks.push(() => bind(details, "isActive", details_isActive_binding));
- return {
- c() {
- create_component(details.$$.fragment);
- },
- m(target, anchor) {
- mount_component(details, target, anchor);
- current = true;
- },
- p(ctx, [dirty]) {
- const details_changes = {};
- if (dirty & /*klass, hideLabel*/ 33) details_changes.buttonClass = arrayJoin([
- "PinturaDropdownButton",
- /*klass*/ ctx[0],
- /*hideLabel*/ ctx[5] && "PinturaDropdownIconOnly"
- ]);
- if (dirty & /*$$scope, name, value, selectedIndex, optionFilter, optionMapper, optionLabelClass, localizedOptions, optionLabelStyle, optionIconStyle, title, locale, innerClass, labelClass, hideLabel, label, selectedLabel, icon*/ 537264126) {
- details_changes.$$scope = { dirty, ctx };
- }
- if (!updating_isActive && dirty & /*dropdownVisible*/ 131072) {
- updating_isActive = true;
- details_changes.isActive = /*dropdownVisible*/ ctx[17];
- add_flush_callback(() => updating_isActive = false);
- }
- details.$set(details_changes);
- },
- i(local) {
- if (current) return;
- transition_in(details.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(details.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(details, detaching);
- }
- };
- }
- function instance$y($$self, $$props, $$invalidate) {
- let localizedOptions;
- let selectedLabel;
- let { class: klass = undefined } = $$props;
- let { title = undefined } = $$props;
- let { label = undefined } = $$props;
- let { labelClass = undefined } = $$props;
- let { innerClass = undefined } = $$props;
- let { hideLabel = false } = $$props;
- let { icon = undefined } = $$props;
- let { name = undefined } = $$props;
- let { options = [] } = $$props;
- let { selectedIndex = -1 } = $$props;
- let { value = undefined } = $$props;
- let { optionLabelClass = undefined } = $$props;
- let { optionFilter = undefined } = $$props;
- let { optionMapper = undefined } = $$props;
- let { optionIconStyle = undefined } = $$props;
- let { optionLabelStyle = undefined } = $$props;
- let { locale = undefined } = $$props;
- let { onchange = noop$1 } = $$props;
- let { onload = noop$1 } = $$props;
- let { ondestroy = noop$1 } = $$props;
- const getUndefinedOptionLabel = options => {
- const option = options.find(option => option[0] === undefined);
- if (!option) return undefined;
- return option[1];
- };
- let dropdownVisible;
- const handleSelect = detail => {
- // triggers label update
- $$invalidate(18, selectedLabel = detail.value);
- // update value
- onchange(detail);
- // hide details
- $$invalidate(17, dropdownVisible = false);
- };
- const handleShowPanel = ({ e, panel }) => {
- if (e && e.key && (/up|down/i).test(e.key)) return panel.querySelector("input:not([disabled])").focus();
- panel.querySelector("fieldset").focus();
- };
- const handleKeydown = e => {
- // don't allow tabbing ([tab] is also blocked in normal <select>)
- if ((/tab/i).test(e.key)) e.preventDefault();
- };
- onMount(() => onload({ options }));
- onDestroy(() => ondestroy({ options }));
- function details_isActive_binding(value) {
- dropdownVisible = value;
- $$invalidate(17, dropdownVisible);
- }
- $$self.$$set = $$props => {
- if ("class" in $$props) $$invalidate(0, klass = $$props.class);
- if ("title" in $$props) $$invalidate(1, title = $$props.title);
- if ("label" in $$props) $$invalidate(2, label = $$props.label);
- if ("labelClass" in $$props) $$invalidate(3, labelClass = $$props.labelClass);
- if ("innerClass" in $$props) $$invalidate(4, innerClass = $$props.innerClass);
- if ("hideLabel" in $$props) $$invalidate(5, hideLabel = $$props.hideLabel);
- if ("icon" in $$props) $$invalidate(6, icon = $$props.icon);
- if ("name" in $$props) $$invalidate(7, name = $$props.name);
- if ("options" in $$props) $$invalidate(22, options = $$props.options);
- if ("selectedIndex" in $$props) $$invalidate(8, selectedIndex = $$props.selectedIndex);
- if ("value" in $$props) $$invalidate(9, value = $$props.value);
- if ("optionLabelClass" in $$props) $$invalidate(10, optionLabelClass = $$props.optionLabelClass);
- if ("optionFilter" in $$props) $$invalidate(11, optionFilter = $$props.optionFilter);
- if ("optionMapper" in $$props) $$invalidate(12, optionMapper = $$props.optionMapper);
- if ("optionIconStyle" in $$props) $$invalidate(13, optionIconStyle = $$props.optionIconStyle);
- if ("optionLabelStyle" in $$props) $$invalidate(14, optionLabelStyle = $$props.optionLabelStyle);
- if ("locale" in $$props) $$invalidate(15, locale = $$props.locale);
- if ("onchange" in $$props) $$invalidate(23, onchange = $$props.onchange);
- if ("onload" in $$props) $$invalidate(24, onload = $$props.onload);
- if ("ondestroy" in $$props) $$invalidate(25, ondestroy = $$props.ondestroy);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*locale, options*/ 4227072) {
- $$invalidate(16, localizedOptions = locale ? localizeOptions$1(options, locale) : options);
- }
- if ($$self.$$.dirty & /*localizedOptions, value*/ 66048) {
- $$invalidate(18, selectedLabel = localizedOptions.reduce(
- (prev, curr) => {
- if (prev) return prev;
- const item = Array.isArray(curr) ? curr : [curr, curr];
- const [optionValue, optionLabel] = item;
- if (isDeepEqual(optionValue, value)) return optionLabel;
- },
- undefined
- ) || getUndefinedOptionLabel(localizedOptions));
- }
- };
- return [
- klass,
- title,
- label,
- labelClass,
- innerClass,
- hideLabel,
- icon,
- name,
- selectedIndex,
- value,
- optionLabelClass,
- optionFilter,
- optionMapper,
- optionIconStyle,
- optionLabelStyle,
- locale,
- localizedOptions,
- dropdownVisible,
- selectedLabel,
- handleSelect,
- handleShowPanel,
- handleKeydown,
- options,
- onchange,
- onload,
- ondestroy,
- details_isActive_binding
- ];
- }
- class Dropdown extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$y, create_fragment$y, safe_not_equal, {
- class: 0,
- title: 1,
- label: 2,
- labelClass: 3,
- innerClass: 4,
- hideLabel: 5,
- icon: 6,
- name: 7,
- options: 22,
- selectedIndex: 8,
- value: 9,
- optionLabelClass: 10,
- optionFilter: 11,
- optionMapper: 12,
- optionIconStyle: 13,
- optionLabelStyle: 14,
- locale: 15,
- onchange: 23,
- onload: 24,
- ondestroy: 25
- });
- }
- }
- var numberRoundTo = (value, fraction) => {
- fraction = 1 / fraction;
- return Math.round(value * fraction) / fraction;
- };
- var toFraction = (value, min, max) => (value - min) / (max - min);
- /* src/core/ui/components/Slider.svelte generated by Svelte v3.37.0 */
- function create_default_slot_1$5(ctx) {
- let path;
- return {
- c() {
- path = svg_element("path");
- attr(path, "d", "M8 12 h8 M12 8 v8");
- },
- m(target, anchor) {
- insert(target, path, anchor);
- },
- d(detaching) {
- if (detaching) detach(path);
- }
- };
- }
- // (153:8) <Icon>
- function create_default_slot$d(ctx) {
- let path;
- return {
- c() {
- path = svg_element("path");
- attr(path, "d", "M9 12 h6");
- },
- m(target, anchor) {
- insert(target, path, anchor);
- },
- d(detaching) {
- if (detaching) detach(path);
- }
- };
- }
- function create_fragment$x(ctx) {
- let div4;
- let div3;
- let input_1;
- let t0;
- let div0;
- let t1;
- let div2;
- let div1;
- let t2;
- let button0;
- let icon0;
- let t3;
- let button1;
- let icon1;
- let div4_class_value;
- let current;
- let mounted;
- let dispose;
- icon0 = new Icon({
- props: {
- $$slots: { default: [create_default_slot_1$5] },
- $$scope: { ctx }
- }
- });
- icon1 = new Icon({
- props: {
- $$slots: { default: [create_default_slot$d] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- div4 = element("div");
- div3 = element("div");
- input_1 = element("input");
- t0 = space();
- div0 = element("div");
- t1 = space();
- div2 = element("div");
- div1 = element("div");
- t2 = space();
- button0 = element("button");
- create_component(icon0.$$.fragment);
- t3 = space();
- button1 = element("button");
- create_component(icon1.$$.fragment);
- attr(input_1, "type", "range");
- attr(input_1, "id", /*id*/ ctx[3]);
- attr(input_1, "min", /*min*/ ctx[0]);
- attr(input_1, "max", /*max*/ ctx[1]);
- attr(input_1, "step", /*step*/ ctx[2]);
- input_1.value = /*numberValue*/ ctx[8];
- attr(div0, "class", "PinturaSliderTrack");
- attr(div0, "style", /*trackStyle*/ ctx[4]);
- attr(div1, "class", "PinturaSliderKnob");
- attr(div1, "style", /*knobStyle*/ ctx[5]);
- attr(div2, "class", "PinturaSliderKnobController");
- attr(div2, "style", /*knobControllerStyle*/ ctx[10]);
- attr(div3, "class", "PinturaSliderControl");
- attr(button0, "type", "button");
- attr(button0, "aria-label", "Increase");
- attr(button1, "type", "button");
- attr(button1, "aria-label", "Decrease");
- attr(div4, "class", div4_class_value = arrayJoin(["PinturaSlider", /*klass*/ ctx[7]]));
- attr(div4, "data-direction", /*direction*/ ctx[6]);
- },
- m(target, anchor) {
- insert(target, div4, anchor);
- append(div4, div3);
- append(div3, input_1);
- /*input_1_binding*/ ctx[22](input_1);
- append(div3, t0);
- append(div3, div0);
- append(div3, t1);
- append(div3, div2);
- append(div2, div1);
- append(div4, t2);
- append(div4, button0);
- mount_component(icon0, button0, null);
- append(div4, t3);
- append(div4, button1);
- mount_component(icon1, button1, null);
- current = true;
- if (!mounted) {
- dispose = [
- listen(input_1, "pointerdown", /*handlePointerDown*/ ctx[13]),
- listen(input_1, "input", /*handleInput*/ ctx[11]),
- listen(input_1, "nudge", /*handleNudge*/ ctx[12]),
- action_destroyer(nudgeable.call(null, input_1)),
- listen(button0, "pointerdown", /*handleUpdaterDown*/ ctx[14](1)),
- listen(button1, "pointerdown", /*handleUpdaterDown*/ ctx[14](-1))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- if (!current || dirty[0] & /*id*/ 8) {
- attr(input_1, "id", /*id*/ ctx[3]);
- }
- if (!current || dirty[0] & /*min*/ 1) {
- attr(input_1, "min", /*min*/ ctx[0]);
- }
- if (!current || dirty[0] & /*max*/ 2) {
- attr(input_1, "max", /*max*/ ctx[1]);
- }
- if (!current || dirty[0] & /*step*/ 4) {
- attr(input_1, "step", /*step*/ ctx[2]);
- }
- if (!current || dirty[0] & /*numberValue*/ 256) {
- input_1.value = /*numberValue*/ ctx[8];
- }
- if (!current || dirty[0] & /*trackStyle*/ 16) {
- attr(div0, "style", /*trackStyle*/ ctx[4]);
- }
- if (!current || dirty[0] & /*knobStyle*/ 32) {
- attr(div1, "style", /*knobStyle*/ ctx[5]);
- }
- if (!current || dirty[0] & /*knobControllerStyle*/ 1024) {
- attr(div2, "style", /*knobControllerStyle*/ ctx[10]);
- }
- const icon0_changes = {};
- if (dirty[1] & /*$$scope*/ 512) {
- icon0_changes.$$scope = { dirty, ctx };
- }
- icon0.$set(icon0_changes);
- const icon1_changes = {};
- if (dirty[1] & /*$$scope*/ 512) {
- icon1_changes.$$scope = { dirty, ctx };
- }
- icon1.$set(icon1_changes);
- if (!current || dirty[0] & /*klass*/ 128 && div4_class_value !== (div4_class_value = arrayJoin(["PinturaSlider", /*klass*/ ctx[7]]))) {
- attr(div4, "class", div4_class_value);
- }
- if (!current || dirty[0] & /*direction*/ 64) {
- attr(div4, "data-direction", /*direction*/ ctx[6]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(icon0.$$.fragment, local);
- transition_in(icon1.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon0.$$.fragment, local);
- transition_out(icon1.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div4);
- /*input_1_binding*/ ctx[22](null);
- destroy_component(icon0);
- destroy_component(icon1);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function instance$x($$self, $$props, $$invalidate) {
- let numberValue;
- let range;
- let position;
- let axis;
- let dimension;
- let offsetSizeProp;
- let offsetAxisProp;
- let pageAxisProp;
- let knobControllerStyle;
- let { min = 0 } = $$props;
- let { max = 100 } = $$props;
- let { step = 1 } = $$props;
- let { id = undefined } = $$props;
- let { value = 0 } = $$props;
- let { trackStyle = undefined } = $$props;
- let { knobStyle = undefined } = $$props;
- let { onchange = undefined } = $$props;
- let { direction = "x" } = $$props;
- let { getValue = passthrough } = $$props;
- let { setValue = passthrough } = $$props;
- let { class: klass = undefined } = $$props;
- let input;
- let inputSize;
- let inputOffset;
- let pageOffset;
- let valuePrev;
- const formatValue = value => setValue(numberRoundTo(clamp(value, min, max), step));
- const setValueByOffset = (offset, size) => {
- $$invalidate(15, value = formatValue(min + offset / size * range));
- if (value === valuePrev) return;
- valuePrev = value;
- onchange(value);
- };
- const handleInput = e => {
- // already handled by pointer events
- if (inputSize) return;
- $$invalidate(15, value = setValue(parseFloat(e.target.value)));
- if (value === valuePrev) return;
- valuePrev = value;
- onchange(value);
- };
- const handleNudge = e => {
- const size = input[offsetSizeProp];
- const offset = numberValue / range * size;
- setValueByOffset(offset + e.detail[direction], size);
- };
- const handlePointerDown = e => {
- e.stopPropagation();
- inputSize = input[offsetSizeProp];
- inputOffset = e[offsetAxisProp];
- pageOffset = e[pageAxisProp];
- setValueByOffset(inputOffset, inputSize);
- document.documentElement.addEventListener("pointermove", handlePointerMove);
- document.documentElement.addEventListener("pointerup", handlePointerUp);
- };
- const handlePointerMove = e => {
- const d = e[pageAxisProp] - pageOffset;
- setValueByOffset(inputOffset + d, inputSize);
- };
- const handlePointerUp = e => {
- inputSize = undefined;
- document.documentElement.removeEventListener("pointermove", handlePointerMove);
- document.documentElement.removeEventListener("pointerup", handlePointerUp);
- onchange(value);
- };
- const update = () => {
- $$invalidate(15, value = formatValue(numberValue + updateDir * step));
- onchange(value);
- };
- let updateTimer;
- let updateDir = 1;
- let didUpdate = false;
- const handleUpdaterDown = dir => e => {
- updateDir = dir;
- didUpdate = false;
- updateTimer = setInterval(
- () => {
- didUpdate = true;
- update();
- },
- 100
- );
- document.addEventListener("pointercancel", handleUpdaterUp);
- document.addEventListener("pointerup", handleUpdaterUp);
- };
- const handleUpdaterUp = e => {
- clearTimeout(updateTimer);
- if (!didUpdate) update();
- document.removeEventListener("pointerup", handleUpdaterUp);
- };
- function input_1_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- input = $$value;
- $$invalidate(9, input);
- });
- }
- $$self.$$set = $$props => {
- if ("min" in $$props) $$invalidate(0, min = $$props.min);
- if ("max" in $$props) $$invalidate(1, max = $$props.max);
- if ("step" in $$props) $$invalidate(2, step = $$props.step);
- if ("id" in $$props) $$invalidate(3, id = $$props.id);
- if ("value" in $$props) $$invalidate(15, value = $$props.value);
- if ("trackStyle" in $$props) $$invalidate(4, trackStyle = $$props.trackStyle);
- if ("knobStyle" in $$props) $$invalidate(5, knobStyle = $$props.knobStyle);
- if ("onchange" in $$props) $$invalidate(16, onchange = $$props.onchange);
- if ("direction" in $$props) $$invalidate(6, direction = $$props.direction);
- if ("getValue" in $$props) $$invalidate(17, getValue = $$props.getValue);
- if ("setValue" in $$props) $$invalidate(18, setValue = $$props.setValue);
- if ("class" in $$props) $$invalidate(7, klass = $$props.class);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*value, getValue*/ 163840) {
- $$invalidate(8, numberValue = value !== undefined ? getValue(value) : 0);
- }
- if ($$self.$$.dirty[0] & /*max, min*/ 3) {
- range = max - min;
- }
- if ($$self.$$.dirty[0] & /*numberValue, min, max*/ 259) {
- $$invalidate(19, position = toFraction(numberValue, min, max) * 100);
- }
- if ($$self.$$.dirty[0] & /*direction*/ 64) {
- $$invalidate(20, axis = direction.toUpperCase());
- }
- if ($$self.$$.dirty[0] & /*direction*/ 64) {
- $$invalidate(21, dimension = direction === "x" ? "Width" : "Height");
- }
- if ($$self.$$.dirty[0] & /*dimension*/ 2097152) {
- offsetSizeProp = `offset${dimension}`;
- }
- if ($$self.$$.dirty[0] & /*axis*/ 1048576) {
- offsetAxisProp = `offset${axis}`;
- }
- if ($$self.$$.dirty[0] & /*axis*/ 1048576) {
- pageAxisProp = `page${axis}`;
- }
- if ($$self.$$.dirty[0] & /*axis, position*/ 1572864) {
- $$invalidate(10, knobControllerStyle = `transform: translate${axis}(${position}%)`);
- }
- };
- return [
- min,
- max,
- step,
- id,
- trackStyle,
- knobStyle,
- direction,
- klass,
- numberValue,
- input,
- knobControllerStyle,
- handleInput,
- handleNudge,
- handlePointerDown,
- handleUpdaterDown,
- value,
- onchange,
- getValue,
- setValue,
- position,
- axis,
- dimension,
- input_1_binding
- ];
- }
- class Slider extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$x,
- create_fragment$x,
- safe_not_equal,
- {
- min: 0,
- max: 1,
- step: 2,
- id: 3,
- value: 15,
- trackStyle: 4,
- knobStyle: 5,
- onchange: 16,
- direction: 6,
- getValue: 17,
- setValue: 18,
- class: 7
- },
- [-1, -1]
- );
- }
- }
- /* src/core/ui/components/ToggleSlider.svelte generated by Svelte v3.37.0 */
- function create_if_block$9(ctx) {
- let icon_1;
- let current;
- icon_1 = new Icon({
- props: {
- class: "PinturaButtonIcon",
- $$slots: { default: [create_default_slot$c] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(icon_1.$$.fragment);
- },
- m(target, anchor) {
- mount_component(icon_1, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const icon_1_changes = {};
- if (dirty & /*$$scope, icon*/ 262148) {
- icon_1_changes.$$scope = { dirty, ctx };
- }
- icon_1.$set(icon_1_changes);
- },
- i(local) {
- if (current) return;
- transition_in(icon_1.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon_1.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(icon_1, detaching);
- }
- };
- }
- // (51:12) <Icon class="PinturaButtonIcon">
- function create_default_slot$c(ctx) {
- let g;
- return {
- c() {
- g = svg_element("g");
- },
- m(target, anchor) {
- insert(target, g, anchor);
- g.innerHTML = /*icon*/ ctx[2];
- },
- p(ctx, dirty) {
- if (dirty & /*icon*/ 4) g.innerHTML = /*icon*/ ctx[2]; },
- d(detaching) {
- if (detaching) detach(g);
- }
- };
- }
- // (45:4)
- function create_label_slot$1(ctx) {
- let span1;
- let t0;
- let span0;
- let t1;
- let span0_class_value;
- let span1_title_value;
- let span1_class_value;
- let current;
- let if_block = /*icon*/ ctx[2] && create_if_block$9(ctx);
- return {
- c() {
- span1 = element("span");
- if (if_block) if_block.c();
- t0 = space();
- span0 = element("span");
- t1 = text(/*currentLabel*/ ctx[8]);
- attr(span0, "class", span0_class_value = arrayJoin([
- "PinturaButtonLabel",
- /*labelClass*/ ctx[3],
- /*hideLabel*/ ctx[5] && "implicit"
- ]));
- attr(span1, "slot", "label");
- attr(span1, "title", span1_title_value = localize(/*title*/ ctx[1], /*locale*/ ctx[6]));
- attr(span1, "class", span1_class_value = arrayJoin(["PinturaButtonInner", /*innerClass*/ ctx[4]]));
- },
- m(target, anchor) {
- insert(target, span1, anchor);
- if (if_block) if_block.m(span1, null);
- append(span1, t0);
- append(span1, span0);
- append(span0, t1);
- current = true;
- },
- p(ctx, dirty) {
- if (/*icon*/ ctx[2]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty & /*icon*/ 4) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block$9(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(span1, t0);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- if (!current || dirty & /*currentLabel*/ 256) set_data(t1, /*currentLabel*/ ctx[8]);
- if (!current || dirty & /*labelClass, hideLabel*/ 40 && span0_class_value !== (span0_class_value = arrayJoin([
- "PinturaButtonLabel",
- /*labelClass*/ ctx[3],
- /*hideLabel*/ ctx[5] && "implicit"
- ]))) {
- attr(span0, "class", span0_class_value);
- }
- if (!current || dirty & /*title, locale*/ 66 && span1_title_value !== (span1_title_value = localize(/*title*/ ctx[1], /*locale*/ ctx[6]))) {
- attr(span1, "title", span1_title_value);
- }
- if (!current || dirty & /*innerClass*/ 16 && span1_class_value !== (span1_class_value = arrayJoin(["PinturaButtonInner", /*innerClass*/ ctx[4]]))) {
- attr(span1, "class", span1_class_value);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(span1);
- if (if_block) if_block.d();
- }
- };
- }
- // (58:4)
- function create_details_slot$1(ctx) {
- let div;
- let slider;
- let current;
- let mounted;
- let dispose;
- const slider_spread_levels = [
- /*$$restProps*/ ctx[11],
- { value: /*value*/ ctx[7] },
- { onchange: /*handleChangeValue*/ ctx[10] }
- ];
- let slider_props = {};
- for (let i = 0; i < slider_spread_levels.length; i += 1) {
- slider_props = assign(slider_props, slider_spread_levels[i]);
- }
- slider = new Slider({ props: slider_props });
- return {
- c() {
- div = element("div");
- create_component(slider.$$.fragment);
- attr(div, "slot", "details");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(slider, div, null);
- current = true;
- if (!mounted) {
- dispose = listen(div, "keydown", /*handleKeydown*/ ctx[9]);
- mounted = true;
- }
- },
- p(ctx, dirty) {
- const slider_changes = (dirty & /*$$restProps, value, handleChangeValue*/ 3200)
- ? get_spread_update(slider_spread_levels, [
- dirty & /*$$restProps*/ 2048 && get_spread_object(/*$$restProps*/ ctx[11]),
- dirty & /*value*/ 128 && { value: /*value*/ ctx[7] },
- dirty & /*handleChangeValue*/ 1024 && { onchange: /*handleChangeValue*/ ctx[10] }
- ])
- : {};
- slider.$set(slider_changes);
- },
- i(local) {
- if (current) return;
- transition_in(slider.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(slider.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(slider);
- mounted = false;
- dispose();
- }
- };
- }
- function create_fragment$w(ctx) {
- let details;
- let current;
- details = new Details({
- props: {
- panelClass: "PinturaSliderPanel",
- buttonClass: arrayJoin([
- "PinturaSliderButton",
- /*klass*/ ctx[0],
- /*hideLabel*/ ctx[5] && "PinturaSliderIconOnly"
- ]),
- $$slots: {
- details: [create_details_slot$1],
- label: [create_label_slot$1]
- },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(details.$$.fragment);
- },
- m(target, anchor) {
- mount_component(details, target, anchor);
- current = true;
- },
- p(ctx, [dirty]) {
- const details_changes = {};
- if (dirty & /*klass, hideLabel*/ 33) details_changes.buttonClass = arrayJoin([
- "PinturaSliderButton",
- /*klass*/ ctx[0],
- /*hideLabel*/ ctx[5] && "PinturaSliderIconOnly"
- ]);
- if (dirty & /*$$scope, $$restProps, value, title, locale, innerClass, labelClass, hideLabel, currentLabel, icon*/ 264702) {
- details_changes.$$scope = { dirty, ctx };
- }
- details.$set(details_changes);
- },
- i(local) {
- if (current) return;
- transition_in(details.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(details.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(details, detaching);
- }
- };
- }
- function instance$w($$self, $$props, $$invalidate) {
- const omit_props_names = [
- "class","title","label","icon","labelClass","innerClass","hideLabel","locale","value","onchange"
- ];
- let $$restProps = compute_rest_props($$props, omit_props_names);
- let { class: klass = undefined } = $$props;
- let { title = undefined } = $$props;
- let { label = value => Math.round(value) } = $$props;
- let { icon = undefined } = $$props;
- let { labelClass = undefined } = $$props;
- let { innerClass = undefined } = $$props;
- let { hideLabel = false } = $$props;
- let { locale = undefined } = $$props;
- let { value = undefined } = $$props;
- let { onchange = noop$1 } = $$props;
- const { min, max, getValue = passthrough } = $$restProps;
- const handleKeydown = e => {
- // don't allow tabbing ([tab] is also blocked in normal <select>)
- if ((/tab/i).test(e.key)) e.preventDefault();
- };
- const getLabel = value => isFunction(label)
- ? label(getValue(value), min, max)
- : label;
- let currentLabel = getLabel(value);
- const handleChangeValue = value => {
- $$invalidate(8, currentLabel = getLabel(value));
- onchange(value);
- };
- $$self.$$set = $$new_props => {
- $$props = assign(assign({}, $$props), exclude_internal_props($$new_props));
- $$invalidate(11, $$restProps = compute_rest_props($$props, omit_props_names));
- if ("class" in $$new_props) $$invalidate(0, klass = $$new_props.class);
- if ("title" in $$new_props) $$invalidate(1, title = $$new_props.title);
- if ("label" in $$new_props) $$invalidate(12, label = $$new_props.label);
- if ("icon" in $$new_props) $$invalidate(2, icon = $$new_props.icon);
- if ("labelClass" in $$new_props) $$invalidate(3, labelClass = $$new_props.labelClass);
- if ("innerClass" in $$new_props) $$invalidate(4, innerClass = $$new_props.innerClass);
- if ("hideLabel" in $$new_props) $$invalidate(5, hideLabel = $$new_props.hideLabel);
- if ("locale" in $$new_props) $$invalidate(6, locale = $$new_props.locale);
- if ("value" in $$new_props) $$invalidate(7, value = $$new_props.value);
- if ("onchange" in $$new_props) $$invalidate(13, onchange = $$new_props.onchange);
- };
- return [
- klass,
- title,
- icon,
- labelClass,
- innerClass,
- hideLabel,
- locale,
- value,
- currentLabel,
- handleKeydown,
- handleChangeValue,
- $$restProps,
- label,
- onchange
- ];
- }
- class ToggleSlider extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$w, create_fragment$w, safe_not_equal, {
- class: 0,
- title: 1,
- label: 12,
- icon: 2,
- labelClass: 3,
- innerClass: 4,
- hideLabel: 5,
- locale: 6,
- value: 7,
- onchange: 13
- });
- }
- }
- /* src/core/ui/components/DynamicComponentTree.svelte generated by Svelte v3.37.0 */
- function get_each_context$6(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[7] = list[i][0];
- child_ctx[8] = list[i][1];
- child_ctx[9] = list[i][2];
- child_ctx[0] = list[i][3];
- return child_ctx;
- }
- // (54:4) {:else}
- function create_else_block$3(ctx) {
- let switch_instance;
- let switch_instance_anchor;
- let current;
- const switch_instance_spread_levels = [/*props*/ ctx[9]];
- var switch_value = /*ComponentMap*/ ctx[1][/*node*/ ctx[7]] || /*node*/ ctx[7];
- function switch_props(ctx) {
- let switch_instance_props = {};
- for (let i = 0; i < switch_instance_spread_levels.length; i += 1) {
- switch_instance_props = assign(switch_instance_props, switch_instance_spread_levels[i]);
- }
- return { props: switch_instance_props };
- }
- if (switch_value) {
- switch_instance = new switch_value(switch_props());
- }
- return {
- c() {
- if (switch_instance) create_component(switch_instance.$$.fragment);
- switch_instance_anchor = empty();
- },
- m(target, anchor) {
- if (switch_instance) {
- mount_component(switch_instance, target, anchor);
- }
- insert(target, switch_instance_anchor, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const switch_instance_changes = (dirty & /*children*/ 1)
- ? get_spread_update(switch_instance_spread_levels, [get_spread_object(/*props*/ ctx[9])])
- : {};
- if (switch_value !== (switch_value = /*ComponentMap*/ ctx[1][/*node*/ ctx[7]] || /*node*/ ctx[7])) {
- if (switch_instance) {
- group_outros();
- const old_component = switch_instance;
- transition_out(old_component.$$.fragment, 1, 0, () => {
- destroy_component(old_component, 1);
- });
- check_outros();
- }
- if (switch_value) {
- switch_instance = new switch_value(switch_props());
- create_component(switch_instance.$$.fragment);
- transition_in(switch_instance.$$.fragment, 1);
- mount_component(switch_instance, switch_instance_anchor.parentNode, switch_instance_anchor);
- } else {
- switch_instance = null;
- }
- } else if (switch_value) {
- switch_instance.$set(switch_instance_changes);
- }
- },
- i(local) {
- if (current) return;
- if (switch_instance) transition_in(switch_instance.$$.fragment, local);
- current = true;
- },
- o(local) {
- if (switch_instance) transition_out(switch_instance.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(switch_instance_anchor);
- if (switch_instance) destroy_component(switch_instance, detaching);
- }
- };
- }
- // (44:4) {#if !isComponent(node)}
- function create_if_block$8(ctx) {
- let tag;
- let current;
- tag = new Tag({
- props: {
- name: /*node*/ ctx[7],
- attributes: /*getElementAttributes*/ ctx[2](/*props*/ ctx[9]),
- $$slots: { default: [create_default_slot$b] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(tag.$$.fragment);
- },
- m(target, anchor) {
- mount_component(tag, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const tag_changes = {};
- if (dirty & /*children*/ 1) tag_changes.name = /*node*/ ctx[7];
- if (dirty & /*children*/ 1) tag_changes.attributes = /*getElementAttributes*/ ctx[2](/*props*/ ctx[9]);
- if (dirty & /*$$scope, children*/ 4097) {
- tag_changes.$$scope = { dirty, ctx };
- }
- tag.$set(tag_changes);
- },
- i(local) {
- if (current) return;
- transition_in(tag.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(tag.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(tag, detaching);
- }
- };
- }
- // (50:38)
- function create_if_block_3$5(ctx) {
- let html_tag;
- let raw_value = /*props*/ ctx[9].innerHTML + "";
- let html_anchor;
- return {
- c() {
- html_anchor = empty();
- html_tag = new HtmlTag(html_anchor);
- },
- m(target, anchor) {
- html_tag.m(raw_value, target, anchor);
- insert(target, html_anchor, anchor);
- },
- p(ctx, dirty) {
- if (dirty & /*children*/ 1 && raw_value !== (raw_value = /*props*/ ctx[9].innerHTML + "")) html_tag.p(raw_value);
- },
- i: noop,
- o: noop,
- d(detaching) {
- if (detaching) detach(html_anchor);
- if (detaching) html_tag.d();
- }
- };
- }
- // (48:40)
- function create_if_block_2$7(ctx) {
- let t_value = /*props*/ ctx[9].textContent + "";
- let t;
- return {
- c() {
- t = text(t_value);
- },
- m(target, anchor) {
- insert(target, t, anchor);
- },
- p(ctx, dirty) {
- if (dirty & /*children*/ 1 && t_value !== (t_value = /*props*/ ctx[9].textContent + "")) set_data(t, t_value);
- },
- i: noop,
- o: noop,
- d(detaching) {
- if (detaching) detach(t);
- }
- };
- }
- // (46:12) {#if children && children.length}
- function create_if_block_1$8(ctx) {
- let dynamiccomponenttree;
- let current;
- dynamiccomponenttree = new DynamicComponentTree_1({
- props: {
- items: /*children*/ ctx[0],
- discardEmptyItems: true
- }
- });
- return {
- c() {
- create_component(dynamiccomponenttree.$$.fragment);
- },
- m(target, anchor) {
- mount_component(dynamiccomponenttree, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const dynamiccomponenttree_changes = {};
- if (dirty & /*children*/ 1) dynamiccomponenttree_changes.items = /*children*/ ctx[0];
- dynamiccomponenttree.$set(dynamiccomponenttree_changes);
- },
- i(local) {
- if (current) return;
- transition_in(dynamiccomponenttree.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(dynamiccomponenttree.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(dynamiccomponenttree, detaching);
- }
- };
- }
- // (45:8) <Tag name={node} attributes={getElementAttributes(props)}>
- function create_default_slot$b(ctx) {
- let current_block_type_index;
- let if_block;
- let t;
- let current;
- const if_block_creators = [create_if_block_1$8, create_if_block_2$7, create_if_block_3$5];
- const if_blocks = [];
- function select_block_type_1(ctx, dirty) {
- if (/*children*/ ctx[0] && /*children*/ ctx[0].length) return 0;
- if (/*props*/ ctx[9].textContent) return 1;
- if (/*props*/ ctx[9].innerHTML) return 2;
- return -1;
- }
- if (~(current_block_type_index = select_block_type_1(ctx))) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- }
- return {
- c() {
- if (if_block) if_block.c();
- t = space();
- },
- m(target, anchor) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].m(target, anchor);
- }
- insert(target, t, anchor);
- current = true;
- },
- p(ctx, dirty) {
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type_1(ctx);
- if (current_block_type_index === previous_block_index) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- }
- } else {
- if (if_block) {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- }
- if (~current_block_type_index) {
- if_block = if_blocks[current_block_type_index];
- if (!if_block) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block.c();
- } else {
- if_block.p(ctx, dirty);
- }
- transition_in(if_block, 1);
- if_block.m(t.parentNode, t);
- } else {
- if_block = null;
- }
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].d(detaching);
- }
- if (detaching) detach(t);
- }
- };
- }
- // (43:0) {#each children as [node, key, props, children] (key)}
- function create_each_block$6(key_1, ctx) {
- let first;
- let show_if;
- let current_block_type_index;
- let if_block;
- let if_block_anchor;
- let current;
- const if_block_creators = [create_if_block$8, create_else_block$3];
- const if_blocks = [];
- function select_block_type(ctx, dirty) {
- if (dirty & /*children*/ 1) show_if = !!!/*isComponent*/ ctx[3](/*node*/ ctx[7]);
- if (show_if) return 0;
- return 1;
- }
- current_block_type_index = select_block_type(ctx, -1);
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- return {
- key: key_1,
- first: null,
- c() {
- first = empty();
- if_block.c();
- if_block_anchor = empty();
- this.first = first;
- },
- m(target, anchor) {
- insert(target, first, anchor);
- if_blocks[current_block_type_index].m(target, anchor);
- insert(target, if_block_anchor, anchor);
- current = true;
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type(ctx, dirty);
- if (current_block_type_index === previous_block_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- } else {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- if_block = if_blocks[current_block_type_index];
- if (!if_block) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block.c();
- } else {
- if_block.p(ctx, dirty);
- }
- transition_in(if_block, 1);
- if_block.m(if_block_anchor.parentNode, if_block_anchor);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(first);
- if_blocks[current_block_type_index].d(detaching);
- if (detaching) detach(if_block_anchor);
- }
- };
- }
- function create_fragment$v(ctx) {
- let each_blocks = [];
- let each_1_lookup = new Map();
- let each_1_anchor;
- let current;
- let each_value = /*children*/ ctx[0];
- const get_key = ctx => /*key*/ ctx[8];
- for (let i = 0; i < each_value.length; i += 1) {
- let child_ctx = get_each_context$6(ctx, each_value, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block$6(key, child_ctx));
- }
- return {
- c() {
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- each_1_anchor = empty();
- },
- m(target, anchor) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].m(target, anchor);
- }
- insert(target, each_1_anchor, anchor);
- current = true;
- },
- p(ctx, [dirty]) {
- if (dirty & /*children, getElementAttributes, isComponent, ComponentMap*/ 15) {
- each_value = /*children*/ ctx[0];
- group_outros();
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, outro_and_destroy_block, create_each_block$6, each_1_anchor, get_each_context$6);
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- for (let i = 0; i < each_value.length; i += 1) {
- transition_in(each_blocks[i]);
- }
- current = true;
- },
- o(local) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- transition_out(each_blocks[i]);
- }
- current = false;
- },
- d(detaching) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d(detaching);
- }
- if (detaching) detach(each_1_anchor);
- }
- };
- }
- function instance$v($$self, $$props, $$invalidate) {
- let children;
- let { items } = $$props;
- let { discardEmptyItems = true } = $$props;
- const ComponentMap = { Button, Dropdown, Slider: ToggleSlider };
- const getElementAttributes = (props = {}) => {
- const { textContent, innerHTML, ...attributes } = props;
- return attributes;
- };
- const isComponent = node => !isString(node) || !!ComponentMap[node];
- const shouldRenderItem = item => {
- // don't render falsy items
- if (!item) return false;
- // get relevant props
- const [node, ,props, children = []] = item;
- // if item is component, we always render it
- if (isComponent(node)) return true;
- // item is tag, we have to check if it has content
- return children.some(shouldRenderItem) || props.textContent || props.innerHTML;
- };
- $$self.$$set = $$props => {
- if ("items" in $$props) $$invalidate(4, items = $$props.items);
- if ("discardEmptyItems" in $$props) $$invalidate(5, discardEmptyItems = $$props.discardEmptyItems);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*items, discardEmptyItems*/ 48) {
- $$invalidate(0, children = (items && discardEmptyItems
- ? items.filter(shouldRenderItem)
- : items) || []);
- }
- };
- return [
- children,
- ComponentMap,
- getElementAttributes,
- isComponent,
- items,
- discardEmptyItems
- ];
- }
- class DynamicComponentTree_1 extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$v, create_fragment$v, safe_not_equal, { items: 4, discardEmptyItems: 5 });
- }
- }
- var smoothstep = (min, max, value, ease = (x) => x * x * (3 - 2 * x)) => ease(Math.max(0, Math.min(1, (value - min) / (max - min))));
- var canvasClone = (canvas) => {
- const clone = h('canvas', { width: canvas.width, height: canvas.height });
- clone.getContext('2d').drawImage(canvas, 0, 0);
- return clone;
- };
- const ImageStoreProps = [
- 'file',
- 'size',
- 'loadState',
- 'processState',
- 'cropAspectRatio',
- 'cropLimitToImage',
- 'crop',
- 'cropMinSize',
- 'cropMaxSize',
- 'cropRange',
- 'cropOrigin',
- 'cropRectAspectRatio',
- 'rotation',
- 'rotationRange',
- 'targetSize',
- 'flipX',
- 'flipY',
- 'perspectiveX',
- 'perspectiveY',
- 'perspective',
- 'colorMatrix',
- 'convolutionMatrix',
- 'gamma',
- 'vignette',
- 'noise',
- 'redaction',
- 'decoration',
- 'annotation',
- 'frame',
- 'backgroundColor',
- 'state',
- ];
- const proxy = function (get, set, update) {
- let subscribers = [];
- return {
- set,
- update,
- publish: (value) => {
- subscribers.forEach((cb) => cb(value));
- },
- subscribe: (cb) => {
- subscribers.push(cb);
- get(cb);
- return () => {
- subscribers = subscribers.filter((item) => item !== cb);
- };
- },
- };
- };
- var createImageProxy = () => {
- let unsubs;
- let image;
- const proxyStores = ImageStoreProps.reduce((prev, curr) => {
- prev[curr] = proxy(
- // getter
- (cb) => {
- // subscribe
- if (!image)
- return cb();
- const unsub = image.stores[curr].subscribe(cb);
- unsub();
- },
- // setter
- (value) => {
- // set value on actual store if is defined
- if (!image)
- return;
- image.stores[curr].set(value);
- },
- // updater
- (cb) => {
- if (!image)
- return;
- image.stores[curr].update(cb);
- });
- return prev;
- }, {});
- const update = (newImage) => {
- image = newImage;
- if (unsubs) {
- // remove subscribers
- unsubs.forEach((unsub) => unsub());
- unsubs = undefined;
- }
- if (!newImage) {
- // need to reset load state
- proxyStores['file'].publish(undefined);
- proxyStores['loadState'].publish(undefined);
- return;
- }
- unsubs = ImageStoreProps.map((prop) => newImage.stores[prop].subscribe((value) => {
- proxyStores[prop].publish(value);
- }));
- };
- return {
- update,
- stores: proxyStores,
- };
- };
- var createPingRouter = (route, cancel = true) => (e) => {
- if (e.type !== 'ping')
- return;
- if (cancel)
- e.stopPropagation();
- route(e.detail.type, e.detail.data);
- };
- var createPing = (type, data) => new CustomEvent('ping', {
- detail: {
- type,
- data,
- },
- cancelable: true,
- bubbles: true,
- });
- var isTextarea = (element) => /textarea/i.test(element.nodeName);
- var isTextInput = (node) => /date|email|number|search|text|url/.test(node.type);
- var isTextField = (node) => isTextarea(node) || isTextInput(node);
- var toKebabCase = (str, abbr) => {
- return (abbr ? stringReplace(str, abbr) : str)
- .replace(/([a-z])([A-Z])/g, '$1-$2')
- .replace(/\s+/g, '-')
- .toLowerCase();
- };
- var matchMedia$1 = (query, cb) => {
- const mql = matchMedia(query);
- mql.addListener(cb);
- cb(mql);
- return {
- get matches() { return mql.matches; },
- destroy: () => mql.removeListener(cb)
- };
- };
- var mediaQueryStore = (query, formatValue = passthrough) => {
- const { subscribe, set } = writable(undefined);
- const mm = matchMedia$1(query, ({ matches }) => set(formatValue(matches)));
- return {
- subscribe,
- unsubscribe: mm.destroy
- };
- };
- var canPreventNavSwipe = () => {
- // if not iOS we can't prevent swipe because it probably isn't a thing
- if (!isIOS())
- return false;
- // extract version number
- const matches = navigator.userAgent.match(/OS (\d+)_(\d+)_?(\d+)?/i) || [];
- const [, major, minor] = matches.map((v) => parseInt(v, 10) || 0);
- // is atleast version 13.4+
- return major > 13 || (major === 13 && minor >= 4);
- };
- var calculateImageTransforms = (stageRect, rootRect, imageSize, cropRect, imageSelectionRect, imageScale, imagePerspectiveX, imagePerspectiveY, imageRotation, imageFlipX, imageFlipY) => {
- if (!stageRect || !rootRect || !imageSize || !cropRect || !imageScale)
- return undefined;
- const viewRect = rectNormalizeOffset(rectClone(rootRect));
- const viewCenter = rectCenter(viewRect);
- const stageCenter = rectCenter(stageRect);
- const imageRect = rectCreateFromSize(imageSize);
- const imageCenter = rectCenter(imageRect);
- const imagePerspective = vectorCreate(imagePerspectiveX, imagePerspectiveY);
- // get base crop rect so we can correctly apply transforms
- const cropRectBase = getBaseCropRect(imageSize, cropRect, imageRotation);
- const cropRectBaseCenter = rectCenter(cropRectBase);
- const imageTranslation = vectorSubtract(vectorClone(imageCenter), cropRectBaseCenter);
- // calculate stage center offset from view center
- const imageOffset = vectorSubtract(vectorClone(stageCenter), viewCenter);
- // correct for stage offset
- imageTranslation.x += imageOffset.x;
- imageTranslation.y += imageOffset.y;
- // set origin of translation (so rotates around center of selection)
- const imageOrigin = vectorInvert(vectorClone(imageTranslation));
- // correct for stage offset
- imageOrigin.x += imageOffset.x;
- imageOrigin.y += imageOffset.y;
- // correct for image selection offset relative to view
- const imageSelectionCenter = rectCenter(rectTranslate(rectClone(imageSelectionRect), stageRect));
- const imageSelectionOffset = vectorSubtract(imageSelectionCenter, stageCenter);
- vectorAdd(imageTranslation, imageSelectionOffset);
- return {
- // offset: imageOffset,
- origin: imageOrigin,
- translation: imageTranslation,
- rotation: {
- x: imageFlipY ? Math.PI : 0,
- y: imageFlipX ? Math.PI : 0,
- z: imageRotation,
- },
- perspective: imagePerspective,
- scale: imageScale,
- };
- };
- // @ts-ignore
- var historyCreate = (getState, setState) => {
- // set up pub/sub for history object
- const { sub, pub } = pubsub();
- // current history state
- //let baseState;//
- const entries = [];
- const index = writable(0);
- const subs = [];
- const updateSubs = () => subs.forEach((cb) => cb({ index: get_store_value(index), length: entries.length }));
- const history = {
- get index() {
- return get_store_value(index);
- },
- set index(i) {
- // validate new index
- i = Number.isInteger(i) ? i : 0;
- i = clamp(i, 0, entries.length - 1);
- // remember
- index.set(i);
- setState(entries[history.index]); // || baseState);
- // update subs
- updateSubs();
- },
- get state() {
- return entries[entries.length - 1]; // || baseState;
- },
- length() {
- return entries.length;
- },
- undo() {
- const newIndex = history.index--;
- pub('undo', newIndex);
- return newIndex;
- },
- redo() {
- const newIndex = history.index++;
- pub('redo', history.index);
- return newIndex;
- },
- revert() {
- entries.length = 1; // retain first state
- history.index = 0;
- pub('revert');
- },
- write(state) {
- // write history entry
- if (state) {
- setState({
- ...getState(),
- ...state,
- });
- }
- const newState = getState();
- const lastState = entries[entries.length - 1];
- // don't update if new state isn't different
- if (JSON.stringify(newState) === JSON.stringify(lastState))
- return;
- // reset length to current index
- entries.length = history.index + 1;
- // add new entry
- entries.push(newState);
- // move pointer to last added index
- index.set(entries.length - 1);
- updateSubs();
- },
- set(state = {}) {
- // set clears all entries
- entries.length = 0;
- history.index = 0;
- // set new entries
- const newStateEntries = !Array.isArray(state) ? [state] : state;
- // add new entries
- entries.push(...newStateEntries);
- // move pointer to last added index
- history.index = entries.length - 1;
- },
- get() {
- return [...entries];
- },
- subscribe(cb) {
- subs.push(cb);
- cb({ index: history.index, length: entries.length });
- return () => subs.splice(subs.indexOf(cb), 1);
- },
- on: sub,
- };
- return history;
- };
- var isChrome = () => isBrowser() && !!window['chrome'];
- var imageBitmapToImageData = async (imageBitmap) => canvasToImageData(await imageDataToCanvas(imageBitmap));
- var blobToImageBitmap = (file, ImageOrienter, canvasMemoryLimit) => new Promise((resolve, reject) => {
- (async () => {
- // get orientation of image, should return 1 for normal orientation
- const orientation = await ImageOrienter.read(file);
- // helper method to apply orientation fix if needed
- const toImageData = (file) => blobToImageData(file, canvasMemoryLimit)
- .then((imageData) => ImageOrienter.apply(imageData, orientation))
- .then(resolve)
- .catch(reject);
- // if cannot create image bitmaps in worker
- // Safari 15 cannot correctly apply orientation, also it will choke on very big images when trying to createImageBitmap in thread, so lets just do it on the main thread
- // we'll ignore safari for now
- if (isSVGFile(file) || !canCreateImageBitmap() || isSafari$1())
- return toImageData(file);
- // create image bitmap in thread
- let imageBitmap;
- try {
- imageBitmap = await thread((file, done) => createImageBitmap(file)
- .then((bitmap) => done(null, bitmap))
- .catch(done), [file]);
- }
- catch (err) {
- // fails silently on purpose, we'll try to turn the blob into image data in the main thread
- // console.error(err);
- }
- // no bitmap returned, something went wrong in `createImageBitmap` logic
- if (!imageBitmap || !imageBitmap.width)
- return toImageData(file);
- // if the browser can't orient images, we need to correct the orientation now
- if (!(await canOrientImages()))
- return resolve(ImageOrienter.apply(imageBitmap, orientation));
- // need to convert so oriented image can be used as WebGL texture
- // converting ImageBitmap to <canvas> (and then optionally to image data) fixes a Chrome render bug where the
- // ImageBitmap when used in WebGL doesn't render in the correct orientation
- // https://bugs.chromium.org/p/chromium/issues/detail?id=1082451&q=orientation%20imagebitmap&can=2
- if (isChrome() && orientation > 1)
- return resolve(await imageBitmapToImageData(imageBitmap));
- // yay we got our bitmap
- resolve(imageBitmap);
- })();
- });
- var imageDataContain = (imageData, size) => new Promise(async (resolve) => {
- if (imageData.width < size.width && imageData.height < size.height)
- return resolve(imageData);
- const scalar = Math.min(size.width / imageData.width, size.height / imageData.height);
- // scale
- const targetWidth = scalar * imageData.width;
- const targetHeight = scalar * imageData.height;
- const canvas = h('canvas', {
- width: targetWidth,
- height: targetHeight,
- });
- const ctx = canvas.getContext('2d');
- const data = isImageData(imageData)
- ? (await imageDataToCanvas(imageData))
- : imageData;
- ctx.drawImage(data, 0, 0, targetWidth, targetHeight);
- resolve(canvasToImageData(canvas));
- });
- var hexToRGB = (str) => {
- const [, q, w, e] = str.split('');
- str = str.length === 4 ? `#${q}${q}${w}${w}${e}${e}` : str;
- const [, r, g, b] = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(str);
- return [r, g, b].map((v) => parseInt(v, 16) / 255);
- };
- var colorStringToColorArray = (color) => {
- color = color.trim();
- // if rgba(128, 128, 128, .5)
- if (/^rgba/.test(color)) {
- return color
- .substr(5)
- .split(',')
- .map(parseFloat)
- .map((v, i) => v / (i === 3 ? 1 : 255));
- }
- // if rgb(128, 128, 128)
- if (/^rgb/.test(color)) {
- return color
- .substr(4)
- .split(',')
- .map(parseFloat)
- .map((v) => v / 255);
- }
- // if #777
- if (/^#/.test(color)) {
- return hexToRGB(color);
- }
- // is possibly 255, 0, 0
- if (/[0-9]{1,3}\s?,\s?[0-9]{1,3}\s?,\s?[0-9]{1,3}/.test(color)) {
- return color
- .split(',')
- .map((v) => parseInt(v, 10))
- .map((v) => v / 255);
- }
- };
- let result$4 = null;
- var supportsWebGL = () => {
- if (result$4 === null) {
- const canvas = h('canvas');
- result$4 = !!getWebGLContext(canvas);
- releaseCanvas(canvas);
- }
- return result$4;
- };
- var isBitmap = (file) => /^image/.test(file.type) && !/svg/.test(file.type);
- // @ts-ignore
- const COLOR_MATRIX_IDENTITY = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
- const SPRING_PROPS = { precision: 0.0001 };
- const SPRING_PROPS_FRACTION = { precision: SPRING_PROPS.precision * 0.01 };
- var createImage = (data, size, options = {}) => {
- const { resize: resizeInitial = 1, opacity: opacityInitial = 0 } = options;
- const stores = {
- // interface
- opacity: [spring(opacityInitial, { ...SPRING_PROPS, stiffness: 0.1 }), passthrough],
- resize: [spring(resizeInitial, { ...SPRING_PROPS, stiffness: 0.1 }), passthrough],
- // transforms
- translation: [spring(undefined, SPRING_PROPS), passthrough],
- rotation: [spring(undefined, SPRING_PROPS_FRACTION), passthrough],
- origin: [spring(undefined, SPRING_PROPS), passthrough],
- scale: [spring(undefined, SPRING_PROPS_FRACTION), passthrough],
- gamma: [spring(undefined, SPRING_PROPS_FRACTION), (v) => v || 1],
- vignette: [spring(undefined, SPRING_PROPS_FRACTION), (v) => v || 0],
- colorMatrix: [
- spring([...COLOR_MATRIX_IDENTITY], SPRING_PROPS),
- (v) => v || [...COLOR_MATRIX_IDENTITY],
- ],
- convolutionMatrix: [writable(undefined), (v) => (v && v.clarity) || undefined],
- backgroundColor: [spring(undefined, SPRING_PROPS), passthrough],
- };
- // shortcut to quickly get all stores from the stores object
- const storeEntries = Object.entries(stores).map(([key, value]) => [key, value[0]]);
- const storeArray = storeEntries.map(([, store]) => store);
- // create quick accessors to store value setter functions, best to do ones on creation instead of on each update
- const storeSetters = Object.entries(stores).reduce((prev, [key, value]) => {
- const [store, getValue] = value;
- prev[key] = (value, opts) => store.set(getValue(value), opts);
- return prev;
- }, {});
- // holds current derived state so can be easily read from from the outside
- let stateCache;
- //
- const state = derived(storeArray, (storeValues) => {
- // get new state
- stateCache = storeValues.reduce((calculatedState, value, index) => {
- const key = storeEntries[index][0];
- calculatedState[key] = value;
- return calculatedState;
- }, {});
- // set base image props
- stateCache.data = data;
- stateCache.size = size;
- // apply resize modifier (is at index 1 of storeValues)
- stateCache.scale *= storeValues[1];
- return stateCache;
- });
- state.get = () => stateCache;
- state.set = (props, animate) => {
- const opts = { hard: !animate };
- Object.entries(props).forEach(([key, value]) => {
- if (!storeSetters[key])
- return;
- storeSetters[key](value, opts);
- });
- };
- return state;
- };
- var storeList = () => {
- const stores = [];
- const subscribers = [];
- const state = [];
- const storeDidUpdate = (store, value) => {
- const index = stores.indexOf(store);
- if (index < 0)
- return;
- state[index] = value;
- triggerUpdate();
- };
- const triggerUpdate = () => {
- subscribers.forEach((fn) => fn(state));
- };
- const addStore = (store) => {
- store.unsub = store.subscribe((value) => storeDidUpdate(store, value));
- triggerUpdate();
- };
- const unshift = (store) => {
- stores.unshift(store);
- addStore(store);
- };
- const push = (store) => {
- stores.push(store);
- addStore(store);
- };
- const clear = () => {
- stores.forEach((store) => store.unsub());
- stores.length = 0;
- state.length = 0;
- };
- const remove = (store) => {
- store.unsub();
- const index = stores.indexOf(store);
- stores.splice(index, 1);
- state.splice(index, 1);
- };
- const subscribe = (fn) => {
- subscribers.push(fn);
- return () => {
- subscribers.splice(subscribers.indexOf(fn), 1);
- };
- };
- const forEach = (fn) => stores.forEach(fn);
- const filter = (fn) => stores.filter(fn);
- const get = (index) => stores[index];
- return {
- get length() {
- return stores.length;
- },
- clear,
- unshift,
- get,
- push,
- remove,
- forEach,
- filter,
- subscribe,
- };
- };
- var isDarkColor = (color) => {
- return color[0] < 0.25 && color[1] < 0.25 && color[2] < 0.25;
- };
- /* src/core/ui/index.svelte generated by Svelte v3.37.0 */
- const { window: window_1$1 } = globals;
- function create_if_block_1$7(ctx) {
- let t;
- let if_block1_anchor;
- let current;
- let if_block0 = /*isStatusVisible*/ ctx[25] && create_if_block_6$1(ctx);
- let if_block1 = /*isReady*/ ctx[26] && create_if_block_2$6(ctx);
- return {
- c() {
- if (if_block0) if_block0.c();
- t = space();
- if (if_block1) if_block1.c();
- if_block1_anchor = empty();
- },
- m(target, anchor) {
- if (if_block0) if_block0.m(target, anchor);
- insert(target, t, anchor);
- if (if_block1) if_block1.m(target, anchor);
- insert(target, if_block1_anchor, anchor);
- current = true;
- },
- p(ctx, dirty) {
- if (/*isStatusVisible*/ ctx[25]) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty[0] & /*isStatusVisible*/ 33554432) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_6$1(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(t.parentNode, t);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (/*isReady*/ ctx[26]) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- if (dirty[0] & /*isReady*/ 67108864) {
- transition_in(if_block1, 1);
- }
- } else {
- if_block1 = create_if_block_2$6(ctx);
- if_block1.c();
- transition_in(if_block1, 1);
- if_block1.m(if_block1_anchor.parentNode, if_block1_anchor);
- }
- } else if (if_block1) {
- group_outros();
- transition_out(if_block1, 1, 1, () => {
- if_block1 = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- transition_in(if_block1);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- transition_out(if_block1);
- current = false;
- },
- d(detaching) {
- if (if_block0) if_block0.d(detaching);
- if (detaching) detach(t);
- if (if_block1) if_block1.d(detaching);
- if (detaching) detach(if_block1_anchor);
- }
- };
- }
- // (2463:8) {#if isStatusVisible}
- function create_if_block_6$1(ctx) {
- let div;
- let p;
- let current_block_type_index;
- let if_block;
- let div_style_value;
- let current;
- const if_block_creators = [create_if_block_7, create_if_block_8];
- const if_blocks = [];
- function select_block_type(ctx, dirty) {
- if (/*isSupportsError*/ ctx[23]) return 0;
- if (/*statusState*/ ctx[13]) return 1;
- return -1;
- }
- if (~(current_block_type_index = select_block_type(ctx))) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- }
- return {
- c() {
- div = element("div");
- p = element("p");
- if (if_block) if_block.c();
- attr(p, "style", /*statusTransform*/ ctx[38]);
- attr(div, "class", "PinturaStatus");
- attr(div, "style", div_style_value = `opacity: ${/*$statusOpacity*/ ctx[24]}`);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- append(div, p);
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].m(p, null);
- }
- current = true;
- },
- p(ctx, dirty) {
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type(ctx);
- if (current_block_type_index === previous_block_index) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- }
- } else {
- if (if_block) {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- }
- if (~current_block_type_index) {
- if_block = if_blocks[current_block_type_index];
- if (!if_block) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block.c();
- } else {
- if_block.p(ctx, dirty);
- }
- transition_in(if_block, 1);
- if_block.m(p, null);
- } else {
- if_block = null;
- }
- }
- if (!current || dirty[1] & /*statusTransform*/ 128) {
- attr(p, "style", /*statusTransform*/ ctx[38]);
- }
- if (!current || dirty[0] & /*$statusOpacity*/ 16777216 && div_style_value !== (div_style_value = `opacity: ${/*$statusOpacity*/ ctx[24]}`)) {
- attr(div, "style", div_style_value);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].d();
- }
- }
- };
- }
- // (2476:42)
- function create_if_block_8(ctx) {
- let statusmessage;
- let t;
- let if_block_anchor;
- let current;
- statusmessage = new StatusMessage({
- props: {
- text: /*statusState*/ ctx[13].text || "",
- onmeasure: /*offsetAside*/ ctx[126]
- }
- });
- let if_block = /*statusState*/ ctx[13].aside && create_if_block_9(ctx);
- return {
- c() {
- create_component(statusmessage.$$.fragment);
- t = space();
- if (if_block) if_block.c();
- if_block_anchor = empty();
- },
- m(target, anchor) {
- mount_component(statusmessage, target, anchor);
- insert(target, t, anchor);
- if (if_block) if_block.m(target, anchor);
- insert(target, if_block_anchor, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const statusmessage_changes = {};
- if (dirty[0] & /*statusState*/ 8192) statusmessage_changes.text = /*statusState*/ ctx[13].text || "";
- statusmessage.$set(statusmessage_changes);
- if (/*statusState*/ ctx[13].aside) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty[0] & /*statusState*/ 8192) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block_9(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(if_block_anchor.parentNode, if_block_anchor);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(statusmessage.$$.fragment, local);
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(statusmessage.$$.fragment, local);
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- destroy_component(statusmessage, detaching);
- if (detaching) detach(t);
- if (if_block) if_block.d(detaching);
- if (detaching) detach(if_block_anchor);
- }
- };
- }
- // (2466:20) {#if isSupportsError}
- function create_if_block_7(ctx) {
- let statusmessage;
- let t;
- let statusaside;
- let current;
- statusmessage = new StatusMessage({
- props: {
- text: /*isSupportsError*/ ctx[23],
- onmeasure: /*offsetAside*/ ctx[126]
- }
- });
- statusaside = new StatusAside({
- props: {
- class: "PinturaStatusIcon",
- offset: /*$asideOffset*/ ctx[42],
- opacity: /*$asideOpacity*/ ctx[43],
- $$slots: { default: [create_default_slot_4$1] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(statusmessage.$$.fragment);
- t = space();
- create_component(statusaside.$$.fragment);
- },
- m(target, anchor) {
- mount_component(statusmessage, target, anchor);
- insert(target, t, anchor);
- mount_component(statusaside, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const statusmessage_changes = {};
- if (dirty[0] & /*isSupportsError*/ 8388608) statusmessage_changes.text = /*isSupportsError*/ ctx[23];
- statusmessage.$set(statusmessage_changes);
- const statusaside_changes = {};
- if (dirty[1] & /*$asideOffset*/ 2048) statusaside_changes.offset = /*$asideOffset*/ ctx[42];
- if (dirty[1] & /*$asideOpacity*/ 4096) statusaside_changes.opacity = /*$asideOpacity*/ ctx[43];
- if (dirty[0] & /*locale*/ 4 | dirty[11] & /*$$scope*/ 134217728) {
- statusaside_changes.$$scope = { dirty, ctx };
- }
- statusaside.$set(statusaside_changes);
- },
- i(local) {
- if (current) return;
- transition_in(statusmessage.$$.fragment, local);
- transition_in(statusaside.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(statusmessage.$$.fragment, local);
- transition_out(statusaside.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(statusmessage, detaching);
- if (detaching) detach(t);
- destroy_component(statusaside, detaching);
- }
- };
- }
- // (2479:24) {#if statusState.aside}
- function create_if_block_9(ctx) {
- let statusaside;
- let current;
- statusaside = new StatusAside({
- props: {
- class: "PinturaStatusButton",
- offset: /*$asideOffset*/ ctx[42],
- opacity: /*$asideOpacity*/ ctx[43],
- $$slots: { default: [create_default_slot_6] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(statusaside.$$.fragment);
- },
- m(target, anchor) {
- mount_component(statusaside, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const statusaside_changes = {};
- if (dirty[1] & /*$asideOffset*/ 2048) statusaside_changes.offset = /*$asideOffset*/ ctx[42];
- if (dirty[1] & /*$asideOpacity*/ 4096) statusaside_changes.opacity = /*$asideOpacity*/ ctx[43];
- if (dirty[0] & /*statusState*/ 8192 | dirty[11] & /*$$scope*/ 134217728) {
- statusaside_changes.$$scope = { dirty, ctx };
- }
- statusaside.$set(statusaside_changes);
- },
- i(local) {
- if (current) return;
- transition_in(statusaside.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(statusaside.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(statusaside, detaching);
- }
- };
- }
- // (2485:32) {#if statusState.progressIndicator.visible}
- function create_if_block_11(ctx) {
- let progressindicator;
- let current;
- progressindicator = new ProgressIndicator({
- props: {
- progress: /*statusState*/ ctx[13].progressIndicator.progress
- }
- });
- return {
- c() {
- create_component(progressindicator.$$.fragment);
- },
- m(target, anchor) {
- mount_component(progressindicator, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const progressindicator_changes = {};
- if (dirty[0] & /*statusState*/ 8192) progressindicator_changes.progress = /*statusState*/ ctx[13].progressIndicator.progress;
- progressindicator.$set(progressindicator_changes);
- },
- i(local) {
- if (current) return;
- transition_in(progressindicator.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(progressindicator.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(progressindicator, detaching);
- }
- };
- }
- // (2491:32) {#if statusState.closeButton && statusState.text}
- function create_if_block_10(ctx) {
- let button;
- let current;
- const button_spread_levels = [/*statusState*/ ctx[13].closeButton, { hideLabel: true }];
- let button_props = {};
- for (let i = 0; i < button_spread_levels.length; i += 1) {
- button_props = assign(button_props, button_spread_levels[i]);
- }
- button = new Button({ props: button_props });
- return {
- c() {
- create_component(button.$$.fragment);
- },
- m(target, anchor) {
- mount_component(button, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const button_changes = (dirty[0] & /*statusState*/ 8192)
- ? get_spread_update(button_spread_levels, [
- get_spread_object(/*statusState*/ ctx[13].closeButton),
- button_spread_levels[1]
- ])
- : {};
- button.$set(button_changes);
- },
- i(local) {
- if (current) return;
- transition_in(button.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(button.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(button, detaching);
- }
- };
- }
- // (2480:28) <StatusAside class="PinturaStatusButton" offset={$asideOffset} opacity={$asideOpacity} >
- function create_default_slot_6(ctx) {
- let t;
- let if_block1_anchor;
- let current;
- let if_block0 = /*statusState*/ ctx[13].progressIndicator.visible && create_if_block_11(ctx);
- let if_block1 = /*statusState*/ ctx[13].closeButton && /*statusState*/ ctx[13].text && create_if_block_10(ctx);
- return {
- c() {
- if (if_block0) if_block0.c();
- t = space();
- if (if_block1) if_block1.c();
- if_block1_anchor = empty();
- },
- m(target, anchor) {
- if (if_block0) if_block0.m(target, anchor);
- insert(target, t, anchor);
- if (if_block1) if_block1.m(target, anchor);
- insert(target, if_block1_anchor, anchor);
- current = true;
- },
- p(ctx, dirty) {
- if (/*statusState*/ ctx[13].progressIndicator.visible) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty[0] & /*statusState*/ 8192) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_11(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(t.parentNode, t);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (/*statusState*/ ctx[13].closeButton && /*statusState*/ ctx[13].text) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- if (dirty[0] & /*statusState*/ 8192) {
- transition_in(if_block1, 1);
- }
- } else {
- if_block1 = create_if_block_10(ctx);
- if_block1.c();
- transition_in(if_block1, 1);
- if_block1.m(if_block1_anchor.parentNode, if_block1_anchor);
- }
- } else if (if_block1) {
- group_outros();
- transition_out(if_block1, 1, 1, () => {
- if_block1 = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- transition_in(if_block1);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- transition_out(if_block1);
- current = false;
- },
- d(detaching) {
- if (if_block0) if_block0.d(detaching);
- if (detaching) detach(t);
- if (if_block1) if_block1.d(detaching);
- if (detaching) detach(if_block1_anchor);
- }
- };
- }
- // (2474:28) <Icon>
- function create_default_slot_5(ctx) {
- let g;
- let raw_value = /*locale*/ ctx[2].iconSupportError + "";
- return {
- c() {
- g = svg_element("g");
- },
- m(target, anchor) {
- insert(target, g, anchor);
- g.innerHTML = raw_value;
- },
- p(ctx, dirty) {
- if (dirty[0] & /*locale*/ 4 && raw_value !== (raw_value = /*locale*/ ctx[2].iconSupportError + "")) g.innerHTML = raw_value; },
- d(detaching) {
- if (detaching) detach(g);
- }
- };
- }
- // (2469:24) <StatusAside class="PinturaStatusIcon" offset={$asideOffset} opacity={$asideOpacity} >
- function create_default_slot_4$1(ctx) {
- let icon;
- let current;
- icon = new Icon({
- props: {
- $$slots: { default: [create_default_slot_5] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(icon.$$.fragment);
- },
- m(target, anchor) {
- mount_component(icon, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const icon_changes = {};
- if (dirty[0] & /*locale*/ 4 | dirty[11] & /*$$scope*/ 134217728) {
- icon_changes.$$scope = { dirty, ctx };
- }
- icon.$set(icon_changes);
- },
- i(local) {
- if (current) return;
- transition_in(icon.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(icon, detaching);
- }
- };
- }
- // (2501:8) {#if isReady}
- function create_if_block_2$6(ctx) {
- let t0;
- let t1;
- let current_block_type_index;
- let if_block2;
- let t2;
- let canvas;
- let t3;
- let div;
- let current;
- let if_block0 = /*enableToolbar*/ ctx[6] && create_if_block_5$3(ctx);
- let if_block1 = /*shouldRenderTabs*/ ctx[17] && /*showUtils*/ ctx[15] && create_if_block_4$4(ctx);
- const if_block_creators = [create_if_block_3$4, create_else_block$2];
- const if_blocks = [];
- function select_block_type_1(ctx, dirty) {
- if (/*shouldRenderTabs*/ ctx[17]) return 0;
- return 1;
- }
- current_block_type_index = select_block_type_1(ctx);
- if_block2 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- canvas = new Canvas({
- props: {
- animate: /*$shouldAnimate*/ ctx[18],
- pixelRatio: /*$pixelRatio*/ ctx[46],
- backgroundColor: /*$rootBackgroundColor*/ ctx[47],
- maskRect: /*$imageSelectionRectPresentation*/ ctx[37],
- maskOpacity: /*imageCanvasState*/ ctx[36]
- ? /*imageCanvasState*/ ctx[36].maskOpacity
- : 1,
- maskFrameOpacity: /*$utilSelectedStore*/ ctx[48] === "frame" && /*$stagePadded*/ ctx[49]
- ? 0
- : 0.95,
- images: /*$activeImages*/ ctx[22],
- interfaceImages: /*$interfaceImages*/ ctx[50],
- loadImageData: /*imageSourceToImageData*/ ctx[8],
- willRender: /*func_2*/ ctx[282]
- }
- });
- return {
- c() {
- if (if_block0) if_block0.c();
- t0 = space();
- if (if_block1) if_block1.c();
- t1 = space();
- if_block2.c();
- t2 = space();
- create_component(canvas.$$.fragment);
- t3 = space();
- div = element("div");
- attr(div, "class", "PinturaRootPortal");
- },
- m(target, anchor) {
- if (if_block0) if_block0.m(target, anchor);
- insert(target, t0, anchor);
- if (if_block1) if_block1.m(target, anchor);
- insert(target, t1, anchor);
- if_blocks[current_block_type_index].m(target, anchor);
- insert(target, t2, anchor);
- mount_component(canvas, target, anchor);
- insert(target, t3, anchor);
- insert(target, div, anchor);
- /*div_binding*/ ctx[283](div);
- current = true;
- },
- p(ctx, dirty) {
- if (/*enableToolbar*/ ctx[6]) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty[0] & /*enableToolbar*/ 64) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_5$3(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(t0.parentNode, t0);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (/*shouldRenderTabs*/ ctx[17] && /*showUtils*/ ctx[15]) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- if (dirty[0] & /*shouldRenderTabs, showUtils*/ 163840) {
- transition_in(if_block1, 1);
- }
- } else {
- if_block1 = create_if_block_4$4(ctx);
- if_block1.c();
- transition_in(if_block1, 1);
- if_block1.m(t1.parentNode, t1);
- }
- } else if (if_block1) {
- group_outros();
- transition_out(if_block1, 1, 1, () => {
- if_block1 = null;
- });
- check_outros();
- }
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type_1(ctx);
- if (current_block_type_index === previous_block_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- } else {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- if_block2 = if_blocks[current_block_type_index];
- if (!if_block2) {
- if_block2 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block2.c();
- } else {
- if_block2.p(ctx, dirty);
- }
- transition_in(if_block2, 1);
- if_block2.m(t2.parentNode, t2);
- }
- const canvas_changes = {};
- if (dirty[0] & /*$shouldAnimate*/ 262144) canvas_changes.animate = /*$shouldAnimate*/ ctx[18];
- if (dirty[1] & /*$pixelRatio*/ 32768) canvas_changes.pixelRatio = /*$pixelRatio*/ ctx[46];
- if (dirty[1] & /*$rootBackgroundColor*/ 65536) canvas_changes.backgroundColor = /*$rootBackgroundColor*/ ctx[47];
- if (dirty[1] & /*$imageSelectionRectPresentation*/ 64) canvas_changes.maskRect = /*$imageSelectionRectPresentation*/ ctx[37];
- if (dirty[1] & /*imageCanvasState*/ 32) canvas_changes.maskOpacity = /*imageCanvasState*/ ctx[36]
- ? /*imageCanvasState*/ ctx[36].maskOpacity
- : 1;
- if (dirty[1] & /*$utilSelectedStore, $stagePadded*/ 393216) canvas_changes.maskFrameOpacity = /*$utilSelectedStore*/ ctx[48] === "frame" && /*$stagePadded*/ ctx[49]
- ? 0
- : 0.95;
- if (dirty[0] & /*$activeImages*/ 4194304) canvas_changes.images = /*$activeImages*/ ctx[22];
- if (dirty[1] & /*$interfaceImages*/ 524288) canvas_changes.interfaceImages = /*$interfaceImages*/ ctx[50];
- if (dirty[0] & /*imageSourceToImageData*/ 256) canvas_changes.loadImageData = /*imageSourceToImageData*/ ctx[8];
- if (dirty[0] & /*willRenderCanvas, blendShapes*/ 268435488 | dirty[1] & /*$imageAnnotation, $imageDecoration, $imageFrame, $imageOverlay*/ 15728640) canvas_changes.willRender = /*func_2*/ ctx[282];
- canvas.$set(canvas_changes);
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- transition_in(if_block1);
- transition_in(if_block2);
- transition_in(canvas.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- transition_out(if_block1);
- transition_out(if_block2);
- transition_out(canvas.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (if_block0) if_block0.d(detaching);
- if (detaching) detach(t0);
- if (if_block1) if_block1.d(detaching);
- if (detaching) detach(t1);
- if_blocks[current_block_type_index].d(detaching);
- if (detaching) detach(t2);
- destroy_component(canvas, detaching);
- if (detaching) detach(t3);
- if (detaching) detach(div);
- /*div_binding*/ ctx[283](null);
- }
- };
- }
- // (2502:12) {#if enableToolbar}
- function create_if_block_5$3(ctx) {
- let div;
- let dynamiccomponenttree;
- let current;
- let mounted;
- let dispose;
- dynamiccomponenttree = new DynamicComponentTree_1({
- props: { items: /*toolbarItems*/ ctx[39] }
- });
- return {
- c() {
- div = element("div");
- create_component(dynamiccomponenttree.$$.fragment);
- attr(div, "class", "PinturaNav PinturaNavTools");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(dynamiccomponenttree, div, null);
- current = true;
- if (!mounted) {
- dispose = [
- listen(div, "measure", /*measure_handler*/ ctx[267]),
- action_destroyer(measurable.call(null, div))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- const dynamiccomponenttree_changes = {};
- if (dirty[1] & /*toolbarItems*/ 256) dynamiccomponenttree_changes.items = /*toolbarItems*/ ctx[39];
- dynamiccomponenttree.$set(dynamiccomponenttree_changes);
- },
- i(local) {
- if (current) return;
- transition_in(dynamiccomponenttree.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(dynamiccomponenttree.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(dynamiccomponenttree);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- // (2512:12) {#if shouldRenderTabs && showUtils}
- function create_if_block_4$4(ctx) {
- let div;
- let scrollable;
- let current;
- scrollable = new Scrollable({
- props: {
- elasticity: /*elasticityMultiplier*/ ctx[4] * scrollElasticity,
- scrollDirection: /*isLandscape*/ ctx[34] ? "y" : "x",
- $$slots: { default: [create_default_slot_1$4] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- div = element("div");
- create_component(scrollable.$$.fragment);
- attr(div, "class", "PinturaNav PinturaNavMain");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(scrollable, div, null);
- current = true;
- },
- p(ctx, dirty) {
- const scrollable_changes = {};
- if (dirty[0] & /*elasticityMultiplier*/ 16) scrollable_changes.elasticity = /*elasticityMultiplier*/ ctx[4] * scrollElasticity;
- if (dirty[1] & /*isLandscape*/ 8) scrollable_changes.scrollDirection = /*isLandscape*/ ctx[34] ? "y" : "x";
- if (dirty[0] & /*tabsConfig, utilSelected*/ 1074266112 | dirty[1] & /*tabs*/ 1 | dirty[11] & /*$$scope*/ 134217728) {
- scrollable_changes.$$scope = { dirty, ctx };
- }
- scrollable.$set(scrollable_changes);
- },
- i(local) {
- if (current) return;
- transition_in(scrollable.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(scrollable.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(scrollable);
- }
- };
- }
- // (2524:28) <Icon>
- function create_default_slot_3$1(ctx) {
- let g;
- let raw_value = /*tab*/ ctx[367].icon + "";
- return {
- c() {
- g = svg_element("g");
- },
- m(target, anchor) {
- insert(target, g, anchor);
- g.innerHTML = raw_value;
- },
- p(ctx, dirty) {
- if (dirty[11] & /*tab*/ 67108864 && raw_value !== (raw_value = /*tab*/ ctx[367].icon + "")) g.innerHTML = raw_value; },
- d(detaching) {
- if (detaching) detach(g);
- }
- };
- }
- // (2518:24) <TabList {...tabsConfig} {tabs} on:select={({ detail }) => (utilSelected = detail)} let:tab >
- function create_default_slot_2$3(ctx) {
- let icon;
- let t0;
- let span;
- let t1_value = /*tab*/ ctx[367].label + "";
- let t1;
- let current;
- icon = new Icon({
- props: {
- $$slots: { default: [create_default_slot_3$1] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(icon.$$.fragment);
- t0 = space();
- span = element("span");
- t1 = text(t1_value);
- },
- m(target, anchor) {
- mount_component(icon, target, anchor);
- insert(target, t0, anchor);
- insert(target, span, anchor);
- append(span, t1);
- current = true;
- },
- p(ctx, dirty) {
- const icon_changes = {};
- if (dirty[11] & /*$$scope, tab*/ 201326592) {
- icon_changes.$$scope = { dirty, ctx };
- }
- icon.$set(icon_changes);
- if ((!current || dirty[11] & /*tab*/ 67108864) && t1_value !== (t1_value = /*tab*/ ctx[367].label + "")) set_data(t1, t1_value);
- },
- i(local) {
- if (current) return;
- transition_in(icon.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(icon, detaching);
- if (detaching) detach(t0);
- if (detaching) detach(span);
- }
- };
- }
- // (2514:20) <Scrollable elasticity={elasticityMultiplier * scrollElasticity} scrollDirection={isLandscape ? 'y' : 'x'} >
- function create_default_slot_1$4(ctx) {
- let tablist;
- let current;
- const tablist_spread_levels = [/*tabsConfig*/ ctx[30], { tabs: /*tabs*/ ctx[31] }];
- let tablist_props = {
- $$slots: {
- default: [
- create_default_slot_2$3,
- ({ tab }) => ({ 367: tab }),
- ({ tab }) => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, tab ? 67108864 : 0]
- ]
- },
- $$scope: { ctx }
- };
- for (let i = 0; i < tablist_spread_levels.length; i += 1) {
- tablist_props = assign(tablist_props, tablist_spread_levels[i]);
- }
- tablist = new TabList({ props: tablist_props });
- tablist.$on("select", /*select_handler*/ ctx[268]);
- return {
- c() {
- create_component(tablist.$$.fragment);
- },
- m(target, anchor) {
- mount_component(tablist, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const tablist_changes = (dirty[0] & /*tabsConfig*/ 1073741824 | dirty[1] & /*tabs*/ 1)
- ? get_spread_update(tablist_spread_levels, [
- dirty[0] & /*tabsConfig*/ 1073741824 && get_spread_object(/*tabsConfig*/ ctx[30]),
- dirty[1] & /*tabs*/ 1 && { tabs: /*tabs*/ ctx[31] }
- ])
- : {};
- if (dirty[11] & /*$$scope, tab*/ 201326592) {
- tablist_changes.$$scope = { dirty, ctx };
- }
- tablist.$set(tablist_changes);
- },
- i(local) {
- if (current) return;
- transition_in(tablist.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(tablist.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(tablist, detaching);
- }
- };
- }
- // (2557:12) {:else}
- function create_else_block$2(ctx) {
- let panel;
- let updating_component;
- let current;
- function panel_component_binding_1(value) {
- /*panel_component_binding_1*/ ctx[277](value);
- }
- let panel_props = {
- class: "PinturaMain",
- content: {
- .../*utilsMerged*/ ctx[20].find(/*func_1*/ ctx[276]),
- props: /*pluginOptions*/ ctx[7][/*utilSelected*/ ctx[19]]
- },
- locale: /*locale*/ ctx[2],
- isAnimated: /*$shouldAnimate*/ ctx[18],
- stores: /*utilStores*/ ctx[115]
- };
- if (/*pluginInterface*/ ctx[0][/*utilSelected*/ ctx[19]] !== void 0) {
- panel_props.component = /*pluginInterface*/ ctx[0][/*utilSelected*/ ctx[19]];
- }
- panel = new Panel({ props: panel_props });
- binding_callbacks.push(() => bind(panel, "component", panel_component_binding_1));
- panel.$on("measure", /*measure_handler_3*/ ctx[278]);
- panel.$on("show", /*show_handler_1*/ ctx[279]);
- panel.$on("hide", /*hide_handler_1*/ ctx[280]);
- panel.$on("fade", /*fade_handler_1*/ ctx[281]);
- return {
- c() {
- create_component(panel.$$.fragment);
- },
- m(target, anchor) {
- mount_component(panel, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const panel_changes = {};
- if (dirty[0] & /*utilsMerged, utilSelected, pluginOptions*/ 1572992) panel_changes.content = {
- .../*utilsMerged*/ ctx[20].find(/*func_1*/ ctx[276]),
- props: /*pluginOptions*/ ctx[7][/*utilSelected*/ ctx[19]]
- };
- if (dirty[0] & /*locale*/ 4) panel_changes.locale = /*locale*/ ctx[2];
- if (dirty[0] & /*$shouldAnimate*/ 262144) panel_changes.isAnimated = /*$shouldAnimate*/ ctx[18];
- if (!updating_component && dirty[0] & /*pluginInterface, utilSelected*/ 524289) {
- updating_component = true;
- panel_changes.component = /*pluginInterface*/ ctx[0][/*utilSelected*/ ctx[19]];
- add_flush_callback(() => updating_component = false);
- }
- panel.$set(panel_changes);
- },
- i(local) {
- if (current) return;
- transition_in(panel.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(panel.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(panel, detaching);
- }
- };
- }
- // (2531:12) {#if shouldRenderTabs}
- function create_if_block_3$4(ctx) {
- let tabpanels;
- let current;
- const tabpanels_spread_levels = [
- { class: "PinturaMain" },
- { visible: /*utilsVisible*/ ctx[27] },
- /*tabsConfig*/ ctx[30],
- { panels: /*panels*/ ctx[32] }
- ];
- let tabpanels_props = {
- $$slots: {
- default: [
- create_default_slot$a,
- ({ panel }) => ({ 366: panel }),
- ({ panel }) => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, panel ? 33554432 : 0]
- ]
- },
- $$scope: { ctx }
- };
- for (let i = 0; i < tabpanels_spread_levels.length; i += 1) {
- tabpanels_props = assign(tabpanels_props, tabpanels_spread_levels[i]);
- }
- tabpanels = new TabPanels({ props: tabpanels_props });
- tabpanels.$on("measure", /*measure_handler_2*/ ctx[275]);
- return {
- c() {
- create_component(tabpanels.$$.fragment);
- },
- m(target, anchor) {
- mount_component(tabpanels, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const tabpanels_changes = (dirty[0] & /*utilsVisible, tabsConfig*/ 1207959552 | dirty[1] & /*panels*/ 2)
- ? get_spread_update(tabpanels_spread_levels, [
- tabpanels_spread_levels[0],
- dirty[0] & /*utilsVisible*/ 134217728 && { visible: /*utilsVisible*/ ctx[27] },
- dirty[0] & /*tabsConfig*/ 1073741824 && get_spread_object(/*tabsConfig*/ ctx[30]),
- dirty[1] & /*panels*/ 2 && { panels: /*panels*/ ctx[32] }
- ])
- : {};
- if (dirty[0] & /*utilsMerged, pluginOptions, locale, utilSelected, $shouldAnimate, pluginInterface, utilsVisible, utilsVisibleFraction*/ 138150021 | dirty[1] & /*$utilRect*/ 16384 | dirty[11] & /*$$scope, panel*/ 167772160) {
- tabpanels_changes.$$scope = { dirty, ctx };
- }
- tabpanels.$set(tabpanels_changes);
- },
- i(local) {
- if (current) return;
- transition_in(tabpanels.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(tabpanels.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(tabpanels, detaching);
- }
- };
- }
- // (2532:16) <TabPanels class="PinturaMain" visible={utilsVisible} {...tabsConfig} {panels} let:panel on:measure={(e) => ($tabRect = e.detail)} >
- function create_default_slot$a(ctx) {
- let panel;
- let updating_component;
- let current;
- function func(...args) {
- return /*func*/ ctx[269](/*panel*/ ctx[366], ...args);
- }
- function panel_component_binding(value) {
- /*panel_component_binding*/ ctx[270](value, /*panel*/ ctx[366]);
- }
- function show_handler() {
- return /*show_handler*/ ctx[272](/*panel*/ ctx[366]);
- }
- function hide_handler() {
- return /*hide_handler*/ ctx[273](/*panel*/ ctx[366]);
- }
- function fade_handler(...args) {
- return /*fade_handler*/ ctx[274](/*panel*/ ctx[366], ...args);
- }
- let panel_props = {
- content: {
- .../*utilsMerged*/ ctx[20].find(func),
- props: /*pluginOptions*/ ctx[7][/*panel*/ ctx[366]]
- },
- locale: /*locale*/ ctx[2],
- isActive: /*panel*/ ctx[366] === /*utilSelected*/ ctx[19],
- isAnimated: /*$shouldAnimate*/ ctx[18],
- stores: /*utilStores*/ ctx[115]
- };
- if (/*pluginInterface*/ ctx[0][/*panel*/ ctx[366]] !== void 0) {
- panel_props.component = /*pluginInterface*/ ctx[0][/*panel*/ ctx[366]];
- }
- panel = new Panel({ props: panel_props });
- binding_callbacks.push(() => bind(panel, "component", panel_component_binding));
- panel.$on("measure", /*measure_handler_1*/ ctx[271]);
- panel.$on("show", show_handler);
- panel.$on("hide", hide_handler);
- panel.$on("fade", fade_handler);
- return {
- c() {
- create_component(panel.$$.fragment);
- },
- m(target, anchor) {
- mount_component(panel, target, anchor);
- current = true;
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- const panel_changes = {};
- if (dirty[0] & /*utilsMerged, pluginOptions*/ 1048704 | dirty[11] & /*panel*/ 33554432) panel_changes.content = {
- .../*utilsMerged*/ ctx[20].find(func),
- props: /*pluginOptions*/ ctx[7][/*panel*/ ctx[366]]
- };
- if (dirty[0] & /*locale*/ 4) panel_changes.locale = /*locale*/ ctx[2];
- if (dirty[0] & /*utilSelected*/ 524288 | dirty[11] & /*panel*/ 33554432) panel_changes.isActive = /*panel*/ ctx[366] === /*utilSelected*/ ctx[19];
- if (dirty[0] & /*$shouldAnimate*/ 262144) panel_changes.isAnimated = /*$shouldAnimate*/ ctx[18];
- if (!updating_component && dirty[0] & /*pluginInterface*/ 1 | dirty[11] & /*panel*/ 33554432) {
- updating_component = true;
- panel_changes.component = /*pluginInterface*/ ctx[0][/*panel*/ ctx[366]];
- add_flush_callback(() => updating_component = false);
- }
- panel.$set(panel_changes);
- },
- i(local) {
- if (current) return;
- transition_in(panel.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(panel.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(panel, detaching);
- }
- };
- }
- // (2619:4) {#if $disabledTransition > 0}
- function create_if_block$7(ctx) {
- let span;
- let span_style_value;
- return {
- c() {
- span = element("span");
- attr(span, "class", "PinturaEditorOverlay");
- attr(span, "style", span_style_value = `opacity:${/*$disabledTransition*/ ctx[55]}`);
- },
- m(target, anchor) {
- insert(target, span, anchor);
- },
- p(ctx, dirty) {
- if (dirty[1] & /*$disabledTransition*/ 16777216 && span_style_value !== (span_style_value = `opacity:${/*$disabledTransition*/ ctx[55]}`)) {
- attr(span, "style", span_style_value);
- }
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- function create_fragment$u(ctx) {
- let div;
- let t;
- let current;
- let mounted;
- let dispose;
- add_render_callback(/*onwindowresize*/ ctx[266]);
- let if_block0 = /*canRender*/ ctx[40] && create_if_block_1$7(ctx);
- let if_block1 = /*$disabledTransition*/ ctx[55] > 0 && create_if_block$7(ctx);
- return {
- c() {
- div = element("div");
- if (if_block0) if_block0.c();
- t = space();
- if (if_block1) if_block1.c();
- attr(div, "id", /*id*/ ctx[3]);
- attr(div, "class", /*className*/ ctx[33]);
- attr(div, "data-env", /*envStr*/ ctx[35]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (if_block0) if_block0.m(div, null);
- append(div, t);
- if (if_block1) if_block1.m(div, null);
- /*div_binding_1*/ ctx[284](div);
- current = true;
- if (!mounted) {
- dispose = [
- listen(window_1$1, "keydown", /*handleKeydown*/ ctx[131]),
- listen(window_1$1, "keyup", /*handleKeyup*/ ctx[132]),
- listen(window_1$1, "blur", /*handleWindowBlur*/ ctx[133]),
- listen(window_1$1, "paste", /*handlePaste*/ ctx[136]),
- listen(window_1$1, "resize", /*onwindowresize*/ ctx[266]),
- listen(div, "ping", function () {
- if (is_function(/*routePing*/ ctx[41])) /*routePing*/ ctx[41].apply(this, arguments);
- }),
- listen(div, "contextmenu", /*handleContextMenu*/ ctx[134]),
- listen(div, "touchstart", /*handleTouchStart*/ ctx[127], { passive: false }),
- listen(div, "touchmove", /*handleTouchMove*/ ctx[128]),
- listen(div, "pointermove", /*handlePointerMove*/ ctx[129]),
- listen(div, "transitionend", /*handleTransitionEnd*/ ctx[116]),
- listen(div, "dropfiles", /*handleDropFiles*/ ctx[135]),
- listen(div, "measure", /*measure_handler_4*/ ctx[285]),
- action_destroyer(measurable.call(null, div, { observeViewRect: true })),
- action_destroyer(focusvisible.call(null, div)),
- action_destroyer(dropable.call(null, div))
- ];
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- if (/*canRender*/ ctx[40]) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty[1] & /*canRender*/ 512) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_1$7(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(div, t);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (/*$disabledTransition*/ ctx[55] > 0) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- } else {
- if_block1 = create_if_block$7(ctx);
- if_block1.c();
- if_block1.m(div, null);
- }
- } else if (if_block1) {
- if_block1.d(1);
- if_block1 = null;
- }
- if (!current || dirty[0] & /*id*/ 8) {
- attr(div, "id", /*id*/ ctx[3]);
- }
- if (!current || dirty[1] & /*className*/ 4) {
- attr(div, "class", /*className*/ ctx[33]);
- }
- if (!current || dirty[1] & /*envStr*/ 16) {
- attr(div, "data-env", /*envStr*/ ctx[35]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (if_block0) if_block0.d();
- if (if_block1) if_block1.d();
- /*div_binding_1*/ ctx[284](null);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- const imageCropRectElasticity = 5;
- // updating crop selection / the intended selection rect, combined with actual selection rect, used to render elasticity visualisation
- const imageSelectionRectElasticity = 1;
- const STAGE_OVERLAY_ID = "stage-overlay";
- const maxOpacity = 0.85;
- const scrollElasticity = 10;
- const rangeInputElasticity = 5;
- function instance$u($$self, $$props, $$invalidate) {
- let isOverlayModeEnabled;
- let showUtils;
- let maxImageDataSize;
- let preprocessShape;
- let imageTargetSizeCurrent;
- let overlayTop;
- let overlayBottom;
- let overlayLeft;
- let overlayRight;
- let gradientOverlays;
- let canAnimate;
- let acceptsAnimations;
- let canUndo;
- let canRedo;
- let utilsFiltered;
- let utilsAvailable;
- let utilsDefined;
- let utilsMerged;
- let utilSelected;
- let utilTools;
- let utilsVisibleFraction;
- let tabsConfig;
- let tabs;
- let panels;
- let shouldRenderTabs;
- let className;
- let horizontalSpace;
- let hasLimitedSpace;
- let verticalSpace;
- let isModal;
- let isCenteredHorizontally;
- let isCenteredVertically;
- let isCentered;
- let isNarrow;
- let orientation;
- let isLandscape;
- let isCompact;
- let hasSwipeNavigation;
- let shouldRenderUtilTools;
- let navigationHorizontalPreference;
- let navigationVerticalPreference;
- let rootElementComputedStyle;
- let envStr;
- let imageCanvasState;
- let hasProps;
- let missingFeatures;
- let isSupportsError;
- let isStartLoadingImageSource;
- let isImageLoadError;
- let isWaitingForImage;
- let imageLoadProgress;
- let isLoadingImageData;
- let isCreatingImagePreview;
- let isProcessingImage;
- let imageLoadShowProgressIndicator;
- let imageLoadStatusLabel;
- let imageProcessStatusLabel;
- let imageProcessProgress;
- let imageProcessShowProgressIndicator;
- let isImageProcessingError;
- let isCustomStatus;
- let isStatusActive;
- let isStatusVisible;
- let hasAside;
- let statusIndent;
- let statusTransform;
- let toolbarItems;
- let hasClientRect;
- let canRender;
- let hasImageRedaction;
- let imageRedactionScalar;
- let routePing;
- let isReady;
- let $images;
- let $shapePreprocessor;
- let $clientRect;
- let $imageCropAspectRatio;
- let $rootRect;
- let $imageLoadState;
- let $imageCropRect;
- let $imageCropRectIntent;
- let $isInteracting;
- let $imageCropRectSnapshot;
- let $previewShouldUpscale;
- let $imageSelectionRect;
- let $shouldAnimate;
- let $imageSelectionRectIntent;
- let $stageRect;
- let $imageOutputSize;
- let $stageScalar;
- let $imageSize;
- let $presentationScalar;
- let $imageSelectionRectSnapshot;
- let $overlayInset;
- let $imageVisualBounds;
- let $overlaySize;
- let $overlayTopOpacity;
- let $overlayBottomOpacity;
- let $overlayLeftOpacity;
- let $overlayRightOpacity;
- let $imageOverlayMarkup;
- let $imageFile;
- let $imagePreview,
- $$unsubscribe_imagePreview = noop,
- $$subscribe_imagePreview = () => ($$unsubscribe_imagePreview(), $$unsubscribe_imagePreview = subscribe(imagePreview, $$value => $$invalidate(202, $imagePreview = $$value)), imagePreview);
- let $imagePreviewSource;
- let $prefersReducedMotion;
- let $imageState;
- let $tabRect;
- let $history,
- $$unsubscribe_history = noop,
- $$subscribe_history = () => ($$unsubscribe_history(), $$unsubscribe_history = subscribe(history, $$value => $$invalidate(208, $history = $$value)), history);
- let $imageProcessingPreparing;
- let $env;
- let $pointerAccuracy;
- let $pointerHoverable;
- let $imageTransforms;
- let $imagePreviewModifiers;
- let $imageProps;
- let $activeImages;
- let $imageSelectionRectPresentation;
- let $imageVisualLoadComplete;
- let $imageProcessState;
- let $wasProcessingImage;
- let $statusOpacity;
- let $statusWidth;
- let $asideWidth;
- let $statusOffset;
- let $pressedKeysStore;
- let $imageRedaction;
- let $imageScrambler;
- let $imageBackgroundColor;
- let $rootForegroundColor;
- let $rootLineColor;
- let $isInteractingFraction;
- let $asideOffset;
- let $asideOpacity;
- let $toolRect;
- let $utilRect;
- let $pixelRatio;
- let $rootBackgroundColor;
- let $utilSelectedStore;
- let $stagePadded;
- let $interfaceImages;
- let $imageAnnotation;
- let $imageDecoration;
- let $imageFrame;
- let $imageOverlay;
- let $disabledTransition;
- component_subscribe($$self, prefersReducedMotion, $$value => $$invalidate(206, $prefersReducedMotion = $$value));
- $$self.$$.on_destroy.push(() => $$unsubscribe_imagePreview());
- $$self.$$.on_destroy.push(() => $$unsubscribe_history());
- const eventProxy = pubsub();
- const dispatch = createEventDispatcher();
- //
- // View Props
- //
- let { class: klass = undefined } = $$props;
- let { layout: layoutMode = undefined } = $$props;
- let { stores } = $$props;
- let { locale = undefined } = $$props;
- let { id = undefined } = $$props;
- let { util = undefined } = $$props;
- let { utils = undefined } = $$props; // which utils are active (list of ids), or is derived from plugins automatically
- let { animations = "auto" } = $$props;
- let { disabled = false } = $$props;
- let { status = undefined } = $$props;
- let { previewUpscale = false } = $$props;
- let { elasticityMultiplier = 10 } = $$props;
- let { willRevert = () => Promise.resolve(true) } = $$props;
- let { willProcessImage = () => Promise.resolve(true) } = $$props;
- let { willRenderCanvas = passthrough } = $$props;
- let { willRenderToolbar = passthrough } = $$props;
- let { willSetHistoryInitialState = passthrough } = $$props;
- let { enableButtonExport = true } = $$props;
- let { enableButtonRevert = true } = $$props;
- let { enableNavigateHistory = true } = $$props;
- let { enableToolbar = true } = $$props;
- let { enableUtils = true } = $$props;
- let { enableButtonClose = false } = $$props;
- let { enableDropImage = false } = $$props;
- let { enablePasteImage = false } = $$props;
- let { previewImageDataMaxSize = undefined } = $$props;
- let { layoutDirectionPreference = "auto" } = $$props;
- let { layoutHorizontalUtilsPreference = "left" } = $$props;
- let { layoutVerticalUtilsPreference = "bottom" } = $$props;
- let { imagePreviewSrc = undefined } = $$props;
- let { imageOrienter = { read: () => 1, apply: v => v } } = $$props;
- let { pluginComponents = undefined } = $$props;
- let { pluginOptions = {} } = $$props;
- const sub = eventProxy.sub;
- const pluginInterface = {};
- let { root } = $$props;
- let registeredPluginsComponents = [];
- // editor disabled spring for animating in and out disabled state
- const disabledTransition = spring();
- component_subscribe($$self, disabledTransition, value => $$invalidate(55, $disabledTransition = value));
- // this method is used to read image resources (preview image / shape images)
- const glMaxTextureSize = getWebGLTextureSizeLimit() || 1024;
- const maxTextureSize = sizeCreate(glMaxTextureSize, glMaxTextureSize);
- const canvasMemoryLimit = getCanvasMemoryLimit();
- let { imageSourceToImageData = src => isString(src)
- ? // it's a url src
- fetch(src).then(res => {
- if (res.status !== 200) throw `${res.status} (${res.statusText})`;
- return res.blob();
- }).then(blob => blobToImageBitmap(blob, imageOrienter, canvasMemoryLimit)).then(imageData => imageDataContain(imageData, maxImageDataSize))
- : isElement(src)
- ? // assume src is a <canvas>
- new Promise(resolve => resolve(canvasToImageData(src)))
- : // assume src is a File or Blob
- blobToImageBitmap(src, imageOrienter, canvasMemoryLimit).then(imageData => imageDataContain(imageData, maxImageDataSize)) } = $$props;
- const imageProxy = createImageProxy();
- const { file: imageFile, size: imageSize, loadState: imageLoadState, processState: imageProcessState, cropAspectRatio: imageCropAspectRatio, cropLimitToImage: imageCropLimitToImage, crop: imageCropRect, cropMinSize: imageCropMinSize, cropMaxSize: imageCropMaxSize, cropRange: imageCropRange, cropOrigin: imageCropRectOrigin, cropRectAspectRatio: imageCropRectAspectRatio, rotation: imageRotation, rotationRange: imageRotationRange, targetSize: imageOutputSize, flipX: imageFlipX, flipY: imageFlipY, backgroundColor: imageBackgroundColor, colorMatrix: imageColorMatrix, convolutionMatrix: imageConvolutionMatrix, gamma: imageGamma, vignette: imageVignette, noise: imageNoise, decoration: imageDecoration, annotation: imageAnnotation, redaction: imageRedaction, frame: imageFrame, state: imageState } = imageProxy.stores;
- component_subscribe($$self, imageFile, value => $$invalidate(201, $imageFile = value));
- component_subscribe($$self, imageSize, value => $$invalidate(186, $imageSize = value));
- component_subscribe($$self, imageLoadState, value => $$invalidate(180, $imageLoadState = value));
- component_subscribe($$self, imageProcessState, value => $$invalidate(245, $imageProcessState = value));
- component_subscribe($$self, imageCropAspectRatio, value => $$invalidate(293, $imageCropAspectRatio = value));
- component_subscribe($$self, imageCropRect, value => $$invalidate(181, $imageCropRect = value));
- component_subscribe($$self, imageOutputSize, value => $$invalidate(185, $imageOutputSize = value));
- component_subscribe($$self, imageBackgroundColor, value => $$invalidate(265, $imageBackgroundColor = value));
- component_subscribe($$self, imageDecoration, value => $$invalidate(52, $imageDecoration = value));
- component_subscribe($$self, imageAnnotation, value => $$invalidate(51, $imageAnnotation = value));
- component_subscribe($$self, imageRedaction, value => $$invalidate(262, $imageRedaction = value));
- component_subscribe($$self, imageFrame, value => $$invalidate(53, $imageFrame = value));
- component_subscribe($$self, imageState, value => $$invalidate(302, $imageState = value));
- const { images, shapePreprocessor, imageScrambler } = stores;
- component_subscribe($$self, images, value => $$invalidate(177, $images = value));
- component_subscribe($$self, shapePreprocessor, value => $$invalidate(178, $shapePreprocessor = value));
- component_subscribe($$self, imageScrambler, value => $$invalidate(264, $imageScrambler = value));
- // let the world know about state changes
- imageState.subscribe(state => eventProxy.pub("update", state));
- // this will hold the currently selected util
- const utilSelectedStore = writable();
- component_subscribe($$self, utilSelectedStore, value => $$invalidate(48, $utilSelectedStore = value));
- //
- // handles the view rect size, makes sure it is offset from the top
- //
- // root element reference used to read styles
- const rootBackgroundColor = writable([0, 0, 0]);
- component_subscribe($$self, rootBackgroundColor, value => $$invalidate(47, $rootBackgroundColor = value));
- const rootForegroundColor = writable([1, 1, 1]);
- component_subscribe($$self, rootForegroundColor, value => $$invalidate(304, $rootForegroundColor = value));
- const rootLineColor = spring();
- component_subscribe($$self, rootLineColor, value => $$invalidate(305, $rootLineColor = value));
- // client rect is the editor rect excluding scroll offset
- const clientRect = writable();
- component_subscribe($$self, clientRect, value => $$invalidate(16, $clientRect = value));
- // root rect is the editor rect including scroll offset
- const rootRect = writable();
- component_subscribe($$self, rootRect, value => $$invalidate(179, $rootRect = value));
- // when in overlay mode force aspect ratio to aspect ratio of editor root
- const syncRootAspectRatio = () => {
- // get current aspect ratio and get next aspect ratio, compare, if different, reset
- const currentAspectRatio = $imageCropAspectRatio;
- const nextAspectRatio = rectAspectRatio($rootRect);
- if (currentAspectRatio && currentAspectRatio === nextAspectRatio) return;
- // set aspect ratio
- imageCropAspectRatio.set(rectAspectRatio($rootRect));
- // need to set history 0 point to this state
- setInitialHistoryState();
- };
- const tabRect = writable(rectCreateEmpty());
- component_subscribe($$self, tabRect, value => $$invalidate(29, $tabRect = value));
- const toolRect = writable(rectCreateEmpty());
- component_subscribe($$self, toolRect, value => $$invalidate(44, $toolRect = value));
- const utilRect = writable(); // is undefined because we wait till util is set before defining stage rect
- component_subscribe($$self, utilRect, value => $$invalidate(45, $utilRect = value));
- //
- // environment
- //
- const pointerAccuracy = mediaQueryStore("(pointer: fine)", matches => matches ? "pointer-fine" : "pointer-coarse");
- component_subscribe($$self, pointerAccuracy, value => $$invalidate(230, $pointerAccuracy = value));
- const pointerHoverable = mediaQueryStore("(hover: hover)", matches => matches ? "pointer-hover" : "pointer-no-hover");
- component_subscribe($$self, pointerHoverable, value => $$invalidate(231, $pointerHoverable = value));
- //
- // app API
- //
- const isInteracting = writable(false);
- component_subscribe($$self, isInteracting, value => $$invalidate(182, $isInteracting = value));
- const isInteractingFraction = readable(undefined, set => {
- const animator = spring(0);
- const updater = value => {
- animator.set(value ? 1 : 0);
- };
- const subs = [isInteracting.subscribe(updater), animator.subscribe(set)];
- // destroy subs
- return () => subs.forEach(unsub => unsub());
- });
- component_subscribe($$self, isInteractingFraction, value => $$invalidate(306, $isInteractingFraction = value));
- const previewShouldUpscale = writable(previewUpscale);
- component_subscribe($$self, previewShouldUpscale, value => $$invalidate(296, $previewShouldUpscale = value));
- const imageCropRectSnapshot = writable();
- component_subscribe($$self, imageCropRectSnapshot, value => $$invalidate(295, $imageCropRectSnapshot = value));
- const imageCropRectIntent = writable(); // should always be set before setting `imageCropRect`
- component_subscribe($$self, imageCropRectIntent, value => $$invalidate(294, $imageCropRectIntent = value));
- const imageCropRectPresentation = readable(undefined, set => {
- const animator = spring(undefined, { precision: 0.0001 });
- const update = () => {
- if (!$imageCropRect) return;
- const instantUpdate = $imageCropRectIntent === undefined || $isInteracting;
- const elasticRect = elastifyRects($imageCropRect, $imageCropRectIntent, imageCropRectElasticity * elasticityMultiplier);
- animator.set(elasticRect, { hard: instantUpdate });
- };
- const subs = [
- // need to update presentation rect when crop rect is updated
- imageCropRect.subscribe(update),
- // update parent store
- animator.subscribe(set)
- ];
- return () => subs.forEach(unsub => unsub());
- });
- const imageSelectionRect = writable();
- component_subscribe($$self, imageSelectionRect, value => $$invalidate(297, $imageSelectionRect = value));
- const imageSelectionRectSnapshot = writable();
- component_subscribe($$self, imageSelectionRectSnapshot, value => $$invalidate(301, $imageSelectionRectSnapshot = value));
- const imageSelectionRectIntent = writable(undefined); // should always be set before setting `imageSelectionRect`
- component_subscribe($$self, imageSelectionRectIntent, value => $$invalidate(298, $imageSelectionRectIntent = value));
- let prevFramePadding = { left: 0, right: 0, top: 0, bottom: 0 };
- const framePadding = derived([imageFrame, imageSelectionRect], ([$imageFrame, $imageSelectionRect], set) => {
- if (!$imageSelectionRect) set(prevFramePadding);
- // set frame padding
- let newPadding = getStagePadding($imageSelectionRect, $imageFrame);
- // exif if no value changes
- if (fixPrecision(prevFramePadding.top, 4) === fixPrecision(newPadding.top, 4) && fixPrecision(prevFramePadding.bottom, 4) === fixPrecision(newPadding.bottom, 4) && fixPrecision(prevFramePadding.right, 4) === fixPrecision(newPadding.right, 4) && fixPrecision(prevFramePadding.left, 4) === fixPrecision(newPadding.left, 4)) return;
- prevFramePadding = newPadding;
- set(newPadding);
- });
- const framePadded = derived([framePadding], ([$framePadding], set) => {
- set(Object.values($framePadding).some(value => value > 0));
- });
- let prevStagePadding = { left: 0, right: 0, top: 0, bottom: 0 };
- const stagePadding = derived([utilSelectedStore, imageFrame, imageSelectionRect], ([$utilSelectedStore, $imageFrame, $imageSelectionRect], set) => {
- if (!$imageSelectionRect) set(prevStagePadding);
- // TODO: configure in plugin
- let newPadding;
- if ($utilSelectedStore === "frame") {
- newPadding = getStagePadding($imageSelectionRect, $imageFrame);
- } else {
- newPadding = { left: 0, right: 0, top: 0, bottom: 0 };
- }
- // exif if no value changes
- if (fixPrecision(prevStagePadding.top, 4) === fixPrecision(newPadding.top, 4) && fixPrecision(prevStagePadding.bottom, 4) === fixPrecision(newPadding.bottom, 4) && fixPrecision(prevStagePadding.right, 4) === fixPrecision(newPadding.right, 4) && fixPrecision(prevStagePadding.left, 4) === fixPrecision(newPadding.left, 4)) return;
- prevStagePadding = newPadding;
- set(newPadding);
- });
- const stagePadded = derived([stagePadding], ([$stagePadding], set) => {
- set(Object.values($stagePadding).some(value => value > 0));
- });
- component_subscribe($$self, stagePadded, value => $$invalidate(49, $stagePadded = value));
- const stageRect = derived([utilRect, tabRect, toolRect, stagePadding], ([$utilRect, $tabRect, $toolRect, $stagePadding], set) => {
- if (!$utilRect) return set(undefined);
- let utilOffsetY = 0;
- // if only one util active, we don't have util tabs, so add additional offset
- if (utilsFiltered.length === 1 && !isOverlayModeEnabled) {
- utilOffsetY = $toolRect.y + $toolRect.height;
- }
- set(rectCreate($utilRect.x + $tabRect.x + $stagePadding.top, $utilRect.y + $tabRect.y + utilOffsetY + $stagePadding.top, $utilRect.width - ($stagePadding.left + $stagePadding.right), $utilRect.height - ($stagePadding.top + $stagePadding.bottom)));
- });
- component_subscribe($$self, stageRect, value => $$invalidate(184, $stageRect = value));
- const stageScalar = derived([stageRect, imageCropRect], ([$stageRect, $imageCropRect], set) => {
- const isManipulatingImageCropRect = !!($imageCropRectSnapshot || $imageCropRectIntent);
- // update stage scalar, the crop output size relative to the stage, if image fits it's 1
- if (!$stageRect || !$imageCropRect || isManipulatingImageCropRect) return;
- // calculate scale factor needed to fit crop rect to stage
- const scalar = Math.min($stageRect.width / $imageCropRect.width, $stageRect.height / $imageCropRect.height);
- // always scaled down to fit stage, if is allowed to upscale, zoom to fit stage
- const scale = $previewShouldUpscale ? scalar : Math.min(1, scalar);
- set(scale);
- });
- component_subscribe($$self, stageScalar, value => $$invalidate(299, $stageScalar = value));
- //
- // Image selection
- //
- const getStagePadding = (presentationRect, imageFrame) => {
- if (!imageFrame || !presentationRect) return { top: 0, right: 0, bottom: 0, left: 0 };
- const shapes = shapesFromCompositShape(imageFrame, presentationRect, preprocessShape);
- const bounds = shapesBounds(shapes, presentationRect);
- return {
- top: Math.abs(bounds.top),
- right: Math.abs(bounds.right),
- bottom: Math.abs(bounds.bottom),
- left: Math.abs(bounds.left)
- };
- };
- const imageSelectionRectPresentation = readable(undefined, set => {
- const animator = spring(undefined, { precision: 0.0001 });
- const updater = () => {
- if (!$imageSelectionRect) return;
- const instantUpdate = $isInteracting || !$shouldAnimate;
- const elasticRect = elastifyRects($imageSelectionRect, $imageSelectionRectIntent, imageSelectionRectElasticity * elasticityMultiplier);
- // prevent negative size (can happen because of elastics)
- if (elasticRect.width < 0) {
- elasticRect.width = 0;
- elasticRect.x = $imageSelectionRect.x;
- }
- if (elasticRect.height < 0) {
- elasticRect.height = 0;
- elasticRect.y = $imageSelectionRect.y;
- }
- // translate elastic rect x,y by stage rect x,y
- rectTranslate(elasticRect, $stageRect);
- // adjust size if needed
- // TODO: MAKE THIS CONTROLLABLE FROM PLUGIN
- if ($imageCropRect) {
- if (utilSelected === "resize") {
- const visualSize = $imageOutputSize || $imageCropRect;
- rectScale(elasticRect, visualSize.width / $imageSelectionRect.width || visualSize.height / $imageSelectionRect.height);
- }
- }
- animator.set(elasticRect, { hard: instantUpdate });
- };
- const subs = [
- // need to update selection rect when stage is resized
- stageRect.subscribe(updater),
- // listen for selection rect changes (as is assigned rect will always trigger, even if assigned same rect, this is needed to also update when intent changes)
- imageSelectionRect.subscribe(updater),
- // if output size changes need to update presentation
- imageOutputSize.subscribe(updater),
- // need to update if frame exceeds bounds
- imageFrame.subscribe(updater),
- // update parent store
- animator.subscribe(set)
- ];
- // destroy subs
- return () => subs.forEach(unsub => unsub());
- });
- component_subscribe($$self, imageSelectionRectPresentation, value => $$invalidate(37, $imageSelectionRectPresentation = value));
- // when scaling the stage we need to recenter the image selection
- let stageRectPrev;
- const calculateImageSelectionRect = rect => {
- // don't recalculate if no change
- if (isOverlayModeEnabled && stageRectPrev && rectEqual(stageRectPrev, rect)) return;
- // remember so we can compare later on if has changed
- stageRectPrev = rect;
- const imageCropRectFitsStage = $imageCropRect.width <= rect.width && $imageCropRect.height <= rect.height;
- const centeredImageSelectionRect = // if we have a crop rect and it fits the stage, center it
- imageCropRectFitsStage
- ? // center the crop rectangle to the stage
- rectCenterRect(rect, rectMultiply(rectClone($imageCropRect), $stageScalar || 1))
- : // render a rectangle based on the fixed crop aspect ratio, or the aspect ratio of the current crop rectangle, or as a last resort the input image
- rectContainRect(rect, rectAspectRatio($imageCropRect || $imageSize));
- imageSelectionRect.set(centeredImageSelectionRect);
- };
- // this runs once so we use the correct scale for the initial image selection rect
- let hasSetInitialStageScalar = false;
- stageScalar.subscribe(scalar => {
- // can't recalculate without these prosp
- if (hasSetInitialStageScalar || scalar === undefined || !$imageCropRect) return;
- calculateImageSelectionRect($stageRect);
- hasSetInitialStageScalar = true;
- });
- // this recenters the crop when the window/stage is resized
- stageRect.subscribe(rect => {
- // can't recalculate without these prosp
- if (!rect || $stageScalar === undefined || !$imageCropRect) return;
- calculateImageSelectionRect(rect);
- });
- // if we've taken a snapshot of the selection, also take a snapshot of the crop rect and the presentationScalar
- // - cropRect so we can adjust it based on the adjustments to the imageSelectionRect
- // - presentationScalar so we can use the snapshot for the calculation of the cropRect scale relative to the original imageSelectionRect (if we use the live $presentationScalar small rounding errors of the scalar result in weird glitches)
- let presentationScalarSnapshot;
- imageSelectionRectSnapshot.subscribe(rect => {
- if (!rect) {
- presentationScalarSnapshot = undefined;
- set_store_value(imageCropRectSnapshot, $imageCropRectSnapshot = undefined, $imageCropRectSnapshot);
- return;
- }
- presentationScalarSnapshot = $presentationScalar;
- const cropRectClone = rectClone($imageCropRect);
- imageCropRectSnapshot.set(cropRectClone);
- });
- // if image selection rect is being manipulated, and imageSelectionRectSnapshot has been defined, we also need to update the crop rect
- imageSelectionRect.subscribe(rect => {
- // only sync crop rect with image selection rect when no longer manipulating
- if (!rect || !$imageSelectionRectSnapshot) return;
- const offset = rectSubtract(rectClone(rect), $imageSelectionRectSnapshot);
- rectDivide(offset, presentationScalarSnapshot);
- const crop = rectAdd(rectClone($imageCropRectSnapshot), offset);
- imageCropRect.set(crop);
- });
- imageCropRect.subscribe(rect => {
- // don't update image selection rect while we're intertacting with the view, this prevents feedback loop from cropRect model updates
- if ($isInteracting || $imageSelectionRectSnapshot || $imageCropRectIntent) return;
- // if no rect, we can't do anything
- // if no selection rect yet, we wait for a selection rect to be loaded
- if (!rect || !$imageSelectionRect) return;
- // only if crop aspect ratio differs from image selection aspect ratio we update image selection rectangle
- const imageSelectionRectAspectRatio = rectAspectRatio($imageSelectionRect);
- const cropRectAspectRatio = rectAspectRatio(rect);
- if (fixPrecision(imageSelectionRectAspectRatio, 6) === fixPrecision(cropRectAspectRatio, 6)) return;
- // TEMP DUPLICATE OF STAGESCALAR DERIVED STORE TO FIX ZOOM OUT AFTER WHEEL ISSUE
- // reproduce -> crop view => resize selection rect vertically, tap recenter, zoom out with scroll wheel
- const scalar = Math.min($stageRect.width / $imageCropRect.width, $stageRect.height / $imageCropRect.height);
- // const scale = $previewShouldUpscale ? scalar : Math.min(1, scalar);
- const size = sizeCreate(rect.width * scalar, rect.height * scalar);
- const tx = ($imageSelectionRect.width - size.width) * 0.5;
- const ty = ($imageSelectionRect.height - size.height) * 0.5;
- const selectionRect = rectCreate($imageSelectionRect.x + tx, $imageSelectionRect.y + ty, size.width, size.height);
- imageSelectionRect.set(selectionRect);
- });
- const imageScalar = derived([stageScalar, imageCropRect, imageSelectionRect], ([$stageScalar, $imageCropRect, $imageSelectionRect], set) => {
- // update the image scalar, the image zoom calculated by the image selection and the actual crop coordinates
- if (!$stageScalar || !$imageCropRect || !$imageSelectionRect) return;
- const selectionScaledWidth = $imageSelectionRect.width / $imageCropRect.width;
- const selectionScaledHeight = $imageSelectionRect.height / $imageCropRect.height;
- // need to correct for scale of stage
- let scalar = Math.max(selectionScaledWidth, selectionScaledHeight) / $stageScalar;
- set(scalar);
- });
- const presentationScalar = derived([stageScalar, imageScalar], ([$stageScalar, $imageScalar], set) => {
- // can't scale presentation if no image scalar defined
- if (!$imageScalar) return;
- const scalar = $stageScalar * $imageScalar;
- set(scalar);
- });
- component_subscribe($$self, presentationScalar, value => $$invalidate(300, $presentationScalar = value));
- // const imagePresentationScale = writable(1);
- // const imagePresentationPan = writable(vectorCreateEmpty());
- //
- // UI Elements
- //
- // image outline
- const imageOutlineOpacity = spring(0.075, {
- stiffness: 0.03,
- damping: 0.4,
- precision: 0.001
- });
- const imageVisualBounds = derived([imageSelectionRectPresentation, framePadding], ([$rect, $padding], set) => {
- if (!$rect) return;
- let { x, y, width, height } = $rect;
- let { left, right, top, bottom } = $padding;
- if (utilSelected === "resize") {
- const visualSize = $imageOutputSize || $imageCropRect;
- const scalar = visualSize.width / $imageSelectionRect.width || visualSize.height / $imageSelectionRect.height;
- left *= scalar;
- right *= scalar;
- top *= scalar;
- bottom *= scalar;
- }
- set({
- x: x - left,
- y: y - right,
- width: width + left + right,
- height: height + top + bottom
- });
- });
- component_subscribe($$self, imageVisualBounds, value => $$invalidate(189, $imageVisualBounds = value));
- const imageOutline = derived(
- [
- rootLineColor,
- imageOutlineOpacity,
- imageSelectionRectPresentation,
- imageFrame,
- framePadded,
- framePadding
- ],
- ([
- $rootLineColor,
- $colorOpacity,
- $rect,
- $imageFrame,
- $framePadded,
- $framePadding
- ], set) => {
- if (!$rect || isOverlayModeEnabled) return set([]);
- let { x, y, width, height } = $rect;
- x += 0.5;
- y += 0.5;
- width -= 0.5;
- height -= 0.5;
- const shapes = [];
- if ($framePadded) {
- if ($colorOpacity > 0.1) {
- // image outline
- shapes.push({
- x,
- y,
- width: width - 0.5,
- height: height - 0.5,
- strokeWidth: 1,
- strokeColor: $rootLineColor,
- opacity: $colorOpacity
- });
- }
- let { left, right, top, bottom } = $framePadding;
- if (utilSelected === "resize") {
- const visualSize = $imageOutputSize || $imageCropRect;
- const scalar = visualSize.width / $imageSelectionRect.width || visualSize.height / $imageSelectionRect.height;
- left *= scalar;
- right *= scalar;
- top *= scalar;
- bottom *= scalar;
- }
- set([
- ...shapes,
- // frame outline
- {
- x: x - left,
- y: y - right,
- width: width + left + right,
- height: height + top + bottom,
- strokeWidth: 1,
- strokeColor: $rootLineColor,
- opacity: 0.05
- }
- ]);
- return;
- }
- // draw shadow behind frame if is dark outline on dark frame or bright outline on bright frame
- const isDarkLine = isDarkColor($rootLineColor);
- const isDarkFrame = $imageFrame && $imageFrame.frameColor && isDarkColor($imageFrame.frameColor);
- if (isDarkLine && isDarkFrame || !isDarkLine && !isDarkLine) {
- const shadeColor = isDarkLine ? [1, 1, 1, 0.3] : [0, 0, 0, 0.075];
- shapes.push({
- x,
- y,
- width,
- height,
- strokeWidth: 3.5,
- strokeColor: shadeColor,
- opacity: $colorOpacity
- });
- }
- set([
- ...shapes,
- // outline
- {
- x,
- y,
- width,
- height,
- strokeWidth: 1,
- strokeColor: $rootLineColor,
- opacity: $colorOpacity
- }
- ]);
- }
- );
- // custom markup rendered on top of image
- const imageOverlayMarkup = writable([]);
- component_subscribe($$self, imageOverlayMarkup, value => $$invalidate(200, $imageOverlayMarkup = value));
- // the resulting overlay markup
- const imageOverlay = derived([imageOutline, imageOverlayMarkup], ([$imageOutline, $imageOverlayMarkup], set) => {
- set([...$imageOutline, ...$imageOverlayMarkup]);
- });
- component_subscribe($$self, imageOverlay, value => $$invalidate(54, $imageOverlay = value));
- //
- // Stage overlay
- //
- // create canvas gradient for use as menu backdrop
- const getOverlayGradient = (width, height, color) => {
- const ctx = h("canvas", {
- width: Math.max(1, width),
- height: Math.max(1, height)
- }).getContext("2d");
- const gradient = ctx.createLinearGradient(0, 0, width, height);
- [
- [0, 0],
- [0.013, 0.081],
- [0.049, 0.155],
- [0.104, 0.225],
- [0.175, 0.29],
- [0.259, 0.353],
- [0.352, 0.412],
- [0.45, 0.471],
- [0.55, 0.529],
- [0.648, 0.588],
- [0.741, 0.647],
- [0.825, 0.71],
- [0.896, 0.775],
- [0.951, 0.845],
- [0.987, 0.919],
- [1, 1]
- ].forEach(([o, s]) => gradient.addColorStop(s, `rgba(${color[0] * 255}, ${color[1] * 255}, ${color[2] * 255}, ${o})`));
- ctx.fillStyle = gradient;
- ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
- return ctx.canvas;
- };
- const calculateImageTargetSize = (outputSize, cropRect) => {
- let { width, height } = outputSize;
- const aspectRatio = rectAspectRatio(cropRect);
- if (width && height) return outputSize;
- if (width && !height) {
- height = width / aspectRatio;
- }
- if (height && !width) {
- width = height * aspectRatio;
- }
- if (!width && !height) {
- width = cropRect.width;
- height = cropRect.height;
- }
- return sizeApply(sizeCreate(width, height), Math.round);
- };
- const overlayInset = spring(40);
- component_subscribe($$self, overlayInset, value => $$invalidate(188, $overlayInset = value));
- const overlaySize = spring(70);
- component_subscribe($$self, overlaySize, value => $$invalidate(191, $overlaySize = value));
- const overlayLeftOpacity = spring(0);
- component_subscribe($$self, overlayLeftOpacity, value => $$invalidate(196, $overlayLeftOpacity = value));
- const overlayRightOpacity = spring(0);
- component_subscribe($$self, overlayRightOpacity, value => $$invalidate(198, $overlayRightOpacity = value));
- const overlayTopOpacity = spring(0);
- component_subscribe($$self, overlayTopOpacity, value => $$invalidate(192, $overlayTopOpacity = value));
- const overlayBottomOpacity = spring(0);
- component_subscribe($$self, overlayBottomOpacity, value => $$invalidate(194, $overlayBottomOpacity = value));
- // make sure canvas only redraws if background color changes
- let gradientOverlayHorizontal;
- let gradientOverlayVertical;
- rootBackgroundColor.subscribe(color => {
- if (!color) return;
- $$invalidate(169, gradientOverlayHorizontal = getOverlayGradient(16, 0, color));
- $$invalidate(169, gradientOverlayHorizontal.dataset.retain = 1, gradientOverlayHorizontal);
- $$invalidate(170, gradientOverlayVertical = getOverlayGradient(0, 16, color));
- $$invalidate(170, gradientOverlayVertical.dataset.retain = 1, gradientOverlayVertical);
- });
- //
- // Loading the preview
- //
- const imageVisualLoadComplete = writable(false);
- component_subscribe($$self, imageVisualLoadComplete, value => $$invalidate(242, $imageVisualLoadComplete = value));
- const imagePreviewSource = writable();
- component_subscribe($$self, imagePreviewSource, value => $$invalidate(203, $imagePreviewSource = value));
- const createImagePreviewLoader = (src, token) => new Promise((resolve, reject) => {
- // try not to show preview loader if updating active images array
- const minPreviewLoaderDuration = activeImages.length ? 0 : 250;
- let cancelled = false;
- let timer;
- token.cancel = () => cancelled = true;
- const now = Date.now();
- imageSourceToImageData(src).then(imageData => {
- const dist = Date.now() - now;
- clearTimeout(timer);
- timer = setTimeout(
- () => {
- if (cancelled) return;
- resolve(imageData);
- },
- Math.max(0, minPreviewLoaderDuration - dist)
- );
- }).catch(reject);
- });
- let imagePreviewLoaderCancelToken;
- const imagePreview = derived([imageVisualLoadComplete, imagePreviewSource], ([$imageVisualLoadComplete, $imagePreviewSource], set) => {
- // no data, reset preview data
- if (!$imageVisualLoadComplete || !$imagePreviewSource) return set(undefined);
- // cancel existing loader
- if (imagePreviewLoaderCancelToken) {
- imagePreviewLoaderCancelToken.cancel();
- $$invalidate(171, imagePreviewLoaderCancelToken = undefined);
- }
- // if image preview source is a canvas we can update immediately
- if (isCanvas($imagePreviewSource)) {
- // update image preview to canvas
- return set(canvasClone($imagePreviewSource));
- }
- // load preview
- $$invalidate(171, imagePreviewLoaderCancelToken = { cancel: noop$1 });
- createImagePreviewLoader($imagePreviewSource, imagePreviewLoaderCancelToken).then(set).catch(err => {
- // update load state
- set_store_value(imageLoadState, $imageLoadState.error = err, $imageLoadState);
- // log to console for debuggin purposes
- }).finally(() => {
- // no longer loading
- $$invalidate(171, imagePreviewLoaderCancelToken = undefined);
- });
- });
- $$subscribe_imagePreview();
- let { imagePreviewCurrent = undefined } = $$props;
- //
- // Calculates the image transforms and effects necessary for the preview
- //
- const imagePreviewModifiers = writable({});
- component_subscribe($$self, imagePreviewModifiers, value => $$invalidate(233, $imagePreviewModifiers = value));
- const interfaceImages = writable([]);
- component_subscribe($$self, interfaceImages, value => $$invalidate(50, $interfaceImages = value));
- // reset image UI previews when new file is loaded
- const resetPreviews = () => interfaceImages.set([]);
- const imageTransforms = derived(
- [
- stageRect,
- rootRect,
- imageSize,
- imageCropRectPresentation,
- imageSelectionRect,
- presentationScalar,
- imageRotation,
- imageFlipX,
- imageFlipY,
- imageOutputSize
- ],
- ([
- $stageRect,
- $rootRect,
- $imageSize,
- $imageCropRectPresentation,
- $imageSelectionRect,
- $presentationScalar,
- $imageRotation,
- $imageFlipX,
- $imageFlipY,
- $imageOutputSize
- ], set) => {
- if (!$stageRect) return;
- // TODO: MAKE THIS CONTROLLABLE FROM PLUGIN
- if (utilSelected === "resize") {
- const visualSize = $imageOutputSize || $imageCropRectPresentation;
- $presentationScalar = visualSize.width / $imageCropRectPresentation.width || visualSize.height / $imageCropRectPresentation.height;
- }
- set(calculateImageTransforms($stageRect, $rootRect, $imageSize, $imageCropRectPresentation, $imageSelectionRect, $presentationScalar, 0, 0, $imageRotation, $imageFlipX, $imageFlipY));
- }
- );
- component_subscribe($$self, imageTransforms, value => $$invalidate(232, $imageTransforms = value));
- const imageEffects = derived(
- [
- imageColorMatrix,
- imageConvolutionMatrix,
- imageGamma,
- imageVignette,
- imageNoise
- ],
- ([$colorMatrix, $convolutionMatrix, $gamma, $vignette, $noise], set) => {
- const colorMatrices = $colorMatrix && Object.keys($colorMatrix).map(name => $colorMatrix[name]).filter(Boolean);
- const effects = {
- gamma: $gamma || undefined,
- vignette: $vignette || undefined,
- noise: $noise || undefined,
- convolutionMatrix: $convolutionMatrix || undefined,
- colorMatrix: colorMatrices && colorMatrices.length && getColorMatrixFromColorMatrices(colorMatrices)
- };
- set(effects);
- }
- );
- //
- // current environment variables
- //
- let windowWidth;
- let windowHeight;
- const shouldPreventSwipe = canPreventNavSwipe();
- const env = writable({});
- component_subscribe($$self, env, value => $$invalidate(229, $env = value));
- const initialPixelRatio = getDevicePixelRatio();
- const pixelRatio = readable(initialPixelRatio, set => {
- const handleResolutionChange = () => set(getDevicePixelRatio());
- const resolutionObserver = matchMedia(`(resolution: ${initialPixelRatio}dppx)`);
- resolutionObserver.addListener(handleResolutionChange);
- return () => resolutionObserver.removeListener(handleResolutionChange);
- });
- component_subscribe($$self, pixelRatio, value => $$invalidate(46, $pixelRatio = value));
- //
- // Animations based on prefers-reduced-motion, automatically checks if user prefers reduced animations
- //
- const shouldAnimate = writable();
- component_subscribe($$self, shouldAnimate, value => $$invalidate(18, $shouldAnimate = value));
- const history = historyCreate(
- () => {
- // $imageState is always a clone of the current state
- return $imageState;
- },
- state => {
- // set new state from history, $imageState will store a clone of the received state
- set_store_value(imageState, $imageState = state, $imageState);
- // trigger recenter of image selection rect
- tabRect.set($tabRect);
- }
- );
- $$subscribe_history();
- const setInitialHistoryState = () => {
- // set history state
- const baseRect = { x: 0, y: 0, ...$imageSize };
- const baseCropRect = rectApply(rectContainRect(baseRect, $imageState.cropAspectRatio), v => Math.round(v));
- const baseEditorState = willSetHistoryInitialState(
- {
- // the base state is the image state but the `rotation` and `crop` are reset
- ...$imageState,
- // should be read from imageInitialProps?
- rotation: 0,
- crop: baseCropRect
- },
- $imageState
- );
- // this will be the base state
- const editorInitialHistoryState = [baseEditorState];
- // only add additional entry if base state and current state are different
- if (JSON.stringify(baseEditorState) !== JSON.stringify($imageState)) {
- editorInitialHistoryState.push({ ...$imageState });
- }
- // loading done, set this as base state
- history.set(editorInitialHistoryState);
- };
- imageLoadState.subscribe(state => {
- // not ready yet
- if (!state || !state.complete) return;
- // set initial state after image load has completed
- setInitialHistoryState();
- });
- const revert = () => willRevert().then(shouldReset => shouldReset && history.revert());
- //
- // Visual processing of the image
- //
- const imageProcessingPreparing = writable(false);
- component_subscribe($$self, imageProcessingPreparing, value => $$invalidate(210, $imageProcessingPreparing = value));
- const handleExport = () => {
- // this will trigger status overlay fade in
- set_store_value(imageProcessingPreparing, $imageProcessingPreparing = true, $imageProcessingPreparing);
- willProcessImage().then(shouldProcess => {
- // nope, restore hide processing overlay and back to editing
- if (!shouldProcess) {
- set_store_value(imageProcessingPreparing, $imageProcessingPreparing = false, $imageProcessingPreparing);
- return;
- }
- // wait for status to be done fading in, then requests image writing
- let unsub;
- unsub = statusOpacity.subscribe(value => {
- if (value !== 1) return;
- // stop listening for
- unsub && unsub();
- // request write image
- dispatch("processImage");
- });
- });
- };
- imageProcessState.subscribe(state => {
- if (!state) return;
- set_store_value(imageProcessingPreparing, $imageProcessingPreparing = true, $imageProcessingPreparing);
- const { complete, abort } = state;
- if (complete || abort) set_store_value(imageProcessingPreparing, $imageProcessingPreparing = false, $imageProcessingPreparing);
- });
- //
- // Configure the available views
- //
- const utilStores = {
- // model stores
- ...stores,
- // image
- imageFile,
- imageSize,
- imageBackgroundColor,
- imageCropAspectRatio,
- imageCropMinSize,
- imageCropMaxSize,
- imageCropLimitToImage,
- imageCropRect,
- imageCropRectOrigin,
- imageCropRectSnapshot,
- imageCropRectAspectRatio,
- imageCropRange,
- imageRotation,
- imageRotationRange,
- imageFlipX,
- imageFlipY,
- imageOutputSize,
- // effects
- imageColorMatrix,
- imageConvolutionMatrix,
- imageGamma,
- imageVignette,
- imageNoise,
- // markup
- imageDecoration,
- imageAnnotation,
- imageRedaction,
- imageFrame,
- // image preview for utils that need access to pixel data
- imagePreview,
- // image preview source so utils can update preview
- imagePreviewSource,
- // top left position of image preview
- imageTransforms,
- // allows utils to control how the preview is presented (for example more opacity for mask)
- imagePreviewModifiers,
- // history state and update
- history,
- // static env info
- animation: shouldAnimate,
- pixelRatio,
- elasticityMultiplier,
- scrollElasticity,
- rangeInputElasticity,
- // dynamic env info
- pointerAccuracy,
- pointerHoverable,
- env,
- rootRect,
- stageRect,
- stageScalar,
- framePadded,
- utilRect,
- presentationScalar,
- rootBackgroundColor,
- rootForegroundColor,
- rootLineColor,
- imageOutlineOpacity,
- // interaction
- // imagePresentationPan,
- // imagePresentationScale,
- // (write) add guides to ui (for example is used by markup util to add lines for shape manipulator)
- imageOverlayMarkup,
- // (write) interface images to render
- interfaceImages,
- // (write) set to true to disable animations
- isInteracting,
- // (read) goes from 0 to 1 while interacting
- isInteractingFraction,
- // (write) the current intended crop rect
- imageCropRectIntent,
- // (read) the current presented crop rect
- imageCropRectPresentation,
- // (write) the current limited size of the image selection rect
- imageSelectionRect,
- // (write) the inteded rectangle by the user
- imageSelectionRectIntent,
- // (read) the current presentation of the image selection rect, includes elasticity etc.
- imageSelectionRectPresentation,
- // (read) a snapshot of the image selection rectangle, use to store the rectangle before modification so alterations to the rectangle can be applied to the snapshot
- imageSelectionRectSnapshot,
- // scalar of image in view
- imageScalar
- };
- // don't expose image store
- delete utilStores.image;
- const utilsUniqueId = `util-${getUniqueId()}`;
- let utilsVisible = [];
- // env
- let iOS = isIOS();
- const getOrientation = (rect, layoutPreference) => {
- if (!$rootRect) return "landscape";
- if (layoutPreference === "auto") return rect.width > rect.height ? "landscape" : "portrait";
- if (layoutPreference === "horizontal") return rect.width < 500 ? "portrait" : "landscape";
- if (layoutPreference === "vertical") return rect.height < 400 ? "landscape" : "portrait";
- };
- const getColorPropertyValue = name => {
- const colorString = rootElementComputedStyle.getPropertyValue(name);
- return colorStringToColorArray(colorString);
- };
- const syncColor = (property, store) => {
- const colorArray = getColorPropertyValue(property);
- // hide transparent color
- if (!colorArray || colorArray[3] === 0) return;
- // limit to opaque colors
- colorArray.length = 3;
- // update store
- store.set(colorArray);
- };
- const syncColors = () => {
- syncColor("color", rootForegroundColor);
- syncColor("background-color", rootBackgroundColor);
- syncColor("outline-color", rootLineColor);
- };
- const handleTransitionEnd = ({ target, propertyName }) => {
- if (target !== root || !(/background|outline/).test(propertyName)) return;
- syncColors();
- };
- const imageProps = derived([imageTransforms, imageEffects, imageBackgroundColor], ([$imageTransforms, $imageEffects, backgroundColor]) => {
- return $imageTransforms && {
- ...$imageTransforms,
- ...$imageEffects,
- backgroundColor
- };
- });
- component_subscribe($$self, imageProps, value => $$invalidate(235, $imageProps = value));
- const activeImages = storeList();
- component_subscribe($$self, activeImages, value => $$invalidate(22, $activeImages = value));
- const addImagePreview = () => {
- // if is first image scale up slightly on entrance
- const imageIntro = activeImages.length ? undefined : { resize: 1.05 };
- // create the new image
- const image = createImage($imagePreview, $imageSize, imageIntro);
- // new image on top
- activeImages.unshift(image);
- // update images in activeImages array
- updateImagePreviews($imageProps);
- };
- const updateImagePreviews = currentImageProps => {
- activeImages.forEach((image, index) => {
- const opacity = index === 0 ? 1 : 0;
- const resize = 1;
- image.set({ ...currentImageProps, opacity, resize }, $shouldAnimate);
- });
- };
- // if image preview changes, push it on the stack
- let lastImagePreview;
- // test if some shapes have left/top/bottom/right offsets, if so, convert to crop space
- // updates original shape (which at this point is a flattened shape (clone))
- const positionDecorationShape = (shape, canvasState) => shapeComputeDisplay(shape, {
- x: $imageSelectionRectPresentation.x / canvasState.scale,
- y: $imageSelectionRectPresentation.y / canvasState.scale,
- width: $imageSelectionRectPresentation.width / canvasState.scale,
- height: $imageSelectionRectPresentation.height / canvasState.scale
- });
- // decoration is drawn relative to view space, so we need to translate relative to crop presentation rect
- const transformDecorationShape = (shape, canvasState) => {
- shapeComputeTransform(shape, $imageSelectionRectPresentation, canvasState.scale, canvasState.size);
- return shape;
- };
- const flattenShapes = shapes => {
- const flattenedShapes = [];
- shapes.forEach(shape => flattenedShapes.push(flattenShape(shape)));
- return flattenedShapes.filter(Boolean);
- };
- const flattenShape = shape => {
- // at this point shape is a copy of the original shape
- if (shapeIsLine(shape)) {
- shape.points = [vectorCreate(shape.x1, shape.y1), vectorCreate(shape.x2, shape.y2)];
- } else if (shapeIsTriangle(shape)) {
- shape.points = [
- vectorCreate(shape.x1, shape.y1),
- vectorCreate(shape.x2, shape.y2),
- vectorCreate(shape.x3, shape.y3)
- ];
- } else // is empty text
- if (shapeIsTextEmpty(shape)) {
- // make sure shape is still visible
- if (shapeIsTextLine(shape)) {
- shape.width = 5;
- shape.height = isFunction(shape.lineHeight)
- ? shape.lineHeight(shape.fontSize)
- : shape.lineHeight;
- }
- // set to empty text style
- shape.strokeWidth = 1;
- shape.strokeColor = [1, 1, 1, 0.5];
- shape.backgroundColor = [0, 0, 0, 0.1];
- } else if (shapeIsText(shape)) {
- shape.fontFamily = shape.fontFamily || "sans-serif";
- shape.fontSize = shape.fontSize || 16;
- }
- return shape;
- };
- const statusOpacity = tweened(undefined, { duration: 500 });
- component_subscribe($$self, statusOpacity, value => $$invalidate(24, $statusOpacity = value));
- let loadTimer;
- // this adds a little delay to the status fade out after an image was processed
- // needed because when the modal fades out this would otherwise create a weird flash (modal fade out, but status fade out as well showing interface)
- const wasProcessingImage = writable(false);
- component_subscribe($$self, wasProcessingImage, value => $$invalidate(254, $wasProcessingImage = value));
- let statusState;
- const asideOffset = spring(undefined, {
- stiffness: 0.1,
- damping: 0.7,
- precision: 0.25
- });
- component_subscribe($$self, asideOffset, value => $$invalidate(42, $asideOffset = value));
- const asideOpacity = spring(0, { stiffness: 0.1, precision: 0.05 });
- component_subscribe($$self, asideOpacity, value => $$invalidate(43, $asideOpacity = value));
- const asideWidth = spring(0, {
- stiffness: 0.02,
- damping: 0.5,
- precision: 0.25
- });
- component_subscribe($$self, asideWidth, value => $$invalidate(258, $asideWidth = value));
- const statusWidth = spring(undefined, {
- stiffness: 0.02,
- damping: 0.5,
- precision: 0.25
- });
- component_subscribe($$self, statusWidth, value => $$invalidate(256, $statusWidth = value));
- const statusOffset = spring(undefined, {
- stiffness: 0.02,
- damping: 0.5,
- precision: 0.25
- });
- component_subscribe($$self, statusOffset, value => $$invalidate(259, $statusOffset = value));
- let asideWidthUpdateTimer;
- const offsetAside = e => {
- // if error occured, snap in possition
- const hard = !!(statusState && statusState.closeButton);
- // where to render the progress indicator or close button
- statusWidth.set(e.detail.width, { hard });
- // offsets text so it's better centered to the viewport
- statusOffset.set(Math.round(-e.detail.width * 0.5), { hard });
- };
- const handleCloseImageLoadError = () => {
- dispatch("abortLoadImage");
- };
- const handleCloseImageProcessError = () => {
- dispatch("abortProcessImage");
- set_store_value(imageProcessingPreparing, $imageProcessingPreparing = false, $imageProcessingPreparing);
- };
- // helper to block iOS events
- const preventDefault = e => e.preventDefault();
- // prevents swipe to navigate back on iOS >= 13.4+
- const handleTouchStart = shouldPreventSwipe
- ? e => {
- // get touch or event itself (fixes issue with chrome dev tools)
- const event = e.touches ? e.touches[0] : e;
- // if is not an attempt to swipe back or forward
- if (event.pageX > 10 && event.pageX < windowWidth - 10) return;
- // stop the navigation attempt
- preventDefault(e);
- }
- : noop$1;
- // these are again needed since iOS 15 (was needed for 12 and lower, but wasn't needed for 13, 14)
- const handleTouchMove = isIOS() ? preventDefault : noop$1;
- const handlePointerMove = isIOS() ? preventDefault : noop$1;
- // context for children to know if a key is down
- const pressedKeysStore = writable([]);
- component_subscribe($$self, pressedKeysStore, value => $$invalidate(303, $pressedKeysStore = value));
- setContext("keysPressed", pressedKeysStore);
- const handleKeydown = e => {
- const { keyCode, metaKey, ctrlKey, shiftKey } = e;
- // prevent tabbing through fields if editor is disabled
- if (keyCode === 9 && disabled) {
- e.preventDefault();
- return;
- }
- // undo/redo
- if (keyCode === 90 && (metaKey || ctrlKey)) {
- if (shiftKey && metaKey) {
- // redo on macos
- history.redo();
- } else {
- // undo
- history.undo();
- }
- return;
- } else if (keyCode === 89 && ctrlKey) {
- // redo on windows
- history.redo();
- return;
- }
- // ignore IME popup keycode, fixes keycode 229 sticking around, as it's not triggered in keyup "If an Input Method Editor is processing key input and the event is keydown, return 229."
- // https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html
- if (keyCode === 229) return;
- // add to set
- const keySet = new Set([...$pressedKeysStore, keyCode]);
- pressedKeysStore.set(Array.from(keySet));
- };
- const handleKeyup = ({ keyCode }) => {
- pressedKeysStore.set($pressedKeysStore.filter(pressedKey => pressedKey !== keyCode));
- };
- // so no keys get stuck when user cmd-tabs out of the window, or when dev-tools open by key-press
- const handleWindowBlur = () => {
- pressedKeysStore.set([]);
- };
- // block context menu on everything but text input fields
- const handleContextMenu = e => {
- if (isTextField(e.target)) return;
- e.preventDefault();
- };
- // handle files being dropped on the editor
- const handleUserFile = file => {
- // no file received, isn't an image file, is not a URL
- if (// no file received
- !file || // if it's a file object it should be a bitmap
- isBinary(file) && !isBitmap(file) || // if it's not a file object it should be a URL
- !isBinary(file) && !(/^http/).test(file)) return;
- // request load image
- dispatch("loadImage", file);
- };
- const handleDropFiles = e => {
- // not allowed to drop
- if (!enableDropImage) return;
- handleUserFile(e.detail.resources[0]);
- };
- const handlePaste = e => {
- // not allowed to paste
- if (!enablePasteImage) return;
- // calculate percentage of editor that is in view
- const xPercentage = clamp((windowWidth - Math.abs($rootRect.x)) / $rootRect.width, 0, 1);
- const yPercentage = clamp((windowHeight - Math.abs($rootRect.y)) / $rootRect.height, 0, 1);
- // editor needs to be in view
- if (xPercentage < 0.75 && yPercentage < 0.75) return;
- // request load image
- handleUserFile((e.clipboardData || window.clipboardData).files[0]);
- };
- //
- // canvas drawing
- //
- let scrambledPreviewImage = undefined;
- const updateScrambledPreview = (imagePreviewData, imageScrambler, imageRedactionScalar, imageBackgroundColor) => {
- if (!imageScrambler) return;
- // remove transparency
- const editorOptions = { dataSizeScalar: imageRedactionScalar };
- if (imageBackgroundColor && imageBackgroundColor[3] > 0) {
- editorOptions.backgroundColor = [...imageBackgroundColor];
- }
- imageScrambler(imagePreviewData, editorOptions).then(scrambledCanvas => {
- // we've created a new scrambled preview so force release memory of old one
- if (scrambledPreviewImage) releaseCanvas(scrambledPreviewImage);
- // update scrambled preview with new image
- $$invalidate(175, scrambledPreviewImage = scrambledCanvas);
- });
- };
- let blendShapes = [];
- const getStageState = () => ({
- // add foreground color
- foregroundColor: [...$rootForegroundColor],
- // add line color
- lineColor: [...$rootLineColor],
- // add information on which util is active
- utilVisibility: { ...utilsVisibleFraction },
- // used to fade in elements when interacting
- isInteracting: $isInteracting,
- isInteractingFraction: $isInteractingFraction,
- // add the root rectangle so will render can use width/height of root element
- rootRect: rectClone($rootRect),
- // add the stage rectangle so will render knows where stage starts and ends
- stageRect: rectClone($stageRect),
- // preview selection rect
- selectionRect: rectClone($imageSelectionRectPresentation)
- });
- const createCanvasState = (canvasState, blendShapes, annotationShapes, decorationShapes, interfaceShapes, frameShapes) => ({
- blendShapes: blendShapes.filter(shapeIsVisible).map(shape => shapeComputeDisplay(shape, $imageSize)),
- annotationShapes: flattenShapes(annotationShapes.filter(shapeIsVisible).map(shapeDeepCopy).map(shape => shapeComputeDisplay(shape, $imageSize)).map(preprocessShape).flat()),
- decorationShapes: flattenShapes(decorationShapes.filter(shapeIsVisible).map(shapeDeepCopy).map(shape => positionDecorationShape(shape, canvasState)).map(preprocessShape).flat().map(shape => transformDecorationShape(shape, canvasState))),
- interfaceShapes: flattenShapes(interfaceShapes.filter(shapeIsVisible)),
- frameShapes: flattenShapes(frameShapes.map(shapeDeepCopy).map(shape => positionDecorationShape(shape, canvasState)).map(preprocessShape).flat().map(shape => transformDecorationShape(shape, canvasState)))
- });
- // setup root portal for detail panel dropdown
- let rootPortal;
- const rootPortalStore = writable();
- setContext("rootPortal", rootPortalStore);
- // setup root rect store for global access
- setContext("rootRect", rootRect);
- function onwindowresize() {
- $$invalidate(11, windowWidth = window_1$1.innerWidth);
- $$invalidate(12, windowHeight = window_1$1.innerHeight);
- }
- const measure_handler = e => set_store_value(toolRect, $toolRect = e.detail, $toolRect);
- const select_handler = ({ detail }) => $$invalidate(19, utilSelected = detail);
- const func = (panel, util) => util.id === panel;
- function panel_component_binding(value, panel) {
- if ($$self.$$.not_equal(pluginInterface[panel], value)) {
- pluginInterface[panel] = value;
- (($$invalidate(0, pluginInterface), $$invalidate(7, pluginOptions)), $$invalidate(166, pluginComponents));
- }
- }
- const measure_handler_1 = e => set_store_value(utilRect, $utilRect = e.detail, $utilRect);
- const show_handler = panel => $$invalidate(27, utilsVisible = utilsVisible.concat(panel));
- const hide_handler = panel => $$invalidate(27, utilsVisible = utilsVisible.filter(util => util !== panel));
- const fade_handler = (panel, { detail }) => $$invalidate(21, utilsVisibleFraction[panel] = detail, utilsVisibleFraction);
- const measure_handler_2 = e => set_store_value(tabRect, $tabRect = e.detail, $tabRect);
- const func_1 = util => util.id === utilSelected;
- function panel_component_binding_1(value) {
- if ($$self.$$.not_equal(pluginInterface[utilSelected], value)) {
- pluginInterface[utilSelected] = value;
- (($$invalidate(0, pluginInterface), $$invalidate(7, pluginOptions)), $$invalidate(166, pluginComponents));
- }
- }
- const measure_handler_3 = e => set_store_value(utilRect, $utilRect = e.detail, $utilRect);
- const show_handler_1 = () => $$invalidate(27, utilsVisible = utilsVisible.concat(utilSelected));
- const hide_handler_1 = () => $$invalidate(27, utilsVisible = utilsVisible.filter(util => util !== utilSelected));
- const fade_handler_1 = ({ detail }) => $$invalidate(21, utilsVisibleFraction[utilSelected] = detail, utilsVisibleFraction);
- const func_2 = canvasState => {
- // current draw state
- const drawState = { ...canvasState, ...getStageState() };
- // allow devs to add custom overlay to `imageOverlay`
- const { annotationShapes, decorationShapes, interfaceShapes, frameShapes } = willRenderCanvas(
- {
- annotationShapes: $imageAnnotation,
- decorationShapes: $imageDecoration,
- frameShapes: [$imageFrame],
- interfaceShapes: $imageOverlay
- },
- drawState
- );
- // need to map shapes
- return createCanvasState(drawState, blendShapes, annotationShapes, decorationShapes, interfaceShapes, frameShapes);
- };
- function div_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- rootPortal = $$value;
- $$invalidate(14, rootPortal);
- });
- }
- function div_binding_1($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- root = $$value;
- $$invalidate(1, root);
- });
- }
- const measure_handler_4 = e => set_store_value(clientRect, $clientRect = e.detail, $clientRect);
- $$self.$$set = $$props => {
- if ("class" in $$props) $$invalidate(141, klass = $$props.class);
- if ("layout" in $$props) $$invalidate(142, layoutMode = $$props.layout);
- if ("stores" in $$props) $$invalidate(143, stores = $$props.stores);
- if ("locale" in $$props) $$invalidate(2, locale = $$props.locale);
- if ("id" in $$props) $$invalidate(3, id = $$props.id);
- if ("util" in $$props) $$invalidate(144, util = $$props.util);
- if ("utils" in $$props) $$invalidate(145, utils = $$props.utils);
- if ("animations" in $$props) $$invalidate(146, animations = $$props.animations);
- if ("disabled" in $$props) $$invalidate(147, disabled = $$props.disabled);
- if ("status" in $$props) $$invalidate(139, status = $$props.status);
- if ("previewUpscale" in $$props) $$invalidate(148, previewUpscale = $$props.previewUpscale);
- if ("elasticityMultiplier" in $$props) $$invalidate(4, elasticityMultiplier = $$props.elasticityMultiplier);
- if ("willRevert" in $$props) $$invalidate(149, willRevert = $$props.willRevert);
- if ("willProcessImage" in $$props) $$invalidate(150, willProcessImage = $$props.willProcessImage);
- if ("willRenderCanvas" in $$props) $$invalidate(5, willRenderCanvas = $$props.willRenderCanvas);
- if ("willRenderToolbar" in $$props) $$invalidate(151, willRenderToolbar = $$props.willRenderToolbar);
- if ("willSetHistoryInitialState" in $$props) $$invalidate(152, willSetHistoryInitialState = $$props.willSetHistoryInitialState);
- if ("enableButtonExport" in $$props) $$invalidate(153, enableButtonExport = $$props.enableButtonExport);
- if ("enableButtonRevert" in $$props) $$invalidate(154, enableButtonRevert = $$props.enableButtonRevert);
- if ("enableNavigateHistory" in $$props) $$invalidate(155, enableNavigateHistory = $$props.enableNavigateHistory);
- if ("enableToolbar" in $$props) $$invalidate(6, enableToolbar = $$props.enableToolbar);
- if ("enableUtils" in $$props) $$invalidate(156, enableUtils = $$props.enableUtils);
- if ("enableButtonClose" in $$props) $$invalidate(157, enableButtonClose = $$props.enableButtonClose);
- if ("enableDropImage" in $$props) $$invalidate(158, enableDropImage = $$props.enableDropImage);
- if ("enablePasteImage" in $$props) $$invalidate(159, enablePasteImage = $$props.enablePasteImage);
- if ("previewImageDataMaxSize" in $$props) $$invalidate(160, previewImageDataMaxSize = $$props.previewImageDataMaxSize);
- if ("layoutDirectionPreference" in $$props) $$invalidate(161, layoutDirectionPreference = $$props.layoutDirectionPreference);
- if ("layoutHorizontalUtilsPreference" in $$props) $$invalidate(162, layoutHorizontalUtilsPreference = $$props.layoutHorizontalUtilsPreference);
- if ("layoutVerticalUtilsPreference" in $$props) $$invalidate(163, layoutVerticalUtilsPreference = $$props.layoutVerticalUtilsPreference);
- if ("imagePreviewSrc" in $$props) $$invalidate(164, imagePreviewSrc = $$props.imagePreviewSrc);
- if ("imageOrienter" in $$props) $$invalidate(165, imageOrienter = $$props.imageOrienter);
- if ("pluginComponents" in $$props) $$invalidate(166, pluginComponents = $$props.pluginComponents);
- if ("pluginOptions" in $$props) $$invalidate(7, pluginOptions = $$props.pluginOptions);
- if ("root" in $$props) $$invalidate(1, root = $$props.root);
- if ("imageSourceToImageData" in $$props) $$invalidate(8, imageSourceToImageData = $$props.imageSourceToImageData);
- if ("imagePreviewCurrent" in $$props) $$invalidate(140, imagePreviewCurrent = $$props.imagePreviewCurrent);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[4] & /*layoutMode*/ 262144) {
- // set to new object to force redraw
- $$invalidate(176, isOverlayModeEnabled = layoutMode === "overlay");
- }
- if ($$self.$$.dirty[5] & /*enableUtils, isOverlayModeEnabled*/ 2097154) {
- $$invalidate(15, showUtils = enableUtils && !isOverlayModeEnabled);
- }
- if ($$self.$$.dirty[0] & /*pluginOptions, pluginInterface*/ 129) {
- // map plugin options to plugin interface
- if (pluginOptions) {
- // for every plugin in plugin options
- Object.entries(pluginOptions).forEach(([name, plugin]) => {
- // for every prop defined for this plugin
- Object.entries(plugin).forEach(([prop, value]) => {
- // set value to interface
- if (!pluginInterface[name]) return;
- // set prop value
- $$invalidate(0, pluginInterface[name][prop] = value, pluginInterface);
- });
- });
- }
- }
- if ($$self.$$.dirty[0] & /*pluginInterface*/ 1 | $$self.$$.dirty[5] & /*pluginComponents*/ 2048) {
- {
- let changed = false;
- pluginComponents.forEach(([key]) => {
- if (pluginInterface[key]) return;
- $$invalidate(0, pluginInterface[key] = {}, pluginInterface);
- changed = true;
- });
- if (changed) {
- $$invalidate(168, registeredPluginsComponents = [...pluginComponents]);
- }
- }
- }
- if ($$self.$$.dirty[4] & /*disabled*/ 8388608) {
- disabledTransition.set(disabled ? 1 : 0);
- }
- if ($$self.$$.dirty[5] & /*previewImageDataMaxSize*/ 32) {
- maxImageDataSize = previewImageDataMaxSize
- ? sizeMin(previewImageDataMaxSize, maxTextureSize)
- : maxTextureSize;
- }
- if ($$self.$$.dirty[5] & /*$images*/ 4194304) {
- imageProxy.update($images[0]);
- }
- if ($$self.$$.dirty[5] & /*$shapePreprocessor*/ 8388608) {
- preprocessShape = $shapePreprocessor
- ? shape => $shapePreprocessor(shape, { isPreview: true })
- : passthrough;
- }
- if ($$self.$$.dirty[0] & /*$clientRect*/ 65536) {
- $clientRect && rootRect.set(rectCreate($clientRect.x, $clientRect.y, $clientRect.width, $clientRect.height));
- }
- if ($$self.$$.dirty[5] & /*$rootRect, isOverlayModeEnabled, $imageLoadState*/ 52428800) {
- $rootRect && isOverlayModeEnabled && $imageLoadState && $imageLoadState.complete && syncRootAspectRatio();
- }
- if ($$self.$$.dirty[0] & /*locale*/ 4 | $$self.$$.dirty[4] & /*utils*/ 2097152 | $$self.$$.dirty[5] & /*registeredPluginsComponents*/ 8192) {
- $$invalidate(183, utilsFiltered = locale && registeredPluginsComponents.length
- ? utils || registeredPluginsComponents.map(([id]) => id)
- : []);
- }
- if ($$self.$$.dirty[5] & /*utilsFiltered*/ 268435456) {
- $$invalidate(17, shouldRenderTabs = utilsFiltered.length > 1);
- }
- if ($$self.$$.dirty[0] & /*shouldRenderTabs*/ 131072) {
- if (!shouldRenderTabs) tabRect.set(rectCreateEmpty());
- }
- if ($$self.$$.dirty[0] & /*enableToolbar*/ 64) {
- if (!enableToolbar) toolRect.set(rectCreateEmpty());
- }
- if ($$self.$$.dirty[4] & /*previewUpscale*/ 16777216 | $$self.$$.dirty[5] & /*isOverlayModeEnabled*/ 2097152) {
- previewShouldUpscale.set(previewUpscale || isOverlayModeEnabled);
- }
- if ($$self.$$.dirty[5] & /*registeredPluginsComponents, utilsFiltered*/ 268443648) {
- $$invalidate(211, utilsAvailable = registeredPluginsComponents.filter(([id]) => utilsFiltered.includes(id)));
- }
- if ($$self.$$.dirty[6] & /*utilsAvailable*/ 33554432) {
- $$invalidate(212, utilsDefined = utilsAvailable.length);
- }
- if ($$self.$$.dirty[4] & /*util*/ 1048576 | $$self.$$.dirty[5] & /*utilsFiltered*/ 268435456 | $$self.$$.dirty[6] & /*utilsDefined*/ 67108864) {
- $$invalidate(19, utilSelected = util && typeof util === "string" && utilsFiltered.includes(util)
- ? util
- : utilsDefined > 0 ? utilsFiltered[0] : undefined);
- }
- if ($$self.$$.dirty[0] & /*utilSelected*/ 524288) {
- utilSelected && imageOutlineOpacity.set(0.075);
- }
- if ($$self.$$.dirty[0] & /*utilSelected*/ 524288) {
- overlayInset.set(utilSelected === "resize" ? 40 : 30);
- }
- if ($$self.$$.dirty[0] & /*utilSelected*/ 524288) {
- overlaySize.set(utilSelected === "resize" ? 140 : 70);
- }
- if ($$self.$$.dirty[5] & /*$imageCropRect, $imageOutputSize*/ 1140850688) {
- $$invalidate(187, imageTargetSizeCurrent = $imageCropRect && calculateImageTargetSize($imageOutputSize || {}, $imageCropRect));
- }
- if ($$self.$$.dirty[5] & /*$stageRect*/ 536870912 | $$self.$$.dirty[6] & /*imageTargetSizeCurrent, $overlayInset, $imageVisualBounds*/ 14) {
- imageTargetSizeCurrent && $stageRect && overlayTopOpacity.set(smoothstep($stageRect.y, $stageRect.y - $overlayInset, $imageVisualBounds.y));
- }
- if ($$self.$$.dirty[5] & /*$stageRect*/ 536870912 | $$self.$$.dirty[6] & /*imageTargetSizeCurrent, $overlayInset, $imageVisualBounds*/ 14) {
- imageTargetSizeCurrent && $stageRect && overlayRightOpacity.set(smoothstep($stageRect.x + $stageRect.width, $stageRect.x + $stageRect.width + $overlayInset, $imageVisualBounds.x + $imageVisualBounds.width));
- }
- if ($$self.$$.dirty[5] & /*$stageRect*/ 536870912 | $$self.$$.dirty[6] & /*imageTargetSizeCurrent, $overlayInset, $imageVisualBounds*/ 14) {
- imageTargetSizeCurrent && $stageRect && overlayBottomOpacity.set(smoothstep($stageRect.y + $stageRect.height, $stageRect.y + $stageRect.height + $overlayInset, $imageVisualBounds.y + $imageVisualBounds.height));
- }
- if ($$self.$$.dirty[5] & /*$stageRect*/ 536870912 | $$self.$$.dirty[6] & /*imageTargetSizeCurrent, $overlayInset, $imageVisualBounds*/ 14) {
- imageTargetSizeCurrent && $stageRect && overlayLeftOpacity.set(smoothstep($stageRect.x, $stageRect.x - $overlayInset, $imageVisualBounds.x));
- }
- if ($$self.$$.dirty[5] & /*$rootRect, gradientOverlayVertical*/ 16809984 | $$self.$$.dirty[6] & /*$overlaySize, $overlayTopOpacity*/ 96) {
- $$invalidate(190, overlayTop = $rootRect && {
- id: STAGE_OVERLAY_ID,
- x: 0,
- y: 0,
- width: $rootRect.width,
- height: $overlaySize,
- rotation: Math.PI,
- opacity: maxOpacity * $overlayTopOpacity,
- backgroundImage: gradientOverlayVertical
- });
- }
- if ($$self.$$.dirty[5] & /*$rootRect, gradientOverlayVertical*/ 16809984 | $$self.$$.dirty[6] & /*$overlaySize, $overlayBottomOpacity*/ 288) {
- $$invalidate(193, overlayBottom = $rootRect && {
- id: STAGE_OVERLAY_ID,
- x: 0,
- y: $rootRect.height - $overlaySize,
- width: $rootRect.width,
- height: $overlaySize,
- opacity: maxOpacity * $overlayBottomOpacity,
- backgroundImage: gradientOverlayVertical
- });
- }
- if ($$self.$$.dirty[5] & /*$rootRect, gradientOverlayHorizontal*/ 16793600 | $$self.$$.dirty[6] & /*$overlaySize, $overlayLeftOpacity*/ 1056) {
- $$invalidate(195, overlayLeft = $rootRect && {
- id: STAGE_OVERLAY_ID,
- x: 0,
- y: 0,
- height: $rootRect.height,
- width: $overlaySize,
- rotation: Math.PI,
- opacity: maxOpacity * $overlayLeftOpacity,
- backgroundImage: gradientOverlayHorizontal
- });
- }
- if ($$self.$$.dirty[5] & /*$rootRect, gradientOverlayHorizontal*/ 16793600 | $$self.$$.dirty[6] & /*$overlaySize, $overlayRightOpacity*/ 4128) {
- $$invalidate(197, overlayRight = $rootRect && {
- id: STAGE_OVERLAY_ID,
- x: $rootRect.width - $overlaySize,
- y: 0,
- height: $rootRect.height,
- width: $overlaySize,
- opacity: maxOpacity * $overlayRightOpacity,
- backgroundImage: gradientOverlayHorizontal
- });
- }
- if ($$self.$$.dirty[6] & /*overlayTop, overlayRight, overlayBottom, overlayLeft*/ 2704) {
- $$invalidate(199, gradientOverlays = [overlayTop, overlayRight, overlayBottom, overlayLeft].filter(Boolean));
- }
- if ($$self.$$.dirty[6] & /*gradientOverlays, $imageOverlayMarkup*/ 24576) {
- // if overlay top changes
- if (gradientOverlays && $imageOverlayMarkup) {
- // remove existing resize overlays
- const overlayMarkup = $imageOverlayMarkup.filter(markup => markup.id !== STAGE_OVERLAY_ID);
- set_store_value(imageOverlayMarkup, $imageOverlayMarkup = [...overlayMarkup, ...gradientOverlays], $imageOverlayMarkup);
- }
- }
- if ($$self.$$.dirty[5] & /*imagePreviewSrc*/ 512 | $$self.$$.dirty[6] & /*$imageFile*/ 32768) {
- imagePreviewSource.set(imagePreviewSrc
- ? imagePreviewSrc
- : $imageFile || undefined);
- }
- if ($$self.$$.dirty[0] & /*root*/ 2 | $$self.$$.dirty[4] & /*imagePreviewCurrent*/ 65536 | $$self.$$.dirty[6] & /*$imagePreview*/ 65536) {
- {
- $$invalidate(140, imagePreviewCurrent = $imagePreview);
- if ($imagePreview) root.dispatchEvent(createPing("loadpreview", imagePreviewCurrent));
- }
- }
- if ($$self.$$.dirty[6] & /*$imagePreviewSource*/ 131072) {
- if ($imagePreviewSource) resetPreviews();
- }
- if ($$self.$$.dirty[5] & /*$isInteracting*/ 134217728) {
- $$invalidate(204, canAnimate = !$isInteracting && !isSoftwareRendering());
- }
- if ($$self.$$.dirty[6] & /*$prefersReducedMotion*/ 1048576) {
- $$invalidate(205, acceptsAnimations = !$prefersReducedMotion);
- }
- if ($$self.$$.dirty[4] & /*animations*/ 4194304 | $$self.$$.dirty[6] & /*canAnimate, acceptsAnimations*/ 786432) {
- set_store_value(
- shouldAnimate,
- $shouldAnimate = animations === "always"
- ? canAnimate
- : animations === "never"
- ? false
- : canAnimate && acceptsAnimations,
- $shouldAnimate
- );
- }
- if ($$self.$$.dirty[6] & /*$history*/ 4194304) {
- $$invalidate(207, canUndo = $history.index > 0);
- }
- if ($$self.$$.dirty[6] & /*$history*/ 4194304) {
- $$invalidate(209, canRedo = $history.index < $history.length - 1);
- }
- if ($$self.$$.dirty[0] & /*locale*/ 4 | $$self.$$.dirty[5] & /*utilsFiltered*/ 268435456 | $$self.$$.dirty[6] & /*utilsAvailable*/ 33554432) {
- $$invalidate(20, utilsMerged = utilsFiltered.map(utilId => {
- const util = utilsAvailable.find(([id]) => utilId === id); // [id, view]
- if (!util) return;
- return {
- id: utilId,
- view: util[1],
- tabIcon: locale[`${utilId}Icon`],
- tabLabel: locale[`${utilId}Label`]
- };
- }).filter(Boolean) || []);
- }
- if ($$self.$$.dirty[0] & /*utilSelected*/ 524288) {
- utilSelectedStore.set(utilSelected);
- }
- if ($$self.$$.dirty[0] & /*utilSelected, pluginInterface*/ 524289) {
- $$invalidate(213, utilTools = utilSelected && pluginInterface[utilSelected].tools || []);
- }
- if ($$self.$$.dirty[0] & /*utilsMerged, utilsVisibleFraction*/ 3145728) {
- $$invalidate(21, utilsVisibleFraction = utilsMerged.reduce(
- (prev, curr) => {
- prev[curr.id] = utilsVisibleFraction && utilsVisibleFraction[curr.id] || 0;
- return prev;
- },
- {}
- ));
- }
- if ($$self.$$.dirty[0] & /*utilSelected*/ 524288) {
- $$invalidate(30, tabsConfig = {
- name: utilsUniqueId,
- selected: utilSelected
- });
- }
- if ($$self.$$.dirty[0] & /*utilsMerged*/ 1048576) {
- $$invalidate(31, tabs = utilsMerged.map(util => ({
- id: util.id,
- icon: util.tabIcon,
- label: util.tabLabel
- })));
- }
- if ($$self.$$.dirty[0] & /*utilsMerged*/ 1048576) {
- $$invalidate(32, panels = utilsMerged.map(util => util.id));
- }
- if ($$self.$$.dirty[4] & /*klass*/ 131072) {
- $$invalidate(33, className = arrayJoin(["PinturaRoot", "PinturaRootComponent", klass]));
- }
- if ($$self.$$.dirty[5] & /*$rootRect*/ 16777216) {
- $$invalidate(214, horizontalSpace = $rootRect && ($rootRect.width > 1000
- ? "wide"
- : $rootRect.width < 600 ? "narrow" : undefined));
- }
- if ($$self.$$.dirty[5] & /*$rootRect*/ 16777216) {
- $$invalidate(215, hasLimitedSpace = $rootRect && ($rootRect.width <= 320 || $rootRect.height <= 460));
- }
- if ($$self.$$.dirty[5] & /*$rootRect*/ 16777216) {
- $$invalidate(216, verticalSpace = $rootRect && ($rootRect.height > 1000
- ? "tall"
- : $rootRect.height < 600 ? "short" : undefined));
- }
- if ($$self.$$.dirty[0] & /*root*/ 2) {
- $$invalidate(217, isModal = root && root.parentNode && root.parentNode.classList.contains("PinturaModal"));
- }
- if ($$self.$$.dirty[0] & /*windowWidth*/ 2048 | $$self.$$.dirty[5] & /*$rootRect*/ 16777216 | $$self.$$.dirty[7] & /*isModal*/ 1) {
- $$invalidate(218, isCenteredHorizontally = isModal && $rootRect && windowWidth > $rootRect.width);
- }
- if ($$self.$$.dirty[0] & /*windowHeight*/ 4096 | $$self.$$.dirty[5] & /*$rootRect*/ 16777216 | $$self.$$.dirty[7] & /*isModal*/ 1) {
- $$invalidate(219, isCenteredVertically = isModal && $rootRect && windowHeight > $rootRect.height);
- }
- if ($$self.$$.dirty[7] & /*isCenteredHorizontally, isCenteredVertically*/ 6) {
- $$invalidate(220, isCentered = isCenteredHorizontally && isCenteredVertically);
- }
- if ($$self.$$.dirty[6] & /*horizontalSpace*/ 268435456) {
- $$invalidate(221, isNarrow = horizontalSpace === "narrow");
- }
- if ($$self.$$.dirty[5] & /*$rootRect, layoutDirectionPreference*/ 16777280) {
- $$invalidate(222, orientation = getOrientation($rootRect, layoutDirectionPreference));
- }
- if ($$self.$$.dirty[7] & /*orientation*/ 32) {
- $$invalidate(34, isLandscape = orientation === "landscape");
- }
- if ($$self.$$.dirty[6] & /*verticalSpace*/ 1073741824 | $$self.$$.dirty[7] & /*isNarrow*/ 16) {
- $$invalidate(223, isCompact = isNarrow || verticalSpace === "short");
- }
- if ($$self.$$.dirty[0] & /*windowWidth*/ 2048 | $$self.$$.dirty[5] & /*$rootRect*/ 16777216) {
- $$invalidate(224, hasSwipeNavigation = iOS && $rootRect && windowWidth === $rootRect.width && !shouldPreventSwipe);
- }
- if ($$self.$$.dirty[5] & /*isOverlayModeEnabled*/ 2097152 | $$self.$$.dirty[6] & /*utilTools, verticalSpace*/ 1207959552) {
- $$invalidate(225, shouldRenderUtilTools = utilTools.length && (verticalSpace === "short" || isOverlayModeEnabled));
- }
- if ($$self.$$.dirty[5] & /*layoutHorizontalUtilsPreference*/ 128) {
- $$invalidate(226, navigationHorizontalPreference = `has-navigation-preference-${layoutHorizontalUtilsPreference}`);
- }
- if ($$self.$$.dirty[5] & /*layoutVerticalUtilsPreference*/ 256) {
- $$invalidate(227, navigationVerticalPreference = `has-navigation-preference-${layoutVerticalUtilsPreference}`);
- }
- if ($$self.$$.dirty[0] & /*root*/ 2) {
- // will update when root element is available (computed style is live, so is updated when the style is updated)
- $$invalidate(228, rootElementComputedStyle = root && getComputedStyle(root));
- }
- if ($$self.$$.dirty[7] & /*rootElementComputedStyle*/ 2048) {
- // sync for first time
- if (rootElementComputedStyle) syncColors();
- }
- if ($$self.$$.dirty[0] & /*$shouldAnimate, enableToolbar, shouldRenderTabs, showUtils*/ 426048 | $$self.$$.dirty[4] & /*layoutMode, disabled*/ 8650752 | $$self.$$.dirty[6] & /*horizontalSpace, verticalSpace, hasLimitedSpace*/ 1879048192 | $$self.$$.dirty[7] & /*$env, orientation, navigationHorizontalPreference, navigationVerticalPreference, isModal, isCentered, isCenteredHorizontally, isCenteredVertically, $pointerAccuracy, $pointerHoverable, isCompact, hasSwipeNavigation*/ 30447) {
- env.set({
- ...$env,
- layoutMode,
- orientation,
- horizontalSpace,
- verticalSpace,
- navigationHorizontalPreference,
- navigationVerticalPreference,
- isModal,
- isDisabled: disabled,
- isCentered,
- isCenteredHorizontally,
- isCenteredVertically,
- isAnimated: $shouldAnimate,
- pointerAccuracy: $pointerAccuracy,
- pointerHoverable: $pointerHoverable,
- isCompact,
- hasSwipeNavigation,
- hasLimitedSpace,
- hasToolbar: enableToolbar,
- hasNavigation: shouldRenderTabs && showUtils,
- isIOS: iOS
- });
- }
- if ($$self.$$.dirty[7] & /*$env*/ 4096) {
- $$invalidate(35, envStr = Object.entries($env).map(([key, value]) => {
- // is true boolean prop, use key
- if ((/^is|has/).test(key)) {
- return value ? toKebabCase(key) : undefined;
- }
- // use value
- return value;
- }).filter(Boolean).join(" "));
- }
- if ($$self.$$.dirty[7] & /*$imageTransforms, $imagePreviewModifiers*/ 98304) {
- $$invalidate(36, imageCanvasState = $imageTransforms && Object.entries($imagePreviewModifiers).filter(([,value]) => value != null).reduce(
- (prev, [,value]) => {
- prev = { ...prev, ...value };
- return prev;
- },
- {}
- ));
- }
- if ($$self.$$.dirty[5] & /*$imageLoadState*/ 33554432) {
- //
- // loading status
- //
- $$invalidate(234, isStartLoadingImageSource = $imageLoadState && $imageLoadState.task === "any-to-file");
- }
- if ($$self.$$.dirty[7] & /*isStartLoadingImageSource*/ 131072) {
- // reset active images when loading a new image source
- if (isStartLoadingImageSource && activeImages) {
- activeImages.clear();
- }
- }
- if ($$self.$$.dirty[7] & /*$imageProps*/ 262144) {
- // if image props are ready
- $$invalidate(236, hasProps = !!$imageProps && !!$imageProps.translation);
- }
- if ($$self.$$.dirty[5] & /*lastImagePreview*/ 131072 | $$self.$$.dirty[6] & /*$imagePreview*/ 65536 | $$self.$$.dirty[7] & /*hasProps*/ 524288) {
- if (hasProps && $imagePreview && $imagePreview !== lastImagePreview) {
- $$invalidate(172, lastImagePreview = $imagePreview);
- addImagePreview();
- }
- }
- if ($$self.$$.dirty[7] & /*hasProps, $imageProps*/ 786432) {
- // update images when image props change
- hasProps && updateImagePreviews($imageProps);
- }
- if ($$self.$$.dirty[0] & /*$activeImages*/ 4194304) {
- // clean active images array, removes 'inactive' images when their opacity is 0
- if ($activeImages && $activeImages.length > 1) {
- let imagesToRemove = [];
- activeImages.forEach((image, index) => {
- if (index === 0) return;
- if (image.get().opacity <= 0) imagesToRemove.push(image);
- });
- imagesToRemove.forEach(image => activeImages.remove(image));
- }
- }
- if ($$self.$$.dirty[0] & /*locale*/ 4 | $$self.$$.dirty[7] & /*missingFeatures*/ 1048576) {
- $$invalidate(23, isSupportsError = locale && missingFeatures.length && locale.labelSupportError(missingFeatures));
- }
- if ($$self.$$.dirty[5] & /*$imageLoadState*/ 33554432) {
- $$invalidate(238, isImageLoadError = $imageLoadState && !!$imageLoadState.error);
- }
- if ($$self.$$.dirty[5] & /*$imageLoadState*/ 33554432) {
- $$invalidate(239, isWaitingForImage = !$imageLoadState || !$imageLoadState.complete && $imageLoadState.task === undefined);
- }
- if ($$self.$$.dirty[5] & /*$imageLoadState*/ 33554432) {
- $$invalidate(240, imageLoadProgress = $imageLoadState && ($imageLoadState.taskLengthComputable
- ? $imageLoadState.taskProgress
- : Infinity));
- }
- if ($$self.$$.dirty[7] & /*isStartLoadingImageSource*/ 131072) {
- if (isStartLoadingImageSource) set_store_value(imageVisualLoadComplete, $imageVisualLoadComplete = false, $imageVisualLoadComplete);
- }
- if ($$self.$$.dirty[5] & /*$imageLoadState, loadTimer*/ 33816576) {
- if ($imageLoadState && $imageLoadState.complete) {
- const minLoaderDuration = 500;
- // TODO: derive visual load complete from interface rest state instead of arbitrary timer
- clearTimeout(loadTimer);
- $$invalidate(173, loadTimer = setTimeout(
- () => {
- set_store_value(imageVisualLoadComplete, $imageVisualLoadComplete = true, $imageVisualLoadComplete);
- },
- minLoaderDuration
- ));
- }
- }
- if ($$self.$$.dirty[5] & /*$imageLoadState*/ 33554432 | $$self.$$.dirty[7] & /*isImageLoadError, isWaitingForImage, $imageVisualLoadComplete*/ 39845888) {
- $$invalidate(241, isLoadingImageData = $imageLoadState && !isImageLoadError && !isWaitingForImage && !$imageVisualLoadComplete);
- }
- if ($$self.$$.dirty[5] & /*imagePreviewLoaderCancelToken*/ 65536 | $$self.$$.dirty[6] & /*$imagePreviewSource, $imagePreview*/ 196608) {
- // is creating a preview while an image source is set and the preview isn't ready or when a cancel token is found
- $$invalidate(243, isCreatingImagePreview = !!$imagePreviewSource && (!$imagePreview || !!imagePreviewLoaderCancelToken));
- }
- if ($$self.$$.dirty[6] & /*$imageProcessingPreparing*/ 16777216 | $$self.$$.dirty[7] & /*$imageProcessState*/ 268435456) {
- //
- // processing status
- //
- $$invalidate(244, isProcessingImage = $imageProcessingPreparing || $imageProcessState && $imageProcessState.progress !== undefined && !$imageProcessState.complete);
- }
- if ($$self.$$.dirty[5] & /*$imageLoadState*/ 33554432 | $$self.$$.dirty[7] & /*isWaitingForImage*/ 4194304) {
- $$invalidate(246, imageLoadShowProgressIndicator = $imageLoadState && !($imageLoadState.error || isWaitingForImage));
- }
- if ($$self.$$.dirty[0] & /*locale*/ 4 | $$self.$$.dirty[5] & /*$imageLoadState*/ 33554432) {
- $$invalidate(247, imageLoadStatusLabel = locale && (!$imageLoadState
- ? locale.statusLabelLoadImage($imageLoadState)
- : !$imageLoadState.complete || $imageLoadState.error
- ? stringReplace(locale.statusLabelLoadImage($imageLoadState), $imageLoadState.error && $imageLoadState.error.metadata, "{", "}")
- : locale.statusLabelLoadImage({
- progress: Infinity,
- task: "blob-to-bitmap"
- })));
- }
- if ($$self.$$.dirty[0] & /*locale*/ 4 | $$self.$$.dirty[7] & /*$imageProcessState*/ 268435456) {
- $$invalidate(248, imageProcessStatusLabel = $imageProcessState && locale && locale.statusLabelProcessImage($imageProcessState));
- }
- if ($$self.$$.dirty[7] & /*$imageProcessState*/ 268435456) {
- $$invalidate(249, imageProcessProgress = $imageProcessState && ($imageProcessState.taskLengthComputable
- ? $imageProcessState.taskProgress
- : Infinity));
- }
- if ($$self.$$.dirty[7] & /*$imageProcessState*/ 268435456) {
- $$invalidate(250, imageProcessShowProgressIndicator = $imageProcessState && !$imageProcessState.error);
- }
- if ($$self.$$.dirty[7] & /*$imageProcessState*/ 268435456) {
- $$invalidate(251, isImageProcessingError = $imageProcessState && $imageProcessState.error);
- }
- if ($$self.$$.dirty[0] & /*locale*/ 4 | $$self.$$.dirty[4] & /*status*/ 32768 | $$self.$$.dirty[7] & /*isWaitingForImage, isImageLoadError, isLoadingImageData, isCreatingImagePreview, imageLoadStatusLabel, imageLoadShowProgressIndicator, imageLoadProgress, isProcessingImage*/ 1843396608 | $$self.$$.dirty[8] & /*imageProcessStatusLabel, isImageProcessingError, imageProcessShowProgressIndicator, imageProcessProgress*/ 15) {
- if (status) {
- let label;
- let progress;
- let showProgress;
- let isError;
- let errorCallback;
- if (isString(status)) label = status;
- if (isNumber(status)) progress = status; else if (Array.isArray(status)) {
- [label, progress, errorCallback] = status;
- if (progress === false) isError = true;
- if (isNumber(progress)) showProgress = true;
- }
- $$invalidate(13, statusState = (label || progress) && {
- text: label,
- aside: isError || showProgress,
- progressIndicator: { visible: showProgress, progress },
- closeButton: isError && {
- label: locale.statusLabelButtonClose,
- icon: locale.statusIconButtonClose,
- onclick: errorCallback || (() => $$invalidate(139, status = undefined))
- }
- });
- } else if (locale && isWaitingForImage || isImageLoadError || isLoadingImageData || isCreatingImagePreview) {
- $$invalidate(13, statusState = {
- text: imageLoadStatusLabel,
- aside: isImageLoadError || imageLoadShowProgressIndicator,
- progressIndicator: {
- visible: imageLoadShowProgressIndicator,
- progress: imageLoadProgress
- },
- closeButton: isImageLoadError && {
- label: locale.statusLabelButtonClose,
- icon: locale.statusIconButtonClose,
- onclick: handleCloseImageLoadError
- }
- });
- } else if (locale && isProcessingImage && imageProcessStatusLabel) {
- $$invalidate(13, statusState = {
- text: imageProcessStatusLabel,
- aside: isImageProcessingError || imageProcessShowProgressIndicator,
- progressIndicator: {
- visible: imageProcessShowProgressIndicator,
- progress: imageProcessProgress
- },
- closeButton: isImageProcessingError && {
- label: locale.statusLabelButtonClose,
- icon: locale.statusIconButtonClose,
- onclick: handleCloseImageProcessError
- }
- });
- } else {
- $$invalidate(13, statusState = undefined);
- }
- }
- if ($$self.$$.dirty[4] & /*status*/ 32768) {
- $$invalidate(252, isCustomStatus = status !== undefined);
- }
- if ($$self.$$.dirty[7] & /*isModal, $imageProcessState*/ 268435457) {
- if (isModal && $imageProcessState && $imageProcessState.complete) {
- wasProcessingImage.set(true);
- setTimeout(() => wasProcessingImage.set(false), 100);
- }
- }
- if ($$self.$$.dirty[0] & /*isSupportsError*/ 8388608 | $$self.$$.dirty[7] & /*isWaitingForImage, isImageLoadError, isLoadingImageData, isCreatingImagePreview, isProcessingImage*/ 224395264 | $$self.$$.dirty[8] & /*$wasProcessingImage, isCustomStatus*/ 80) {
- $$invalidate(253, isStatusActive = $wasProcessingImage || isSupportsError || isWaitingForImage || isImageLoadError || isLoadingImageData || isCreatingImagePreview || isProcessingImage || isCustomStatus);
- }
- if ($$self.$$.dirty[8] & /*isStatusActive*/ 32) {
- set_store_value(statusOpacity, $statusOpacity = isStatusActive ? 1 : 0, $statusOpacity);
- }
- if ($$self.$$.dirty[0] & /*$statusOpacity*/ 16777216) {
- $$invalidate(25, isStatusVisible = $statusOpacity > 0);
- }
- if ($$self.$$.dirty[0] & /*statusState*/ 8192) {
- $$invalidate(255, hasAside = !!(statusState && statusState.aside));
- }
- if ($$self.$$.dirty[0] & /*isStatusVisible, statusState*/ 33562624 | $$self.$$.dirty[5] & /*asideWidthUpdateTimer*/ 524288 | $$self.$$.dirty[8] & /*hasAside, $statusWidth*/ 384) {
- if (isStatusVisible && statusState) {
- clearTimeout(asideWidthUpdateTimer);
- // has aside
- if (hasAside) {
- // if error occured, snap in possition
- const hard = !!statusState.error;
- asideOpacity.set(1);
- // update offset of aside
- asideOffset.set($statusWidth, { hard });
- // update width of aside, this pushes message to left so it stays centered
- $$invalidate(174, asideWidthUpdateTimer = setTimeout(
- () => {
- asideWidth.set(16);
- },
- 1
- ));
- } else {
- asideOpacity.set(0);
- $$invalidate(174, asideWidthUpdateTimer = setTimeout(
- () => {
- asideWidth.set(0);
- },
- 1
- ));
- }
- }
- }
- if ($$self.$$.dirty[0] & /*isStatusVisible*/ 33554432) {
- if (!isStatusVisible) {
- statusOffset.set(undefined, { hard: true });
- asideOffset.set(undefined, { hard: true });
- asideWidth.set(0, { hard: true });
- }
- }
- if ($$self.$$.dirty[8] & /*$asideWidth*/ 1024) {
- $$invalidate(257, statusIndent = $asideWidth * 0.5);
- }
- if ($$self.$$.dirty[8] & /*$statusOffset, statusIndent*/ 2560) {
- $$invalidate(38, statusTransform = `transform: translateX(${$statusOffset - statusIndent}px)`);
- }
- if ($$self.$$.dirty[0] & /*locale*/ 4 | $$self.$$.dirty[4] & /*willRenderToolbar, enableButtonRevert, enableButtonExport*/ 1744830464 | $$self.$$.dirty[5] & /*enableButtonClose, enableNavigateHistory*/ 5 | $$self.$$.dirty[6] & /*canUndo, canRedo, utilTools*/ 144703488 | $$self.$$.dirty[7] & /*shouldRenderUtilTools, isNarrow, $env*/ 4368) {
- // dynamic IO menu
- $$invalidate(39, toolbarItems = locale && willRenderToolbar(
- [
- [
- "div",
- "alpha",
- { class: "PinturaNavGroup" },
- [
- [
- "div",
- "alpha-set",
- { class: "PinturaNavSet" },
- [
- // button close
- enableButtonClose && [
- "Button",
- "close",
- {
- label: locale.labelClose,
- icon: locale.iconButtonClose,
- onclick: () => dispatch("close"),
- hideLabel: true
- }
- ],
- // button revert
- enableButtonRevert && [
- "Button",
- "revert",
- {
- label: locale.labelButtonRevert,
- icon: locale.iconButtonRevert,
- disabled: !canUndo,
- onclick: revert,
- hideLabel: true
- }
- ]
- ]
- ]
- ]
- ],
- [
- "div",
- "beta",
- {
- class: "PinturaNavGroup PinturaNavGroupFloat"
- },
- [
- enableNavigateHistory && [
- "div",
- "history",
- { class: "PinturaNavSet" },
- [
- [
- "Button",
- "undo",
- {
- label: locale.labelButtonUndo,
- icon: locale.iconButtonUndo,
- disabled: !canUndo,
- onclick: history.undo,
- hideLabel: true
- }
- ],
- [
- "Button",
- "redo",
- {
- label: locale.labelButtonRedo,
- icon: locale.iconButtonRedo,
- disabled: !canRedo,
- onclick: history.redo,
- hideLabel: true
- }
- ]
- ]
- ],
- shouldRenderUtilTools && [
- "div",
- "plugin-tools",
- { class: "PinturaNavSet" },
- utilTools.filter(Boolean).map(// in
- ([component, key, props]) => // out
- [component, key, { ...props, hideLabel: true }])
- ]
- ]
- ],
- [
- "div",
- "gamma",
- { class: "PinturaNavGroup" },
- [
- enableButtonExport && [
- "Button",
- "export",
- {
- label: locale.labelButtonExport,
- icon: isNarrow && locale.iconButtonExport,
- class: "PinturaButtonExport",
- onclick: handleExport,
- hideLabel: isNarrow
- }
- ]
- ]
- ]
- ],
- { ...$env }
- ));
- }
- if ($$self.$$.dirty[0] & /*$clientRect*/ 65536) {
- $$invalidate(260, hasClientRect = $clientRect && $clientRect.width > 0 && $clientRect.height > 0);
- }
- if ($$self.$$.dirty[0] & /*locale*/ 4 | $$self.$$.dirty[6] & /*utilsDefined*/ 67108864 | $$self.$$.dirty[8] & /*hasClientRect*/ 4096) {
- $$invalidate(40, canRender = hasClientRect && locale && utilsDefined);
- }
- if ($$self.$$.dirty[8] & /*$imageRedaction*/ 16384) {
- // toggles on/off depending on active redaction shapes
- $$invalidate(261, hasImageRedaction = $imageRedaction && !!$imageRedaction.length);
- }
- if ($$self.$$.dirty[6] & /*$imageSize*/ 1 | $$self.$$.dirty[8] & /*hasImageRedaction, $imageRedaction*/ 24576) {
- // scales down resolution of scrambled image if redaction takes up more than half of view
- $$invalidate(263, imageRedactionScalar = hasImageRedaction && getImageRedactionScaleFactor($imageSize, $imageRedaction));
- }
- if ($$self.$$.dirty[6] & /*$imagePreview*/ 65536 | $$self.$$.dirty[8] & /*hasImageRedaction, $imageScrambler, imageRedactionScalar, $imageBackgroundColor*/ 237568) {
- // only update/render preview if image redaction shapes are found
- hasImageRedaction && updateScrambledPreview($imagePreview, $imageScrambler, imageRedactionScalar, $imageBackgroundColor);
- }
- if ($$self.$$.dirty[5] & /*scrambledPreviewImage*/ 1048576 | $$self.$$.dirty[6] & /*$imageSize*/ 1 | $$self.$$.dirty[8] & /*$imageRedaction*/ 16384) {
- if ($imageRedaction && scrambledPreviewImage && $imageSize) {
- // used to calculate fraction x y coordinates of shape corners
- const { width, height } = $imageSize;
- // to blended shapes
- $$invalidate(28, blendShapes = $imageRedaction.map(shape => {
- const rect = rectCreate(shape.x, shape.y, shape.width, shape.height);
- const corners = rectRotate(rectClone(rect), shape.rotation);
- const backgroundCorners = corners.map(corner => vectorCreate(corner.x / width, corner.y / height));
- return {
- ...shape,
- id: "redaction",
- flipX: false,
- flipY: false,
- cornerRadius: 0,
- strokeWidth: 0,
- strokeColor: undefined,
- backgroundColor: [0, 0, 0],
- backgroundImage: scrambledPreviewImage,
- backgroundImageRendering: "pixelated",
- backgroundCorners
- };
- }));
- }
- }
- if ($$self.$$.dirty[0] & /*rootPortal*/ 16384) {
- rootPortal && rootPortalStore.set(rootPortal);
- }
- if ($$self.$$.dirty[0] & /*isSupportsError*/ 8388608 | $$self.$$.dirty[6] & /*$imagePreview*/ 65536) {
- // ready bool
- $$invalidate(26, isReady = $imagePreview && !isSupportsError);
- }
- if ($$self.$$.dirty[0] & /*isReady, root*/ 67108866) {
- // now ready for interaction
- isReady && root.dispatchEvent(createPing("ready"));
- }
- };
- $$invalidate(237, missingFeatures = [!supportsWebGL() && "WebGL"].filter(Boolean));
- // used to route ping events
- $$invalidate(41, routePing = createPingRouter(eventProxy.pub));
- return [
- pluginInterface,
- root,
- locale,
- id,
- elasticityMultiplier,
- willRenderCanvas,
- enableToolbar,
- pluginOptions,
- imageSourceToImageData,
- imagePreview,
- history,
- windowWidth,
- windowHeight,
- statusState,
- rootPortal,
- showUtils,
- $clientRect,
- shouldRenderTabs,
- $shouldAnimate,
- utilSelected,
- utilsMerged,
- utilsVisibleFraction,
- $activeImages,
- isSupportsError,
- $statusOpacity,
- isStatusVisible,
- isReady,
- utilsVisible,
- blendShapes,
- $tabRect,
- tabsConfig,
- tabs,
- panels,
- className,
- isLandscape,
- envStr,
- imageCanvasState,
- $imageSelectionRectPresentation,
- statusTransform,
- toolbarItems,
- canRender,
- routePing,
- $asideOffset,
- $asideOpacity,
- $toolRect,
- $utilRect,
- $pixelRatio,
- $rootBackgroundColor,
- $utilSelectedStore,
- $stagePadded,
- $interfaceImages,
- $imageAnnotation,
- $imageDecoration,
- $imageFrame,
- $imageOverlay,
- $disabledTransition,
- disabledTransition,
- imageFile,
- imageSize,
- imageLoadState,
- imageProcessState,
- imageCropAspectRatio,
- imageCropRect,
- imageOutputSize,
- imageBackgroundColor,
- imageDecoration,
- imageAnnotation,
- imageRedaction,
- imageFrame,
- imageState,
- images,
- shapePreprocessor,
- imageScrambler,
- utilSelectedStore,
- rootBackgroundColor,
- rootForegroundColor,
- rootLineColor,
- clientRect,
- rootRect,
- tabRect,
- toolRect,
- utilRect,
- pointerAccuracy,
- pointerHoverable,
- isInteracting,
- isInteractingFraction,
- previewShouldUpscale,
- imageCropRectSnapshot,
- imageCropRectIntent,
- imageSelectionRect,
- imageSelectionRectSnapshot,
- imageSelectionRectIntent,
- stagePadded,
- stageRect,
- stageScalar,
- imageSelectionRectPresentation,
- presentationScalar,
- imageVisualBounds,
- imageOverlayMarkup,
- imageOverlay,
- overlayInset,
- overlaySize,
- overlayLeftOpacity,
- overlayRightOpacity,
- overlayTopOpacity,
- overlayBottomOpacity,
- imageVisualLoadComplete,
- imagePreviewSource,
- imagePreviewModifiers,
- interfaceImages,
- imageTransforms,
- env,
- pixelRatio,
- shouldAnimate,
- imageProcessingPreparing,
- utilStores,
- handleTransitionEnd,
- imageProps,
- activeImages,
- statusOpacity,
- wasProcessingImage,
- asideOffset,
- asideOpacity,
- asideWidth,
- statusWidth,
- statusOffset,
- offsetAside,
- handleTouchStart,
- handleTouchMove,
- handlePointerMove,
- pressedKeysStore,
- handleKeydown,
- handleKeyup,
- handleWindowBlur,
- handleContextMenu,
- handleDropFiles,
- handlePaste,
- getStageState,
- createCanvasState,
- status,
- imagePreviewCurrent,
- klass,
- layoutMode,
- stores,
- util,
- utils,
- animations,
- disabled,
- previewUpscale,
- willRevert,
- willProcessImage,
- willRenderToolbar,
- willSetHistoryInitialState,
- enableButtonExport,
- enableButtonRevert,
- enableNavigateHistory,
- enableUtils,
- enableButtonClose,
- enableDropImage,
- enablePasteImage,
- previewImageDataMaxSize,
- layoutDirectionPreference,
- layoutHorizontalUtilsPreference,
- layoutVerticalUtilsPreference,
- imagePreviewSrc,
- imageOrienter,
- pluginComponents,
- sub,
- registeredPluginsComponents,
- gradientOverlayHorizontal,
- gradientOverlayVertical,
- imagePreviewLoaderCancelToken,
- lastImagePreview,
- loadTimer,
- asideWidthUpdateTimer,
- scrambledPreviewImage,
- isOverlayModeEnabled,
- $images,
- $shapePreprocessor,
- $rootRect,
- $imageLoadState,
- $imageCropRect,
- $isInteracting,
- utilsFiltered,
- $stageRect,
- $imageOutputSize,
- $imageSize,
- imageTargetSizeCurrent,
- $overlayInset,
- $imageVisualBounds,
- overlayTop,
- $overlaySize,
- $overlayTopOpacity,
- overlayBottom,
- $overlayBottomOpacity,
- overlayLeft,
- $overlayLeftOpacity,
- overlayRight,
- $overlayRightOpacity,
- gradientOverlays,
- $imageOverlayMarkup,
- $imageFile,
- $imagePreview,
- $imagePreviewSource,
- canAnimate,
- acceptsAnimations,
- $prefersReducedMotion,
- canUndo,
- $history,
- canRedo,
- $imageProcessingPreparing,
- utilsAvailable,
- utilsDefined,
- utilTools,
- horizontalSpace,
- hasLimitedSpace,
- verticalSpace,
- isModal,
- isCenteredHorizontally,
- isCenteredVertically,
- isCentered,
- isNarrow,
- orientation,
- isCompact,
- hasSwipeNavigation,
- shouldRenderUtilTools,
- navigationHorizontalPreference,
- navigationVerticalPreference,
- rootElementComputedStyle,
- $env,
- $pointerAccuracy,
- $pointerHoverable,
- $imageTransforms,
- $imagePreviewModifiers,
- isStartLoadingImageSource,
- $imageProps,
- hasProps,
- missingFeatures,
- isImageLoadError,
- isWaitingForImage,
- imageLoadProgress,
- isLoadingImageData,
- $imageVisualLoadComplete,
- isCreatingImagePreview,
- isProcessingImage,
- $imageProcessState,
- imageLoadShowProgressIndicator,
- imageLoadStatusLabel,
- imageProcessStatusLabel,
- imageProcessProgress,
- imageProcessShowProgressIndicator,
- isImageProcessingError,
- isCustomStatus,
- isStatusActive,
- $wasProcessingImage,
- hasAside,
- $statusWidth,
- statusIndent,
- $asideWidth,
- $statusOffset,
- hasClientRect,
- hasImageRedaction,
- $imageRedaction,
- imageRedactionScalar,
- $imageScrambler,
- $imageBackgroundColor,
- onwindowresize,
- measure_handler,
- select_handler,
- func,
- panel_component_binding,
- measure_handler_1,
- show_handler,
- hide_handler,
- fade_handler,
- measure_handler_2,
- func_1,
- panel_component_binding_1,
- measure_handler_3,
- show_handler_1,
- hide_handler_1,
- fade_handler_1,
- func_2,
- div_binding,
- div_binding_1,
- measure_handler_4
- ];
- }
- class Ui extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$u,
- create_fragment$u,
- safe_not_equal,
- {
- class: 141,
- layout: 142,
- stores: 143,
- locale: 2,
- id: 3,
- util: 144,
- utils: 145,
- animations: 146,
- disabled: 147,
- status: 139,
- previewUpscale: 148,
- elasticityMultiplier: 4,
- willRevert: 149,
- willProcessImage: 150,
- willRenderCanvas: 5,
- willRenderToolbar: 151,
- willSetHistoryInitialState: 152,
- enableButtonExport: 153,
- enableButtonRevert: 154,
- enableNavigateHistory: 155,
- enableToolbar: 6,
- enableUtils: 156,
- enableButtonClose: 157,
- enableDropImage: 158,
- enablePasteImage: 159,
- previewImageDataMaxSize: 160,
- layoutDirectionPreference: 161,
- layoutHorizontalUtilsPreference: 162,
- layoutVerticalUtilsPreference: 163,
- imagePreviewSrc: 164,
- imageOrienter: 165,
- pluginComponents: 166,
- pluginOptions: 7,
- sub: 167,
- pluginInterface: 0,
- root: 1,
- imageSourceToImageData: 8,
- imagePreview: 9,
- imagePreviewCurrent: 140,
- history: 10
- },
- [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
- );
- }
- get class() {
- return this.$$.ctx[141];
- }
- set class(klass) {
- this.$set({ class: klass });
- flush();
- }
- get layout() {
- return this.$$.ctx[142];
- }
- set layout(layoutMode) {
- this.$set({ layout: layoutMode });
- flush();
- }
- get stores() {
- return this.$$.ctx[143];
- }
- set stores(stores) {
- this.$set({ stores });
- flush();
- }
- get locale() {
- return this.$$.ctx[2];
- }
- set locale(locale) {
- this.$set({ locale });
- flush();
- }
- get id() {
- return this.$$.ctx[3];
- }
- set id(id) {
- this.$set({ id });
- flush();
- }
- get util() {
- return this.$$.ctx[144];
- }
- set util(util) {
- this.$set({ util });
- flush();
- }
- get utils() {
- return this.$$.ctx[145];
- }
- set utils(utils) {
- this.$set({ utils });
- flush();
- }
- get animations() {
- return this.$$.ctx[146];
- }
- set animations(animations) {
- this.$set({ animations });
- flush();
- }
- get disabled() {
- return this.$$.ctx[147];
- }
- set disabled(disabled) {
- this.$set({ disabled });
- flush();
- }
- get status() {
- return this.$$.ctx[139];
- }
- set status(status) {
- this.$set({ status });
- flush();
- }
- get previewUpscale() {
- return this.$$.ctx[148];
- }
- set previewUpscale(previewUpscale) {
- this.$set({ previewUpscale });
- flush();
- }
- get elasticityMultiplier() {
- return this.$$.ctx[4];
- }
- set elasticityMultiplier(elasticityMultiplier) {
- this.$set({ elasticityMultiplier });
- flush();
- }
- get willRevert() {
- return this.$$.ctx[149];
- }
- set willRevert(willRevert) {
- this.$set({ willRevert });
- flush();
- }
- get willProcessImage() {
- return this.$$.ctx[150];
- }
- set willProcessImage(willProcessImage) {
- this.$set({ willProcessImage });
- flush();
- }
- get willRenderCanvas() {
- return this.$$.ctx[5];
- }
- set willRenderCanvas(willRenderCanvas) {
- this.$set({ willRenderCanvas });
- flush();
- }
- get willRenderToolbar() {
- return this.$$.ctx[151];
- }
- set willRenderToolbar(willRenderToolbar) {
- this.$set({ willRenderToolbar });
- flush();
- }
- get willSetHistoryInitialState() {
- return this.$$.ctx[152];
- }
- set willSetHistoryInitialState(willSetHistoryInitialState) {
- this.$set({ willSetHistoryInitialState });
- flush();
- }
- get enableButtonExport() {
- return this.$$.ctx[153];
- }
- set enableButtonExport(enableButtonExport) {
- this.$set({ enableButtonExport });
- flush();
- }
- get enableButtonRevert() {
- return this.$$.ctx[154];
- }
- set enableButtonRevert(enableButtonRevert) {
- this.$set({ enableButtonRevert });
- flush();
- }
- get enableNavigateHistory() {
- return this.$$.ctx[155];
- }
- set enableNavigateHistory(enableNavigateHistory) {
- this.$set({ enableNavigateHistory });
- flush();
- }
- get enableToolbar() {
- return this.$$.ctx[6];
- }
- set enableToolbar(enableToolbar) {
- this.$set({ enableToolbar });
- flush();
- }
- get enableUtils() {
- return this.$$.ctx[156];
- }
- set enableUtils(enableUtils) {
- this.$set({ enableUtils });
- flush();
- }
- get enableButtonClose() {
- return this.$$.ctx[157];
- }
- set enableButtonClose(enableButtonClose) {
- this.$set({ enableButtonClose });
- flush();
- }
- get enableDropImage() {
- return this.$$.ctx[158];
- }
- set enableDropImage(enableDropImage) {
- this.$set({ enableDropImage });
- flush();
- }
- get enablePasteImage() {
- return this.$$.ctx[159];
- }
- set enablePasteImage(enablePasteImage) {
- this.$set({ enablePasteImage });
- flush();
- }
- get previewImageDataMaxSize() {
- return this.$$.ctx[160];
- }
- set previewImageDataMaxSize(previewImageDataMaxSize) {
- this.$set({ previewImageDataMaxSize });
- flush();
- }
- get layoutDirectionPreference() {
- return this.$$.ctx[161];
- }
- set layoutDirectionPreference(layoutDirectionPreference) {
- this.$set({ layoutDirectionPreference });
- flush();
- }
- get layoutHorizontalUtilsPreference() {
- return this.$$.ctx[162];
- }
- set layoutHorizontalUtilsPreference(layoutHorizontalUtilsPreference) {
- this.$set({ layoutHorizontalUtilsPreference });
- flush();
- }
- get layoutVerticalUtilsPreference() {
- return this.$$.ctx[163];
- }
- set layoutVerticalUtilsPreference(layoutVerticalUtilsPreference) {
- this.$set({ layoutVerticalUtilsPreference });
- flush();
- }
- get imagePreviewSrc() {
- return this.$$.ctx[164];
- }
- set imagePreviewSrc(imagePreviewSrc) {
- this.$set({ imagePreviewSrc });
- flush();
- }
- get imageOrienter() {
- return this.$$.ctx[165];
- }
- set imageOrienter(imageOrienter) {
- this.$set({ imageOrienter });
- flush();
- }
- get pluginComponents() {
- return this.$$.ctx[166];
- }
- set pluginComponents(pluginComponents) {
- this.$set({ pluginComponents });
- flush();
- }
- get pluginOptions() {
- return this.$$.ctx[7];
- }
- set pluginOptions(pluginOptions) {
- this.$set({ pluginOptions });
- flush();
- }
- get sub() {
- return this.$$.ctx[167];
- }
- get pluginInterface() {
- return this.$$.ctx[0];
- }
- get root() {
- return this.$$.ctx[1];
- }
- set root(root) {
- this.$set({ root });
- flush();
- }
- get imageSourceToImageData() {
- return this.$$.ctx[8];
- }
- set imageSourceToImageData(imageSourceToImageData) {
- this.$set({ imageSourceToImageData });
- flush();
- }
- get imagePreview() {
- return this.$$.ctx[9];
- }
- get imagePreviewCurrent() {
- return this.$$.ctx[140];
- }
- set imagePreviewCurrent(imagePreviewCurrent) {
- this.$set({ imagePreviewCurrent });
- flush();
- }
- get history() {
- return this.$$.ctx[10];
- }
- }
- // which props to filter out of exported props
- const utilPrivateProps = ['klass', 'stores', 'isVisible', 'isActive', 'isActiveFraction', 'locale'];
- const viewPrivateProps = [
- // methods
- 'history',
- // props
- 'klass',
- 'stores',
- 'navButtons',
- 'pluginComponents',
- 'pluginInterface',
- 'pluginOptions',
- 'sub',
- 'imagePreviewSrc',
- 'imagePreview',
- 'imagePreviewCurrent',
- ];
- // view options array
- let editorProps;
- const pluginProps = new Set([]);
- const propPluginRef = {};
- // loops over plugins and registers all available options so we can define getters/setters
- const pluginComponents = new Map();
- const setEditorViewPlugins = (...args) => {
- args.filter((plugin) => !!plugin.util).forEach((plugin) => {
- const [id, Component] = plugin.util;
- if (pluginComponents.has(id))
- return;
- pluginComponents.set(id, Component);
- getComponentExportedProps(Component)
- .filter((prop) => !utilPrivateProps.includes(prop))
- .forEach((prop) => {
- pluginProps.add(prop);
- if (propPluginRef[prop]) {
- propPluginRef[prop].push(id);
- return;
- }
- propPluginRef[prop] = [id];
- });
- });
- };
- const getEditorViewProps = () => {
- editorProps = new Set(getComponentExportedProps(Ui).filter((prop) => !viewPrivateProps.includes(prop)));
- return [...editorProps, ...pluginProps];
- };
- const attachEditorView = (target, stores) => {
- const accessors = {};
- // creates the editor component instance
- const editor = new Ui({
- target,
- props: {
- stores,
- pluginComponents: Array.from(pluginComponents),
- },
- });
- // destroys the editor component instance
- let isDestroyed = false;
- const destroy = () => {
- if (isDestroyed)
- return;
- if (isBrowser())
- window.removeEventListener('pagehide', destroy);
- if (!editor)
- return;
- isDestroyed = true;
- editor.$destroy();
- };
- // set up accessors for editor props
- if (!editorProps)
- editorProps = new Set(getComponentExportedProps(Ui).filter((prop) => !viewPrivateProps.includes(prop)));
- editorProps.forEach((prop) => {
- Object.defineProperty(accessors, prop, {
- get: () => editor[prop],
- set: (value) => (editor[prop] = value),
- });
- });
- // this reads the imagePreview store so third parties can interact with image data
- Object.defineProperty(accessors, 'previewImageData', {
- get: () => editor.imagePreviewCurrent,
- });
- // set up accessors for plugin props
- pluginProps.forEach((prop) => {
- const plugins = propPluginRef[prop];
- const plugin = plugins[0]; // will always get value from first plugin, when plugins share a property the value will be in sync when set
- Object.defineProperty(accessors, prop, {
- get: () => editor.pluginInterface[plugin][prop],
- set: (value) => {
- const opts = plugins.reduce((prev, plugin) => {
- prev[plugin] = {
- ...editor.pluginOptions[plugin],
- [prop]: value,
- };
- return prev;
- }, {});
- editor.pluginOptions = {
- ...editor.pluginOptions,
- ...opts,
- };
- },
- });
- });
- // add `element` root query
- Object.defineProperty(accessors, 'element', {
- get: () => editor.root,
- set: () => undefined,
- });
- // history shortcut
- const history = editor.history;
- defineMethods(accessors, {
- on: (event, cb) => {
- // exit if editor was destroyed, will return stub function so unsubs can be called without issues
- if (isDestroyed)
- return () => {
- // Do nothing
- };
- // catch history events and route to history object
- if (/undo|redo|revert/.test(event))
- return history.on(event, cb);
- // gather unsub methods
- const unsubs = [
- editor.sub(event, cb),
- editor.$on(event, (e) => cb(e instanceof CustomEvent && !e.detail ? undefined : e)),
- ].filter(Boolean);
- // set up unsubscribe group
- return () => unsubs.forEach((unsub) => unsub());
- },
- updateImagePreview: (src) => {
- editor.imagePreviewSrc = src;
- },
- close: () => !isDestroyed && editor.pub('close'),
- destroy,
- });
- Object.defineProperty(accessors, 'history', {
- get: () => ({
- undo: () => history.undo(),
- redo: () => history.redo(),
- revert: () => history.revert(),
- get: () => history.get(),
- set: (entries) => history.set(entries),
- write: (state) => history.write(state),
- get length() {
- return history.length();
- },
- get index() {
- return history.index;
- },
- }),
- });
- // clean up on window unload
- if (isBrowser())
- window.addEventListener('pagehide', destroy);
- return accessors;
- };
- var editorEvents = [
- // core editor events that should be re-dispatched
- ...editorEventsToBubble,
- // ui editor events
- 'undo',
- 'redo',
- 'update',
- 'revert',
- 'destroy',
- 'show',
- 'hide',
- 'close',
- 'ready',
- 'loadpreview',
- 'selectshape',
- 'updateshape',
- 'addshape',
- 'removeshape',
- ];
- const dispatchElementEvent = (target, event, detail) => target.dispatchEvent(new CustomEvent(event, { detail, bubbles: true, cancelable: true }));
- var dispatchEditorEvents = (editor, handler, options = {}) => {
- const { prefix = 'pintura:' } = options;
- return editorEvents.map((event) => editor.on(event, (value) => isElement(handler)
- ? dispatchElementEvent(handler, `${prefix}${event}`, value)
- : handler(event, value)));
- };
- var arrayInsert = (array, index, item) => {
- array.splice(index, 0, item);
- return array;
- };
- // first index is always id, so if is string, it's a node
- const isNode = (item) => isString(item[0]);
- // if it's not a node, it's a nodelist
- const isNodeList = (item) => !isNode(item);
- const getNodeId = (node) => node[1];
- const getNodeChildren = (node) => node[3] || [];
- function createNode(instance, id, props, children) {
- // if three arguments received, props can be children
- if (Array.isArray(props)) {
- children = props;
- props = {};
- }
- // node is always array of four entries
- return [instance, id, props || {}, children || []];
- }
- const insertNode = (node, needle, haystack, getIndex = (index) => index) => {
- const nodeList = findNodeList(needle, haystack);
- const targetIndex = nodeList.findIndex((item) => getNodeId(item) === needle);
- arrayInsert(nodeList, getIndex(targetIndex), node);
- };
- const insertNodeBefore = (node, needle, haystack) => insertNode(node, needle, haystack);
- const insertNodeAfter = (node, needle, haystack) => insertNode(node, needle, haystack, (index) => index + 1);
- const appendNode = (node, haystack) => {
- // if is list, add to list
- if (isNodeList(haystack))
- return haystack.push(node);
- // else it's a node, add to node children
- haystack[3] = [...getNodeChildren(haystack), node];
- };
- const removeNode = (needle, haystack) => {
- const nodeList = findNodeList(needle, haystack);
- arrayRemove(nodeList, (item) => getNodeId(item) === needle);
- return nodeList;
- };
- const findNode = (needle, haystack) => {
- return isNode(haystack)
- ? // haystack is a node, maybe node is a match or one of children is a match
- getNodeId(haystack) === needle
- ? haystack
- : findNode(needle, getNodeChildren(haystack))
- : // haystack is a list of nodes
- haystack.find((item) => findNode(needle, item));
- };
- const findNodeList = (needle, haystack) => {
- // haystack is node list
- if (isNodeList(haystack)) {
- // lets search nodes in this haystack
- if (haystack.find((item) => getNodeId(item) === needle))
- return haystack;
- // not found, lets move the search to the childnodes
- return haystack.find((item) => findNodeList(needle, getNodeChildren(item)));
- }
- // is node, lets find in children
- return findNodeList(needle, getNodeChildren(haystack));
- };
- //#region markup
- const propertyMap = {
- borderColor: 'strokeColor',
- borderWidth: 'strokeWidth',
- lineWidth: 'strokeWidth',
- fontColor: 'color',
- lineColor: 'strokeColor',
- src: 'backgroundImage',
- fit: 'backgroundSize',
- };
- const convertValue = (value) => {
- if (value === 0)
- return 0;
- if (value === '0%')
- return 0;
- if (value === '0px')
- return 0;
- if (/px$/.test(value))
- return parseInt(value, 10);
- if (/\%$/.test(value))
- return value;
- if (value <= 1)
- return `${value * 100}%`;
- };
- const addValues = (a, b) => {
- let _a, _b;
- if (/%$/.test(a)) {
- _a = parseFloat(a);
- _b = parseFloat(b);
- return `${_a + _b}%`;
- }
- if (/px$/.test(a)) {
- _a = parseInt(a, 10);
- _b = parseInt(b, 10);
- return `${_a + _b}px`;
- }
- };
- const shapeFromLegacyMarkup = (crop, type, style) => {
- const shape = Object.keys(style).reduce((res, prop) => {
- let value = style[prop];
- // rename prop
- prop = propertyMap[prop] || prop;
- // if is px value
- if (/px$/.test(value)) {
- value = convertValue(value);
- }
- // if is number convert to percentage
- else if (/^(?:x|y|left|right|top|bottom|width|height|fontSize|strokeWidth)$/.test(prop) &&
- typeof value === 'number') {
- if (/strokeWidth/.test(prop))
- value *= 2;
- value = convertValue(value);
- }
- // if is color value
- if (/color/i.test(prop)) {
- value = colorStringToColorArray(value);
- }
- if (value === null)
- value = undefined;
- res[prop] = value;
- return res;
- }, {});
- if (type === 'line') {
- if (shape.lineDecoration.length === 1)
- shape.lineEnd = 'arrow';
- if (shape.lineDecoration.length === 2)
- shape.lineStart = 'arrow';
- shape.x1 = shape.x;
- shape.y1 = shape.y;
- shape.x2 = addValues(shape.x, shape.width);
- shape.y2 = addValues(shape.y, shape.height);
- delete shape.x;
- delete shape.y;
- delete shape.width;
- delete shape.height;
- delete shape.lineDecoration;
- delete shape.lineStyle;
- }
- if (type === 'text') {
- shape.y = addValues(shape.y, '-' + shape.fontSize);
- delete shape.width;
- delete shape.height;
- delete shape.borderStyle;
- }
- if (type === 'ellipse') {
- let w, h;
- // calculate `rx` and `ry` based on `width` and `h`eight`
- if (/%$/.test(shape.width)) {
- w = parseFloat(shape.width) / 100;
- h = parseFloat(shape.height) / 100;
- const widthAbsolute = w * crop.width;
- const heightAbsolute = h * crop.height;
- w = (widthAbsolute / crop.width) * 100;
- h = (heightAbsolute / crop.height) * 100;
- }
- else {
- w = shape.width;
- h = shape.height;
- }
- shape.rx = w * 0.5;
- shape.ry = h * 0.5;
- if (/%$/.test(shape.width)) {
- shape.rx += '%';
- shape.ry += '%';
- }
- shape.x = addValues(shape.x, shape.rx);
- shape.y = addValues(shape.y, shape.ry);
- delete shape.width;
- delete shape.height;
- delete shape.borderStyle;
- }
- if (type === 'rect') {
- delete shape.borderStyle;
- }
- if (type === 'path') {
- shape.points = shape.points.map((point) => {
- return {
- x: convertValue(point.x),
- y: convertValue(point.y),
- };
- });
- }
- return shape;
- };
- //#endregion
- //#region crop
- const getOffsetPointOnEdge = (length, rotation) => {
- const a = length;
- const A = 1.5707963267948966;
- const B = rotation;
- const C = 1.5707963267948966 - rotation;
- const sinA = Math.sin(A);
- const sinB = Math.sin(B);
- const sinC = Math.sin(C);
- const cosC = Math.cos(C);
- const ratio = a / sinA;
- const b = ratio * sinB;
- const c = ratio * sinC;
- return vectorCreate(cosC * b, cosC * c);
- };
- const getRotatedRectSize = (rect, rotation) => {
- const w = rect.width;
- const h = rect.height;
- const hor = getOffsetPointOnEdge(w, rotation);
- const ver = getOffsetPointOnEdge(h, rotation);
- const tl = vectorCreate(rect.x + Math.abs(hor.x), rect.y - Math.abs(hor.y));
- const tr = vectorCreate(rect.x + rect.width + Math.abs(ver.y), rect.y + Math.abs(ver.x));
- const bl = vectorCreate(rect.x - Math.abs(ver.y), rect.y + rect.height - Math.abs(ver.x));
- return {
- width: vectorDistance(tl, tr),
- height: vectorDistance(tl, bl),
- };
- };
- const getBoundsAroundCenter = (imageSize, center) => {
- const cx = center.x > 0.5 ? 1 - center.x : center.x;
- const cy = center.y > 0.5 ? 1 - center.y : center.y;
- return sizeCreate(cx * 2 * imageSize.width, cy * 2 * imageSize.height);
- };
- const getCanvasSize = (imageSize, canvasAspectRatio, zoom = 1) => {
- const imageAspectRatio = imageSize.height / imageSize.width;
- // determine actual pixels on x and y axis
- let canvasWidth = 1;
- let canvasHeight = canvasAspectRatio;
- let imgWidth = 1;
- let imgHeight = imageAspectRatio;
- if (imgHeight > canvasHeight) {
- imgHeight = canvasHeight;
- imgWidth = imgHeight / imageAspectRatio;
- }
- const scalar = Math.max(canvasWidth / imgWidth, canvasHeight / imgHeight);
- const width = imageSize.width / (zoom * scalar * imgWidth);
- const height = width * canvasAspectRatio;
- return {
- width: width,
- height: height,
- };
- };
- const getCenteredCropRect = (imageSize, aspectRatio) => {
- let width = imageSize.width;
- let height = width * aspectRatio;
- if (height > imageSize.height) {
- height = imageSize.height;
- width = height / aspectRatio;
- }
- const x = (imageSize.width - width) * 0.5;
- const y = (imageSize.height - height) * 0.5;
- return rectCreate(x, y, width, height);
- };
- const getCorrectedLegacyAspectRatio = (imageSize, aspectRatio) => aspectRatio != null
- ? // fox the aspect ratio
- 1 / aspectRatio
- : // set image aspect ratio
- imageSize.width / imageSize.height;
- const imagePropertiesFromLegacyCrop = (imageSize, { flip, aspectRatio, rotation, center, zoom, scaleToFit }) => {
- const res = {};
- // is centered crop
- const isCenteredCrop = !center || (center && center.x === 0.5 && center.y === 0.5);
- // handle basic props
- if (flip && flip.horizontal)
- res.flipHorizontal = flip.horizontal;
- if (flip && flip.vertical)
- res.flipVertical = flip.vertical;
- // fix aspect ratio, in FilePond and editor v6 it's height/width instead of width/height
- const correctedAspectRatio = getCorrectedLegacyAspectRatio(imageSize, aspectRatio);
- // image bounds
- const cropLimit = !(scaleToFit === false);
- const canvasSize = getCanvasSize(imageSize, aspectRatio, zoom);
- const cropSize = isCenteredCrop
- ? imageSize
- : getBoundsAroundCenter(imageSize, cropLimit ? center : { x: 0.5, y: 0.5 });
- const cropCentered = getCenteredCropRect(imageSize, aspectRatio);
- // has different aspect ratio than image
- if (aspectRatio || !isCenteredCrop || zoom) {
- res.crop = rectContainRect(rectCreateFromSize(cropSize), correctedAspectRatio);
- }
- if (typeof rotation === 'number' && rotation !== null) {
- if (rotation != null)
- res.rotation = rotation;
- const rotatedCropSize = getRotatedRectSize(cropCentered, rotation);
- const scalar = Math.max(rotatedCropSize.width / cropSize.width, rotatedCropSize.height / cropSize.height);
- // crop position in non-rotated image
- const cropCenter = vectorCreate(center.x * imageSize.width, center.y * imageSize.height);
- // const imageCenter = sizeCenter(imageSize);
- // const imageCenterToCropCenter = vectorCreate(
- // imageCenter.x - cropCenter.x,
- // imageCenter.y - cropCenter.y
- // );
- // get rotated image center
- const rotatedImageSize = getImageTransformedRect(imageSize, rotation);
- const rotatedImageCenter = sizeCenter(rotatedImageSize);
- const rotatedImageOffset = vectorCreate((rotatedImageSize.width - imageSize.width) * 0.5, (rotatedImageSize.height - imageSize.height) * 0.5);
- // window.draw(rotatedImageCenter, 'red');
- // window.draw(rotatedImageSize, 'red');
- // window.draw(
- // {
- // x: rotatedImageOffset.x,
- // y: rotatedImageOffset.y,
- // width: imageSize.width,
- // height: imageSize.height,
- // },
- // 'cyan'
- // );
- // const imagePoints = rectRotate(
- // rectCreate(
- // rotatedImageOffset.x,
- // rotatedImageOffset.y,
- // imageSize.width,
- // imageSize.height
- // ),
- // rotation
- // );
- // window.draw(imagePoints, 'orange');
- const cropPoints = rectRotate({
- x: rotatedImageOffset.x + cropCenter.x - (canvasSize.width / scalar) * 0.5,
- y: rotatedImageOffset.y + cropCenter.y - (canvasSize.height / scalar) * 0.5,
- width: canvasSize.width / scalar,
- height: canvasSize.height / scalar,
- }, rotation);
- // window.draw(cropPoints, 'cyan');
- const cropBoundsPoints = vectorsRotate(cropPoints.map(vectorClone), rotation, rotatedImageCenter.x, rotatedImageCenter.y);
- // window.draw(cropBoundsPoints, 'orange');
- const cropBoundsPointsCenter = rectCenter(rectCreateFromPoints(cropBoundsPoints));
- // window.draw(cropBoundsPointsCenter, 'green');
- const deRotatedCropBoundsPoints = vectorsRotate(cropBoundsPoints.map(vectorClone), -(rotation * 2), cropBoundsPointsCenter.x, cropBoundsPointsCenter.y);
- // window.draw(deRotatedCropBoundsPoints, 'green');
- res.crop = rectCreateFromPoints(deRotatedCropBoundsPoints);
- }
- else if (zoom != null) {
- rectScale(res.crop, 1 / zoom);
- }
- if (!cropLimit) {
- res.cropLimitToImage = false;
- }
- return res;
- };
- //#endregion
- const isLegacyData = (data = {}) => {
- if ('markup' in data || 'color' in data || 'filter' in data)
- return true;
- const { crop } = data;
- if (crop && ('flip' in crop || 'center' in crop || 'aspectRatio' in crop || 'rotation' in crop))
- return true;
- return false;
- };
- var legacyDataToImageState = (editor, imageSize, data = {}) => {
- const res = {};
- // test if isn't legacy data
- if (!isLegacyData(data))
- return data;
- if (data.crop) {
- Object.assign(res, imagePropertiesFromLegacyCrop(imageSize, data.crop));
- }
- if (data.markup) {
- const markup = Array.isArray(data.markup) ? data.markup : Object.values(data.markup);
- res.decoration = markup.map((markup) => shapeFromLegacyMarkup(res.crop || imageSize, markup[0], markup[1]));
- }
- if (data.color) {
- Object.keys(data.color)
- .filter((key) => data.color[key])
- .map((key) => [
- key,
- Array.isArray(data.color[key].matrix)
- ? data.color[key].matrix
- : Object.values(data.color[key].matrix),
- ])
- .forEach(([key, value]) => {
- if (!res.colorMatrix)
- res.colorMatrix = {};
- res.colorMatrix[key] = value;
- });
- }
- if (data.filter) {
- if (!res.colorMatrix)
- res.colorMatrix = {};
- res.colorMatrix.filter =
- typeof data.filter === 'string' && editor['filterFunctions'][data.filter]
- ? editor['filterFunctions'][data.filter]()
- : data.filter.matrix;
- }
- return res;
- };
- const isOperaMini = () => Object.prototype.toString.call(window['operamini']) === '[object OperaMini]';
- const hasPromises = () => 'Promise' in window;
- const hasCreateObjectURL = () => 'URL' in window && 'createObjectURL' in window.URL;
- const hasVisibility = () => 'visibilityState' in document;
- const hasTiming = () => 'performance' in window; // iOS 8.x
- const hasFileConstructor = () => 'File' in window; // excludes IE11
- let result$3 = null;
- var isModernBrowser = () => {
- if (result$3 === null)
- result$3 =
- isBrowser() &&
- // Can't run on Opera Mini due to lack of everything
- !isOperaMini() &&
- // Require these APIs to feature detect a modern browser
- hasVisibility() &&
- hasPromises() &&
- hasFileConstructor() &&
- hasCreateObjectURL() &&
- hasTiming();
- return result$3;
- };
- var toPercentageNumber = (v) => Math.round(v * 100);
- const brightness = {
- base: 0,
- min: -0.25,
- max: 0.25,
- getLabel: (value) => toPercentageNumber(value / 0.25),
- getStore: ({ imageColorMatrix }) => imageColorMatrix,
- getValue: (store) => {
- if (!store.brightness)
- return;
- return store.brightness[4];
- },
- setValue: (store, v) => store.update((matrices) => ({
- // clone existing matrices
- ...matrices,
- // prettier-ignore
- brightness: [
- 1, 0, 0, 0, v,
- 0, 1, 0, 0, v,
- 0, 0, 1, 0, v,
- 0, 0, 0, 1, 0
- ],
- })),
- };
- const contrast = {
- base: 1,
- min: 0.5,
- max: 1.5,
- getLabel: (value) => toPercentageNumber(-1 + (value - 0.5) * 2),
- getStore: ({ imageColorMatrix }) => imageColorMatrix,
- getValue: (store) => {
- if (!store.contrast)
- return;
- return store.contrast[0];
- },
- setValue: (store, v) => store.update((matrices) => ({
- // clone existing matrices
- ...matrices,
- // prettier-ignore
- contrast: [
- v, 0, 0, 0, .5 * (1 - v),
- 0, v, 0, 0, .5 * (1 - v),
- 0, 0, v, 0, .5 * (1 - v),
- 0, 0, 0, 1, 0
- ],
- })),
- };
- const saturation = {
- base: 1,
- min: 0,
- max: 2,
- getLabel: (value) => toPercentageNumber(value - 1),
- getStore: ({ imageColorMatrix }) => imageColorMatrix,
- getValue: (store) => {
- if (!store.saturation)
- return;
- return (store.saturation[0] - 0.213) / 0.787;
- },
- setValue: (store, v) => store.update((matrices) => ({
- ...matrices,
- // prettier-ignore
- saturation: [
- .213 + .787 * v, .715 - .715 * v, .072 - .072 * v, 0, 0,
- .213 - .213 * v, .715 + .285 * v, .072 - .072 * v, 0, 0,
- .213 - .213 * v, .715 - .715 * v, .072 + .928 * v, 0, 0,
- 0, 0, 0, 1, 0
- ],
- })),
- };
- const exposure = {
- base: 1,
- min: 0.5,
- max: 1.5,
- getLabel: (value) => toPercentageNumber(-1 + (value - 0.5) * 2),
- getStore: ({ imageColorMatrix }) => imageColorMatrix,
- getValue: (store) => {
- if (!store.exposure)
- return;
- return store.exposure[0];
- },
- setValue: (store, v) => store.update((matrices) => ({
- ...matrices,
- // prettier-ignore
- exposure: [
- v, 0, 0, 0, 0,
- 0, v, 0, 0, 0,
- 0, 0, v, 0, 0,
- 0, 0, 0, 1, 0
- ],
- })),
- };
- const gamma = {
- base: 1,
- min: 0.15,
- max: 4,
- getLabel: (value) => {
- if (value < 1) {
- return toPercentageNumber((value - 0.15) / 0.85 - 1);
- }
- return toPercentageNumber((value - 1) / 3);
- },
- getStore: ({ imageGamma }) => imageGamma,
- };
- const vignette = {
- base: 0,
- min: -1,
- max: 1,
- getStore: ({ imageVignette }) => imageVignette,
- };
- const clarity = {
- base: 0,
- min: -1,
- max: 1,
- getStore: ({ imageConvolutionMatrix }) => imageConvolutionMatrix,
- getValue: (store) => {
- if (!store.clarity)
- return;
- if (store.clarity[0] === 0) {
- return store.clarity[1] / -1;
- }
- else {
- return store.clarity[1] / -2;
- }
- },
- setValue: (store, v) => {
- store.update((matrices) => ({
- ...matrices,
- // prettier-ignore
- clarity: v >= 0
- ? [0, -1 * v, 0,
- -1 * v, 1 + 4 * v, -1 * v,
- 0, -1 * v, 0
- ]
- : [-1 * v, -2 * v, -1 * v,
- -2 * v, 1 + -3 * v, -2 * v,
- -1 * v, -2 * v, -1 * v
- ],
- }));
- },
- };
- const temperature = {
- base: 0,
- min: -1,
- max: 1,
- getStore: ({ imageColorMatrix }) => imageColorMatrix,
- getValue: (store) => {
- if (!store.temperature)
- return;
- const v = store.temperature[0];
- if (v >= 1) {
- return (v - 1) / 0.1;
- }
- return (1 - v) / -0.15;
- },
- setValue: (store, v) => store.update((matrices) => ({
- ...matrices,
- // prettier-ignore
- temperature: v > 0 ? [
- 1 + (v * .1), 0, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 0, 1 + (-v * .1), 0, 0,
- 0, 0, 0, 1, 0
- ] : [
- 1 + (v * .15), 0, 0, 0, 0,
- 0, 1 + (v * .05), 0, 0, 0,
- 0, 0, 1 + (-v * .15), 0, 0,
- 0, 0, 0, 1, 0
- ],
- })),
- };
- const finetuneControlConfigurationDefault = {
- gamma,
- brightness,
- contrast,
- saturation,
- exposure,
- temperature,
- clarity,
- vignette,
- };
- const finetuneOptionsDefault = [
- ['brightness', (locale) => locale.finetuneLabelBrightness],
- ['contrast', (locale) => locale.finetuneLabelContrast],
- ['saturation', (locale) => locale.finetuneLabelSaturation],
- ['exposure', (locale) => locale.finetuneLabelExposure],
- ['temperature', (locale) => locale.finetuneLabelTemperature],
- ['gamma', (locale) => locale.finetuneLabelGamma],
- !isSoftwareRendering() && ['clarity', (locale) => locale.finetuneLabelClarity],
- ['vignette', (locale) => locale.finetuneLabelVignette],
- ].filter(Boolean);
- var _plugin_finetune_defaults = {
- finetuneControlConfiguration: finetuneControlConfigurationDefault,
- finetuneOptions: finetuneOptionsDefault,
- };
- /*
- TODO: fix inverse fn in getValue
- export const hue = {
- base: 0,
- min: 0,
- max: Math.PI,
- getStore: ({ imageColorMatrix }) => imageColorMatrix,
- getValue: (store) => {
- if (!store.hue) return;
- const v = store.hue[1];
- const o = -(Math.acos((0.715 - v) / Math.sqrt(2) / 0.715) - Math.PI / 4);
- return o;
- },
- setValue: (store, v: number) => {
- store.update((matrices) => {
- // const value = v * (Math.PI);
- const cos = Math.cos(v);
- const sin = Math.sin(v);
- const a00 = 0.213 + cos * 0.787 - sin * 0.213;
- const a01 = 0.715 - cos * 0.715 - sin * 0.715;
- const a02 = 0.072 - cos * 0.072 + sin * 0.928;
- const a10 = 0.213 - cos * 0.213 + sin * 0.143;
- const a11 = 0.715 + cos * 0.285 + sin * 0.14;
- const a12 = 0.072 - cos * 0.072 - sin * 0.283;
- const a20 = 0.213 - cos * 0.213 - sin * 0.787;
- const a21 = 0.715 - cos * 0.715 + sin * 0.715;
- const a22 = 0.072 + cos * 0.928 + sin * 0.072;
- return {
- ...matrices,
- // prettier-ignore
- hue: [
- a00, a01, a02, 0, 0,
- a10, a11, a12, 0, 0,
- a20, a21, a22, 0, 0,
- 0, 0, 0, 1, 0,
- ]
- };
- });
- },
- };
- */
- const pastel = () =>
- // prettier-ignore
- [
- 0.75, 0.25, 0.25, 0, 0,
- 0.25, 0.75, 0.25, 0, 0,
- 0.25, 0.25, 0.75, 0, 0,
- 0, 0, 0, 1, 0
- ];
- const chrome = () =>
- // prettier-ignore
- [
- 1.398, -0.316, 0.065, -0.273, 0.201,
- -0.051, 1.278, -0.080, -0.273, 0.201,
- -0.051, 0.119, 1.151, -0.290, 0.215,
- 0, 0, 0, 1, 0
- ];
- const fade = () =>
- // prettier-ignore
- [
- 1.073, -0.015, 0.092, -0.115, -0.017,
- 0.107, 0.859, 0.184, -0.115, -0.017,
- 0.015, 0.077, 1.104, -0.115, -0.017,
- 0, 0, 0, 1, 0
- ];
- const warm = () =>
- // prettier-ignore
- [
- 1.06, 0, 0, 0, 0,
- 0, 1.01, 0, 0, 0,
- 0, 0, 0.93, 0, 0,
- 0, 0, 0, 1, 0,
- ];
- const cold = () =>
- // prettier-ignore
- [
- 1.1, 0, 0, 0, -.1,
- 0, 1.1, 0, 0, -.1,
- 0, 0, 1.2, 0, -.1,
- 0, 0, 0, 1, 0,
- ];
- const invert = () =>
- // prettier-ignore
- [
- -1, 0, 0, 1, 0,
- 0, -1, 0, 1, 0,
- 0, 0, -1, 1, 0,
- 0, 0, 0, 1, 0,
- ];
- const monoDefault = () =>
- // prettier-ignore
- [
- 0.212, 0.715, 0.114, 0, 0,
- 0.212, 0.715, 0.114, 0, 0,
- 0.212, 0.715, 0.114, 0, 0,
- 0, 0, 0, 1, 0
- ];
- const monoNoir = () =>
- // prettier-ignore
- [
- 0.15, 1.3, -0.25, 0.1, -0.2,
- 0.15, 1.3, -0.25, 0.1, -0.2,
- 0.15, 1.3, -0.25, 0.1, -0.2,
- 0, 0, 0, 1, 0
- ];
- const monoWash = () =>
- // prettier-ignore
- [
- 0.163, 0.518, 0.084, -0.010, 0.208,
- 0.163, 0.529, 0.082, -0.020, 0.210,
- 0.171, 0.529, 0.084, 0.000, 0.214,
- 0.000, 0.000, 0.000, 1.000, 0.000,
- ];
- const monoStark = () =>
- // prettier-ignore
- [
- 0.338, 0.991, 0.117, 0.093, -0.196,
- 0.302, 1.049, 0.096, 0.078, -0.196,
- 0.286, 1.016, 0.146, 0.101, -0.196,
- 0.000, 0.000, 0.000, 1.000, 0.000,
- ];
- const sepiaDefault = () =>
- // prettier-ignore
- [
- 0.393, 0.768, 0.188, 0, 0,
- 0.349, 0.685, 0.167, 0, 0,
- 0.272, 0.533, 0.130, 0, 0,
- 0, 0, 0, 1, 0,
- ];
- const sepiaBlues = () =>
- // prettier-ignore
- [
- 0.289, 0.620, 0.185, 0.000, 0.077,
- 0.257, 0.566, 0.163, 0.000, 0.115,
- 0.200, 0.430, 0.128, 0.000, 0.188,
- 0.000, 0.000, 0.000, 1.000, 0.000,
- ];
- const sepiaRust = () =>
- // prettier-ignore
- [
- 0.269, 0.764, 0.172, 0.050, 0.100,
- 0.239, 0.527, 0.152, 0.000, 0.176,
- 0.186, 0.400, 0.119, 0.000, 0.159,
- 0.000, 0.000, 0.000, 1.000, 0.000,
- ];
- const sepiaColor = () =>
- // prettier-ignore
- [
- 0.547, 0.764, 0.134, 0.000, -0.147,
- 0.281, 0.925, 0.120, 0.000, -0.135,
- 0.225, 0.558, 0.330, 0.000, -0.113,
- 0.000, 0.000, 0.000, 1.000, 0.000,
- ];
- //
- // default filter set
- //
- const filterFunctionsDefault = {
- chrome,
- fade,
- pastel,
- cold,
- warm,
- monoDefault,
- monoWash,
- monoNoir,
- monoStark,
- sepiaDefault,
- sepiaRust,
- sepiaBlues,
- sepiaColor,
- };
- const filterOptionsDefault = [
- ['Default', [[undefined, (locale) => locale.labelDefault]]],
- [
- 'Classic',
- [
- ['chrome', (locale) => locale.filterLabelChrome],
- ['fade', (locale) => locale.filterLabelFade],
- ['cold', (locale) => locale.filterLabelCold],
- ['warm', (locale) => locale.filterLabelWarm],
- ['pastel', (locale) => locale.filterLabelPastel],
- ],
- ],
- [
- 'Monochrome',
- [
- ['monoDefault', (locale) => locale.filterLabelMonoDefault],
- ['monoNoir', (locale) => locale.filterLabelMonoNoir],
- ['monoStark', (locale) => locale.filterLabelMonoStark],
- ['monoWash', (locale) => locale.filterLabelMonoWash],
- ],
- ],
- [
- 'Sepia',
- [
- ['sepiaDefault', (locale) => locale.filterLabelSepiaDefault],
- ['sepiaRust', (locale) => locale.filterLabelSepiaRust],
- ['sepiaBlues', (locale) => locale.filterLabelSepiaBlues],
- ['sepiaColor', (locale) => locale.filterLabelSepiaColor],
- ],
- ],
- ];
- var _plugin_filter_defaults = {
- filterFunctions: filterFunctionsDefault,
- filterOptions: filterOptionsDefault,
- };
- const solidSharp = {
- shape: {
- frameStyle: 'solid',
- frameSize: '2.5%',
- },
- thumb: '<rect stroke-width="5" x="0" y="0" width="100%" height="100%"/>',
- };
- const solidRound = {
- shape: {
- frameStyle: 'solid',
- frameSize: '2.5%',
- frameRound: true,
- },
- thumb: '<rect stroke-width="5" x="0" y="0" width="100%" height="100%" rx="12%"/>',
- };
- const lineSingle = {
- shape: {
- frameStyle: 'line',
- frameInset: '2.5%',
- frameSize: '.3125%',
- frameRadius: 0,
- },
- thumb: '<div style="top:.5em;left:.5em;right:.5em;bottom:.5em;box-shadow:inset 0 0 0 1px currentColor"></div>',
- };
- const lineMultiple = {
- shape: {
- frameStyle: 'line',
- frameAmount: 2,
- frameInset: '2.5%',
- frameSize: '.3125%',
- frameOffset: '1.25%',
- frameRadius: 0,
- },
- thumb: '<div style="top:.75em;left:.75em;right:.75em;bottom:.75em; outline: 3px double"></div>',
- };
- const edgeSeparate = {
- shape: {
- frameStyle: 'edge',
- frameInset: '2.5%',
- frameOffset: '5%',
- frameSize: '.3125%',
- },
- thumb: '<div style="top:.75em;left:.5em;bottom:.75em;border-left:1px solid"></div><div style="top:.75em;right:.5em;bottom:.75em;border-right:1px solid"></div><div style="top:.5em;left:.75em;right:.75em;border-top:1px solid"></div><div style="bottom:.5em;left:.75em;right:.75em;border-bottom:1px solid"></div>',
- };
- const edgeCross = {
- shape: {
- frameStyle: 'edge',
- frameInset: '2.5%',
- frameSize: '.3125%',
- },
- thumb: '<div style="top:-.5em;left:.5em;right:.5em;bottom:-.5em; box-shadow: inset 0 0 0 1px currentColor"></div><div style="top:.5em;left:-.5em;right:-.5em;bottom:.5em;box-shadow:inset 0 0 0 1px currentColor"></div>',
- };
- const edgeOverlap = {
- shape: {
- frameStyle: 'edge',
- frameOffset: '1.5%',
- frameSize: '.3125%',
- },
- thumb: '<div style="top:.3125em;left:.5em;bottom:.3125em;border-left:1px solid"></div><div style="top:.3125em;right:.5em;bottom:.3125em;border-right:1px solid"></div><div style="top:.5em;left:.3125em;right:.3125em;border-top:1px solid"></div><div style="bottom:.5em;left:.3125em;right:.3125em;border-bottom:1px solid"></div>',
- };
- const hook = {
- shape: {
- frameStyle: 'hook',
- frameInset: '2.5%',
- frameSize: '.3125%',
- frameLength: '5%',
- },
- thumb: '<div style="top:.5em;left:.5em;width:.75em;height:.75em; border-left: 1px solid;border-top: 1px solid;"></div><div style="top:.5em;right:.5em;width:.75em;height:.75em; border-right: 1px solid;border-top: 1px solid;"></div><div style="bottom:.5em;left:.5em;width:.75em;height:.75em; border-left: 1px solid;border-bottom: 1px solid;"></div><div style="bottom:.5em;right:.5em;width:.75em;height:.75em; border-right: 1px solid;border-bottom: 1px solid;"></div>',
- };
- const polaroid = {
- shape: {
- frameStyle: 'polaroid',
- },
- thumb: '<rect stroke-width="20%" x="-5%" y="-5%" width="110%" height="96%"/>',
- };
- const frameStylesDefault = {
- solidSharp,
- solidRound,
- lineSingle,
- lineMultiple,
- edgeSeparate,
- edgeCross,
- edgeOverlap,
- hook,
- polaroid,
- };
- const frameOptionsDefault = [
- [undefined, (locale) => locale.labelNone],
- ['solidSharp', (locale) => locale.frameLabelMatSharp],
- ['solidRound', (locale) => locale.frameLabelMatRound],
- ['lineSingle', (locale) => locale.frameLabelLineSingle],
- ['lineMultiple', (locale) => locale.frameLabelLineMultiple],
- ['edgeCross', (locale) => locale.frameLabelEdgeCross],
- ['edgeSeparate', (locale) => locale.frameLabelEdgeSeparate],
- ['edgeOverlap', (locale) => locale.frameLabelEdgeOverlap],
- ['hook', (locale) => locale.frameLabelCornerHooks],
- ['polaroid', (locale) => locale.frameLabelPolaroid],
- ];
- var _plugin_frame_defaults = {
- frameStyles: frameStylesDefault,
- frameOptions: frameOptionsDefault,
- };
- var RGBToHSV = (r, g, b) => {
- let v = Math.max(r, g, b), n = v - Math.min(r, g, b);
- let h = n && (v == r ? (g - b) / n : v == g ? 2 + (b - r) / n : 4 + (r - g) / n);
- return [(60 * (h < 0 ? h + 6 : h)) / 360, v && n / v, v];
- };
- var HSVToRGB = (h, s, v) => {
- let r, g, b;
- const i = Math.floor(h * 6);
- const f = h * 6 - i;
- const p = v * (1 - s);
- const q = v * (1 - f * s);
- const t = v * (1 - (1 - f) * s);
- switch (i % 6) {
- case 0:
- (r = v), (g = t), (b = p);
- break;
- case 1:
- (r = q), (g = v), (b = p);
- break;
- case 2:
- (r = p), (g = v), (b = t);
- break;
- case 3:
- (r = p), (g = q), (b = v);
- break;
- case 4:
- (r = t), (g = p), (b = v);
- break;
- case 5:
- (r = v), (g = p), (b = q);
- break;
- }
- return [r, g, b];
- };
- /* src/core/ui/components/ColorPreview.svelte generated by Svelte v3.37.0 */
- function create_fragment$t(ctx) {
- let div;
- let span;
- let div_style_value;
- return {
- c() {
- div = element("div");
- span = element("span");
- attr(div, "class", "PinturaColorPreview");
- attr(div, "title", /*title*/ ctx[0]);
- attr(div, "style", div_style_value = `--color:${/*colorValue*/ ctx[1]}`);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- append(div, span);
- },
- p(ctx, [dirty]) {
- if (dirty & /*title*/ 1) {
- attr(div, "title", /*title*/ ctx[0]);
- }
- if (dirty & /*colorValue*/ 2 && div_style_value !== (div_style_value = `--color:${/*colorValue*/ ctx[1]}`)) {
- attr(div, "style", div_style_value);
- }
- },
- i: noop,
- o: noop,
- d(detaching) {
- if (detaching) detach(div);
- }
- };
- }
- function instance$t($$self, $$props, $$invalidate) {
- let colorValue;
- let { color = undefined } = $$props;
- let { title = undefined } = $$props;
- $$self.$$set = $$props => {
- if ("color" in $$props) $$invalidate(2, color = $$props.color);
- if ("title" in $$props) $$invalidate(0, title = $$props.title);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*color*/ 4) {
- $$invalidate(1, colorValue = color ? colorArrayToRGBA(color) : "transparent");
- }
- };
- return [title, colorValue, color];
- }
- class ColorPreview extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$t, create_fragment$t, safe_not_equal, { color: 2, title: 0 });
- }
- }
- /* src/core/ui/components/ColorPicker.svelte generated by Svelte v3.37.0 */
- function create_if_block_4$3(ctx) {
- let span;
- let t;
- return {
- c() {
- span = element("span");
- t = text(/*label*/ ctx[0]);
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- },
- p(ctx, dirty) {
- if (dirty[0] & /*label*/ 1) set_data(t, /*label*/ ctx[0]);
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- // (160:4)
- function create_label_slot(ctx) {
- let span;
- let colorpreview;
- let t;
- let current;
- colorpreview = new ColorPreview({
- props: {
- color: /*value*/ ctx[4],
- title: localize(/*title*/ ctx[8], /*locale*/ ctx[10])
- }
- });
- let if_block = !/*hidePresetLabel*/ ctx[9] && create_if_block_4$3(ctx);
- return {
- c() {
- span = element("span");
- create_component(colorpreview.$$.fragment);
- t = space();
- if (if_block) if_block.c();
- attr(span, "slot", "label");
- attr(span, "class", "PinturaButtonLabel");
- },
- m(target, anchor) {
- insert(target, span, anchor);
- mount_component(colorpreview, span, null);
- append(span, t);
- if (if_block) if_block.m(span, null);
- current = true;
- },
- p(ctx, dirty) {
- const colorpreview_changes = {};
- if (dirty[0] & /*value*/ 16) colorpreview_changes.color = /*value*/ ctx[4];
- if (dirty[0] & /*title, locale*/ 1280) colorpreview_changes.title = localize(/*title*/ ctx[8], /*locale*/ ctx[10]);
- colorpreview.$set(colorpreview_changes);
- if (!/*hidePresetLabel*/ ctx[9]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- } else {
- if_block = create_if_block_4$3(ctx);
- if_block.c();
- if_block.m(span, null);
- }
- } else if (if_block) {
- if_block.d(1);
- if_block = null;
- }
- },
- i(local) {
- if (current) return;
- transition_in(colorpreview.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(colorpreview.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(span);
- destroy_component(colorpreview);
- if (if_block) if_block.d();
- }
- };
- }
- // (171:8) {#if enablePicker}
- function create_if_block_2$5(ctx) {
- let div3;
- let div2;
- let div1;
- let div0;
- let div0_style_value;
- let div1_style_value;
- let div2_style_value;
- let t0;
- let slider;
- let t1;
- let current;
- let mounted;
- let dispose;
- slider = new Slider({
- props: {
- class: "PinturaHuePicker",
- knobStyle: `background-color:${/*valueAsRGBAFullySaturated*/ ctx[19]}`,
- onchange: /*updateHue*/ ctx[24],
- value: /*hue*/ ctx[14],
- min: 0,
- max: 1,
- step: 0.01
- }
- });
- let if_block = /*enableOpacity*/ ctx[11] && create_if_block_3$3(ctx);
- return {
- c() {
- div3 = element("div");
- div2 = element("div");
- div1 = element("div");
- div0 = element("div");
- t0 = space();
- create_component(slider.$$.fragment);
- t1 = space();
- if (if_block) if_block.c();
- attr(div0, "role", "button");
- attr(div0, "aria-label", "Saturation slider");
- attr(div0, "class", "PinturaPickerKnob");
- attr(div0, "tabindex", "0");
- attr(div0, "style", div0_style_value = `background-color:${/*valueAsRGBAFullyOpaque*/ ctx[18]};`);
- attr(div1, "class", "PinturaPickerKnobController");
- attr(div1, "style", div1_style_value = `transform:translate(${/*sx*/ ctx[21]}%,${/*sy*/ ctx[22]}%)`);
- attr(div2, "class", "PinturaSaturationPicker");
- attr(div2, "style", div2_style_value = `background-color: ${/*valueAsRGBAFullySaturated*/ ctx[19]}`);
- attr(div3, "class", "PinturaPicker");
- },
- m(target, anchor) {
- insert(target, div3, anchor);
- append(div3, div2);
- append(div2, div1);
- append(div1, div0);
- /*div2_binding*/ ctx[31](div2);
- append(div3, t0);
- mount_component(slider, div3, null);
- append(div3, t1);
- if (if_block) if_block.m(div3, null);
- current = true;
- if (!mounted) {
- dispose = [
- listen(div0, "nudge", /*handleNudge*/ ctx[27]),
- action_destroyer(nudgeable.call(null, div0)),
- listen(div2, "pointerdown", /*handlePointerDown*/ ctx[26])
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- if (!current || dirty[0] & /*valueAsRGBAFullyOpaque*/ 262144 && div0_style_value !== (div0_style_value = `background-color:${/*valueAsRGBAFullyOpaque*/ ctx[18]};`)) {
- attr(div0, "style", div0_style_value);
- }
- if (!current || dirty[0] & /*sx, sy*/ 6291456 && div1_style_value !== (div1_style_value = `transform:translate(${/*sx*/ ctx[21]}%,${/*sy*/ ctx[22]}%)`)) {
- attr(div1, "style", div1_style_value);
- }
- if (!current || dirty[0] & /*valueAsRGBAFullySaturated*/ 524288 && div2_style_value !== (div2_style_value = `background-color: ${/*valueAsRGBAFullySaturated*/ ctx[19]}`)) {
- attr(div2, "style", div2_style_value);
- }
- const slider_changes = {};
- if (dirty[0] & /*valueAsRGBAFullySaturated*/ 524288) slider_changes.knobStyle = `background-color:${/*valueAsRGBAFullySaturated*/ ctx[19]}`;
- if (dirty[0] & /*hue*/ 16384) slider_changes.value = /*hue*/ ctx[14];
- slider.$set(slider_changes);
- if (/*enableOpacity*/ ctx[11]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty[0] & /*enableOpacity*/ 2048) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block_3$3(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(div3, null);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(slider.$$.fragment, local);
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(slider.$$.fragment, local);
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div3);
- /*div2_binding*/ ctx[31](null);
- destroy_component(slider);
- if (if_block) if_block.d();
- mounted = false;
- run_all(dispose);
- }
- };
- }
- // (205:16) {#if enableOpacity}
- function create_if_block_3$3(ctx) {
- let slider;
- let current;
- slider = new Slider({
- props: {
- class: "PinturaOpacityPicker",
- knobStyle: `background-color: ${/*valueAsRGBA*/ ctx[16]}`,
- trackStyle: `background-image: linear-gradient(to right, ${/*valueAsRGBAFullyTransparent*/ ctx[17]}, ${/*valueAsRGBAFullyOpaque*/ ctx[18]})`,
- onchange: /*updateOpacity*/ ctx[25],
- value: /*opacity*/ ctx[15],
- min: 0,
- max: 1,
- step: 0.01
- }
- });
- return {
- c() {
- create_component(slider.$$.fragment);
- },
- m(target, anchor) {
- mount_component(slider, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const slider_changes = {};
- if (dirty[0] & /*valueAsRGBA*/ 65536) slider_changes.knobStyle = `background-color: ${/*valueAsRGBA*/ ctx[16]}`;
- if (dirty[0] & /*valueAsRGBAFullyTransparent, valueAsRGBAFullyOpaque*/ 393216) slider_changes.trackStyle = `background-image: linear-gradient(to right, ${/*valueAsRGBAFullyTransparent*/ ctx[17]}, ${/*valueAsRGBAFullyOpaque*/ ctx[18]})`;
- if (dirty[0] & /*opacity*/ 32768) slider_changes.value = /*opacity*/ ctx[15];
- slider.$set(slider_changes);
- },
- i(local) {
- if (current) return;
- transition_in(slider.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(slider.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(slider, detaching);
- }
- };
- }
- // (221:8) {#if enablePresets}
- function create_if_block$6(ctx) {
- let radiogroup;
- let current;
- radiogroup = new RadioGroup({
- props: {
- label: "Presets",
- class: arrayJoin([
- "PinturaColorPresets",
- /*hidePresetLabel*/ ctx[9]
- ? "PinturaColorPresetsGrid"
- : "PinturaColorPresetsList"
- ]),
- hideLabel: false,
- name: /*name*/ ctx[1],
- value: /*value*/ ctx[4],
- optionGroupClass: "PinturaDropdownOptionGroup",
- optionClass: "PinturaDropdownOption",
- options: /*options*/ ctx[2].map(/*func*/ ctx[32]),
- selectedIndex: /*selectedIndex*/ ctx[3],
- optionMapper: /*optionMapper*/ ctx[7],
- optionLabelClass: /*optionLabelClass*/ ctx[6],
- onchange: /*func_1*/ ctx[33],
- $$slots: {
- option: [
- create_option_slot$3,
- ({ option }) => ({ 44: option }),
- ({ option }) => [0, option ? 8192 : 0]
- ],
- group: [
- create_group_slot,
- ({ option }) => ({ 44: option }),
- ({ option }) => [0, option ? 8192 : 0]
- ]
- },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(radiogroup.$$.fragment);
- },
- m(target, anchor) {
- mount_component(radiogroup, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const radiogroup_changes = {};
- if (dirty[0] & /*hidePresetLabel*/ 512) radiogroup_changes.class = arrayJoin([
- "PinturaColorPresets",
- /*hidePresetLabel*/ ctx[9]
- ? "PinturaColorPresetsGrid"
- : "PinturaColorPresetsList"
- ]);
- if (dirty[0] & /*name*/ 2) radiogroup_changes.name = /*name*/ ctx[1];
- if (dirty[0] & /*value*/ 16) radiogroup_changes.value = /*value*/ ctx[4];
- if (dirty[0] & /*options, locale*/ 1028) radiogroup_changes.options = /*options*/ ctx[2].map(/*func*/ ctx[32]);
- if (dirty[0] & /*selectedIndex*/ 8) radiogroup_changes.selectedIndex = /*selectedIndex*/ ctx[3];
- if (dirty[0] & /*optionMapper*/ 128) radiogroup_changes.optionMapper = /*optionMapper*/ ctx[7];
- if (dirty[0] & /*optionLabelClass*/ 64) radiogroup_changes.optionLabelClass = /*optionLabelClass*/ ctx[6];
- if (dirty[0] & /*hidePresetLabel*/ 512 | dirty[1] & /*$$scope, option*/ 24576) {
- radiogroup_changes.$$scope = { dirty, ctx };
- }
- radiogroup.$set(radiogroup_changes);
- },
- i(local) {
- if (current) return;
- transition_in(radiogroup.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(radiogroup.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(radiogroup, detaching);
- }
- };
- }
- // (243:16)
- function create_group_slot(ctx) {
- let span;
- let t_value = /*option*/ ctx[44].label + "";
- let t;
- return {
- c() {
- span = element("span");
- t = text(t_value);
- attr(span, "slot", "group");
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- },
- p(ctx, dirty) {
- if (dirty[1] & /*option*/ 8192 && t_value !== (t_value = /*option*/ ctx[44].label + "")) set_data(t, t_value);
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- // (248:20) {#if !hidePresetLabel}
- function create_if_block_1$6(ctx) {
- let span;
- let t_value = /*option*/ ctx[44].label + "";
- let t;
- return {
- c() {
- span = element("span");
- t = text(t_value);
- attr(span, "class", "PinturaButtonLabel");
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- },
- p(ctx, dirty) {
- if (dirty[1] & /*option*/ 8192 && t_value !== (t_value = /*option*/ ctx[44].label + "")) set_data(t, t_value);
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- // (246:16)
- function create_option_slot$3(ctx) {
- let span;
- let colorpreview;
- let t;
- let current;
- colorpreview = new ColorPreview({
- props: {
- title: /*option*/ ctx[44].label,
- color: /*option*/ ctx[44].value
- }
- });
- let if_block = !/*hidePresetLabel*/ ctx[9] && create_if_block_1$6(ctx);
- return {
- c() {
- span = element("span");
- create_component(colorpreview.$$.fragment);
- t = space();
- if (if_block) if_block.c();
- attr(span, "slot", "option");
- },
- m(target, anchor) {
- insert(target, span, anchor);
- mount_component(colorpreview, span, null);
- append(span, t);
- if (if_block) if_block.m(span, null);
- current = true;
- },
- p(ctx, dirty) {
- const colorpreview_changes = {};
- if (dirty[1] & /*option*/ 8192) colorpreview_changes.title = /*option*/ ctx[44].label;
- if (dirty[1] & /*option*/ 8192) colorpreview_changes.color = /*option*/ ctx[44].value;
- colorpreview.$set(colorpreview_changes);
- if (!/*hidePresetLabel*/ ctx[9]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- } else {
- if_block = create_if_block_1$6(ctx);
- if_block.c();
- if_block.m(span, null);
- }
- } else if (if_block) {
- if_block.d(1);
- if_block = null;
- }
- },
- i(local) {
- if (current) return;
- transition_in(colorpreview.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(colorpreview.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(span);
- destroy_component(colorpreview);
- if (if_block) if_block.d();
- }
- };
- }
- // (169:4)
- function create_details_slot(ctx) {
- let div;
- let t;
- let current;
- let if_block0 = /*enablePicker*/ ctx[13] && create_if_block_2$5(ctx);
- let if_block1 = /*enablePresets*/ ctx[12] && create_if_block$6(ctx);
- return {
- c() {
- div = element("div");
- if (if_block0) if_block0.c();
- t = space();
- if (if_block1) if_block1.c();
- attr(div, "slot", "details");
- attr(div, "class", "PinturaColorPickerPanel");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (if_block0) if_block0.m(div, null);
- append(div, t);
- if (if_block1) if_block1.m(div, null);
- current = true;
- },
- p(ctx, dirty) {
- if (/*enablePicker*/ ctx[13]) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty[0] & /*enablePicker*/ 8192) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_2$5(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(div, t);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (/*enablePresets*/ ctx[12]) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- if (dirty[0] & /*enablePresets*/ 4096) {
- transition_in(if_block1, 1);
- }
- } else {
- if_block1 = create_if_block$6(ctx);
- if_block1.c();
- transition_in(if_block1, 1);
- if_block1.m(div, null);
- }
- } else if (if_block1) {
- group_outros();
- transition_out(if_block1, 1, 1, () => {
- if_block1 = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- transition_in(if_block1);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- transition_out(if_block1);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (if_block0) if_block0.d();
- if (if_block1) if_block1.d();
- }
- };
- }
- function create_fragment$s(ctx) {
- let details;
- let current;
- details = new Details({
- props: {
- buttonClass: arrayJoin(["PinturaColorPickerButton", /*buttonClass*/ ctx[5]]),
- $$slots: {
- details: [create_details_slot],
- label: [create_label_slot]
- },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(details.$$.fragment);
- },
- m(target, anchor) {
- mount_component(details, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const details_changes = {};
- if (dirty[0] & /*buttonClass*/ 32) details_changes.buttonClass = arrayJoin(["PinturaColorPickerButton", /*buttonClass*/ ctx[5]]);
- if (dirty[0] & /*hidePresetLabel, name, value, options, locale, selectedIndex, optionMapper, optionLabelClass, enablePresets, valueAsRGBA, valueAsRGBAFullyTransparent, valueAsRGBAFullyOpaque, opacity, enableOpacity, valueAsRGBAFullySaturated, hue, input, sx, sy, enablePicker, label, title*/ 8388575 | dirty[1] & /*$$scope*/ 16384) {
- details_changes.$$scope = { dirty, ctx };
- }
- details.$set(details_changes);
- },
- i(local) {
- if (current) return;
- transition_in(details.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(details.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(details, detaching);
- }
- };
- }
- function instance$s($$self, $$props, $$invalidate) {
- let sx;
- let sy;
- let { label = undefined } = $$props;
- let { name = undefined } = $$props;
- let { options = [] } = $$props;
- let { selectedIndex = -1 } = $$props;
- let { value = undefined } = $$props;
- let { buttonClass = undefined } = $$props;
- let { optionLabelClass = undefined } = $$props;
- let { optionMapper = undefined } = $$props;
- let { onchange = undefined } = $$props;
- let { title = undefined } = $$props;
- let { hidePresetLabel = true } = $$props;
- let { locale = undefined } = $$props;
- let { enableOpacity = true } = $$props;
- let { enablePresets = true } = $$props;
- let { enablePicker = true } = $$props;
- // inputs
- let hue;
- let saturation;
- let brightness;
- let opacity;
- // shortcuts
- let valueAsRGB;
- let valueAsRGBA;
- let valueAsRGBAFullyTransparent;
- let valueAsRGBAFullyOpaque;
- let valueAsRGBAFullySaturated;
- const updateProps = (color, syncControls) => {
- valueAsRGB = [color[0], color[1], color[2]];
- if (syncControls) {
- let valueAsHSV = RGBToHSV(...valueAsRGB);
- $$invalidate(14, hue = valueAsHSV[0]);
- $$invalidate(29, saturation = valueAsHSV[1]);
- $$invalidate(30, brightness = valueAsHSV[2]);
- $$invalidate(15, opacity = isNumber(color[3]) ? color[3] : 1);
- }
- $$invalidate(16, valueAsRGBA = colorArrayToRGBA(color));
- $$invalidate(17, valueAsRGBAFullyTransparent = colorArrayToRGBA([...valueAsRGB, 0]));
- $$invalidate(18, valueAsRGBAFullyOpaque = colorArrayToRGBA([...valueAsRGB, 1]));
- $$invalidate(19, valueAsRGBAFullySaturated = colorArrayToRGBA(HSVToRGB(hue, 1, 1)));
- };
- value && updateProps(value, true);
- const update = () => {
- const rgb = HSVToRGB(hue, saturation, brightness);
- const rgba = [...rgb, opacity];
- updateProps(rgba);
- onchange(rgba);
- };
- const updateColorArray = arr => {
- const rgba = arr.length === 3 ? [...arr, 1] : arr;
- updateProps(rgba, true);
- onchange(rgba);
- };
- const updateHue = h => {
- $$invalidate(14, hue = h);
- if (opacity === 0) $$invalidate(15, opacity = 1);
- update();
- };
- const updateSaturationAndBrightness = (s, b) => {
- $$invalidate(29, saturation = s);
- $$invalidate(30, brightness = b);
- if (opacity === 0) $$invalidate(15, opacity = 1);
- update();
- };
- const updateOpacity = o => {
- $$invalidate(15, opacity = o);
- update();
- };
- const setValueByOffset = (offset, inputSize) => {
- const x = clamp(offset.x / inputSize.width, 0, 1);
- const y = clamp(offset.y / inputSize.height, 0, 1);
- updateSaturationAndBrightness(x, 1 - y);
- };
- let input;
- let inputSize;
- let inputOffset;
- let inputPageOffset;
- const handlePointerDown = e => {
- e.stopPropagation();
- inputSize = sizeCreate(input.offsetWidth, input.offsetHeight);
- inputOffset = vectorCreateFromPointerEventOffset(e);
- inputPageOffset = vectorCreateFromPointerEvent(e);
- setValueByOffset(inputOffset, inputSize);
- document.documentElement.addEventListener("pointermove", handlePointerMove);
- document.documentElement.addEventListener("pointerup", handlePointerUp);
- };
- const handlePointerMove = e => {
- const d = vectorSubtract(vectorCreateFromPointerEvent(e), inputPageOffset);
- setValueByOffset(vectorAdd(vectorClone(inputOffset), d), inputSize);
- };
- const handlePointerUp = e => {
- inputSize = undefined;
- document.documentElement.removeEventListener("pointermove", handlePointerMove);
- document.documentElement.removeEventListener("pointerup", handlePointerUp);
- };
- const handleNudge = e => {
- inputSize = sizeCreate(input.offsetWidth, input.offsetHeight);
- const x = sx / 100 * inputSize.width;
- const y = sy / 100 * inputSize.height;
- setValueByOffset({ x: x + e.detail.x, y: y + e.detail.y }, inputSize);
- };
- function div2_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- input = $$value;
- $$invalidate(20, input);
- });
- }
- const func = ([color, label]) => [color, isFunction(label) ? label(locale) : label];
- const func_1 = detail => updateColorArray(detail.value);
- $$self.$$set = $$props => {
- if ("label" in $$props) $$invalidate(0, label = $$props.label);
- if ("name" in $$props) $$invalidate(1, name = $$props.name);
- if ("options" in $$props) $$invalidate(2, options = $$props.options);
- if ("selectedIndex" in $$props) $$invalidate(3, selectedIndex = $$props.selectedIndex);
- if ("value" in $$props) $$invalidate(4, value = $$props.value);
- if ("buttonClass" in $$props) $$invalidate(5, buttonClass = $$props.buttonClass);
- if ("optionLabelClass" in $$props) $$invalidate(6, optionLabelClass = $$props.optionLabelClass);
- if ("optionMapper" in $$props) $$invalidate(7, optionMapper = $$props.optionMapper);
- if ("onchange" in $$props) $$invalidate(28, onchange = $$props.onchange);
- if ("title" in $$props) $$invalidate(8, title = $$props.title);
- if ("hidePresetLabel" in $$props) $$invalidate(9, hidePresetLabel = $$props.hidePresetLabel);
- if ("locale" in $$props) $$invalidate(10, locale = $$props.locale);
- if ("enableOpacity" in $$props) $$invalidate(11, enableOpacity = $$props.enableOpacity);
- if ("enablePresets" in $$props) $$invalidate(12, enablePresets = $$props.enablePresets);
- if ("enablePicker" in $$props) $$invalidate(13, enablePicker = $$props.enablePicker);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*saturation*/ 536870912) {
- $$invalidate(21, sx = saturation * 100);
- }
- if ($$self.$$.dirty[0] & /*brightness*/ 1073741824) {
- $$invalidate(22, sy = 100 - brightness * 100);
- }
- };
- return [
- label,
- name,
- options,
- selectedIndex,
- value,
- buttonClass,
- optionLabelClass,
- optionMapper,
- title,
- hidePresetLabel,
- locale,
- enableOpacity,
- enablePresets,
- enablePicker,
- hue,
- opacity,
- valueAsRGBA,
- valueAsRGBAFullyTransparent,
- valueAsRGBAFullyOpaque,
- valueAsRGBAFullySaturated,
- input,
- sx,
- sy,
- updateColorArray,
- updateHue,
- updateOpacity,
- handlePointerDown,
- handleNudge,
- onchange,
- saturation,
- brightness,
- div2_binding,
- func,
- func_1
- ];
- }
- class ColorPicker extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$s,
- create_fragment$s,
- safe_not_equal,
- {
- label: 0,
- name: 1,
- options: 2,
- selectedIndex: 3,
- value: 4,
- buttonClass: 5,
- optionLabelClass: 6,
- optionMapper: 7,
- onchange: 28,
- title: 8,
- hidePresetLabel: 9,
- locale: 10,
- enableOpacity: 11,
- enablePresets: 12,
- enablePicker: 13
- },
- [-1, -1]
- );
- }
- }
- var upperCaseFirstLetter = (str) => str.charAt(0).toUpperCase() + str.slice(1);
- let result$2 = null;
- var canCheckFontAvailability = () => {
- if (result$2 === null) {
- if (!isBrowser())
- result$2 = false;
- else {
- try {
- // if browser can detect font as non existend then it supports font checking (only chrome)
- // @ts-ignore
- result$2 = document.fonts.check('16px TestNonExistingFont') === false;
- }
- catch (err) {
- // if throws assume can't check
- result$2 = false;
- }
- }
- }
- return result$2;
- };
- // @ts-ignore
- const toLocaleFn = (key, localePrefix) => (locale) => locale[localePrefix ? `${localePrefix}${upperCaseFirstLetter(key)}` : key];
- const mapToSizeOption = (v) => [v, `${v}`];
- const createLocaleMapper = (options, localePrefix) => (key) => [
- options[key],
- toLocaleFn(key, localePrefix),
- ];
- const toolColorDefault = [1, 0.2549, 0.2118];
- const toolStrokeColorDefault = [1, 1, 1, 0];
- //#region tools
- const toolShapeDefaults = {
- path: () => ({
- points: [],
- disableErase: false,
- }),
- eraser: () => ({
- eraseRadius: 0,
- }),
- line: () => ({
- x1: 0,
- y1: 0,
- x2: 0,
- y2: 0,
- disableErase: false,
- }),
- rectangle: () => ({
- x: 0,
- y: 0,
- width: 0,
- height: 0,
- }),
- ellipse: () => ({
- x: 0,
- y: 0,
- rx: 0,
- ry: 0,
- }),
- text: () => ({
- x: 0,
- y: 0,
- text: 'Text',
- }),
- };
- const createToolStyle = (type, shape = {}, options = { position: 'relative' }) => {
- if (!toolShapeDefaults[type])
- return;
- const shapeDef = {
- ...toolShapeDefaults[type](),
- ...shape,
- };
- return [shapeDef, options];
- };
- const createToolStyles = (tools) => ({
- sharpie: createToolStyle('path', {
- strokeWidth: '0.5%',
- strokeColor: [...toolColorDefault],
- disableMove: true,
- }),
- eraser: createToolStyle('eraser'),
- line: createToolStyle('line', {
- strokeColor: [...toolColorDefault],
- strokeWidth: '0.5%',
- }),
- arrow: createToolStyle('line', {
- lineStart: 'none',
- lineEnd: 'arrow-solid',
- strokeColor: [...toolColorDefault],
- strokeWidth: '0.5%',
- }),
- rectangle: createToolStyle('rectangle', {
- strokeColor: [...toolStrokeColorDefault],
- backgroundColor: [...toolColorDefault],
- }),
- ellipse: createToolStyle('ellipse', {
- strokeColor: [...toolStrokeColorDefault],
- backgroundColor: [...toolColorDefault],
- }),
- text: createToolStyle('text', {
- color: [...toolColorDefault],
- fontSize: '2%',
- }),
- ...tools,
- });
- //#endregion
- //#region toolbar
- const createToolbarItem = (tool, label, props) => [
- tool,
- label || toLocaleFn(tool, 'shapeLabelTool'),
- {
- icon: toLocaleFn(tool, 'shapeIconTool'),
- ...props,
- },
- ];
- const createToolbar = (tools = ['sharpie', 'eraser', 'line', 'arrow', 'rectangle', 'ellipse', 'text', 'preset']) => tools
- .map((tool) => {
- // default tool definition, assume locale in
- if (isString(tool))
- return createToolbarItem(tool);
- // tool def with propery
- if (Array.isArray(tool)) {
- // state update of tool with key in locale object
- if (isObject(tool[1]))
- return createToolbarItem(tool[0], undefined, tool[1]);
- // should be string, string
- return createToolbarItem(tool[0], tool[1], tool[2]);
- }
- })
- .filter(Boolean);
- //#endregion
- //#region style option defaults
- const createDefaultColorOptions = () => ({
- transparent: [1, 1, 1, 0],
- white: [1, 1, 1],
- silver: [0.8667, 0.8667, 0.8667],
- gray: [0.6667, 0.6667, 0.6667],
- black: [0, 0, 0],
- navy: [0, 0.1216, 0.2471],
- blue: [0, 0.4549, 0.851],
- aqua: [0.498, 0.8588, 1],
- teal: [0.2235, 0.8, 0.8],
- olive: [0.2392, 0.6, 0.4392],
- green: [0.1804, 0.8, 0.251],
- yellow: [1, 0.8627, 0],
- orange: [1, 0.5216, 0.1059],
- red: [1, 0.2549, 0.2118],
- maroon: [0.5216, 0.0784, 0.2941],
- fuchsia: [0.9412, 0.0706, 0.7451],
- purple: [0.6941, 0.051, 0.7882],
- });
- const createDefaultFontSizeOptions = () => [16, 18, 20, 24, 30, 36, 48, 64, 72, 96, 144];
- const createDefaultFontScaleOptions = () => ({
- extraSmall: '2%',
- small: '4%',
- mediumSmall: '8%',
- medium: '10%',
- mediumLarge: '15%',
- large: '20%',
- extraLarge: '25%',
- });
- const createDefaultStrokeWidthOptions = () => [1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 48, 64];
- const createDefaultStrokeScaleOptions = () => ({
- extraSmall: '0.25%',
- small: '0.5%',
- mediumSmall: '1%',
- medium: '1.75%',
- mediumLarge: '2.5%',
- large: '3.5%',
- extraLarge: '5%',
- });
- const createDefaultLineEndStyleOptions = () => [
- 'bar',
- 'arrow',
- 'arrowSolid',
- 'circle',
- 'circleSolid',
- 'square',
- 'squareSolid',
- ];
- const createDefaultFontFamilyOptions = () => [
- [`Helvetica, Arial, Verdana, 'Droid Sans', sans-serif`, 'Sans Serif'],
- [`'Arial Black', 'Avenir-Black', 'Arial Bold'`, 'Black'],
- [`'Arial Narrow', 'Futura-CondensedMedium'`, 'Narrow'],
- [`'Trebuchet MS'`, 'Humanist'],
- [`Georgia, 'Avenir-Black', 'Times New Roman', 'Droid Serif', serif`, 'Serif'],
- [`Palatino`, 'Old-Style'],
- [`'Times New Roman', 'TimesNewRomanPSMT'`, 'Transitional'],
- [`Menlo, Monaco, 'Lucida Console', monospace`, 'Monospaced'],
- [`'Courier New', monospace`, 'Slab Serif'],
- ];
- const createDefaultTextAlignOptions = () => ['left', 'center', 'right'];
- const createDefaultFontStyleOptions = () => [
- ['normal', 'bold'],
- ['italic', 'normal'],
- ['italic', 'bold'],
- ];
- //#endregion
- //#region style options
- const createColorOptions = (colors) => Object.keys(colors).map(createLocaleMapper(colors, 'shapeTitleColor'));
- const createFontSizeOptions = (sizes) => sizes.map(mapToSizeOption);
- const createFontScaleOptions = (scales) => Object.keys(scales).map(createLocaleMapper(scales, 'labelSize'));
- const createStrokeWidthOptions = (sizes) => sizes.map(mapToSizeOption);
- const createStrokeScaleOptions = (scales) => Object.keys(scales).map(createLocaleMapper(scales, 'labelSize'));
- const createFontFamilyOptions = (fonts) => [...fonts];
- const createFontStyleOptions = (styles) => styles.map((style) => [
- style,
- (locale) => locale[`shapeLabelFontStyle${style
- .filter((v) => v !== 'normal')
- .map(upperCaseFirstLetter)
- .join('')}`],
- ]);
- const createLineEndStyleOptions = (styles) => styles.map((style) => [
- toKebabCase(style),
- (locale) => locale[`shapeTitleLineDecoration${upperCaseFirstLetter(style)}`],
- { icon: (locale) => locale[`shapeIconLineDecoration${upperCaseFirstLetter(style)}`] },
- ]);
- const createTextAlignOptions = (options) => options.map((align) => [
- align,
- (locale) => locale[`shapeTitleTextAlign${upperCaseFirstLetter(align)}`],
- {
- hideLabel: true,
- icon: (locale) => locale[`shapeIconTextAlign${upperCaseFirstLetter(align)}`],
- },
- ]);
- const createControlOptions = (items, options) => {
- const { defaultKey, defaultOptions } = options || {};
- let arr = [];
- if (defaultKey)
- arr[0] = [undefined, (locale) => locale[defaultKey], { ...defaultOptions }];
- return [...arr, ...items];
- };
- //#endregion
- //#region shape style controls
- const someFontsAvailableInStack = (stack) => stack
- .split(',')
- .map((name) => name.trim())
- .some((name) => {
- // @ts-ignore
- return document.fonts.check(`16px ${name}`);
- });
- const createColorControl = (items) => [
- ColorPicker,
- {
- title: (locale) => locale.labelColor,
- options: createControlOptions(items),
- },
- ];
- const createSliderControl = (options = {}) => [
- ToggleSlider,
- {
- ...options,
- },
- ];
- const createFontFamilyControl = (fontFamilies) => [
- Dropdown,
- {
- title: (locale) => locale.shapeTitleFontFamily,
- onload: ({ options = [] }) => {
- // can't check for font availability so don't
- if (!canCheckFontAvailability())
- return;
- options
- // map to font stack (option value)
- .map(([stack]) => stack)
- // filter out undefined
- .filter(Boolean)
- // filter out fonts that are available
- .filter((stack) => !someFontsAvailableInStack(stack))
- // remaining fonts should have dom elements for future check
- .forEach((stack) => {
- // get as id
- const testId = `PinturaFontTest-${stack
- .replace(/[^a-zA-Z0-9]+/g, '')
- .toLowerCase()}`;
- // already added this tester
- if (document.getElementById(testId))
- return;
- // add font tester
- document.body.appendChild(h('span', {
- textContent: ' ',
- id: testId,
- style: `font-family:${stack};font-size:0;color:transparent;`,
- }));
- });
- },
- ondestroy: () => {
- // can't check for font availability so no need to clean up
- if (!canCheckFontAvailability())
- return;
- // clean up testers
- const testers = document.querySelectorAll('.PinturaFontTest');
- testers.forEach((tester) => tester.remove());
- },
- optionLabelStyle: (value) => `font-family: ${value}`,
- options: createControlOptions(fontFamilies, { defaultKey: 'labelDefault' }),
- optionFilter: (fontFamilyOption) => {
- // don't filter if not in browser context
- if (!canCheckFontAvailability())
- return true;
- // get font stack
- const [stack] = fontFamilyOption;
- // allow if undefined
- if (!stack)
- return true;
- // filter out fonts that aren't available
- const res = someFontsAvailableInStack(stack);
- return res;
- },
- },
- ];
- const createBackgroundColorControl = (items) => [
- ColorPicker,
- {
- title: (locale) => locale.shapeTitleBackgroundColor,
- options: createControlOptions(items),
- },
- ];
- const createStrokeColorControl = (items, options = {}) => [
- ColorPicker,
- {
- title: (locale) => locale.shapeTitleStrokeColor,
- options: createControlOptions(items),
- buttonClass: 'PinturaColorPickerButtonStroke',
- onchange: (value, shape) => {
- // get shape strokeWidth as number
- const strokeWidth = shape.strokeWidth;
- const strokeWidthParsed = isNumber(strokeWidth) || isString(strokeWidth) ? parseFloat(strokeWidth) : 0;
- // already has outline
- if (strokeWidthParsed > 0)
- return;
- // set outline to first stroke width
- shape.strokeWidth = (options && options.defaultStrokeWidth) || '0.5%';
- },
- },
- ];
- const createStrokeWidthControl = (items) => [
- Dropdown,
- {
- title: (locale) => locale.shapeTitleStrokeWidth,
- options: (shape) => {
- if (hasProp(shape, 'backgroundColor'))
- return createControlOptions(items, {
- defaultKey: 'shapeLabelStrokeNone',
- });
- return createControlOptions(items);
- },
- },
- ];
- const createLineControl = (items, titleKey, optionIconStyle) => [
- Dropdown,
- {
- title: (locale) => locale[titleKey],
- options: createControlOptions(items, {
- defaultKey: 'labelNone',
- defaultOptions: {
- icon: `<g stroke="currentColor" stroke-linecap="round" stroke-width=".125em"><path d="M5,12 H14"/></g>`,
- },
- }),
- optionIconStyle,
- },
- ];
- const createLineStartStyleControl = (items) => createLineControl(items, 'shapeTitleLineStart', `transform: scaleX(-1)`);
- const createLineEndStyleControl = (items) => createLineControl(items, 'shapeTitleLineEnd');
- const createFontColorControl = (items) => [
- ColorPicker,
- {
- title: (locale) => locale.shapeTitleTextColor,
- options: createControlOptions(items),
- },
- ];
- const createFontStyleControl = (items) => [
- Dropdown,
- {
- title: (locale) => locale.shapeTitleFontStyle,
- optionLabelStyle: (value) => value && `font-style:${value[0]};font-weight:${value[1]}`,
- options: createControlOptions(items, {
- defaultKey: 'shapeLabelFontStyleNormal',
- }),
- },
- ];
- const createFontSizeControl = (items) => [
- Dropdown,
- {
- title: (locale) => locale.shapeTitleFontSize,
- options: createControlOptions(items, { defaultKey: 'labelDefault' }),
- },
- ];
- const createTextAlignControl = (items) => [
- RadioGroup,
- {
- title: (locale) => locale.shapeTitleTextAlign,
- options: createControlOptions(items),
- },
- ];
- const createLineHeightControl = (items) => [
- Dropdown,
- {
- title: (locale) => locale.shapeTitleLineHeight,
- options: createControlOptions(items, { defaultKey: 'labelAuto' }),
- },
- ];
- const createShapeStyleControls = (options = {}) => {
- const { colorOptions = createColorOptions(createDefaultColorOptions()), strokeWidthOptions = createStrokeScaleOptions(createDefaultStrokeScaleOptions()), lineEndStyleOptions = createLineEndStyleOptions(createDefaultLineEndStyleOptions()), fontFamilyOptions = createFontFamilyOptions(createDefaultFontFamilyOptions()), fontStyleOptions = createFontStyleOptions(createDefaultFontStyleOptions()), fontSizeOptions = createFontScaleOptions(createDefaultFontScaleOptions()), textAlignOptions = createTextAlignOptions(createDefaultTextAlignOptions()), } = options;
- return {
- // generic
- defaultColor: colorOptions && createColorControl(colorOptions),
- defaultNumber: createSliderControl(),
- defaultPercentage: createSliderControl({
- getValue: (value) => parseFloat(value),
- setValue: (value) => `${value}%`,
- step: 0.05,
- label: (value, min, max) => `${Math.round((value / max) * 100)}%`,
- labelClass: 'PinturaPercentageLabel',
- }),
- // shape background
- backgroundColor: colorOptions && createBackgroundColorControl(colorOptions),
- // line/outline
- strokeColor: colorOptions && createStrokeColorControl(colorOptions),
- strokeWidth: strokeWidthOptions && createStrokeWidthControl(strokeWidthOptions),
- // line
- lineStart: lineEndStyleOptions && createLineStartStyleControl(lineEndStyleOptions),
- lineEnd: lineEndStyleOptions && createLineEndStyleControl(lineEndStyleOptions),
- // text
- color: colorOptions && createFontColorControl(colorOptions),
- fontFamily: fontFamilyOptions && createFontFamilyControl(fontFamilyOptions),
- fontStyle_fontWeight: fontStyleOptions && createFontStyleControl(fontStyleOptions),
- fontSize: fontSizeOptions && createFontSizeControl(fontSizeOptions),
- textAlign: textAlignOptions && createTextAlignControl(textAlignOptions),
- // lineHeight: lineHeightOptions && createLineHeightControl(lineHeightOptions),
- // generic options
- frameColor: ['defaultColor'],
- frameSize: [
- 'defaultPercentage',
- {
- min: 0.2,
- max: 10,
- title: (locale) => locale.labelSize,
- },
- ],
- frameInset: [
- 'defaultPercentage',
- { min: 0.5, max: 10, title: (locale) => locale.labelInset },
- ],
- frameOffset: [
- 'defaultPercentage',
- { min: 0.5, max: 10, title: (locale) => locale.labelOffset },
- ],
- frameRadius: [
- 'defaultPercentage',
- { min: 0.5, max: 10, title: (locale) => locale.labelRadius },
- ],
- frameAmount: [
- 'defaultNumber',
- { min: 1, max: 5, step: 1, title: (locale) => locale.labelAmount },
- ],
- };
- };
- //#endregion
- /* src/core/ui/components/Measure.svelte generated by Svelte v3.37.0 */
- function create_fragment$r(ctx) {
- let div;
- let current;
- let mounted;
- let dispose;
- const default_slot_template = /*#slots*/ ctx[3].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[2], null);
- return {
- c() {
- div = element("div");
- if (default_slot) default_slot.c();
- attr(div, "class", /*klass*/ ctx[0]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (default_slot) {
- default_slot.m(div, null);
- }
- current = true;
- if (!mounted) {
- dispose = [
- listen(div, "measure", /*handleResize*/ ctx[1]),
- action_destroyer(measurable.call(null, div))
- ];
- mounted = true;
- }
- },
- p(ctx, [dirty]) {
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope*/ 4) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[2], dirty, null, null);
- }
- }
- if (!current || dirty & /*klass*/ 1) {
- attr(div, "class", /*klass*/ ctx[0]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (default_slot) default_slot.d(detaching);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function instance$r($$self, $$props, $$invalidate) {
- let { $$slots: slots = {}, $$scope } = $$props;
- const dispatch = createEventDispatcher();
- let { class: klass = null } = $$props;
- const handleResize = ({ detail }) => dispatch("measure", detail);
- $$self.$$set = $$props => {
- if ("class" in $$props) $$invalidate(0, klass = $$props.class);
- if ("$$scope" in $$props) $$invalidate(2, $$scope = $$props.$$scope);
- };
- return [klass, handleResize, $$scope, slots];
- }
- class Measure extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$r, create_fragment$r, safe_not_equal, { class: 0 });
- }
- }
- /* src/core/ui/components/Util.svelte generated by Svelte v3.37.0 */
- const get_footer_slot_changes = dirty => ({});
- const get_footer_slot_context = ctx => ({});
- const get_main_slot_changes = dirty => ({});
- const get_main_slot_context = ctx => ({});
- const get_header_slot_changes = dirty => ({});
- const get_header_slot_context = ctx => ({});
- // (10:0) {#if hasHeader}
- function create_if_block_2$4(ctx) {
- let div;
- let current;
- const header_slot_template = /*#slots*/ ctx[4].header;
- const header_slot = create_slot(header_slot_template, ctx, /*$$scope*/ ctx[3], get_header_slot_context);
- return {
- c() {
- div = element("div");
- if (header_slot) header_slot.c();
- attr(div, "class", "PinturaUtilHeader");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (header_slot) {
- header_slot.m(div, null);
- }
- current = true;
- },
- p(ctx, dirty) {
- if (header_slot) {
- if (header_slot.p && dirty & /*$$scope*/ 8) {
- update_slot(header_slot, header_slot_template, ctx, /*$$scope*/ ctx[3], dirty, get_header_slot_changes, get_header_slot_context);
- }
- }
- },
- i(local) {
- if (current) return;
- transition_in(header_slot, local);
- current = true;
- },
- o(local) {
- transition_out(header_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (header_slot) header_slot.d(detaching);
- }
- };
- }
- // (17:22) <Measure class="PinturaStage" on:measure />
- function fallback_block(ctx) {
- let measure;
- let current;
- measure = new Measure({ props: { class: "PinturaStage" } });
- measure.$on("measure", /*measure_handler*/ ctx[5]);
- return {
- c() {
- create_component(measure.$$.fragment);
- },
- m(target, anchor) {
- mount_component(measure, target, anchor);
- current = true;
- },
- p: noop,
- i(local) {
- if (current) return;
- transition_in(measure.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(measure.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(measure, detaching);
- }
- };
- }
- // (20:0) {#if hasFooter}
- function create_if_block_1$5(ctx) {
- let div;
- let current;
- const footer_slot_template = /*#slots*/ ctx[4].footer;
- const footer_slot = create_slot(footer_slot_template, ctx, /*$$scope*/ ctx[3], get_footer_slot_context);
- return {
- c() {
- div = element("div");
- if (footer_slot) footer_slot.c();
- attr(div, "class", "PinturaUtilFooter");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (footer_slot) {
- footer_slot.m(div, null);
- }
- current = true;
- },
- p(ctx, dirty) {
- if (footer_slot) {
- if (footer_slot.p && dirty & /*$$scope*/ 8) {
- update_slot(footer_slot, footer_slot_template, ctx, /*$$scope*/ ctx[3], dirty, get_footer_slot_changes, get_footer_slot_context);
- }
- }
- },
- i(local) {
- if (current) return;
- transition_in(footer_slot, local);
- current = true;
- },
- o(local) {
- transition_out(footer_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (footer_slot) footer_slot.d(detaching);
- }
- };
- }
- function create_fragment$q(ctx) {
- let t0;
- let div;
- let t1;
- let t2;
- let if_block2_anchor;
- let current;
- let if_block0 = /*hasHeader*/ ctx[1] && create_if_block_2$4(ctx);
- const main_slot_template = /*#slots*/ ctx[4].main;
- const main_slot = create_slot(main_slot_template, ctx, /*$$scope*/ ctx[3], get_main_slot_context);
- const main_slot_or_fallback = main_slot || fallback_block(ctx);
- let if_block1 = /*hasFooter*/ ctx[2] && create_if_block_1$5(ctx);
- let if_block2 = false ;
- return {
- c() {
- if (if_block0) if_block0.c();
- t0 = space();
- div = element("div");
- if (main_slot_or_fallback) main_slot_or_fallback.c();
- t1 = space();
- if (if_block1) if_block1.c();
- t2 = space();
- if_block2_anchor = empty();
- attr(div, "class", "PinturaUtilMain");
- },
- m(target, anchor) {
- if (if_block0) if_block0.m(target, anchor);
- insert(target, t0, anchor);
- insert(target, div, anchor);
- if (main_slot_or_fallback) {
- main_slot_or_fallback.m(div, null);
- }
- /*div_binding*/ ctx[6](div);
- insert(target, t1, anchor);
- if (if_block1) if_block1.m(target, anchor);
- insert(target, t2, anchor);
- insert(target, if_block2_anchor, anchor);
- current = true;
- },
- p(ctx, [dirty]) {
- if (/*hasHeader*/ ctx[1]) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty & /*hasHeader*/ 2) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_2$4(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(t0.parentNode, t0);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (main_slot) {
- if (main_slot.p && dirty & /*$$scope*/ 8) {
- update_slot(main_slot, main_slot_template, ctx, /*$$scope*/ ctx[3], dirty, get_main_slot_changes, get_main_slot_context);
- }
- }
- if (/*hasFooter*/ ctx[2]) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- if (dirty & /*hasFooter*/ 4) {
- transition_in(if_block1, 1);
- }
- } else {
- if_block1 = create_if_block_1$5(ctx);
- if_block1.c();
- transition_in(if_block1, 1);
- if_block1.m(t2.parentNode, t2);
- }
- } else if (if_block1) {
- group_outros();
- transition_out(if_block1, 1, 1, () => {
- if_block1 = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- transition_in(main_slot_or_fallback, local);
- transition_in(if_block1);
- transition_in(if_block2);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- transition_out(main_slot_or_fallback, local);
- transition_out(if_block1);
- transition_out(if_block2);
- current = false;
- },
- d(detaching) {
- if (if_block0) if_block0.d(detaching);
- if (detaching) detach(t0);
- if (detaching) detach(div);
- if (main_slot_or_fallback) main_slot_or_fallback.d(detaching);
- /*div_binding*/ ctx[6](null);
- if (detaching) detach(t1);
- if (if_block1) if_block1.d(detaching);
- if (detaching) detach(t2);
- if (detaching) detach(if_block2_anchor);
- }
- };
- }
- function instance$q($$self, $$props, $$invalidate) {
- let { $$slots: slots = {}, $$scope } = $$props;
- let { hasHeader = !!$$props.$$slots.header } = $$props;
- let { hasFooter = !!$$props.$$slots.footer } = $$props;
- let { root = undefined } = $$props;
- function measure_handler(event) {
- bubble($$self, event);
- }
- function div_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- root = $$value;
- $$invalidate(0, root);
- });
- }
- $$self.$$set = $$new_props => {
- $$invalidate(7, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props)));
- if ("hasHeader" in $$new_props) $$invalidate(1, hasHeader = $$new_props.hasHeader);
- if ("hasFooter" in $$new_props) $$invalidate(2, hasFooter = $$new_props.hasFooter);
- if ("root" in $$new_props) $$invalidate(0, root = $$new_props.root);
- if ("$$scope" in $$new_props) $$invalidate(3, $$scope = $$new_props.$$scope);
- };
- $$props = exclude_internal_props($$props);
- return [root, hasHeader, hasFooter, $$scope, slots, measure_handler, div_binding];
- }
- class Util extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$q, create_fragment$q, safe_not_equal, { hasHeader: 1, hasFooter: 2, root: 0 });
- }
- }
- /* src/core/ui/components/RangeInput.svelte generated by Svelte v3.37.0 */
- function create_if_block$5(ctx) {
- let div;
- let div_style_value;
- return {
- c() {
- div = element("div");
- attr(div, "class", "PinturaRangeInputMeter");
- attr(div, "style", div_style_value = `transform: translateX(${/*$position*/ ctx[8].x - /*svgPadding*/ ctx[9].x}px) translateY(${/*$position*/ ctx[8].y - /*svgPadding*/ ctx[9].y}px)`);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- div.innerHTML = /*svg*/ ctx[6];
- },
- p(ctx, dirty) {
- if (dirty[0] & /*svg*/ 64) div.innerHTML = /*svg*/ ctx[6];
- if (dirty[0] & /*$position*/ 256 && div_style_value !== (div_style_value = `transform: translateX(${/*$position*/ ctx[8].x - /*svgPadding*/ ctx[9].x}px) translateY(${/*$position*/ ctx[8].y - /*svgPadding*/ ctx[9].y}px)`)) {
- attr(div, "style", div_style_value);
- }
- },
- d(detaching) {
- if (detaching) detach(div);
- }
- };
- }
- function create_fragment$p(ctx) {
- let div1;
- let span;
- let t0;
- let t1;
- let button;
- let t2;
- let button_disabled_value;
- let t3;
- let div0;
- let mounted;
- let dispose;
- let if_block = /*$position*/ ctx[8] && create_if_block$5(ctx);
- return {
- c() {
- div1 = element("div");
- span = element("span");
- t0 = text(/*valueLabel*/ ctx[3]);
- t1 = space();
- button = element("button");
- t2 = text(/*labelReset*/ ctx[1]);
- t3 = space();
- div0 = element("div");
- if (if_block) if_block.c();
- attr(span, "class", "PinturaRangeInputValue");
- attr(button, "class", "PinturaRangeInputReset");
- attr(button, "type", "button");
- button.disabled = button_disabled_value = /*value*/ ctx[0] === /*base*/ ctx[2];
- attr(div0, "class", "PinturaRangeInputInner");
- attr(div0, "style", /*rangeMask*/ ctx[7]);
- attr(div0, "data-value-limited", /*isLimited*/ ctx[5]);
- attr(div1, "class", "PinturaRangeInput");
- attr(div1, "tabindex", "0");
- },
- m(target, anchor) {
- insert(target, div1, anchor);
- append(div1, span);
- append(span, t0);
- append(div1, t1);
- append(div1, button);
- append(button, t2);
- append(div1, t3);
- append(div1, div0);
- if (if_block) if_block.m(div0, null);
- if (!mounted) {
- dispose = [
- listen(button, "click", /*handleReset*/ ctx[14]),
- listen(div0, "interactionstart", /*handleDragStart*/ ctx[10]),
- listen(div0, "interactionupdate", /*handleDragMove*/ ctx[12]),
- listen(div0, "interactionend", /*handleDragEnd*/ ctx[13]),
- listen(div0, "interactionrelease", /*handleDragRelease*/ ctx[11]),
- action_destroyer(interactable.call(null, div0, { inertia: true })),
- listen(div0, "measure", /*measure_handler*/ ctx[32]),
- action_destroyer(measurable.call(null, div0)),
- listen(div1, "wheel", /*handleWheel*/ ctx[16], { passive: false }),
- listen(div1, "nudge", /*handleNudge*/ ctx[17]),
- action_destroyer(nudgeable.call(null, div1, { direction: "horizontal" }))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- if (dirty[0] & /*valueLabel*/ 8) set_data(t0, /*valueLabel*/ ctx[3]);
- if (dirty[0] & /*labelReset*/ 2) set_data(t2, /*labelReset*/ ctx[1]);
- if (dirty[0] & /*value, base*/ 5 && button_disabled_value !== (button_disabled_value = /*value*/ ctx[0] === /*base*/ ctx[2])) {
- button.disabled = button_disabled_value;
- }
- if (/*$position*/ ctx[8]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- } else {
- if_block = create_if_block$5(ctx);
- if_block.c();
- if_block.m(div0, null);
- }
- } else if (if_block) {
- if_block.d(1);
- if_block = null;
- }
- if (dirty[0] & /*rangeMask*/ 128) {
- attr(div0, "style", /*rangeMask*/ ctx[7]);
- }
- if (dirty[0] & /*isLimited*/ 32) {
- attr(div0, "data-value-limited", /*isLimited*/ ctx[5]);
- }
- },
- i: noop,
- o: noop,
- d(detaching) {
- if (detaching) detach(div1);
- if (if_block) if_block.d();
- mounted = false;
- run_all(dispose);
- }
- };
- }
- const radiusBig = 2; // 2
- const radiusSmall = 0.75; // .75
- const indicatorSpacing = 10;
- const indicatorInterval = 5;
- const indicatorCount = 40; // must be even
- function instance$p($$self, $$props, $$invalidate) {
- let range;
- let valueMinLimited;
- let valueMaxLimited;
- let barSize;
- let baseFraction;
- let isLimited;
- let rangeMask;
- let $position;
- let { labelReset = "Reset" } = $$props;
- let { direction = "x" } = $$props;
- let { min = 0 } = $$props;
- let { max = 1 } = $$props;
- let { base = min } = $$props;
- let { value = 0 } = $$props;
- let { valueLabel = 0 } = $$props;
- let { valueMin = undefined } = $$props;
- let { valueMax = undefined } = $$props;
- let { oninputstart = noop$1 } = $$props;
- let { oninputmove = noop$1 } = $$props;
- let { oninputend = noop$1 } = $$props;
- let { elasticity = 0 } = $$props;
- const round = (number, increment, offset) => Math.ceil((number - offset) / increment) * increment + offset;
- let size;
- let svg;
- let svgSize;
- const svgPadding = { x: 2, y: 0 };
- const createPathCircle = (cx, cy, r) => `M ${cx - r} ${cy} a ${r} ${r} 0 1 0 0 -1`;
- function getMask(limitedMin, limitedMax) {
- const step = 1 / indicatorCount;
- const from = toFraction(limitedMin, min, max);
- const to = toFraction(limitedMax, min, max);
- const fromSnapped = fixPrecision(round(from, step, 0) - step * 0.5);
- const toSnapped = fixPrecision(round(to, step, 0) - step * 0.5);
- return `--range-mask-from:${fromSnapped * 100}%;--range-mask-to:${toSnapped * 100}%`;
- }
- //
- // Dragging related
- //
- let interactionOrigin = undefined;
- let interactionReleased = false;
- let interactionRange;
- let interactionOptions = { snap: false, elastic: false };
- const handleDragStart = () => {
- interactionReleased = false;
- interactionOrigin = get_store_value(position);
- interactionRange = [
- valueToPosition(valueMin != null ? valueMin : min, direction),
- valueToPosition(valueMax != null ? valueMax : max, direction)
- ];
- oninputstart();
- };
- const handleDragRelease = () => {
- interactionReleased = true;
- };
- const handleDragMove = ({ detail }) => {
- interactionOptions.snap = !interactionReleased;
- interactionOptions.elastic = !interactionReleased;
- translatePosition(interactionOrigin, detail.translation, interactionOptions);
- };
- const handleDragEnd = ({ detail }) => {
- interactionOptions.snap = false;
- interactionOptions.elastic = false;
- const valueAtPosition = translatePosition(interactionOrigin, detail.translation, interactionOptions);
- interactionOrigin = undefined;
- interactionRange = undefined;
- // if is near base position, set to base
- if (Math.abs(valueAtPosition - base) < 0.01) return oninputend(base);
- oninputend(valueAtPosition);
- };
- const translatePosition = (origin, translation, options) => {
- const target = origin[direction] + translation[direction];
- const targetLimited = clamp(target, interactionRange[1][direction], interactionRange[0][direction]);
- const targetElastic = elasticity
- ? targetLimited + elastify(target - targetLimited, elasticity)
- : targetLimited;
- const targetVisual = options.elastic ? targetElastic : targetLimited;
- // set position
- const targetValid = vectorCreate(0, 0);
- targetValid[direction] = targetVisual;
- position.set(targetValid, { hard: options.snap });
- return clamp(positionToValue(targetValid, direction), min, max);
- };
- const handleReset = () => {
- $$invalidate(0, value = clamp(base, valueMinLimited, valueMaxLimited));
- oninputstart();
- oninputend(value);
- };
- //
- // Meter position and value updates
- //
- const position = spring();
- component_subscribe($$self, position, value => $$invalidate(8, $position = value));
- const valueToPosition = (value, axis) => {
- const offset = (size[axis] - barSize[axis]) * 0.5;
- const fraction = toFraction(value, min, max);
- const v = fraction * barSize[axis] - barSize[axis] * 0.5;
- const pos = offset - v;
- return {
- x: axis === "x" ? pos : 0,
- y: axis === "y" ? pos : 0
- };
- };
- const positionToValue = (position, axis) => {
- const dist = position[axis] - size[axis] * 0.5;
- const fraction = -(dist / barSize[axis]);
- return min + fraction * range;
- };
- position.subscribe(currentPosition => {
- // if not positioned yet or is not interacting we're not interested in this event
- if (!currentPosition || !interactionOrigin) return;
- oninputmove(clamp(positionToValue(currentPosition, direction), min, max));
- });
- const updatePosition = value => {
- const interactionRange = [
- valueToPosition(valueMin != null ? valueMin : min, direction),
- valueToPosition(valueMax != null ? valueMax : max, direction)
- ];
- const target = {
- x: direction === "x" ? $position.x + value : 0,
- y: direction === "y" ? $position.y + value : 0
- };
- const targetLimited = clamp(target[direction], interactionRange[1][direction], interactionRange[0][direction]);
- const positionTarget = { ...$position, [direction]: targetLimited };
- set_store_value(position, $position = positionTarget, $position);
- const result = clamp(positionToValue(positionTarget, direction), min, max);
- oninputstart();
- oninputmove(result);
- oninputend(result);
- };
- const handleWheel = e => {
- // don't run default actions, prevent other actions from running
- e.preventDefault();
- e.stopPropagation();
- // apply wheel delta to offset
- const step = 8;
- const delta = getWheelDelta(e) * step;
- updatePosition(delta);
- };
- const handleNudge = ({ detail }) => {
- updatePosition(detail[direction] * 8);
- };
- const measure_handler = e => $$invalidate(4, size = vectorCreateFromSize(e.detail));
- $$self.$$set = $$props => {
- if ("labelReset" in $$props) $$invalidate(1, labelReset = $$props.labelReset);
- if ("direction" in $$props) $$invalidate(18, direction = $$props.direction);
- if ("min" in $$props) $$invalidate(19, min = $$props.min);
- if ("max" in $$props) $$invalidate(20, max = $$props.max);
- if ("base" in $$props) $$invalidate(2, base = $$props.base);
- if ("value" in $$props) $$invalidate(0, value = $$props.value);
- if ("valueLabel" in $$props) $$invalidate(3, valueLabel = $$props.valueLabel);
- if ("valueMin" in $$props) $$invalidate(21, valueMin = $$props.valueMin);
- if ("valueMax" in $$props) $$invalidate(22, valueMax = $$props.valueMax);
- if ("oninputstart" in $$props) $$invalidate(23, oninputstart = $$props.oninputstart);
- if ("oninputmove" in $$props) $$invalidate(24, oninputmove = $$props.oninputmove);
- if ("oninputend" in $$props) $$invalidate(25, oninputend = $$props.oninputend);
- if ("elasticity" in $$props) $$invalidate(26, elasticity = $$props.elasticity);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*max, min*/ 1572864) {
- //
- // derived
- //
- $$invalidate(28, range = max - min);
- }
- if ($$self.$$.dirty[0] & /*valueMin, min*/ 2621440) {
- $$invalidate(29, valueMinLimited = valueMin != null ? Math.max(valueMin, min) : min);
- }
- if ($$self.$$.dirty[0] & /*valueMax, max*/ 5242880) {
- $$invalidate(30, valueMaxLimited = valueMax != null ? Math.min(valueMax, max) : max);
- }
- if ($$self.$$.dirty[0] & /*base, min, max*/ 1572868) {
- $$invalidate(31, baseFraction = toFraction(base, min, max));
- }
- if ($$self.$$.dirty[0] & /*size*/ 16 | $$self.$$.dirty[1] & /*baseFraction*/ 1) {
- if (size) {
- const centerY = size.y * 0.5;
- let indicatorCenter = indicatorCount * baseFraction;
- let d = "";
- let svgWidth;
- let svgHeight = size.y;
- let centerShape = "";
- for (let i = 0; i <= indicatorCount; i++) {
- const x = svgPadding.x + i * indicatorSpacing;
- const y = centerY;
- const r = i % indicatorInterval === 0 ? radiusBig : radiusSmall;
- d += createPathCircle(x, y, r) + " ";
- svgWidth = x + svgPadding.x;
- if (i === indicatorCenter) {
- centerShape = `<path d="M${x} ${y - 4} l2 3 l-2 -1 l-2 1 z"/>`;
- }
- }
- $$invalidate(6, svg = `<svg width="${svgWidth}" height="${svgHeight}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${svgWidth} ${svgHeight}" aria-hidden="true" focusable="false">
- ${centerShape}
- <rect rx="4" ry="4" y="${centerY - 4}"" height="8"/>
- <path fill-rule="evenodd" d="${d.trim()}"/></svg>`);
- $$invalidate(27, svgSize = {
- x: svgWidth - svgPadding.x * 2,
- y: svgHeight
- });
- }
- }
- if ($$self.$$.dirty[0] & /*size, svgSize*/ 134217744) {
- barSize = size && svgSize;
- }
- if ($$self.$$.dirty[0] & /*valueMinLimited, min, valueMaxLimited, max*/ 1612185600) {
- $$invalidate(5, isLimited = valueMinLimited !== min || valueMaxLimited !== max);
- }
- if ($$self.$$.dirty[0] & /*isLimited, valueMinLimited, valueMaxLimited*/ 1610612768) {
- $$invalidate(7, rangeMask = isLimited
- ? getMask(valueMinLimited, valueMaxLimited)
- : "");
- }
- if ($$self.$$.dirty[0] & /*range, size, value, direction*/ 268697617) {
- // if has size (range is in here so the position is updated if the range is changed)
- if (range && size && size.x && size.y) {
- position.set(valueToPosition(value, direction));
- }
- }
- };
- return [
- value,
- labelReset,
- base,
- valueLabel,
- size,
- isLimited,
- svg,
- rangeMask,
- $position,
- svgPadding,
- handleDragStart,
- handleDragRelease,
- handleDragMove,
- handleDragEnd,
- handleReset,
- position,
- handleWheel,
- handleNudge,
- direction,
- min,
- max,
- valueMin,
- valueMax,
- oninputstart,
- oninputmove,
- oninputend,
- elasticity,
- svgSize,
- range,
- valueMinLimited,
- valueMaxLimited,
- baseFraction,
- measure_handler
- ];
- }
- class RangeInput extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$p,
- create_fragment$p,
- safe_not_equal,
- {
- labelReset: 1,
- direction: 18,
- min: 19,
- max: 20,
- base: 2,
- value: 0,
- valueLabel: 3,
- valueMin: 21,
- valueMax: 22,
- oninputstart: 23,
- oninputmove: 24,
- oninputend: 25,
- elasticity: 26
- },
- [-1, -1]
- );
- }
- }
- /* src/core/ui/components/Toolbar.svelte generated by Svelte v3.37.0 */
- function create_fragment$o(ctx) {
- let div1;
- let div0;
- let current;
- let mounted;
- let dispose;
- const default_slot_template = /*#slots*/ ctx[7].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[6], null);
- return {
- c() {
- div1 = element("div");
- div0 = element("div");
- if (default_slot) default_slot.c();
- attr(div0, "class", "PinturaToolbarInner");
- attr(div1, "class", "PinturaToolbar");
- attr(div1, "data-layout", /*layout*/ ctx[1]);
- attr(div1, "data-overflow", /*overflow*/ ctx[0]);
- },
- m(target, anchor) {
- insert(target, div1, anchor);
- append(div1, div0);
- if (default_slot) {
- default_slot.m(div0, null);
- }
- current = true;
- if (!mounted) {
- dispose = [
- listen(div0, "measure", /*handleChildResizeEvent*/ ctx[3]),
- action_destroyer(measurable.call(null, div0)),
- listen(div1, "measure", /*handleParentResizeEvent*/ ctx[2]),
- action_destroyer(measurable.call(null, div1))
- ];
- mounted = true;
- }
- },
- p(ctx, [dirty]) {
- if (default_slot) {
- if (default_slot.p && dirty & /*$$scope*/ 64) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[6], dirty, null, null);
- }
- }
- if (!current || dirty & /*layout*/ 2) {
- attr(div1, "data-layout", /*layout*/ ctx[1]);
- }
- if (!current || dirty & /*overflow*/ 1) {
- attr(div1, "data-overflow", /*overflow*/ ctx[0]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(default_slot, local);
- current = true;
- },
- o(local) {
- transition_out(default_slot, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div1);
- if (default_slot) default_slot.d(detaching);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function instance$o($$self, $$props, $$invalidate) {
- let layout;
- let { $$slots: slots = {}, $$scope } = $$props;
- let childWidth = 0;
- let childMaxWidth = 0;
- let parentWidth = 0;
- let overflow;
- const testOverflow = () => {
- $$invalidate(0, overflow = layout === "compact" && childWidth > parentWidth
- ? "overflow"
- : undefined);
- };
- const handleParentResizeEvent = ({ detail }) => {
- const { width } = detail;
- $$invalidate(5, parentWidth = width);
- testOverflow();
- };
- const handleChildResizeEvent = ({ detail }) => {
- const { width } = detail;
- if (width > childMaxWidth) {
- $$invalidate(4, childMaxWidth = width);
- }
- childWidth = width;
- if (!overflow) testOverflow();
- };
- $$self.$$set = $$props => {
- if ("$$scope" in $$props) $$invalidate(6, $$scope = $$props.$$scope);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*childMaxWidth, parentWidth*/ 48) {
- $$invalidate(1, layout = childMaxWidth > parentWidth ? "compact" : "default");
- }
- };
- return [
- overflow,
- layout,
- handleParentResizeEvent,
- handleChildResizeEvent,
- childMaxWidth,
- parentWidth,
- $$scope,
- slots
- ];
- }
- class Toolbar extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$o, create_fragment$o, safe_not_equal, {});
- }
- }
- // enum Direction {
- // Top = 't',
- // Right = 'r',
- // Bottom = 'b',
- // Left = 'l',
- // TopLeft = 'tl',
- // TopRight = 'tr',
- // BottomRight = 'br',
- // BottomLeft = 'bl',
- // }
- // export const { Top, Right, Bottom, Left, TopLeft, TopRight, BottomRight, BottomLeft } = Direction;
- // export default Direction;
- const Direction = {
- Top: 't',
- Right: 'r',
- Bottom: 'b',
- Left: 'l',
- TopLeft: 'tl',
- TopRight: 'tr',
- BottomRight: 'br',
- BottomLeft: 'bl',
- };
- const { Top, Right, Bottom, Left, TopLeft, TopRight, BottomRight, BottomLeft } = Direction;
- var DirectionRectMap = {
- [Top]: (rect) => ({ x: rect.x, y: rect.y }),
- [TopRight]: (rect) => ({ x: rect.x + rect.width, y: rect.y }),
- [Right]: (rect) => ({ x: rect.x + rect.width, y: rect.y }),
- [BottomRight]: (rect) => ({ x: rect.x + rect.width, y: rect.y + rect.height }),
- [Bottom]: (rect) => ({ x: rect.x, y: rect.y + rect.height }),
- [BottomLeft]: (rect) => ({ x: rect.x, y: rect.y + rect.height }),
- [Left]: (rect) => ({ x: rect.x, y: rect.y }),
- [TopLeft]: (rect) => ({ x: rect.x, y: rect.y }),
- };
- /* src/core/ui/components/RectManipulator.svelte generated by Svelte v3.37.0 */
- function get_each_context$5(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[12] = list[i].key;
- child_ctx[13] = list[i].translate;
- child_ctx[14] = list[i].scale;
- child_ctx[15] = list[i].type;
- child_ctx[16] = list[i].opacity;
- return child_ctx;
- }
- // (107:0) {#each mappedDirections as { key, translate, scale, type, opacity }
- function create_each_block$5(key_1, ctx) {
- let div;
- let div_aria_label_value;
- let div_tabindex_value;
- let div_data_direction_value;
- let div_data_shape_value;
- let div_style_value;
- let mounted;
- let dispose;
- return {
- key: key_1,
- first: null,
- c() {
- div = element("div");
- attr(div, "role", "button");
- attr(div, "aria-label", div_aria_label_value = `Drag ${/*type*/ ctx[15]} ${/*key*/ ctx[12]}`);
- attr(div, "tabindex", div_tabindex_value = /*type*/ ctx[15] === "edge" ? -1 : 0);
- attr(div, "class", "PinturaRectManipulator");
- attr(div, "data-direction", div_data_direction_value = /*key*/ ctx[12]);
- attr(div, "data-shape", div_data_shape_value = `${/*type*/ ctx[15] === "edge"
- ? "edge"
- : `${/*style*/ ctx[0]}`}`);
- attr(div, "style", div_style_value = `transform: translate3d(${/*translate*/ ctx[13].x}px, ${/*translate*/ ctx[13].y}px, 0) scale(${/*scale*/ ctx[14].x}, ${/*scale*/ ctx[14].y}); opacity: ${/*opacity*/ ctx[16]}`);
- this.first = div;
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (!mounted) {
- dispose = [
- listen(div, "nudge", function () {
- if (is_function(/*nudge*/ ctx[5](/*key*/ ctx[12]))) /*nudge*/ ctx[5](/*key*/ ctx[12]).apply(this, arguments);
- }),
- action_destroyer(nudgeable.call(null, div)),
- listen(div, "interactionstart", function () {
- if (is_function(/*route*/ ctx[4]("resizestart", /*key*/ ctx[12]))) /*route*/ ctx[4]("resizestart", /*key*/ ctx[12]).apply(this, arguments);
- }),
- listen(div, "interactionupdate", function () {
- if (is_function(/*route*/ ctx[4]("resizemove", /*key*/ ctx[12]))) /*route*/ ctx[4]("resizemove", /*key*/ ctx[12]).apply(this, arguments);
- }),
- listen(div, "interactionend", function () {
- if (is_function(/*route*/ ctx[4]("resizeend", /*key*/ ctx[12]))) /*route*/ ctx[4]("resizeend", /*key*/ ctx[12]).apply(this, arguments);
- }),
- action_destroyer(interactable.call(null, div))
- ];
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- if (dirty & /*mappedDirections*/ 2 && div_aria_label_value !== (div_aria_label_value = `Drag ${/*type*/ ctx[15]} ${/*key*/ ctx[12]}`)) {
- attr(div, "aria-label", div_aria_label_value);
- }
- if (dirty & /*mappedDirections*/ 2 && div_tabindex_value !== (div_tabindex_value = /*type*/ ctx[15] === "edge" ? -1 : 0)) {
- attr(div, "tabindex", div_tabindex_value);
- }
- if (dirty & /*mappedDirections*/ 2 && div_data_direction_value !== (div_data_direction_value = /*key*/ ctx[12])) {
- attr(div, "data-direction", div_data_direction_value);
- }
- if (dirty & /*mappedDirections, style*/ 3 && div_data_shape_value !== (div_data_shape_value = `${/*type*/ ctx[15] === "edge"
- ? "edge"
- : `${/*style*/ ctx[0]}`}`)) {
- attr(div, "data-shape", div_data_shape_value);
- }
- if (dirty & /*mappedDirections*/ 2 && div_style_value !== (div_style_value = `transform: translate3d(${/*translate*/ ctx[13].x}px, ${/*translate*/ ctx[13].y}px, 0) scale(${/*scale*/ ctx[14].x}, ${/*scale*/ ctx[14].y}); opacity: ${/*opacity*/ ctx[16]}`)) {
- attr(div, "style", div_style_value);
- }
- },
- d(detaching) {
- if (detaching) detach(div);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function create_fragment$n(ctx) {
- let each_blocks = [];
- let each_1_lookup = new Map();
- let each_1_anchor;
- let each_value = /*mappedDirections*/ ctx[1];
- const get_key = ctx => /*key*/ ctx[12];
- for (let i = 0; i < each_value.length; i += 1) {
- let child_ctx = get_each_context$5(ctx, each_value, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block$5(key, child_ctx));
- }
- return {
- c() {
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- each_1_anchor = empty();
- },
- m(target, anchor) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].m(target, anchor);
- }
- insert(target, each_1_anchor, anchor);
- },
- p(ctx, [dirty]) {
- if (dirty & /*mappedDirections, style, nudge, route*/ 51) {
- each_value = /*mappedDirections*/ ctx[1];
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, destroy_block, create_each_block$5, each_1_anchor, get_each_context$5);
- }
- },
- i: noop,
- o: noop,
- d(detaching) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d(detaching);
- }
- if (detaching) detach(each_1_anchor);
- }
- };
- }
- function instance$n($$self, $$props, $$invalidate) {
- let mappedDirections;
- let $selectionScale;
- let $selectionOpacity;
- let { rect = null } = $$props;
- let { visible = false } = $$props;
- let { style = undefined } = $$props;
- // is `undefined` to prevent bounce when first rendering view
- const selectionScale = spring(undefined, {
- precision: 0.0001,
- stiffness: 0.2,
- damping: 0.4
- });
- component_subscribe($$self, selectionScale, value => $$invalidate(8, $selectionScale = value));
- const selectionOpacity = spring(0, { precision: 0.001 });
- component_subscribe($$self, selectionOpacity, value => $$invalidate(9, $selectionOpacity = value));
- //
- // dragging
- //
- let currentDirection;
- const dispatch = createEventDispatcher();
- const route = (type, direction) => ({ detail }) => {
- // don't handle other interactions while manipulating on axis
- if (currentDirection && direction !== currentDirection) return;
- // ignore move and end events if no direction has been set
- if (type !== "resizestart" && currentDirection === undefined) return;
- // set new direction
- if (type === "resizestart") currentDirection = direction;
- // release direction
- if (type === "resizeend") currentDirection = undefined;
- dispatch(type, {
- direction,
- translation: detail && detail.translation
- });
- };
- const nudge = direction => ({ detail }) => {
- dispatch(`resizestart`, { direction, translation: { x: 0, y: 0 } });
- dispatch(`resizemove`, { direction, translation: detail });
- dispatch(`resizeend`, { direction, translation: { x: 0, y: 0 } });
- };
- $$self.$$set = $$props => {
- if ("rect" in $$props) $$invalidate(6, rect = $$props.rect);
- if ("visible" in $$props) $$invalidate(7, visible = $$props.visible);
- if ("style" in $$props) $$invalidate(0, style = $$props.style);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*visible*/ 128) {
- selectionScale.set(visible ? 1 : 0.5);
- }
- if ($$self.$$.dirty & /*visible*/ 128) {
- selectionOpacity.set(visible ? 1 : 0);
- }
- if ($$self.$$.dirty & /*rect, $selectionScale, $selectionOpacity*/ 832) {
- //
- // rendering
- //
- $$invalidate(1, mappedDirections = Object.keys(Direction).map((key, i) => {
- // get direction enum
- const direction = Direction[key];
- // get position from direction
- const position = DirectionRectMap[direction](rect);
- // corner or edge
- const type = direction.length === 1 ? "edge" : "corner";
- const isCorner = type === "corner";
- return {
- key: direction,
- type,
- scale: {
- x: (/^(t|b)$/).test(direction)
- ? rect.width
- : isCorner ? clamp($selectionScale, 0.5, 1.25) : 1,
- y: (/^(r|l)$/).test(direction)
- ? rect.height
- : isCorner ? clamp($selectionScale, 0.5, 1.25) : 1
- },
- translate: { x: position.x, y: position.y },
- opacity: $selectionOpacity
- };
- }));
- }
- };
- return [
- style,
- mappedDirections,
- selectionScale,
- selectionOpacity,
- route,
- nudge,
- rect,
- visible,
- $selectionScale,
- $selectionOpacity
- ];
- }
- class RectManipulator extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$n, create_fragment$n, safe_not_equal, { rect: 6, visible: 7, style: 0 });
- }
- }
- var gesturable = (element) => {
- function dispatch(type, detail) {
- element.dispatchEvent(new CustomEvent(type, { detail }));
- }
- const handleGestureStart = (e) => {
- e.preventDefault();
- element.addEventListener('gesturechange', handleGestureChange);
- element.addEventListener('gestureend', handleGestureEnd);
- dispatch('gesturedown');
- };
- const handleGestureChange = (e) => {
- e.preventDefault();
- dispatch('gestureupdate', e.scale);
- };
- const handleGestureEnd = (e) => {
- dispatch('gestureup', e.scale);
- e.preventDefault();
- clean();
- };
- const clean = () => {
- element.removeEventListener('gesturechange', handleGestureChange);
- element.removeEventListener('gestureend', handleGestureEnd);
- };
- element.addEventListener('gesturestart', handleGestureStart);
- return {
- destroy: () => {
- clean();
- element.removeEventListener('gesturestart', handleGestureStart);
- },
- };
- };
- var getEventPositionInViewport = (e) => vectorCreate(e.clientX, e.clientY);
- var getEventPositionInStage = (e, viewOffset, stageOffset) => {
- const positionInViewport = getEventPositionInViewport(e);
- return vectorSubtract(vectorSubtract(positionInViewport, viewOffset), stageOffset);
- };
- var DirectionInversionTable = {
- [Top]: Bottom,
- [Right]: Left,
- [Bottom]: Top,
- [Left]: Right,
- [TopLeft]: BottomRight,
- [TopRight]: BottomLeft,
- [BottomRight]: TopLeft,
- [BottomLeft]: TopRight,
- };
- var DirectionCoordinateTable = {
- [Top]: [0.5, 0],
- [Right]: [1, 0.5],
- [Bottom]: [0.5, 1],
- [Left]: [0, 0.5],
- [TopLeft]: [0, 0],
- [TopRight]: [1, 0],
- [BottomRight]: [1, 1],
- [BottomLeft]: [0, 1],
- };
- var getTranslationInfo = (target) => {
- const translateToRight = target === Right || target === TopRight || target === BottomRight;
- const translateToLeft = target === Left || target === BottomLeft || target === TopLeft;
- const translateToTop = target === Top || target === TopRight || target === TopLeft;
- const translateToBottom = target === Bottom || target === BottomRight || target === BottomLeft;
- const translateHorizontally = target === Left || target === Right;
- const translateVertically = target === Top || target === Bottom;
- const translateAxis = translateHorizontally || translateVertically;
- return [
- translateToRight,
- translateToLeft,
- translateToTop,
- translateToBottom,
- translateHorizontally,
- translateVertically,
- translateAxis,
- ];
- };
- var limitRectDirectionTranslation = (rect, transform, bounds, options = {}) => {
- // the transforms to apply
- const { target, translate } = transform;
- // the transform requirements
- const { aspectRatio, minSize, maxSize } = options;
- // get anchor coordinates and x,y position we need this for relative scaling of the view rectangle
- const anchor = DirectionInversionTable[target];
- const anchorDirectionCoordinates = DirectionCoordinateTable[anchor];
- const anchorPosition = vectorAdd(vectorCreate(rect.x, rect.y), vectorCreate(anchorDirectionCoordinates[0] * rect.width, anchorDirectionCoordinates[1] * rect.height));
- // get coordinate of direction
- const targetDirectionCoordinates = DirectionCoordinateTable[target];
- const targetPosition = vectorAdd(rectClone(rect), vectorCreate(targetDirectionCoordinates[0] * rect.width, targetDirectionCoordinates[1] * rect.height));
- // bools to determine which direction the interaction is moving in
- const [translateToRight, translateToLeft, translateToTop, translateToBottom, translateHorizontally, translateVertically, translateAxis,] = getTranslationInfo(target);
- let tx = translate.x;
- let ty = translate.y;
- if (translateHorizontally)
- ty = 0;
- else if (translateVertically)
- tx = 0;
- const interactionBounds = getInteractionBounds(anchorPosition, target, bounds, {
- aspectRatio,
- minSize,
- maxSize,
- });
- // current bounds
- let [t, r, b, l] = rectToBounds(rect);
- // update view bounds with anchor based on translation direction (one side is always locked)
- if (translateToRight)
- l = anchorPosition.x;
- else if (translateToLeft)
- r = anchorPosition.x;
- if (translateToBottom)
- t = anchorPosition.y;
- else if (translateToTop)
- b = anchorPosition.y;
- // update view bounds with interaction limits
- if (translateToRight) {
- const innerR = interactionBounds.inner.x + interactionBounds.inner.width;
- const outerR = interactionBounds.outer.x + interactionBounds.outer.width;
- r = clamp(targetPosition.x + tx, innerR, outerR);
- }
- else if (translateToLeft) {
- const innerL = interactionBounds.outer.x;
- const outerL = interactionBounds.inner.x;
- l = clamp(targetPosition.x + tx, innerL, outerL);
- }
- if (translateToBottom) {
- const innerB = interactionBounds.inner.y + interactionBounds.inner.height;
- const outerB = interactionBounds.outer.y + interactionBounds.outer.height;
- b = clamp(targetPosition.y + ty, innerB, outerB);
- }
- else if (translateToTop) {
- const innerT = interactionBounds.outer.y;
- const outerT = interactionBounds.inner.y;
- t = clamp(targetPosition.y + ty, innerT, outerT);
- }
- // if aspect ratio is set we need to scale both axis
- if (aspectRatio) {
- // if translating over horizontal or vertical axis we need to update the other axis based on the aspect ratio as well
- if (translateAxis) {
- let dx = r - l;
- let dy = b - t;
- if (translateHorizontally) {
- dy = dx / aspectRatio;
- t = anchorPosition.y - dy * 0.5;
- b = anchorPosition.y + dy * 0.5;
- }
- else if (translateVertically) {
- dx = dy * aspectRatio;
- l = anchorPosition.x - dx * 0.5;
- r = anchorPosition.x + dx * 0.5;
- }
- }
- // we're translating one of the corners in both the x and y direction, need to make sure it conforms to aspect ratio
- else {
- const pointer = vectorCreate(targetPosition.x + tx - anchorPosition.x, targetPosition.y + ty - anchorPosition.y);
- // translations cannot be inverted, limited by anchor position
- if (target === TopRight) {
- pointer.x = Math.max(0, pointer.x);
- pointer.y = Math.min(0, pointer.y);
- }
- else if (target === BottomRight) {
- pointer.x = Math.max(0, pointer.x);
- pointer.y = Math.max(0, pointer.y);
- }
- else if (target === BottomLeft) {
- pointer.x = Math.min(0, pointer.x);
- pointer.y = Math.max(0, pointer.y);
- }
- else if (target === TopLeft) {
- pointer.x = Math.min(0, pointer.x);
- pointer.y = Math.min(0, pointer.y);
- }
- // calculate the translation pointer, then get its length, now create a new pointer based on the aspect ratio, and scale it based on the original (limited) length
- const pointerLength = vectorLength(pointer);
- const pointerLengthMin = vectorLength(vectorCreate(interactionBounds.inner.width, interactionBounds.inner.height));
- const pointerLengthMax = vectorLength(vectorCreate(interactionBounds.outer.width, interactionBounds.outer.height));
- const pointerLengthLimited = clamp(pointerLength, pointerLengthMin, pointerLengthMax);
- const pointerAspectRatio = vectorCreate(aspectRatio, 1);
- const pointerScaled = vectorMultiply(vectorNormalize(pointerAspectRatio), pointerLengthLimited);
- if (target === TopRight) {
- r = anchorPosition.x + pointerScaled.x;
- t = anchorPosition.y - pointerScaled.y;
- }
- else if (target === BottomRight) {
- r = anchorPosition.x + pointerScaled.x;
- b = anchorPosition.y + pointerScaled.y;
- }
- else if (target === BottomLeft) {
- l = anchorPosition.x - pointerScaled.x;
- b = anchorPosition.y + pointerScaled.y;
- }
- else if (target === TopLeft) {
- l = anchorPosition.x - pointerScaled.x;
- t = anchorPosition.y - pointerScaled.y;
- }
- }
- }
- return rectCreate(l, t, r - l, b - t);
- };
- const getInteractionBounds = (anchor, dir, bounds, options) => {
- const { aspectRatio, minSize, maxSize } = options;
- const translateToRight = dir === Right || dir === TopRight || dir === BottomRight;
- const translateToLeft = dir === Left || dir === BottomLeft || dir === TopLeft;
- const translateToTop = dir === Top || dir === TopRight || dir === TopLeft;
- const translateToBottom = dir === Bottom || dir === BottomRight || dir === BottomLeft;
- const translateHorizontally = dir === Left || dir === Right;
- const translateVertically = dir === Top || dir === Bottom;
- // limit bounds based on anchor and direction
- const limitedBounds = rectClone(bounds);
- if (translateToRight) {
- limitedBounds.x = anchor.x;
- limitedBounds.width -= anchor.x;
- }
- else if (translateToLeft) {
- limitedBounds.width = anchor.x;
- }
- if (translateToBottom) {
- limitedBounds.y = anchor.y;
- limitedBounds.height -= anchor.y;
- }
- else if (translateToTop) {
- limitedBounds.height = anchor.y;
- }
- // limit max size based on bounds
- const maxSizeLimitedToBounds = rectCreateFromDimensions(Math.min(limitedBounds.width, maxSize.width), Math.min(limitedBounds.height, maxSize.height));
- if (aspectRatio) {
- // limit height
- if (translateHorizontally) {
- const verticalSpace = Math.min(anchor.y, bounds.height - anchor.y);
- maxSizeLimitedToBounds.height = Math.min(verticalSpace * 2, maxSizeLimitedToBounds.height);
- }
- // limit width
- else if (translateVertically) {
- const horizontalSpace = Math.min(anchor.x, bounds.width - anchor.x);
- maxSizeLimitedToBounds.width = Math.min(horizontalSpace * 2, maxSizeLimitedToBounds.width);
- }
- }
- const maxSizeLimited = aspectRatio
- ? sizeCreateFromRect(rectContainRect(maxSizeLimitedToBounds, aspectRatio))
- : maxSizeLimitedToBounds;
- // limit min size
- const minSizeLimited = aspectRatio
- ? sizeCreateFromRect(rectCoverRect(rectCreateFromSize(minSize), aspectRatio))
- : minSize;
- let l, r, t, b;
- // set bounds
- if (translateToRight)
- l = anchor.x;
- else if (translateToLeft)
- r = anchor.x;
- if (translateToBottom)
- t = anchor.y;
- else if (translateToTop)
- b = anchor.y;
- // inner
- if (translateToRight) {
- r = l + minSizeLimited.width;
- }
- else if (translateToLeft) {
- l = r - minSizeLimited.width;
- }
- if (translateToBottom) {
- b = t + minSizeLimited.height;
- }
- else if (translateToTop) {
- t = b - minSizeLimited.height;
- }
- if (translateHorizontally) {
- t = anchor.y - minSizeLimited.height * 0.5;
- b = anchor.y + minSizeLimited.height * 0.5;
- }
- else if (translateVertically) {
- l = anchor.x - minSizeLimited.width * 0.5;
- r = anchor.x + minSizeLimited.width * 0.5;
- }
- const inner = rectCreateFromPoints(vectorCreate(l, t), vectorCreate(r, b));
- // outer
- if (translateToRight) {
- r = l + maxSizeLimited.width;
- }
- else if (translateToLeft) {
- l = r - maxSizeLimited.width;
- }
- if (translateToBottom) {
- b = t + maxSizeLimited.height;
- }
- else if (translateToTop) {
- t = b - maxSizeLimited.height;
- }
- if (translateHorizontally) {
- t = anchor.y - maxSizeLimited.height * 0.5;
- b = anchor.y + maxSizeLimited.height * 0.5;
- }
- else if (translateVertically) {
- l = anchor.x - maxSizeLimited.width * 0.5;
- r = anchor.x + maxSizeLimited.width * 0.5;
- }
- const outer = rectCreateFromPoints(vectorCreate(l, t), vectorCreate(r, b));
- return {
- inner,
- outer,
- };
- };
- var applyRectDirectionTranslation = (rect, transform, options = {}) => {
- // the transforms to apply
- const { target, translate } = transform;
- // the transform requirements
- const { aspectRatio } = options;
- // get anchor coordinates and x,y position we need this for relative scaling of the view rectangle
- const anchor = DirectionInversionTable[target];
- const anchorDirectionCoordinates = DirectionCoordinateTable[anchor];
- const anchorPosition = vectorAdd(rectClone(rect), vectorCreate(anchorDirectionCoordinates[0] * rect.width, anchorDirectionCoordinates[1] * rect.height));
- // get coordinate of direction
- const targetDirectionCoordinates = DirectionCoordinateTable[target];
- const targetPosition = vectorAdd(rectClone(rect), vectorCreate(targetDirectionCoordinates[0] * rect.width, targetDirectionCoordinates[1] * rect.height));
- // bools to determine which direction the interaction is moving in
- const [translateToRight, translateToLeft, translateToTop, translateToBottom, translateHorizontally, translateVertically, translateAxis,] = getTranslationInfo(target);
- let tx = translate.x;
- let ty = translate.y;
- if (translateHorizontally)
- ty = 0;
- else if (translateVertically)
- tx = 0;
- // current bounds
- let [t, r, b, l] = rectToBounds(rect);
- // update view bounds with anchor based on translation direction (one side is always locked)
- if (translateToRight)
- l = anchorPosition.x;
- else if (translateToLeft)
- r = anchorPosition.x;
- if (translateToBottom)
- t = anchorPosition.y;
- else if (translateToTop)
- b = anchorPosition.y;
- // update view bounds with interaction limits
- if (translateToRight) {
- r = targetPosition.x + tx;
- }
- else if (translateToLeft) {
- l = targetPosition.x + tx;
- }
- if (translateToBottom) {
- b = targetPosition.y + ty;
- }
- else if (translateToTop) {
- t = targetPosition.y + ty;
- }
- // if aspect ratio is set we need to scale both axis
- if (aspectRatio) {
- // if translating over horizontal or vertical axis we need to update the other axis based on the aspect ratio as well
- if (translateAxis) {
- let dx = r - l;
- let dy = b - t;
- if (translateHorizontally) {
- dy = dx / aspectRatio;
- t = anchorPosition.y - dy * 0.5;
- b = anchorPosition.y + dy * 0.5;
- }
- else if (translateVertically) {
- dx = dy * aspectRatio;
- l = anchorPosition.x - dx * 0.5;
- r = anchorPosition.x + dx * 0.5;
- }
- }
- // we're translating one of the corners in both the x and y direction, need to make sure it conforms to aspect ratio
- else {
- const pointer = vectorCreate(targetPosition.x + tx - anchorPosition.x, targetPosition.y + ty - anchorPosition.y);
- // translations cannot be inverted, limited by anchor position
- if (target === TopRight) {
- pointer.x = Math.max(0, pointer.x);
- pointer.y = Math.min(0, pointer.y);
- }
- else if (target === BottomRight) {
- pointer.x = Math.max(0, pointer.x);
- pointer.y = Math.max(0, pointer.y);
- }
- else if (target === BottomLeft) {
- pointer.x = Math.min(0, pointer.x);
- pointer.y = Math.max(0, pointer.y);
- }
- else if (target === TopLeft) {
- pointer.x = Math.min(0, pointer.x);
- pointer.y = Math.min(0, pointer.y);
- }
- // calculate the translation pointer, then get its length, now create a new pointer based on the aspect ratio, and scale it based on the original (limited) length
- const pointerLength = vectorLength(pointer);
- const pointerAspectRatio = vectorCreate(aspectRatio, 1);
- const pointerScaled = vectorMultiply(vectorNormalize(pointerAspectRatio), pointerLength);
- if (target === TopRight) {
- r = anchorPosition.x + pointerScaled.x;
- t = anchorPosition.y - pointerScaled.y;
- }
- else if (target === BottomRight) {
- r = anchorPosition.x + pointerScaled.x;
- b = anchorPosition.y + pointerScaled.y;
- }
- else if (target === BottomLeft) {
- l = anchorPosition.x - pointerScaled.x;
- b = anchorPosition.y + pointerScaled.y;
- }
- else if (target === TopLeft) {
- l = anchorPosition.x - pointerScaled.x;
- t = anchorPosition.y - pointerScaled.y;
- }
- }
- }
- return rectCreate(l, t, r - l, b - t);
- };
- var radToDeg = (rad) => rad * 180 / Math.PI;
- /* src/core/ui/plugins/crop/components/ImageRotator.svelte generated by Svelte v3.37.0 */
- function create_fragment$m(ctx) {
- let div;
- let rangeinput;
- let current;
- rangeinput = new RangeInput({
- props: {
- elasticity: /*elasticity*/ ctx[5],
- min: /*min*/ ctx[7],
- max: /*max*/ ctx[8],
- value: /*value*/ ctx[12],
- valueMin: /*valueMin*/ ctx[0],
- valueMax: /*valueMax*/ ctx[1],
- labelReset: /*labelReset*/ ctx[6],
- base: /*center*/ ctx[11],
- valueLabel: `${Math.round(radToDeg(/*value*/ ctx[12]))}°`,
- oninputstart: /*oninputstart*/ ctx[2],
- oninputmove: /*func*/ ctx[14],
- oninputend: /*func_1*/ ctx[15]
- }
- });
- return {
- c() {
- div = element("div");
- create_component(rangeinput.$$.fragment);
- attr(div, "class", "PinturaImageRotator");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(rangeinput, div, null);
- current = true;
- },
- p(ctx, [dirty]) {
- const rangeinput_changes = {};
- if (dirty & /*elasticity*/ 32) rangeinput_changes.elasticity = /*elasticity*/ ctx[5];
- if (dirty & /*min*/ 128) rangeinput_changes.min = /*min*/ ctx[7];
- if (dirty & /*max*/ 256) rangeinput_changes.max = /*max*/ ctx[8];
- if (dirty & /*value*/ 4096) rangeinput_changes.value = /*value*/ ctx[12];
- if (dirty & /*valueMin*/ 1) rangeinput_changes.valueMin = /*valueMin*/ ctx[0];
- if (dirty & /*valueMax*/ 2) rangeinput_changes.valueMax = /*valueMax*/ ctx[1];
- if (dirty & /*labelReset*/ 64) rangeinput_changes.labelReset = /*labelReset*/ ctx[6];
- if (dirty & /*center*/ 2048) rangeinput_changes.base = /*center*/ ctx[11];
- if (dirty & /*value*/ 4096) rangeinput_changes.valueLabel = `${Math.round(radToDeg(/*value*/ ctx[12]))}°`;
- if (dirty & /*oninputstart*/ 4) rangeinput_changes.oninputstart = /*oninputstart*/ ctx[2];
- if (dirty & /*oninputmove, sign, turns*/ 1544) rangeinput_changes.oninputmove = /*func*/ ctx[14];
- if (dirty & /*oninputend, sign, turns*/ 1552) rangeinput_changes.oninputend = /*func_1*/ ctx[15];
- rangeinput.$set(rangeinput_changes);
- },
- i(local) {
- if (current) return;
- transition_in(rangeinput.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(rangeinput.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(rangeinput);
- }
- };
- }
- const MARGIN = 1e-9;
- function instance$m($$self, $$props, $$invalidate) {
- let min;
- let max;
- let center;
- let sign;
- let turns;
- let value;
- const HALF_PI = Math.PI / 2;
- const QUARTER_PI = Math.PI / 4;
- let { rotation } = $$props;
- let { valueMin } = $$props;
- let { valueMax } = $$props;
- let { oninputstart = noop$1 } = $$props;
- let { oninputmove = noop$1 } = $$props;
- let { oninputend = noop$1 } = $$props;
- let { elasticity = 0 } = $$props;
- let { labelReset = undefined } = $$props;
- const func = value => oninputmove(sign * turns + value);
- const func_1 = value => oninputend(sign * turns + value);
- $$self.$$set = $$props => {
- if ("rotation" in $$props) $$invalidate(13, rotation = $$props.rotation);
- if ("valueMin" in $$props) $$invalidate(0, valueMin = $$props.valueMin);
- if ("valueMax" in $$props) $$invalidate(1, valueMax = $$props.valueMax);
- if ("oninputstart" in $$props) $$invalidate(2, oninputstart = $$props.oninputstart);
- if ("oninputmove" in $$props) $$invalidate(3, oninputmove = $$props.oninputmove);
- if ("oninputend" in $$props) $$invalidate(4, oninputend = $$props.oninputend);
- if ("elasticity" in $$props) $$invalidate(5, elasticity = $$props.elasticity);
- if ("labelReset" in $$props) $$invalidate(6, labelReset = $$props.labelReset);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*min, max*/ 384) {
- $$invalidate(11, center = min + (max - min) * 0.5);
- }
- if ($$self.$$.dirty & /*rotation*/ 8192) {
- $$invalidate(9, sign = Math.sign(rotation));
- }
- if ($$self.$$.dirty & /*rotation*/ 8192) {
- $$invalidate(10, turns = Math.round(Math.abs(rotation) / HALF_PI) * HALF_PI);
- }
- if ($$self.$$.dirty & /*rotation, sign, turns*/ 9728) {
- $$invalidate(12, value = rotation - sign * turns);
- }
- };
- $$invalidate(7, min = -QUARTER_PI + MARGIN);
- $$invalidate(8, max = QUARTER_PI - MARGIN);
- return [
- valueMin,
- valueMax,
- oninputstart,
- oninputmove,
- oninputend,
- elasticity,
- labelReset,
- min,
- max,
- sign,
- turns,
- center,
- value,
- rotation,
- func,
- func_1
- ];
- }
- class ImageRotator extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$m, create_fragment$m, safe_not_equal, {
- rotation: 13,
- valueMin: 0,
- valueMax: 1,
- oninputstart: 2,
- oninputmove: 3,
- oninputend: 4,
- elasticity: 5,
- labelReset: 6
- });
- }
- }
- /* src/core/ui/plugins/crop/components/ImageInfo.svelte generated by Svelte v3.37.0 */
- function create_fragment$l(ctx) {
- let div;
- let p;
- let t0;
- let t1;
- let t2;
- return {
- c() {
- div = element("div");
- p = element("p");
- t0 = text(/*width*/ ctx[0]);
- t1 = text(" × ");
- t2 = text(/*height*/ ctx[1]);
- attr(div, "class", "PinturaImageInfo");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- append(div, p);
- append(p, t0);
- append(p, t1);
- append(p, t2);
- },
- p(ctx, [dirty]) {
- if (dirty & /*width*/ 1) set_data(t0, /*width*/ ctx[0]);
- if (dirty & /*height*/ 2) set_data(t2, /*height*/ ctx[1]);
- },
- i: noop,
- o: noop,
- d(detaching) {
- if (detaching) detach(div);
- }
- };
- }
- function instance$l($$self, $$props, $$invalidate) {
- let { width } = $$props;
- let { height } = $$props;
- $$self.$$set = $$props => {
- if ("width" in $$props) $$invalidate(0, width = $$props.width);
- if ("height" in $$props) $$invalidate(1, height = $$props.height);
- };
- return [width, height];
- }
- class ImageInfo extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$l, create_fragment$l, safe_not_equal, { width: 0, height: 1 });
- }
- }
- var getSelectionPresetOptionIcon = (value, options = {}) => {
- const { width = 24, height = 24, bounds = 16, radius = 3 } = options;
- let aspectRatio = isArray(value) ? getAspectRatio(value[0], value[1]) : value;
- let aspectRatioDefined = !!aspectRatio;
- aspectRatio = aspectRatioDefined ? aspectRatio : 1;
- let x;
- let y;
- let w;
- let h;
- w = aspectRatio > 1 ? bounds : aspectRatio * bounds;
- h = w / aspectRatio;
- x = Math.round((width - w) * 0.5);
- y = Math.round((height - h) * 0.5);
- const fill = aspectRatioDefined ? 'currentColor' : 'none';
- const stroke = aspectRatioDefined ? 'none' : 'currentColor';
- const strokeWidth = width / 16;
- const strokeDashArray = [width / 12, width / 6].join(' ');
- return `<rect fill="${fill}" stroke="${stroke}" stroke-width="${strokeWidth}" stroke-dasharray="${strokeDashArray}" x="${x}" y="${y}" width="${w}" height="${h}" rx="${radius}"/>`;
- };
- /* src/core/ui/plugins/crop/index.svelte generated by Svelte v3.37.0 */
- function create_default_slot_2$2(ctx) {
- let dynamiccomponenttree;
- let current;
- dynamiccomponenttree = new DynamicComponentTree_1({ props: { items: /*tools*/ ctx[0] } });
- return {
- c() {
- create_component(dynamiccomponenttree.$$.fragment);
- },
- m(target, anchor) {
- mount_component(dynamiccomponenttree, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const dynamiccomponenttree_changes = {};
- if (dirty[0] & /*tools*/ 1) dynamiccomponenttree_changes.items = /*tools*/ ctx[0];
- dynamiccomponenttree.$set(dynamiccomponenttree_changes);
- },
- i(local) {
- if (current) return;
- transition_in(dynamiccomponenttree.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(dynamiccomponenttree.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(dynamiccomponenttree, detaching);
- }
- };
- }
- // (1423:4)
- function create_header_slot(ctx) {
- let div;
- let toolbar;
- let current;
- toolbar = new Toolbar({
- props: {
- $$slots: { default: [create_default_slot_2$2] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- div = element("div");
- create_component(toolbar.$$.fragment);
- attr(div, "slot", "header");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(toolbar, div, null);
- current = true;
- },
- p(ctx, dirty) {
- const toolbar_changes = {};
- if (dirty[0] & /*tools*/ 1 | dirty[6] & /*$$scope*/ 64) {
- toolbar_changes.$$scope = { dirty, ctx };
- }
- toolbar.$set(toolbar_changes);
- },
- i(local) {
- if (current) return;
- transition_in(toolbar.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(toolbar.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(toolbar);
- }
- };
- }
- // (1452:12) {#if shouldRenderImageSelection && shouldRenderImageSelectionRecenterButton}
- function create_if_block_5$2(ctx) {
- let button;
- let current;
- button = new Button({
- props: {
- onclick: /*handleRecenterAction*/ ctx[80],
- label: /*locale*/ ctx[4].cropLabelButtonRecenter,
- icon: /*locale*/ ctx[4].cropIconButtonRecenter,
- class: "PinturaButtonCenter",
- disabled: !/*canCenter*/ ctx[10],
- hideLabel: true,
- style: `opacity: ${/*$recenterOpacity*/ ctx[27]}; transform: translate3d(${/*$recenterOffset*/ ctx[28].x}px, ${/*$recenterOffset*/ ctx[28].y}px, 0)`
- }
- });
- return {
- c() {
- create_component(button.$$.fragment);
- },
- m(target, anchor) {
- mount_component(button, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const button_changes = {};
- if (dirty[0] & /*locale*/ 16) button_changes.label = /*locale*/ ctx[4].cropLabelButtonRecenter;
- if (dirty[0] & /*locale*/ 16) button_changes.icon = /*locale*/ ctx[4].cropIconButtonRecenter;
- if (dirty[0] & /*canCenter*/ 1024) button_changes.disabled = !/*canCenter*/ ctx[10];
- if (dirty[0] & /*$recenterOpacity, $recenterOffset*/ 402653184) button_changes.style = `opacity: ${/*$recenterOpacity*/ ctx[27]}; transform: translate3d(${/*$recenterOffset*/ ctx[28].x}px, ${/*$recenterOffset*/ ctx[28].y}px, 0)`;
- button.$set(button_changes);
- },
- i(local) {
- if (current) return;
- transition_in(button.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(button.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(button, detaching);
- }
- };
- }
- // (1464:12) {#if shouldRenderImageSelection}
- function create_if_block_4$2(ctx) {
- let rectmanipulator;
- let current;
- rectmanipulator = new RectManipulator({
- props: {
- rect: /*imageSelectionRectOffset*/ ctx[11],
- visible: /*$isActive*/ ctx[9],
- style: /*cropImageSelectionCornerStyle*/ ctx[2]
- }
- });
- rectmanipulator.$on("resizestart", /*handleSelectionGrab*/ ctx[60]);
- rectmanipulator.$on("resizemove", /*handleSelectionDrag*/ ctx[61]);
- rectmanipulator.$on("resizeend", /*handleSelectionRelease*/ ctx[62]);
- return {
- c() {
- create_component(rectmanipulator.$$.fragment);
- },
- m(target, anchor) {
- mount_component(rectmanipulator, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const rectmanipulator_changes = {};
- if (dirty[0] & /*imageSelectionRectOffset*/ 2048) rectmanipulator_changes.rect = /*imageSelectionRectOffset*/ ctx[11];
- if (dirty[0] & /*$isActive*/ 512) rectmanipulator_changes.visible = /*$isActive*/ ctx[9];
- if (dirty[0] & /*cropImageSelectionCornerStyle*/ 4) rectmanipulator_changes.style = /*cropImageSelectionCornerStyle*/ ctx[2];
- rectmanipulator.$set(rectmanipulator_changes);
- },
- i(local) {
- if (current) return;
- transition_in(rectmanipulator.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(rectmanipulator.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(rectmanipulator, detaching);
- }
- };
- }
- // (1477:8) {#if shouldRenderInfoIndicator}
- function create_if_block_3$2(ctx) {
- let imageinfo;
- let current;
- imageinfo = new ImageInfo({
- props: {
- width: Math.round(/*$imageCropRect*/ ctx[7].width),
- height: Math.round(/*$imageCropRect*/ ctx[7].height)
- }
- });
- return {
- c() {
- create_component(imageinfo.$$.fragment);
- },
- m(target, anchor) {
- mount_component(imageinfo, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const imageinfo_changes = {};
- if (dirty[0] & /*$imageCropRect*/ 128) imageinfo_changes.width = Math.round(/*$imageCropRect*/ ctx[7].width);
- if (dirty[0] & /*$imageCropRect*/ 128) imageinfo_changes.height = Math.round(/*$imageCropRect*/ ctx[7].height);
- imageinfo.$set(imageinfo_changes);
- },
- i(local) {
- if (current) return;
- transition_in(imageinfo.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(imageinfo.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(imageinfo, detaching);
- }
- };
- }
- // (1429:4)
- function create_main_slot$1(ctx) {
- let div1;
- let div0;
- let t0;
- let interactable_action;
- let t1;
- let current;
- let mounted;
- let dispose;
- let if_block0 = /*shouldRenderImageSelection*/ ctx[17] && /*shouldRenderImageSelectionRecenterButton*/ ctx[18] && create_if_block_5$2(ctx);
- let if_block1 = /*shouldRenderImageSelection*/ ctx[17] && create_if_block_4$2(ctx);
- let if_block2 = /*shouldRenderInfoIndicator*/ ctx[16] && create_if_block_3$2(ctx);
- return {
- c() {
- div1 = element("div");
- div0 = element("div");
- if (if_block0) if_block0.c();
- t0 = space();
- if (if_block1) if_block1.c();
- t1 = space();
- if (if_block2) if_block2.c();
- attr(div0, "class", "PinturaStage");
- attr(div1, "slot", "main");
- },
- m(target, anchor) {
- insert(target, div1, anchor);
- append(div1, div0);
- if (if_block0) if_block0.m(div0, null);
- append(div0, t0);
- if (if_block1) if_block1.m(div0, null);
- /*div0_binding*/ ctx[145](div0);
- append(div1, t1);
- if (if_block2) if_block2.m(div1, null);
- current = true;
- if (!mounted) {
- dispose = [
- listen(div0, "measure", /*measure_handler_1*/ ctx[143]),
- action_destroyer(measurable.call(null, div0)),
- listen(
- div0,
- "wheel",
- function () {
- if (is_function(/*cropEnableZoom*/ ctx[3] && /*handleWheel*/ ctx[79])) (/*cropEnableZoom*/ ctx[3] && /*handleWheel*/ ctx[79]).apply(this, arguments);
- },
- { passive: false }
- ),
- listen(div0, "interactionstart", /*handleImageDragStart*/ ctx[66]),
- listen(div0, "interactionupdate", /*handleImageDrag*/ ctx[67]),
- listen(div0, "interactionrelease", /*handleImageDragRelease*/ ctx[69]),
- listen(div0, "interactionend", /*handleImageDragEnd*/ ctx[68]),
- action_destroyer(interactable_action = interactable.call(null, div0, {
- drag: true,
- pinch: /*cropEnableZoom*/ ctx[3],
- inertia: true,
- matchTarget: true,
- getEventPosition: /*interactable_function*/ ctx[146]
- })),
- listen(div0, "gesturedown", /*handleGestureStart*/ ctx[76]),
- listen(div0, "gestureupdate", /*handleGestureUpdate*/ ctx[77]),
- listen(div0, "gestureup", /*handleGestureEnd*/ ctx[78]),
- action_destroyer(gesturable.call(null, div0))
- ];
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- if (/*shouldRenderImageSelection*/ ctx[17] && /*shouldRenderImageSelectionRecenterButton*/ ctx[18]) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty[0] & /*shouldRenderImageSelection, shouldRenderImageSelectionRecenterButton*/ 393216) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_5$2(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(div0, t0);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (/*shouldRenderImageSelection*/ ctx[17]) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- if (dirty[0] & /*shouldRenderImageSelection*/ 131072) {
- transition_in(if_block1, 1);
- }
- } else {
- if_block1 = create_if_block_4$2(ctx);
- if_block1.c();
- transition_in(if_block1, 1);
- if_block1.m(div0, null);
- }
- } else if (if_block1) {
- group_outros();
- transition_out(if_block1, 1, 1, () => {
- if_block1 = null;
- });
- check_outros();
- }
- if (interactable_action && is_function(interactable_action.update) && dirty[0] & /*cropEnableZoom, $rootRect*/ 32776) interactable_action.update.call(null, {
- drag: true,
- pinch: /*cropEnableZoom*/ ctx[3],
- inertia: true,
- matchTarget: true,
- getEventPosition: /*interactable_function*/ ctx[146]
- });
- if (/*shouldRenderInfoIndicator*/ ctx[16]) {
- if (if_block2) {
- if_block2.p(ctx, dirty);
- if (dirty[0] & /*shouldRenderInfoIndicator*/ 65536) {
- transition_in(if_block2, 1);
- }
- } else {
- if_block2 = create_if_block_3$2(ctx);
- if_block2.c();
- transition_in(if_block2, 1);
- if_block2.m(div1, null);
- }
- } else if (if_block2) {
- group_outros();
- transition_out(if_block2, 1, 1, () => {
- if_block2 = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- transition_in(if_block1);
- transition_in(if_block2);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- transition_out(if_block1);
- transition_out(if_block2);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div1);
- if (if_block0) if_block0.d();
- if (if_block1) if_block1.d();
- /*div0_binding*/ ctx[145](null);
- if (if_block2) if_block2.d();
- mounted = false;
- run_all(dispose);
- }
- };
- }
- // (1485:8) {#if shouldRenderFooter}
- function create_if_block$4(ctx) {
- let tablist;
- let t;
- let tabpanels;
- let current;
- const tablist_spread_levels = [
- { class: "PinturaControlList" },
- { tabs: /*tabs*/ ctx[12] },
- /*tabsConfig*/ ctx[21]
- ];
- let tablist_props = {
- $$slots: {
- default: [
- create_default_slot_1$3,
- ({ tab }) => ({ 191: tab }),
- ({ tab }) => [0, 0, 0, 0, 0, 0, tab ? 32 : 0]
- ]
- },
- $$scope: { ctx }
- };
- for (let i = 0; i < tablist_spread_levels.length; i += 1) {
- tablist_props = assign(tablist_props, tablist_spread_levels[i]);
- }
- tablist = new TabList({ props: tablist_props });
- tablist.$on("select", /*select_handler*/ ctx[144]);
- const tabpanels_spread_levels = [
- { class: "PinturaControlPanels" },
- { panelClass: "PinturaControlPanel" },
- { panels: /*panels*/ ctx[22] },
- /*tabsConfig*/ ctx[21]
- ];
- let tabpanels_props = {
- $$slots: {
- default: [
- create_default_slot$9,
- ({ panel }) => ({ 190: panel }),
- ({ panel }) => [0, 0, 0, 0, 0, 0, panel ? 16 : 0]
- ]
- },
- $$scope: { ctx }
- };
- for (let i = 0; i < tabpanels_spread_levels.length; i += 1) {
- tabpanels_props = assign(tabpanels_props, tabpanels_spread_levels[i]);
- }
- tabpanels = new TabPanels({ props: tabpanels_props });
- return {
- c() {
- create_component(tablist.$$.fragment);
- t = space();
- create_component(tabpanels.$$.fragment);
- },
- m(target, anchor) {
- mount_component(tablist, target, anchor);
- insert(target, t, anchor);
- mount_component(tabpanels, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const tablist_changes = (dirty[0] & /*tabs, tabsConfig*/ 2101248)
- ? get_spread_update(tablist_spread_levels, [
- tablist_spread_levels[0],
- dirty[0] & /*tabs*/ 4096 && { tabs: /*tabs*/ ctx[12] },
- dirty[0] & /*tabsConfig*/ 2097152 && get_spread_object(/*tabsConfig*/ ctx[21])
- ])
- : {};
- if (dirty[6] & /*$$scope, tab*/ 96) {
- tablist_changes.$$scope = { dirty, ctx };
- }
- tablist.$set(tablist_changes);
- const tabpanels_changes = (dirty[0] & /*panels, tabsConfig*/ 6291456)
- ? get_spread_update(tabpanels_spread_levels, [
- tabpanels_spread_levels[0],
- tabpanels_spread_levels[1],
- dirty[0] & /*panels*/ 4194304 && { panels: /*panels*/ ctx[22] },
- dirty[0] & /*tabsConfig*/ 2097152 && get_spread_object(/*tabsConfig*/ ctx[21])
- ])
- : {};
- if (dirty[0] & /*$imageRotation, locale, $imageRotationRange, imageZoomLevelMin, $imageZoomLevelRange, $imageZoomLevel*/ 117457168 | dirty[6] & /*$$scope, panel*/ 80) {
- tabpanels_changes.$$scope = { dirty, ctx };
- }
- tabpanels.$set(tabpanels_changes);
- },
- i(local) {
- if (current) return;
- transition_in(tablist.$$.fragment, local);
- transition_in(tabpanels.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(tablist.$$.fragment, local);
- transition_out(tabpanels.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(tablist, detaching);
- if (detaching) detach(t);
- destroy_component(tabpanels, detaching);
- }
- };
- }
- // (1486:12) <TabList class="PinturaControlList" {tabs} {...tabsConfig} on:select={({ detail }) => (transformSelected = detail)} let:tab >
- function create_default_slot_1$3(ctx) {
- let span;
- let t_value = /*tab*/ ctx[191].label + "";
- let t;
- return {
- c() {
- span = element("span");
- t = text(t_value);
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- },
- p(ctx, dirty) {
- if (dirty[6] & /*tab*/ 32 && t_value !== (t_value = /*tab*/ ctx[191].label + "")) set_data(t, t_value);
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- // (1514:59)
- function create_if_block_2$3(ctx) {
- let rangeinput;
- let current;
- rangeinput = new RangeInput({
- props: {
- elasticity: /*elasticityMultiplier*/ ctx[35] * /*rangeInputElasticity*/ ctx[36],
- base: imageZoomLevelBase,
- min: /*imageZoomLevelMin*/ ctx[14],
- max: imageZoomLevelMax,
- valueMin: /*$imageZoomLevelRange*/ ctx[25][0],
- valueMax: /*$imageZoomLevelRange*/ ctx[25][1],
- value: /*$imageZoomLevel*/ ctx[26],
- labelReset: /*locale*/ ctx[4].labelReset,
- valueLabel: `${Math.round(/*$imageZoomLevel*/ ctx[26] * 100)}%`,
- oninputstart: /*handleResizeStart*/ ctx[73],
- oninputmove: /*handleResizeMove*/ ctx[74],
- oninputend: /*handleResizeEnd*/ ctx[75]
- }
- });
- return {
- c() {
- create_component(rangeinput.$$.fragment);
- },
- m(target, anchor) {
- mount_component(rangeinput, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const rangeinput_changes = {};
- if (dirty[0] & /*imageZoomLevelMin*/ 16384) rangeinput_changes.min = /*imageZoomLevelMin*/ ctx[14];
- if (dirty[0] & /*$imageZoomLevelRange*/ 33554432) rangeinput_changes.valueMin = /*$imageZoomLevelRange*/ ctx[25][0];
- if (dirty[0] & /*$imageZoomLevelRange*/ 33554432) rangeinput_changes.valueMax = /*$imageZoomLevelRange*/ ctx[25][1];
- if (dirty[0] & /*$imageZoomLevel*/ 67108864) rangeinput_changes.value = /*$imageZoomLevel*/ ctx[26];
- if (dirty[0] & /*locale*/ 16) rangeinput_changes.labelReset = /*locale*/ ctx[4].labelReset;
- if (dirty[0] & /*$imageZoomLevel*/ 67108864) rangeinput_changes.valueLabel = `${Math.round(/*$imageZoomLevel*/ ctx[26] * 100)}%`;
- rangeinput.$set(rangeinput_changes);
- },
- i(local) {
- if (current) return;
- transition_in(rangeinput.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(rangeinput.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(rangeinput, detaching);
- }
- };
- }
- // (1503:16) {#if panel === cropUniqueId + '-rotation'}
- function create_if_block_1$4(ctx) {
- let imagerotator;
- let current;
- imagerotator = new ImageRotator({
- props: {
- elasticity: /*elasticityMultiplier*/ ctx[35] * /*rangeInputElasticity*/ ctx[36],
- rotation: /*$imageRotation*/ ctx[8],
- labelReset: /*locale*/ ctx[4].labelReset,
- valueMin: /*$imageRotationRange*/ ctx[24][0],
- valueMax: /*$imageRotationRange*/ ctx[24][1],
- oninputstart: /*handleRotateStart*/ ctx[63],
- oninputmove: /*handleRotateMove*/ ctx[64],
- oninputend: /*handleRotateEnd*/ ctx[65]
- }
- });
- return {
- c() {
- create_component(imagerotator.$$.fragment);
- },
- m(target, anchor) {
- mount_component(imagerotator, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const imagerotator_changes = {};
- if (dirty[0] & /*$imageRotation*/ 256) imagerotator_changes.rotation = /*$imageRotation*/ ctx[8];
- if (dirty[0] & /*locale*/ 16) imagerotator_changes.labelReset = /*locale*/ ctx[4].labelReset;
- if (dirty[0] & /*$imageRotationRange*/ 16777216) imagerotator_changes.valueMin = /*$imageRotationRange*/ ctx[24][0];
- if (dirty[0] & /*$imageRotationRange*/ 16777216) imagerotator_changes.valueMax = /*$imageRotationRange*/ ctx[24][1];
- imagerotator.$set(imagerotator_changes);
- },
- i(local) {
- if (current) return;
- transition_in(imagerotator.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(imagerotator.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(imagerotator, detaching);
- }
- };
- }
- // (1496:12) <TabPanels class="PinturaControlPanels" panelClass="PinturaControlPanel" {panels} {...tabsConfig} let:panel >
- function create_default_slot$9(ctx) {
- let current_block_type_index;
- let if_block;
- let if_block_anchor;
- let current;
- const if_block_creators = [create_if_block_1$4, create_if_block_2$3];
- const if_blocks = [];
- function select_block_type(ctx, dirty) {
- if (/*panel*/ ctx[190] === /*cropUniqueId*/ ctx[85] + "-rotation") return 0;
- if (/*panel*/ ctx[190] === /*cropUniqueId*/ ctx[85] + "-zoom") return 1;
- return -1;
- }
- if (~(current_block_type_index = select_block_type(ctx))) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- }
- return {
- c() {
- if (if_block) if_block.c();
- if_block_anchor = empty();
- },
- m(target, anchor) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].m(target, anchor);
- }
- insert(target, if_block_anchor, anchor);
- current = true;
- },
- p(ctx, dirty) {
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type(ctx);
- if (current_block_type_index === previous_block_index) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- }
- } else {
- if (if_block) {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- }
- if (~current_block_type_index) {
- if_block = if_blocks[current_block_type_index];
- if (!if_block) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block.c();
- } else {
- if_block.p(ctx, dirty);
- }
- transition_in(if_block, 1);
- if_block.m(if_block_anchor.parentNode, if_block_anchor);
- } else {
- if_block = null;
- }
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].d(detaching);
- }
- if (detaching) detach(if_block_anchor);
- }
- };
- }
- // (1484:4)
- function create_footer_slot$5(ctx) {
- let div;
- let current;
- let if_block = /*shouldRenderFooter*/ ctx[20] && create_if_block$4(ctx);
- return {
- c() {
- div = element("div");
- if (if_block) if_block.c();
- attr(div, "slot", "footer");
- attr(div, "style", /*footerStyle*/ ctx[23]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (if_block) if_block.m(div, null);
- current = true;
- },
- p(ctx, dirty) {
- if (/*shouldRenderFooter*/ ctx[20]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty[0] & /*shouldRenderFooter*/ 1048576) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block$4(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(div, null);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- if (!current || dirty[0] & /*footerStyle*/ 8388608) {
- attr(div, "style", /*footerStyle*/ ctx[23]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (if_block) if_block.d();
- }
- };
- }
- function create_fragment$k(ctx) {
- let util;
- let updating_root;
- let current;
- function util_root_binding(value) {
- /*util_root_binding*/ ctx[147](value);
- }
- let util_props = {
- hasHeader: /*shouldRenderToolbar*/ ctx[19],
- $$slots: {
- footer: [create_footer_slot$5],
- main: [create_main_slot$1],
- header: [create_header_slot]
- },
- $$scope: { ctx }
- };
- if (/*root*/ ctx[13] !== void 0) {
- util_props.root = /*root*/ ctx[13];
- }
- util = new Util({ props: util_props });
- binding_callbacks.push(() => bind(util, "root", util_root_binding));
- util.$on("measure", /*measure_handler*/ ctx[148]);
- return {
- c() {
- create_component(util.$$.fragment);
- },
- m(target, anchor) {
- mount_component(util, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const util_changes = {};
- if (dirty[0] & /*shouldRenderToolbar*/ 524288) util_changes.hasHeader = /*shouldRenderToolbar*/ ctx[19];
- if (dirty[0] & /*footerStyle, panels, tabsConfig, $imageRotation, locale, $imageRotationRange, imageZoomLevelMin, $imageZoomLevelRange, $imageZoomLevel, tabs, transformSelected, shouldRenderFooter, $imageCropRect, shouldRenderInfoIndicator, stageRef, cropEnableZoom, $rootRect, imageSelectionRectOffset, $isActive, cropImageSelectionCornerStyle, shouldRenderImageSelection, canCenter, $recenterOpacity, $recenterOffset, shouldRenderImageSelectionRecenterButton, tools*/ 536338429 | dirty[6] & /*$$scope*/ 64) {
- util_changes.$$scope = { dirty, ctx };
- }
- if (!updating_root && dirty[0] & /*root*/ 8192) {
- updating_root = true;
- util_changes.root = /*root*/ ctx[13];
- add_flush_callback(() => updating_root = false);
- }
- util.$set(util_changes);
- },
- i(local) {
- if (current) return;
- transition_in(util.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(util.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(util, detaching);
- }
- };
- }
- const imageZoomLevelMax = 1;
- const imageZoomLevelBase = 0;
- function instance$k($$self, $$props, $$invalidate) {
- let imageZoomLevelMin;
- let imageSelectionOffset;
- let imageSelectionCenter;
- let imageSelectionCenteredRect;
- let isImageSelectionDisplayed;
- let isImageSelectionCentered;
- let isResizingSelection;
- let isMaxSelectionRect;
- let isOverlayMode;
- let canZoomToCenter;
- let canCenter;
- let shouldRenderInfoIndicator;
- let shouldRenderImageSelection;
- let shouldRenderImageSelectionRecenterButton;
- let imageSelectionRectOffset;
- let hasPlentyVerticalSpace;
- let shouldRenderPresetSelect;
- let shouldRenderToolbar;
- let couldRenderZoomInput;
- let shouldRenderZoomInput;
- let shouldRenderFooter;
- let tabsConfig;
- let tabs;
- let panels;
- let footerStyle;
- let $imageCropAspectRatio;
- let $imageCropRect;
- let $imageSize;
- let $imageRotation;
- let $imageFlipY;
- let $imageFlipX;
- let $selectedPresetIndex;
- let $imageOutputSize;
- let $imageCropMinSize;
- let $imageCropLimitToImage;
- let $env;
- let $isActive,
- $$unsubscribe_isActive = noop,
- $$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(9, $isActive = $$value)), isActive);
- let $isInteracting;
- let $imageSelectionRectSnapshot;
- let $imageSelectionRect;
- let $presentationScalar;
- let $imageCropMaxSize;
- let $imageSelectionRectIntent;
- let $utilRect;
- let $imageCropRectOrigin;
- let $imageCropRectIntent;
- let $imageCropRange;
- let $rootRect;
- let $stageRect;
- let $imageCropRangeAspectRatio;
- let $imageSelectionRectPresentation;
- let $imageScalar;
- let $framePadded;
- let $imagePreviewModifiers;
- let $imageOverlayMarkup;
- let $imageSelectionGuides;
- let $animation;
- let $footerOffset;
- let $imageRotationRange;
- let $imageZoomLevelRange;
- let $imageZoomLevel;
- let $recenterOpacity;
- let $recenterOffset;
- $$self.$$.on_destroy.push(() => $$unsubscribe_isActive());
- const name = "crop";
- let { isActive } = $$props;
- $$subscribe_isActive();
- let { stores } = $$props;
- let { cropImageSelectionCornerStyle = "circle" } = $$props; // 'circle', 'hook', 'invisible'
- let { cropWillRenderImageSelectionGuides = (interaction, interactionFraction) => {
- const isRotating = interaction == "rotate";
- return {
- rows: isRotating ? 5 : 3,
- cols: isRotating ? 5 : 3,
- opacity: interactionFraction * 0.25
- };
- } } = $$props;
- let { cropAutoCenterImageSelectionTimeout = undefined } = $$props;
- let { cropEnableZoomMatchImageAspectRatio = true } = $$props;
- let { cropEnableRotateMatchImageAspectRatio = "never" } = $$props; // 'always' | 'custom' | 'never'
- let { cropEnableRotationInput = true } = $$props;
- let { cropEnableZoom = true } = $$props;
- let { cropEnableZoomInput = true } = $$props;
- let { cropEnableZoomAutoHide = true } = $$props;
- let { cropEnableImageSelection = true } = $$props;
- let { cropEnableInfoIndicator = false } = $$props;
- let { cropEnableZoomTowardsWheelPosition = true } = $$props;
- let { cropEnableLimitWheelInputToCropSelection = true } = $$props;
- let { cropEnableCenterImageSelection = true } = $$props;
- let { cropEnableButtonRotateLeft = true } = $$props;
- let { cropEnableButtonRotateRight = false } = $$props;
- let { cropEnableButtonFlipHorizontal = true } = $$props;
- let { cropEnableButtonFlipVertical = false } = $$props;
- let { cropSelectPresetOptions = undefined } = $$props;
- let { cropEnableSelectPreset = true } = $$props;
- let { cropEnableButtonToggleCropLimit = false } = $$props;
- let { cropWillRenderTools = passthrough } = $$props;
- let { locale = {} } = $$props;
- let { tools = [] } = $$props;
- // state
- let interaction = "idle";
- // helpers
- const isCustomCrop = () => $imageCropAspectRatio === undefined;
- const turnAspectRatio = aspectRatio => 1 / aspectRatio;
- const hasValidRotatedCropAspectRatio = () => {
- if ($imageCropAspectRatio === 1) return false;
- const rotatedImageCropAspectRatio = turnAspectRatio($imageCropAspectRatio);
- // no options available, forced crop aspect ratio
- if (!cropSelectPresetOptions) return false;
- // options available but no valid option in list
- if (!flattenOptions(cropSelectPresetOptions).find(([aspectRatio]) => aspectRatio === rotatedImageCropAspectRatio)) return false;
- return true;
- };
- const isCropMaxSize = (imageCropRect, imageSize, imageRotation) => isRotatedSideways(imageRotation)
- ? imageSize.width === Math.round(imageCropRect.height) || imageSize.height === Math.round(imageCropRect.width)
- : imageSize.width === Math.round(imageCropRect.width) || imageSize.height === Math.round(imageCropRect.height);
- const isCropCentered = (imageCropRect, imageSize, imageRotation) => {
- const imageSizeRotated = sizeApply(sizeRotate(sizeClone(imageSize), imageRotation), v => Math.abs(Math.round(v)));
- const imageCenter = sizeCenter(imageSizeRotated);
- const cropCenter = rectCenter(imageCropRect);
- return vectorEqual(imageCenter, cropCenter);
- };
- const canMatchCropAspectRatioToRotation = () => // is custom crop mode
- (isCustomCrop() || // can match preset crop and preset is available
- cropEnableRotateMatchImageAspectRatio === "always" && hasValidRotatedCropAspectRatio()) && isCropCentered($imageCropRect, $imageSize, $imageRotation) && isCropMaxSize($imageCropRect, $imageSize, $imageRotation);
- const applyRotation = value => {
- if (cropEnableRotateMatchImageAspectRatio !== "never" && canMatchCropAspectRatioToRotation()) {
- set_store_value(imageRotation, $imageRotation += value, $imageRotation);
- const isRotated = isRotatedSideways($imageRotation);
- const w = isRotated ? $imageSize.height : $imageSize.width;
- const h = isRotated ? $imageSize.width : $imageSize.height;
- set_store_value(imageCropRect, $imageCropRect = rectCreate(0, 0, w, h), $imageCropRect);
- if (!isCustomCrop()) set_store_value(imageCropAspectRatio, $imageCropAspectRatio = getAspectRatio(w, h), $imageCropAspectRatio);
- } else {
- set_store_value(imageRotation, $imageRotation += value, $imageRotation);
- }
- };
- const { history, env, isInteracting, isInteractingFraction, rootRect, stageRect, utilRect, rootLineColor, animation, elasticityMultiplier, rangeInputElasticity, presentationScalar, // effect filtering
- imagePreviewModifiers, imageOutlineOpacity, // crop selection
- imageFlipX, imageFlipY, imageRotation, imageRotationRange, imageOutputSize, imageSelectionRect, imageSelectionRectSnapshot, imageSelectionRectIntent, imageSelectionRectPresentation, imageCropRectIntent, imageCropRectOrigin, imageCropRect, imageCropMinSize, imageCropMaxSize, imageCropRange, imageCropAspectRatio, imageCropRectAspectRatio, imageCropLimitToImage, imageSize, imageScalar, imageOverlayMarkup, framePadded } = stores; // the actual limited rectangle
- // used to calculate rectangle while dragging
- // can be used to set set intended rectangle
- // readonly
- component_subscribe($$self, env, value => $$invalidate(118, $env = value));
- component_subscribe($$self, isInteracting, value => $$invalidate(119, $isInteracting = value));
- component_subscribe($$self, rootRect, value => $$invalidate(15, $rootRect = value));
- component_subscribe($$self, stageRect, value => $$invalidate(124, $stageRect = value));
- component_subscribe($$self, utilRect, value => $$invalidate(123, $utilRect = value));
- component_subscribe($$self, animation, value => $$invalidate(141, $animation = value));
- component_subscribe($$self, presentationScalar, value => $$invalidate(122, $presentationScalar = value));
- component_subscribe($$self, imagePreviewModifiers, value => $$invalidate(136, $imagePreviewModifiers = value));
- component_subscribe($$self, imageFlipX, value => $$invalidate(112, $imageFlipX = value));
- component_subscribe($$self, imageFlipY, value => $$invalidate(111, $imageFlipY = value));
- component_subscribe($$self, imageRotation, value => $$invalidate(8, $imageRotation = value));
- component_subscribe($$self, imageRotationRange, value => $$invalidate(24, $imageRotationRange = value));
- component_subscribe($$self, imageOutputSize, value => $$invalidate(159, $imageOutputSize = value));
- component_subscribe($$self, imageSelectionRect, value => $$invalidate(121, $imageSelectionRect = value));
- component_subscribe($$self, imageSelectionRectSnapshot, value => $$invalidate(120, $imageSelectionRectSnapshot = value));
- component_subscribe($$self, imageSelectionRectIntent, value => $$invalidate(161, $imageSelectionRectIntent = value));
- component_subscribe($$self, imageSelectionRectPresentation, value => $$invalidate(127, $imageSelectionRectPresentation = value));
- component_subscribe($$self, imageCropRectIntent, value => $$invalidate(163, $imageCropRectIntent = value));
- component_subscribe($$self, imageCropRectOrigin, value => $$invalidate(162, $imageCropRectOrigin = value));
- component_subscribe($$self, imageCropRect, value => $$invalidate(7, $imageCropRect = value));
- component_subscribe($$self, imageCropMinSize, value => $$invalidate(116, $imageCropMinSize = value));
- component_subscribe($$self, imageCropMaxSize, value => $$invalidate(160, $imageCropMaxSize = value));
- component_subscribe($$self, imageCropRange, value => $$invalidate(164, $imageCropRange = value));
- component_subscribe($$self, imageCropAspectRatio, value => $$invalidate(158, $imageCropAspectRatio = value));
- component_subscribe($$self, imageCropLimitToImage, value => $$invalidate(117, $imageCropLimitToImage = value));
- component_subscribe($$self, imageSize, value => $$invalidate(110, $imageSize = value));
- component_subscribe($$self, imageScalar, value => $$invalidate(134, $imageScalar = value));
- component_subscribe($$self, imageOverlayMarkup, value => $$invalidate(166, $imageOverlayMarkup = value));
- component_subscribe($$self, framePadded, value => $$invalidate(135, $framePadded = value));
- //
- // resizing crop
- //
- let presentationScalarSnapshot;
- let imageSelectionRectMinSize;
- let imageSelectionRectMaxSize;
- const handleSelectionGrab = () => {
- interaction = "select";
- // now interacting
- set_store_value(isInteracting, $isInteracting = true, $isInteracting);
- // we remember the current view rect and crop rect, because that is the crop rect we use as a starting point to transform while dragging
- set_store_value(imageSelectionRectSnapshot, $imageSelectionRectSnapshot = rectClone($imageSelectionRect), $imageSelectionRectSnapshot);
- // remember current scalar so we can update min and max size correctly
- presentationScalarSnapshot = $presentationScalar;
- imageSelectionRectMinSize = sizeScale(sizeClone($imageCropMinSize), presentationScalarSnapshot);
- imageSelectionRectMaxSize = sizeScale(sizeClone($imageCropMaxSize), presentationScalarSnapshot);
- };
- const handleSelectionDrag = ({ detail }) => {
- const { boundsLimited, boundsIntent } = translateSelection(detail.direction, detail.translation);
- // update actual image selection rectangle
- set_store_value(imageSelectionRectIntent, $imageSelectionRectIntent = boundsIntent, $imageSelectionRectIntent); // intent needs to be updated first because has no listeners attached
- set_store_value(imageSelectionRect, $imageSelectionRect = boundsLimited, $imageSelectionRect);
- };
- const handleSelectionRelease = ({ detail }) => {
- const { boundsLimited } = translateSelection(detail.direction, detail.translation);
- // we're no longer interacting with the image selection, we need to set this here so the image selection presentation is animated when applying the new bounds below
- set_store_value(isInteracting, $isInteracting = false, $isInteracting);
- // no more intent as we're finalizing the selection, so before setting the final selection, we set this to undefined | intent needs to be updated first because has no listeners attached
- set_store_value(imageSelectionRectIntent, $imageSelectionRectIntent = undefined, $imageSelectionRectIntent);
- // confirm the limited rect if actually made a change
- if (vectorLength(detail.translation)) {
- set_store_value(imageSelectionRect, $imageSelectionRect = boundsLimited, $imageSelectionRect);
- history.write();
- }
- // need to set this to undefined after setting the final rect, the snapshot is used to calculate the crop rect transform
- set_store_value(imageSelectionRectSnapshot, $imageSelectionRectSnapshot = undefined, $imageSelectionRectSnapshot);
- // done interacting with selection
- interaction = undefined;
- };
- const translateSelection = (target, translate) => {
- // - selection may grow to max bounds (util bounds)
- // - the image preview(!) is scaled to fit the selection, actual image size is not affected
- // - we need to make sure the selection adheres to the aspect ratio of the min size
- const directionTranslation = { target, translate };
- let rectIntended = applyRectDirectionTranslation($imageSelectionRectSnapshot, directionTranslation, { aspectRatio: $imageCropAspectRatio });
- let cropAspectRatioLimited;
- // size in crop rect
- const cropSize = sizeCreateFromRect(rectDivide(rectClone(rectIntended), $presentationScalar));
- getImagePolygon($imageSize, $imageRotation);
- // if one of the edges is small and not both are smaller we need to correct
- if (cropSize.width < $imageCropMinSize.width || cropSize.height < $imageCropMinSize.height) {
- // if moving towards the center of the crop, it can't exceed bounds
- const translateUp = translate.y < 0;
- const translateRight = translate.x > 0;
- const translateLeft = translate.x < 0;
- const translateDown = translate.y > 0;
- const couldExceedBounds = target === "t" && translateUp || target === "r" && translateRight || target === "b" && translateDown || target === "l" && translateLeft || target === "tr" && (translateRight || translateUp) || target === "tl" && (translateLeft || translateUp) || target === "br" && (translateRight || translateDown) || target === "bl" && (translateLeft || translateDown);
- // need the aspect ratio of the crop to determine if it violates min size
- const cropAspectRatio = rectAspectRatio(cropSize);
- // find the maximum size for the current aspect ratio
- const cropSizeMax = getMaxSizeInRect($imageSize, $imageRotation, cropAspectRatio);
- if (couldExceedBounds && (cropSizeMax.width < $imageCropMinSize.width || cropSizeMax.height < $imageCropMinSize.height)) {
- if ($imageRotation !== 0) {
- const sign = Math.sign($imageRotation);
- const turns = Math.round(Math.abs($imageRotation) / HALF_PI) * HALF_PI;
- const value = $imageRotation - sign * turns;
- const imageIsRotated = turns / HALF_PI % 2 === 1;
- const imageWidth = imageIsRotated ? $imageSize.height : $imageSize.width;
- const imageHeight = imageIsRotated ? $imageSize.width : $imageSize.height;
- const r = Math.abs(value);
- const sin = Math.sin(r);
- const cos = Math.cos(r);
- if (cropSize.width < $imageCropMinSize.width) {
- // width doesn't fit, let's limit the width to the min size
- cropSize.width = $imageCropMinSize.width;
- // And now calculate the height
- // - rotation = .15
- // - image size = 384 x 288
- // - crop size width = 200
- // height = 288 - (Math.sin(.15) * 200) / Math.cos(.15)
- const w = cos * cropSize.width + sin * cropSize.height;
- const h = sin * cropSize.width + cos * cropSize.height;
- const dx = imageWidth - w;
- const dy = imageHeight - h;
- if (dx < dy) {
- cropSize.height = (imageWidth - cos * cropSize.width) / sin;
- } else if (dy < dx) {
- cropSize.height = (imageHeight - sin * cropSize.width) / cos;
- }
- }
- if (cropSize.height < $imageCropMinSize.height) {
- // height doesn't fit, let's limit the height to the min size
- cropSize.height = $imageCropMinSize.height;
- // And now calculate the width
- // - rotation = .15
- // - image size = 384 x 288
- // - crop size height = 200
- const w = cos * cropSize.width + sin * cropSize.height;
- const h = sin * cropSize.width + cos * cropSize.height;
- const dx = imageWidth - w;
- const dy = imageHeight - h;
- if (dx < dy) {
- // (384 - (Math.sin(.15) * 250)) / Math.cos(.15)
- cropSize.width = (imageWidth - sin * cropSize.height) / cos;
- } else if (dy < dx) {
- // (288 - (Math.cos(.15) * 250)) / Math.sin(.15)
- cropSize.width = (imageHeight - cos * cropSize.height) / sin;
- }
- }
- } else {
- if (cropSize.width < $imageCropMinSize.width) {
- cropSize.width = $imageCropMinSize.width;
- cropSize.height = $imageSize.height;
- }
- if (cropSize.height < $imageCropMinSize.height) {
- cropSize.height = $imageCropMinSize.height;
- cropSize.width = $imageSize.width;
- }
- }
- // we now have a corrected size, let's calculate the new aspect ratio and use that to limit the translation
- cropAspectRatioLimited = rectAspectRatio(cropSize);
- }
- }
- if (cropAspectRatioLimited) {
- rectIntended = applyRectDirectionTranslation($imageSelectionRectSnapshot, directionTranslation, {
- aspectRatio: cropAspectRatioLimited || $imageCropAspectRatio
- });
- }
- let rectLimited = limitRectDirectionTranslation($imageSelectionRectSnapshot, directionTranslation, $utilRect, {
- aspectRatio: $imageCropAspectRatio || cropAspectRatioLimited,
- minSize: imageSelectionRectMinSize,
- maxSize: imageSelectionRectMaxSize
- });
- return {
- boundsLimited: rectLimited,
- boundsIntent: rectIntended
- };
- };
- //
- // rotating
- //
- const handleRotateStart = () => {
- interaction = "rotate";
- // now interacting with view
- set_store_value(isInteracting, $isInteracting = true, $isInteracting);
- // we need to know the origin of the crop so we can "shrink" the image to fit the crop rect while rotating
- set_store_value(imageCropRectOrigin, $imageCropRectOrigin = rectClone($imageCropRect), $imageCropRectOrigin);
- };
- const handleRotateMove = value => {
- set_store_value(imageRotation, $imageRotation = value, $imageRotation); // will auto validate
- };
- const handleRotateEnd = value => {
- // we're done interacting
- set_store_value(isInteracting, $isInteracting = false, $isInteracting);
- // apply our final rotation value
- set_store_value(imageRotation, $imageRotation = value, $imageRotation);
- history.write();
- // done, so we no longer need to "shrink" the image
- set_store_value(imageCropRectOrigin, $imageCropRectOrigin = undefined, $imageCropRectOrigin);
- };
- //
- // moving
- //
- let interactionCropRect = undefined;
- let interactionCropRectForce = undefined;
- const handleImageDragStart = () => {
- interaction = "pan";
- interactionCropRectForce = undefined;
- set_store_value(isInteracting, $isInteracting = true, $isInteracting);
- interactionCropRect = rectClone($imageCropRect);
- };
- const handleImageDrag = ({ detail }) => manipulateImage(detail);
- const handleImageDragEnd = ({ detail }) => {
- // done interacting
- set_store_value(isInteracting, $isInteracting = false, $isInteracting);
- // apply translation to the crop rect only if did make changes
- if (vectorLength(detail.translation) > 0 || detail.scalar !== 0) {
- manipulateImage(detail);
- history.write();
- }
- // no intent (needs to be set before crop rect is updated)
- set_store_value(imageCropRectIntent, $imageCropRectIntent = undefined, $imageCropRectIntent);
- // now done
- interactionCropRect = undefined;
- };
- const handleImageDragRelease = ({ detail }) => {
- interactionCropRectForce = detail.translation;
- set_store_value(isInteracting, $isInteracting = false, $isInteracting);
- };
- const manipulateImage = ({ translation, scalar }) => {
- const imageSelectionRectZoomFactor = Math.min($imageSelectionRect.width / $imageCropRect.width, $imageSelectionRect.height / $imageCropRect.height);
- const scaledTranslation = vectorMultiply(vectorClone(translation), 1 / imageSelectionRectZoomFactor);
- // while we're interacting we apply changes to the original crop rectangle, after we apply a force
- let cropIntent;
- if (!interactionCropRectForce) {
- cropIntent = rectTranslate(rectClone(interactionCropRect), vectorInvert(vectorClone(scaledTranslation)));
- if (scalar !== undefined) {
- rectScale(cropIntent, 1 / scalar);
- } // rectScale(cropIntent, scalar);
- } else {
- // we apply the force to the existing crop rect so animation is not borked
- const forceTranslation = vectorSubtract(vectorClone(interactionCropRectForce), translation);
- interactionCropRectForce = translation;
- cropIntent = rectTranslate(rectClone($imageCropRect), forceTranslation);
- }
- // update crop rect
- set_store_value(imageCropRectIntent, $imageCropRectIntent = cropIntent, $imageCropRectIntent); // auto calculates an elastic effect if bounds exceeded (needs to be set before crop rect is updated)
- set_store_value(imageCropRect, $imageCropRect = cropIntent, $imageCropRect); // auto limits to bounds if needed
- };
- //
- // resizing with range input
- //
- const calculateZoomLevel = (imageSize, size, imageRotation) => {
- if (isRotatedSideways(imageRotation)) {
- return 1 - 1 / Math.min(imageSize.height / size.width, imageSize.width / size.height);
- }
- return 1 - 1 / Math.min(imageSize.width / size.width, imageSize.height / size.height);
- };
- const imageCropRangeAspectRatio = derived([imageCropRange, imageCropRect], ([$imageCropRange, $imageCropRect], set) => {
- if (!$imageCropRect) return;
- const [minSize, maxSize] = $imageCropRange;
- const aspectRatio = rectAspectRatio($imageCropRect);
- set([
- sizeCreateFromRect(rectApply(rectCoverRect(minSize, aspectRatio), fixPrecision)),
- sizeCreateFromRect(rectApply(rectContainRect(maxSize, aspectRatio), fixPrecision))
- ]);
- });
- component_subscribe($$self, imageCropRangeAspectRatio, value => $$invalidate(165, $imageCropRangeAspectRatio = value));
- // this is the max value range that can be set (triggers white range indicator bar)
- const imageZoomLevelRange = derived(
- [
- imageSize,
- imageCropLimitToImage,
- imageCropMinSize,
- imageCropMaxSize,
- imageCropRange,
- imageRotation
- ],
- ([
- $imageSize,
- $imageCropLimitToImage,
- $imageCropMinSize,
- $imageCropMaxSize,
- $imageCropRange,
- $imageRotation
- ], set) => {
- if (!$imageSize) return;
- const rangeMinSize = $imageCropRange[0];
- const rangeMaxSize = $imageCropRange[1];
- let minZoom;
- let maxZoom;
- // can't zoom out
- if ($imageCropLimitToImage) {
- minZoom = calculateZoomLevel($imageSize, rangeMaxSize, $imageRotation);
- maxZoom = Math.min(rangeMinSize.width / $imageCropMinSize.width, rangeMinSize.height / $imageCropMinSize.height);
- } else {
- maxZoom = 1;
- minZoom = -1;
- }
- const range = [fixPrecision(minZoom), fixPrecision(maxZoom)];
- set(range);
- }
- );
- component_subscribe($$self, imageZoomLevelRange, value => $$invalidate(25, $imageZoomLevelRange = value));
- const imageZoomLevel = derived([imageSize, imageCropRect, imageCropRange, imageRotation], ([$imageSize, $imageCropRect, $imageCropRange, $imageRotation], set) => {
- // need to check if this value is set, could be that it's empty while loading a new image
- if (!$imageSize || !$imageCropRect) return set(0);
- let z;
- const rangeMinSize = $imageCropRange[0];
- const rangeMaxSize = $imageCropRange[1];
- const currentCropWidth = $imageCropRect.width;
- const currentCropHeight = $imageCropRect.height;
- const currentCropAspectRatio = rectAspectRatio($imageCropRect);
- const imageRect = isRotatedSideways($imageRotation)
- ? sizeCreate($imageSize.height, $imageSize.width)
- : $imageSize;
- const imageCropMaxRect = rectContainRect(imageRect, currentCropAspectRatio);
- if (currentCropWidth <= imageCropMaxRect.width || currentCropHeight <= imageCropMaxRect.height) {
- // zoomed in
- const w = imageCropMaxRect.width - rangeMinSize.width;
- const h = imageCropMaxRect.height - rangeMinSize.height;
- // cannot zoom in
- if (w === 0 || h === 0) {
- z = 1;
- } else {
- z = 1 - Math.min((currentCropWidth - rangeMinSize.width) / w, (currentCropHeight - rangeMinSize.height) / h);
- }
- } else {
- // zoomed out
- const w = rangeMaxSize.width - imageCropMaxRect.width;
- const h = rangeMaxSize.height - imageCropMaxRect.height;
- const r = rectContainRect({ width: w, height: h }, currentCropAspectRatio);
- z = -Math.min((currentCropWidth - imageCropMaxRect.width) / r.width, (currentCropHeight - imageCropMaxRect.height) / r.height);
- }
- set(z);
- });
- component_subscribe($$self, imageZoomLevel, value => $$invalidate(26, $imageZoomLevel = value));
- const snapshotCropRect = () => {
- interactionCropRect = rectClone($imageCropRect);
- };
- const resizeImage = zoom => {
- const aspectRatio = rectAspectRatio(interactionCropRect);
- let targetWidth;
- let targetHeight;
- let r;
- const imageRect = isRotatedSideways($imageRotation)
- ? sizeCreate($imageSize.height, $imageSize.width)
- : $imageSize;
- const imageCropMaxRect = rectContainRect(imageRect, aspectRatio);
- if (zoom >= 0) {
- // zoom in
- const rangeWidth = imageCropMaxRect.width - $imageCropRange[0].width;
- const rangeHeight = imageCropMaxRect.height - $imageCropRange[0].height;
- targetWidth = imageCropMaxRect.width - rangeWidth * zoom;
- targetHeight = imageCropMaxRect.height - rangeHeight * zoom;
- r = rectCoverRect({ width: targetWidth, height: targetHeight }, aspectRatio);
- } else {
- // zoom out
- const rangeWidth = $imageCropRange[1].width - imageCropMaxRect.width;
- const rangeHeight = $imageCropRange[1].height - imageCropMaxRect.height;
- targetWidth = imageCropMaxRect.width + rangeWidth * -zoom;
- targetHeight = imageCropMaxRect.height + rangeHeight * -zoom;
- r = rectContainRect({ width: targetWidth, height: targetHeight }, aspectRatio);
- }
- targetWidth = r.width;
- targetHeight = r.height;
- const targetX = interactionCropRect.x + interactionCropRect.width * 0.5 - targetWidth * 0.5;
- const targetY = interactionCropRect.y + interactionCropRect.height * 0.5 - targetHeight * 0.5;
- set_store_value(
- imageCropRect,
- $imageCropRect = {
- x: targetX,
- y: targetY,
- width: targetWidth,
- height: targetHeight
- },
- $imageCropRect
- );
- };
- const handleResizeStart = () => {
- interaction = "zoom";
- // now interacting with view
- set_store_value(isInteracting, $isInteracting = true, $isInteracting);
- snapshotCropRect();
- };
- const handleResizeMove = value => {
- // value range from 0 (no zoom) to 1 (100% zoom, 1x1 pixel)
- resizeImage(value);
- };
- const handleResizeEnd = value => {
- resizeImage(value);
- history.write();
- // we're done interacting
- set_store_value(isInteracting, $isInteracting = false, $isInteracting);
- // now done
- interactionCropRect = undefined;
- };
- //
- // resizing with gesture (MacBook trackpad Safari)
- //
- let gestureOriginCropRect;
- const handleGestureStart = () => {
- interaction = "zoom";
- // don't handle gesture as we're already handling input with interactable
- if (interactionCropRect) return;
- gestureOriginCropRect = rectClone($imageCropRect);
- // now interacting
- set_store_value(isInteracting, $isInteracting = true, $isInteracting);
- };
- const handleGestureUpdate = ({ detail }) => {
- // don't handle gesture as we're already handling input with interactable
- if (!gestureOriginCropRect) return;
- handleScaleGesture(detail);
- };
- const handleScaleGesture = scale => {
- const cropIntent = rectScale(rectClone(gestureOriginCropRect), 1 / scale);
- set_store_value(imageCropRectIntent, $imageCropRectIntent = cropIntent, $imageCropRectIntent);
- set_store_value(imageCropRect, $imageCropRect = cropIntent, $imageCropRect);
- };
- const handleGestureEnd = ({ detail }) => {
- // don't handle gesture as we're already handling input with interactable
- if (!gestureOriginCropRect) return;
- // now interacting
- set_store_value(isInteracting, $isInteracting = false, $isInteracting);
- handleScaleGesture(detail);
- // no intent (needs to be set before crop rect is updated)
- set_store_value(imageCropRectIntent, $imageCropRectIntent = undefined, $imageCropRectIntent);
- gestureOriginCropRect = undefined;
- history.write();
- };
- //
- // resizing with wheel
- //
- let zoomHistoryTimeoutId;
- const handleWheel = e => {
- const stageWheelPosition = getEventPositionInStage(e, $rootRect, $stageRect);
- // only block input if wheel is used within image rectangle
- if (cropEnableLimitWheelInputToCropSelection && !rectContainsPoint($imageSelectionRect, stageWheelPosition)) return;
- interaction = "zoom";
- // now interacting
- set_store_value(isInteracting, $isInteracting = true, $isInteracting);
- // don't run default actions, prevent other actions from running
- e.preventDefault();
- e.stopPropagation();
- // convert wheel delta to scalar
- const delta = getWheelDelta(e);
- const scalar = 1 + delta / 100;
- // get current crop rect
- const currentCropRect = rectClone($imageCropRect);
- // if already zoomed in, block further zoom in instructions
- const isMinSize = Math.min($imageCropRect.width / $imageCropMinSize.width, $imageCropRect.height / $imageCropMinSize.height) === 1;
- // if is fully zoomed out and trying to zoom out more and crop shape is free, fit image aspect ratio
- if (cropEnableZoomMatchImageAspectRatio && $imageCropLimitToImage) {
- const isAtMaxCropSize = isCropMaxSize($imageCropRect, $imageSize, $imageRotation);
- if (isCustomCrop() && isAtMaxCropSize && delta > 0 && isImageSelectionCentered) {
- set_store_value(isInteracting, $isInteracting = false, $isInteracting);
- const newCropRect = isRotatedSideways($imageRotation)
- ? rectCreateFromSize({
- height: $imageSize.width,
- width: $imageSize.height
- })
- : rectCreateFromSize($imageSize);
- // no change, exit
- if (rectEqual(currentCropRect, newCropRect)) return;
- // if we were previously zooming in we need to clear the timeout to prevent two history entries
- clearTimeout(zoomHistoryTimeoutId);
- // test if crop rect in history is same as new crop rect, this is possible when zooming in and out real quick
- if (rectEqual(history.state.crop, newCropRect)) return;
- // store new crop rect
- set_store_value(imageCropRect, $imageCropRect = newCropRect, $imageCropRect);
- history.write();
- return;
- }
- }
- // by default when zooming, zoom from center of crop rectangle
- let origin = rectCenter($imageCropRect);
- // when zooming in, zoom in on the part of the image below the mouse cursor
- if (cropEnableZoomTowardsWheelPosition && delta < 0 && !isMinSize) {
- const selectionOffset = vectorSubtract(vectorClone(stageWheelPosition), $imageSelectionRect);
- const imageSelectionScale = Math.min($imageSelectionRect.width / $imageCropRect.width, $imageSelectionRect.height / $imageCropRect.height);
- // if wheel is inside image selection rectangle (slightly expanded version), we zoom based on position in the rectangle, if not, we use the selection center
- const expandedImageSelection = rectScale(rectClone($imageSelectionRect), 1.1);
- origin = rectContainsPoint(expandedImageSelection, stageWheelPosition)
- ? vectorAdd(rectClone($imageCropRect), vectorMultiply(selectionOffset, 1 / imageSelectionScale))
- : origin;
- }
- let newCropRect = rectScale(rectClone($imageCropRect), scalar, origin);
- // determin if is new crop rect exceeds min or max size, if so, limit
- if (!sizeContains($imageCropRangeAspectRatio[1], newCropRect)) {
- // exceeds max size, limit to max size and position at new crop rect center
- newCropRect = rectCreateWithCenter(rectCenter(newCropRect), $imageCropRangeAspectRatio[1]);
- }
- if (!sizeContains(newCropRect, $imageCropRangeAspectRatio[0])) {
- // exceeds min size, limit to min size and position at new crop rect center
- newCropRect = rectCreateWithCenter(rectCenter(newCropRect), $imageCropRangeAspectRatio[0]);
- }
- // no change, exit
- if (rectEqual(currentCropRect, newCropRect, fixPrecision)) {
- set_store_value(isInteracting, $isInteracting = false, $isInteracting);
- return;
- }
- // attempt to update the rectangle, we use fixPrecision so the width and height are nice integers when at max zoom (this makes sure the `isMinSize` variable is set to true at this point)
- set_store_value(imageCropRect, $imageCropRect = rectApply(newCropRect, v => fixPrecision(v, 5)), $imageCropRect);
- // done!
- set_store_value(isInteracting, $isInteracting = false, $isInteracting);
- // write history timer
- clearTimeout(zoomHistoryTimeoutId);
- zoomHistoryTimeoutId = setTimeout(
- () => {
- history.write();
- },
- 500
- );
- };
- //
- // recenter
- //
- // the 'measure' event triggers the editor to center and scale up the crop
- const dispatch = createEventDispatcher();
- const handleRecenterAction = () => {
- dispatch("measure", rectClone($utilRect));
- };
- // auto recenter after timeout
- let cropAutoCenterImageSelectionTimeoutId;
- // animations
- const recenterOpacity = spring(0, { precision: 0.0001 });
- component_subscribe($$self, recenterOpacity, value => $$invalidate(27, $recenterOpacity = value));
- const recenterOffset = spring();
- component_subscribe($$self, recenterOffset, value => $$invalidate(28, $recenterOffset = value));
- //
- // crop selection presets
- //
- const selectedPresetIndex = derived([imageCropAspectRatio, imageOutputSize], ([$cropAspectRatio, $imageOutputSize], set) => {
- if (!cropSelectPresetOptions) return;
- const options = flattenOptions(cropSelectPresetOptions);
- const matchedOptionValue = [...options].// to value
- map(option => option[0]).// sort sizes first
- sort((a, b) => {
- if (isArray(a[0]) && !isArray(b[0])) return 1;
- return -1;
- }).// match value
- find(value => {
- if (isArray(value) && $imageOutputSize) {
- // size + aspect ratio
- const [width, height] = value;
- const outputSizeMatches = $imageOutputSize.width === width && $imageOutputSize.height === height;
- const aspectRatioMatches = $cropAspectRatio === getAspectRatio(width, height);
- return outputSizeMatches && aspectRatioMatches;
- }
- // aspect ratio
- return value === $cropAspectRatio;
- });
- const index = options.// to value
- map(option => option[0]).// find index of matching value
- findIndex(value => isArray(value)
- ? arrayEqual(value, matchedOptionValue)
- : value === matchedOptionValue);
- set(index);
- });
- component_subscribe($$self, selectedPresetIndex, value => $$invalidate(114, $selectedPresetIndex = value));
- const getAspectRatioBySelectedIndex = selectedIndex => {
- if (!cropSelectPresetOptions || selectedIndex === -1) return;
- const selectedValue = flattenOptions(cropSelectPresetOptions)[selectedIndex][0];
- return !selectedValue
- ? undefined
- : isArray(selectedValue)
- ? getAspectRatio(selectedValue[0], selectedValue[1])
- : selectedValue;
- };
- //
- // crop guides
- //
- const imageSelectionGuides = derived([rootLineColor, imageSelectionRectPresentation, isInteractingFraction], ([$rootLineColor, $rect, $isInteractingFraction], set) => {
- const { rows, cols, opacity } = cropWillRenderImageSelectionGuides(interaction, $isInteractingFraction);
- if (!$rect || opacity <= 0) return set([]);
- const { x, y, width, height } = $rect;
- const w = width / cols;
- const h = height / rows;
- const shapes = [];
- // rows
- for (let r = 1; r <= rows - 1; r++) {
- const yo = y + h * r;
- shapes.push({
- id: `image-selection-guide-row-${r}`,
- points: [vectorCreate(x, yo), vectorCreate(x + width, yo)],
- opacity,
- strokeWidth: 1,
- strokeColor: $rootLineColor
- });
- }
- // cols
- for (let c = 1; c <= cols - 1; c++) {
- const xo = x + w * c;
- shapes.push({
- id: `image-selection-guide-col-${c}`,
- points: [vectorCreate(xo, y), vectorCreate(xo, y + height)],
- opacity,
- strokeWidth: 1,
- strokeColor: $rootLineColor
- });
- }
- set(shapes);
- });
- component_subscribe($$self, imageSelectionGuides, value => $$invalidate(137, $imageSelectionGuides = value));
- const syncGuides = () => {
- // remove existing guides
- const overlayMarkup = $imageOverlayMarkup.filter(markup => !(/^image\-selection\-guide/).test(markup.id));
- if ($isActive) {
- set_store_value(imageOverlayMarkup, $imageOverlayMarkup = [...overlayMarkup, ...$imageSelectionGuides], $imageOverlayMarkup);
- } else {
- set_store_value(imageOverlayMarkup, $imageOverlayMarkup = overlayMarkup, $imageOverlayMarkup);
- }
- };
- const cropUniqueId = `crop-${getUniqueId()}`;
- let transformInitial = cropEnableRotationInput ? "rotation" : "zoom";
- let transformToolInitial = cropUniqueId + "-" + transformInitial;
- let transformSelected = transformToolInitial;
- let root = undefined;
- // fixes rendering issue with stage being empty in overlay mode, this basically redispatches the measure event so the stage is correctly measured
- let stageRef;
- const footerOffset = spring($animation ? 20 : 0);
- component_subscribe($$self, footerOffset, value => $$invalidate(142, $footerOffset = value));
- function measure_handler_1(event) {
- bubble($$self, event);
- }
- const select_handler = ({ detail }) => $$invalidate(5, transformSelected = detail);
- function div0_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- stageRef = $$value;
- $$invalidate(6, stageRef);
- });
- }
- const interactable_function = e => getEventPositionInViewport(e);
- function util_root_binding(value) {
- root = value;
- $$invalidate(13, root);
- }
- function measure_handler(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("isActive" in $$props) $$subscribe_isActive($$invalidate(1, isActive = $$props.isActive));
- if ("stores" in $$props) $$invalidate(88, stores = $$props.stores);
- if ("cropImageSelectionCornerStyle" in $$props) $$invalidate(2, cropImageSelectionCornerStyle = $$props.cropImageSelectionCornerStyle);
- if ("cropWillRenderImageSelectionGuides" in $$props) $$invalidate(89, cropWillRenderImageSelectionGuides = $$props.cropWillRenderImageSelectionGuides);
- if ("cropAutoCenterImageSelectionTimeout" in $$props) $$invalidate(90, cropAutoCenterImageSelectionTimeout = $$props.cropAutoCenterImageSelectionTimeout);
- if ("cropEnableZoomMatchImageAspectRatio" in $$props) $$invalidate(91, cropEnableZoomMatchImageAspectRatio = $$props.cropEnableZoomMatchImageAspectRatio);
- if ("cropEnableRotateMatchImageAspectRatio" in $$props) $$invalidate(92, cropEnableRotateMatchImageAspectRatio = $$props.cropEnableRotateMatchImageAspectRatio);
- if ("cropEnableRotationInput" in $$props) $$invalidate(93, cropEnableRotationInput = $$props.cropEnableRotationInput);
- if ("cropEnableZoom" in $$props) $$invalidate(3, cropEnableZoom = $$props.cropEnableZoom);
- if ("cropEnableZoomInput" in $$props) $$invalidate(94, cropEnableZoomInput = $$props.cropEnableZoomInput);
- if ("cropEnableZoomAutoHide" in $$props) $$invalidate(95, cropEnableZoomAutoHide = $$props.cropEnableZoomAutoHide);
- if ("cropEnableImageSelection" in $$props) $$invalidate(96, cropEnableImageSelection = $$props.cropEnableImageSelection);
- if ("cropEnableInfoIndicator" in $$props) $$invalidate(97, cropEnableInfoIndicator = $$props.cropEnableInfoIndicator);
- if ("cropEnableZoomTowardsWheelPosition" in $$props) $$invalidate(98, cropEnableZoomTowardsWheelPosition = $$props.cropEnableZoomTowardsWheelPosition);
- if ("cropEnableLimitWheelInputToCropSelection" in $$props) $$invalidate(99, cropEnableLimitWheelInputToCropSelection = $$props.cropEnableLimitWheelInputToCropSelection);
- if ("cropEnableCenterImageSelection" in $$props) $$invalidate(100, cropEnableCenterImageSelection = $$props.cropEnableCenterImageSelection);
- if ("cropEnableButtonRotateLeft" in $$props) $$invalidate(101, cropEnableButtonRotateLeft = $$props.cropEnableButtonRotateLeft);
- if ("cropEnableButtonRotateRight" in $$props) $$invalidate(102, cropEnableButtonRotateRight = $$props.cropEnableButtonRotateRight);
- if ("cropEnableButtonFlipHorizontal" in $$props) $$invalidate(103, cropEnableButtonFlipHorizontal = $$props.cropEnableButtonFlipHorizontal);
- if ("cropEnableButtonFlipVertical" in $$props) $$invalidate(104, cropEnableButtonFlipVertical = $$props.cropEnableButtonFlipVertical);
- if ("cropSelectPresetOptions" in $$props) $$invalidate(105, cropSelectPresetOptions = $$props.cropSelectPresetOptions);
- if ("cropEnableSelectPreset" in $$props) $$invalidate(106, cropEnableSelectPreset = $$props.cropEnableSelectPreset);
- if ("cropEnableButtonToggleCropLimit" in $$props) $$invalidate(107, cropEnableButtonToggleCropLimit = $$props.cropEnableButtonToggleCropLimit);
- if ("cropWillRenderTools" in $$props) $$invalidate(108, cropWillRenderTools = $$props.cropWillRenderTools);
- if ("locale" in $$props) $$invalidate(4, locale = $$props.locale);
- if ("tools" in $$props) $$invalidate(0, tools = $$props.tools);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[3] & /*$env*/ 33554432) {
- $$invalidate(132, isOverlayMode = $env.layoutMode === "overlay");
- }
- if ($$self.$$.dirty[3] & /*cropEnableSelectPreset*/ 8192 | $$self.$$.dirty[4] & /*isOverlayMode*/ 256) {
- $$invalidate(113, shouldRenderPresetSelect = cropEnableSelectPreset && !isOverlayMode);
- }
- if ($$self.$$.dirty[3] & /*$utilRect, $imageSelectionRect*/ 1342177280) {
- // determine if we can center the crop, if we can, show the crop center button
- $$invalidate(128, imageSelectionCenteredRect = $utilRect && $imageSelectionRect && rectCenterRect($utilRect, $imageSelectionRect));
- }
- if ($$self.$$.dirty[3] & /*$imageSelectionRect*/ 268435456 | $$self.$$.dirty[4] & /*imageSelectionCenteredRect*/ 16) {
- $$invalidate(129, isImageSelectionDisplayed = !!($imageSelectionRect && imageSelectionCenteredRect));
- }
- if ($$self.$$.dirty[3] & /*$imageSelectionRect*/ 268435456 | $$self.$$.dirty[4] & /*isImageSelectionDisplayed, imageSelectionCenteredRect*/ 48) {
- $$invalidate(115, isImageSelectionCentered = isImageSelectionDisplayed && rectEqual($imageSelectionRect, imageSelectionCenteredRect, value => fixPrecision(value, 5)));
- }
- if ($$self.$$.dirty[0] & /*locale, $imageRotation*/ 272 | $$self.$$.dirty[3] & /*cropWillRenderTools, cropEnableButtonRotateLeft, cropEnableButtonRotateRight, cropEnableButtonFlipHorizontal, $imageFlipY, $imageFlipX, cropEnableButtonFlipVertical, shouldRenderPresetSelect, cropSelectPresetOptions, $selectedPresetIndex, isImageSelectionCentered, $imageSize, $imageCropMinSize, cropEnableButtonToggleCropLimit, $imageCropLimitToImage, $env*/ 67034880) {
- $$invalidate(0, tools = cropWillRenderTools(
- [
- cropEnableButtonRotateLeft && [
- "Button",
- "rotate-left",
- {
- label: locale.cropLabelButtonRotateLeft,
- labelClass: "PinturaToolbarContentWide",
- icon: locale.cropIconButtonRotateLeft,
- onclick: () => {
- applyRotation(-Math.PI / 2);
- history.write();
- }
- }
- ],
- cropEnableButtonRotateRight && [
- "Button",
- "rotate-right",
- {
- label: locale.cropLabelButtonRotateRight,
- labelClass: "PinturaToolbarContentWide",
- icon: locale.cropIconButtonRotateRight,
- onclick: () => {
- applyRotation(Math.PI / 2);
- history.write();
- }
- }
- ],
- cropEnableButtonFlipHorizontal && [
- "Button",
- "flip-horizontal",
- {
- label: locale.cropLabelButtonFlipHorizontal,
- labelClass: "PinturaToolbarContentWide",
- icon: locale.cropIconButtonFlipHorizontal,
- onclick: () => {
- if (isRotatedSideways($imageRotation)) {
- set_store_value(imageFlipY, $imageFlipY = !$imageFlipY, $imageFlipY);
- } else {
- set_store_value(imageFlipX, $imageFlipX = !$imageFlipX, $imageFlipX);
- }
- history.write();
- }
- }
- ],
- cropEnableButtonFlipVertical && [
- "Button",
- "flip-vertical",
- {
- label: locale.cropLabelButtonFlipVertical,
- labelClass: "PinturaToolbarContentWide",
- icon: locale.cropIconButtonFlipVertical,
- onclick: () => {
- if (isRotatedSideways($imageRotation)) {
- set_store_value(imageFlipX, $imageFlipX = !$imageFlipX, $imageFlipX);
- } else {
- set_store_value(imageFlipY, $imageFlipY = !$imageFlipY, $imageFlipY);
- }
- history.write();
- }
- }
- ],
- shouldRenderPresetSelect && cropSelectPresetOptions && [
- "Dropdown",
- "select-preset",
- {
- icon: localize(locale.cropIconSelectPreset, locale, getAspectRatioBySelectedIndex($selectedPresetIndex)),
- label: locale.cropLabelSelectPreset,
- labelClass: "PinturaToolbarContentWide",
- options: cropSelectPresetOptions,
- selectedIndex: $selectedPresetIndex,
- onchange: ({ value }) => {
- if (isArray(value)) {
- set_store_value(imageCropAspectRatio, $imageCropAspectRatio = getAspectRatio(value[0], value[1]), $imageCropAspectRatio);
- set_store_value(imageOutputSize, $imageOutputSize = sizeCreateFromArray(value), $imageOutputSize);
- } else {
- set_store_value(imageCropAspectRatio, $imageCropAspectRatio = value, $imageCropAspectRatio);
- }
- if (isImageSelectionCentered) {
- handleRecenterAction();
- }
- history.write();
- },
- optionMapper: option => {
- // if no aspect ratio found we enable the option by default
- let disabled = false;
- // get aspect ratio for this option
- const optionAspectRatio = isArray(option.value)
- ? option.value[0] / option.value[1]
- : option.value;
- // can be undefined in which case we don't need to check anything
- if (optionAspectRatio) {
- const maxCropSize = getMaxSizeInRect($imageSize, $imageRotation, optionAspectRatio);
- disabled = maxCropSize.width < $imageCropMinSize.width || maxCropSize.height < $imageCropMinSize.height;
- }
- // add icon for this option
- option.icon = getSelectionPresetOptionIcon(option.value, { bounds: 14 });
- return { ...option, disabled };
- }
- }
- ],
- cropEnableButtonToggleCropLimit && [
- "Dropdown",
- "select-crop-limit",
- {
- icon: localize(locale.cropIconCropBoundary, locale, $imageCropLimitToImage),
- label: locale.cropLabelCropBoundary,
- labelClass: "PinturaToolbarContentWide",
- onchange: ({ value }) => {
- set_store_value(imageCropLimitToImage, $imageCropLimitToImage = value, $imageCropLimitToImage);
- history.write();
- },
- options: [
- [
- true,
- locale.cropLabelCropBoundaryEdge,
- {
- icon: localize(locale.cropIconCropBoundary, locale, true)
- }
- ],
- [
- false,
- locale.cropLabelCropBoundaryNone,
- {
- icon: localize(locale.cropIconCropBoundary, locale, false)
- }
- ]
- ]
- }
- ]
- ].filter(Boolean),
- $env,
- () => ({})
- ).filter(Boolean));
- }
- if ($$self.$$.dirty[0] & /*$isActive*/ 512) {
- $isActive && imageOutlineOpacity.set(1);
- }
- if ($$self.$$.dirty[3] & /*$imageCropLimitToImage*/ 16777216) {
- $$invalidate(14, imageZoomLevelMin = $imageCropLimitToImage ? 0 : -1);
- }
- if ($$self.$$.dirty[3] & /*$utilRect*/ 1073741824 | $$self.$$.dirty[4] & /*$stageRect*/ 1) {
- $$invalidate(125, imageSelectionOffset = $utilRect && vectorCreate(-($stageRect.x - $utilRect.x), -($stageRect.y - $utilRect.y)));
- }
- if ($$self.$$.dirty[4] & /*$imageSelectionRectPresentation, imageSelectionOffset*/ 10) {
- // normalized crop bounds, we use these to limit the crop interactions to the view
- $$invalidate(126, imageSelectionCenter = $imageSelectionRectPresentation && vectorCreate(snapToPixel($imageSelectionRectPresentation.x + $imageSelectionRectPresentation.width * 0.5 + imageSelectionOffset.x), snapToPixel($imageSelectionRectPresentation.y + $imageSelectionRectPresentation.height * 0.5 + imageSelectionOffset.y)));
- }
- if ($$self.$$.dirty[3] & /*$imageSelectionRectSnapshot*/ 134217728) {
- $$invalidate(130, isResizingSelection = $imageSelectionRectSnapshot != null);
- }
- if ($$self.$$.dirty[3] & /*$utilRect*/ 1073741824 | $$self.$$.dirty[4] & /*imageSelectionCenteredRect*/ 16) {
- $$invalidate(131, isMaxSelectionRect = $utilRect && imageSelectionCenteredRect && (imageSelectionCenteredRect.height === $utilRect.height || imageSelectionCenteredRect.width === $utilRect.width));
- }
- if ($$self.$$.dirty[3] & /*$presentationScalar*/ 536870912 | $$self.$$.dirty[4] & /*isMaxSelectionRect, $imageScalar*/ 1152) {
- $$invalidate(133, canZoomToCenter = !isMaxSelectionRect && $presentationScalar < 1 && $imageScalar < 1);
- }
- if ($$self.$$.dirty[3] & /*isImageSelectionCentered*/ 4194304 | $$self.$$.dirty[4] & /*isImageSelectionDisplayed, isResizingSelection, canZoomToCenter*/ 608) {
- $$invalidate(10, canCenter = isImageSelectionDisplayed && !isResizingSelection && (!isImageSelectionCentered || canZoomToCenter));
- }
- if ($$self.$$.dirty[0] & /*$imageCropRect*/ 128 | $$self.$$.dirty[3] & /*cropEnableInfoIndicator*/ 16 | $$self.$$.dirty[4] & /*isOverlayMode*/ 256) {
- $$invalidate(16, shouldRenderInfoIndicator = cropEnableInfoIndicator && !!$imageCropRect && !isOverlayMode);
- }
- if ($$self.$$.dirty[4] & /*$imageSelectionRectPresentation, imageSelectionOffset*/ 10) {
- $$invalidate(11, imageSelectionRectOffset = $imageSelectionRectPresentation && imageSelectionOffset && {
- x: $imageSelectionRectPresentation.x + imageSelectionOffset.x,
- y: $imageSelectionRectPresentation.y + imageSelectionOffset.y,
- width: $imageSelectionRectPresentation.width,
- height: $imageSelectionRectPresentation.height
- });
- }
- if ($$self.$$.dirty[0] & /*imageSelectionRectOffset*/ 2048 | $$self.$$.dirty[3] & /*cropEnableImageSelection*/ 8 | $$self.$$.dirty[4] & /*isOverlayMode*/ 256) {
- $$invalidate(17, shouldRenderImageSelection = cropEnableImageSelection && !!imageSelectionRectOffset && !isOverlayMode);
- }
- if ($$self.$$.dirty[2] & /*cropAutoCenterImageSelectionTimeout*/ 268435456 | $$self.$$.dirty[3] & /*cropEnableCenterImageSelection*/ 128 | $$self.$$.dirty[4] & /*imageSelectionCenter*/ 4) {
- $$invalidate(18, shouldRenderImageSelectionRecenterButton = cropEnableCenterImageSelection && !!imageSelectionCenter && !cropAutoCenterImageSelectionTimeout);
- }
- if ($$self.$$.dirty[0] & /*canCenter*/ 1024 | $$self.$$.dirty[2] & /*cropAutoCenterImageSelectionTimeout*/ 268435456 | $$self.$$.dirty[3] & /*$isInteracting, cropAutoCenterImageSelectionTimeoutId*/ 67174400) {
- if (canCenter && cropAutoCenterImageSelectionTimeout && !$isInteracting) {
- clearTimeout(cropAutoCenterImageSelectionTimeoutId);
- $$invalidate(109, cropAutoCenterImageSelectionTimeoutId = setTimeout(handleRecenterAction, cropAutoCenterImageSelectionTimeout));
- }
- }
- if ($$self.$$.dirty[3] & /*$isInteracting, cropAutoCenterImageSelectionTimeoutId*/ 67174400) {
- if ($isInteracting) clearTimeout(cropAutoCenterImageSelectionTimeoutId);
- }
- if ($$self.$$.dirty[0] & /*canCenter*/ 1024) {
- recenterOpacity.set(canCenter ? 1 : 0);
- }
- if ($$self.$$.dirty[4] & /*imageSelectionCenter*/ 4) {
- recenterOffset.set(imageSelectionCenter);
- }
- if ($$self.$$.dirty[0] & /*$isActive*/ 512 | $$self.$$.dirty[4] & /*$framePadded, $imagePreviewModifiers*/ 6144) {
- //
- // enable seeing the image outside of the crop area, and disable the vignette effect
- //
- if ($isActive && !$framePadded) {
- set_store_value(
- imagePreviewModifiers,
- $imagePreviewModifiers["crop"] = {
- maskOpacity: 0.85,
- maskMarkupOpacity: 0.85
- },
- $imagePreviewModifiers
- );
- } else {
- delete $imagePreviewModifiers["crop"];
- }
- }
- if ($$self.$$.dirty[4] & /*$imageSelectionGuides*/ 8192) {
- // if overlay top changes
- $imageSelectionGuides && syncGuides();
- }
- if ($$self.$$.dirty[3] & /*$env*/ 33554432) {
- //
- // Transform tabs
- //
- $$invalidate(138, hasPlentyVerticalSpace = $env.verticalSpace !== "short");
- }
- if ($$self.$$.dirty[4] & /*hasPlentyVerticalSpace, isOverlayMode*/ 16640) {
- $$invalidate(19, shouldRenderToolbar = hasPlentyVerticalSpace && !isOverlayMode);
- }
- if ($$self.$$.dirty[0] & /*cropEnableZoom*/ 8 | $$self.$$.dirty[3] & /*cropEnableZoomInput*/ 2) {
- $$invalidate(139, couldRenderZoomInput = cropEnableZoom && cropEnableZoomInput);
- }
- if ($$self.$$.dirty[3] & /*cropEnableZoomAutoHide*/ 4 | $$self.$$.dirty[4] & /*hasPlentyVerticalSpace, couldRenderZoomInput*/ 49152) {
- $$invalidate(140, shouldRenderZoomInput = cropEnableZoomAutoHide
- ? hasPlentyVerticalSpace && couldRenderZoomInput
- : couldRenderZoomInput);
- }
- if ($$self.$$.dirty[3] & /*cropEnableRotationInput*/ 1 | $$self.$$.dirty[4] & /*shouldRenderZoomInput*/ 65536) {
- $$invalidate(20, shouldRenderFooter = cropEnableRotationInput || shouldRenderZoomInput);
- }
- if ($$self.$$.dirty[4] & /*shouldRenderZoomInput*/ 65536) {
- if (!shouldRenderZoomInput) {
- $$invalidate(5, transformSelected = transformToolInitial);
- }
- }
- if ($$self.$$.dirty[0] & /*transformSelected*/ 32) {
- $$invalidate(21, tabsConfig = {
- name: cropUniqueId,
- selected: transformSelected
- });
- }
- if ($$self.$$.dirty[0] & /*locale*/ 16 | $$self.$$.dirty[3] & /*cropEnableRotationInput*/ 1 | $$self.$$.dirty[4] & /*shouldRenderZoomInput*/ 65536) {
- $$invalidate(12, tabs = [
- cropEnableRotationInput && {
- id: cropUniqueId + "-rotation",
- label: locale.cropLabelTabRotation
- },
- shouldRenderZoomInput && {
- id: cropUniqueId + "-zoom",
- label: locale.cropLabelTabZoom
- }
- ].filter(Boolean));
- }
- if ($$self.$$.dirty[0] & /*tabs*/ 4096) {
- $$invalidate(22, panels = tabs.map(tab => tab.id));
- }
- if ($$self.$$.dirty[0] & /*stageRef*/ 64 | $$self.$$.dirty[4] & /*isOverlayMode*/ 256) {
- if (stageRef && !stageRef.children.length && isOverlayMode) {
- stageRef.dispatchEvent(new CustomEvent("measure", { detail: stageRef.rect }));
- }
- }
- if ($$self.$$.dirty[0] & /*$isActive*/ 512 | $$self.$$.dirty[4] & /*$animation*/ 131072) {
- $animation && footerOffset.set($isActive ? 0 : 20);
- }
- if ($$self.$$.dirty[4] & /*$footerOffset*/ 262144) {
- $$invalidate(23, footerStyle = $footerOffset
- ? `transform: translateY(${$footerOffset}px)`
- : undefined);
- }
- };
- return [
- tools,
- isActive,
- cropImageSelectionCornerStyle,
- cropEnableZoom,
- locale,
- transformSelected,
- stageRef,
- $imageCropRect,
- $imageRotation,
- $isActive,
- canCenter,
- imageSelectionRectOffset,
- tabs,
- root,
- imageZoomLevelMin,
- $rootRect,
- shouldRenderInfoIndicator,
- shouldRenderImageSelection,
- shouldRenderImageSelectionRecenterButton,
- shouldRenderToolbar,
- shouldRenderFooter,
- tabsConfig,
- panels,
- footerStyle,
- $imageRotationRange,
- $imageZoomLevelRange,
- $imageZoomLevel,
- $recenterOpacity,
- $recenterOffset,
- env,
- isInteracting,
- rootRect,
- stageRect,
- utilRect,
- animation,
- elasticityMultiplier,
- rangeInputElasticity,
- presentationScalar,
- imagePreviewModifiers,
- imageFlipX,
- imageFlipY,
- imageRotation,
- imageRotationRange,
- imageOutputSize,
- imageSelectionRect,
- imageSelectionRectSnapshot,
- imageSelectionRectIntent,
- imageSelectionRectPresentation,
- imageCropRectIntent,
- imageCropRectOrigin,
- imageCropRect,
- imageCropMinSize,
- imageCropMaxSize,
- imageCropRange,
- imageCropAspectRatio,
- imageCropLimitToImage,
- imageSize,
- imageScalar,
- imageOverlayMarkup,
- framePadded,
- handleSelectionGrab,
- handleSelectionDrag,
- handleSelectionRelease,
- handleRotateStart,
- handleRotateMove,
- handleRotateEnd,
- handleImageDragStart,
- handleImageDrag,
- handleImageDragEnd,
- handleImageDragRelease,
- imageCropRangeAspectRatio,
- imageZoomLevelRange,
- imageZoomLevel,
- handleResizeStart,
- handleResizeMove,
- handleResizeEnd,
- handleGestureStart,
- handleGestureUpdate,
- handleGestureEnd,
- handleWheel,
- handleRecenterAction,
- recenterOpacity,
- recenterOffset,
- selectedPresetIndex,
- imageSelectionGuides,
- cropUniqueId,
- footerOffset,
- name,
- stores,
- cropWillRenderImageSelectionGuides,
- cropAutoCenterImageSelectionTimeout,
- cropEnableZoomMatchImageAspectRatio,
- cropEnableRotateMatchImageAspectRatio,
- cropEnableRotationInput,
- cropEnableZoomInput,
- cropEnableZoomAutoHide,
- cropEnableImageSelection,
- cropEnableInfoIndicator,
- cropEnableZoomTowardsWheelPosition,
- cropEnableLimitWheelInputToCropSelection,
- cropEnableCenterImageSelection,
- cropEnableButtonRotateLeft,
- cropEnableButtonRotateRight,
- cropEnableButtonFlipHorizontal,
- cropEnableButtonFlipVertical,
- cropSelectPresetOptions,
- cropEnableSelectPreset,
- cropEnableButtonToggleCropLimit,
- cropWillRenderTools,
- cropAutoCenterImageSelectionTimeoutId,
- $imageSize,
- $imageFlipY,
- $imageFlipX,
- shouldRenderPresetSelect,
- $selectedPresetIndex,
- isImageSelectionCentered,
- $imageCropMinSize,
- $imageCropLimitToImage,
- $env,
- $isInteracting,
- $imageSelectionRectSnapshot,
- $imageSelectionRect,
- $presentationScalar,
- $utilRect,
- $stageRect,
- imageSelectionOffset,
- imageSelectionCenter,
- $imageSelectionRectPresentation,
- imageSelectionCenteredRect,
- isImageSelectionDisplayed,
- isResizingSelection,
- isMaxSelectionRect,
- isOverlayMode,
- canZoomToCenter,
- $imageScalar,
- $framePadded,
- $imagePreviewModifiers,
- $imageSelectionGuides,
- hasPlentyVerticalSpace,
- couldRenderZoomInput,
- shouldRenderZoomInput,
- $animation,
- $footerOffset,
- measure_handler_1,
- select_handler,
- div0_binding,
- interactable_function,
- util_root_binding,
- measure_handler
- ];
- }
- class Crop extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$k,
- create_fragment$k,
- safe_not_equal,
- {
- name: 87,
- isActive: 1,
- stores: 88,
- cropImageSelectionCornerStyle: 2,
- cropWillRenderImageSelectionGuides: 89,
- cropAutoCenterImageSelectionTimeout: 90,
- cropEnableZoomMatchImageAspectRatio: 91,
- cropEnableRotateMatchImageAspectRatio: 92,
- cropEnableRotationInput: 93,
- cropEnableZoom: 3,
- cropEnableZoomInput: 94,
- cropEnableZoomAutoHide: 95,
- cropEnableImageSelection: 96,
- cropEnableInfoIndicator: 97,
- cropEnableZoomTowardsWheelPosition: 98,
- cropEnableLimitWheelInputToCropSelection: 99,
- cropEnableCenterImageSelection: 100,
- cropEnableButtonRotateLeft: 101,
- cropEnableButtonRotateRight: 102,
- cropEnableButtonFlipHorizontal: 103,
- cropEnableButtonFlipVertical: 104,
- cropSelectPresetOptions: 105,
- cropEnableSelectPreset: 106,
- cropEnableButtonToggleCropLimit: 107,
- cropWillRenderTools: 108,
- locale: 4,
- tools: 0
- },
- [-1, -1, -1, -1, -1, -1, -1]
- );
- }
- get name() {
- return this.$$.ctx[87];
- }
- get isActive() {
- return this.$$.ctx[1];
- }
- set isActive(isActive) {
- this.$set({ isActive });
- flush();
- }
- get stores() {
- return this.$$.ctx[88];
- }
- set stores(stores) {
- this.$set({ stores });
- flush();
- }
- get cropImageSelectionCornerStyle() {
- return this.$$.ctx[2];
- }
- set cropImageSelectionCornerStyle(cropImageSelectionCornerStyle) {
- this.$set({ cropImageSelectionCornerStyle });
- flush();
- }
- get cropWillRenderImageSelectionGuides() {
- return this.$$.ctx[89];
- }
- set cropWillRenderImageSelectionGuides(cropWillRenderImageSelectionGuides) {
- this.$set({ cropWillRenderImageSelectionGuides });
- flush();
- }
- get cropAutoCenterImageSelectionTimeout() {
- return this.$$.ctx[90];
- }
- set cropAutoCenterImageSelectionTimeout(cropAutoCenterImageSelectionTimeout) {
- this.$set({ cropAutoCenterImageSelectionTimeout });
- flush();
- }
- get cropEnableZoomMatchImageAspectRatio() {
- return this.$$.ctx[91];
- }
- set cropEnableZoomMatchImageAspectRatio(cropEnableZoomMatchImageAspectRatio) {
- this.$set({ cropEnableZoomMatchImageAspectRatio });
- flush();
- }
- get cropEnableRotateMatchImageAspectRatio() {
- return this.$$.ctx[92];
- }
- set cropEnableRotateMatchImageAspectRatio(cropEnableRotateMatchImageAspectRatio) {
- this.$set({ cropEnableRotateMatchImageAspectRatio });
- flush();
- }
- get cropEnableRotationInput() {
- return this.$$.ctx[93];
- }
- set cropEnableRotationInput(cropEnableRotationInput) {
- this.$set({ cropEnableRotationInput });
- flush();
- }
- get cropEnableZoom() {
- return this.$$.ctx[3];
- }
- set cropEnableZoom(cropEnableZoom) {
- this.$set({ cropEnableZoom });
- flush();
- }
- get cropEnableZoomInput() {
- return this.$$.ctx[94];
- }
- set cropEnableZoomInput(cropEnableZoomInput) {
- this.$set({ cropEnableZoomInput });
- flush();
- }
- get cropEnableZoomAutoHide() {
- return this.$$.ctx[95];
- }
- set cropEnableZoomAutoHide(cropEnableZoomAutoHide) {
- this.$set({ cropEnableZoomAutoHide });
- flush();
- }
- get cropEnableImageSelection() {
- return this.$$.ctx[96];
- }
- set cropEnableImageSelection(cropEnableImageSelection) {
- this.$set({ cropEnableImageSelection });
- flush();
- }
- get cropEnableInfoIndicator() {
- return this.$$.ctx[97];
- }
- set cropEnableInfoIndicator(cropEnableInfoIndicator) {
- this.$set({ cropEnableInfoIndicator });
- flush();
- }
- get cropEnableZoomTowardsWheelPosition() {
- return this.$$.ctx[98];
- }
- set cropEnableZoomTowardsWheelPosition(cropEnableZoomTowardsWheelPosition) {
- this.$set({ cropEnableZoomTowardsWheelPosition });
- flush();
- }
- get cropEnableLimitWheelInputToCropSelection() {
- return this.$$.ctx[99];
- }
- set cropEnableLimitWheelInputToCropSelection(cropEnableLimitWheelInputToCropSelection) {
- this.$set({ cropEnableLimitWheelInputToCropSelection });
- flush();
- }
- get cropEnableCenterImageSelection() {
- return this.$$.ctx[100];
- }
- set cropEnableCenterImageSelection(cropEnableCenterImageSelection) {
- this.$set({ cropEnableCenterImageSelection });
- flush();
- }
- get cropEnableButtonRotateLeft() {
- return this.$$.ctx[101];
- }
- set cropEnableButtonRotateLeft(cropEnableButtonRotateLeft) {
- this.$set({ cropEnableButtonRotateLeft });
- flush();
- }
- get cropEnableButtonRotateRight() {
- return this.$$.ctx[102];
- }
- set cropEnableButtonRotateRight(cropEnableButtonRotateRight) {
- this.$set({ cropEnableButtonRotateRight });
- flush();
- }
- get cropEnableButtonFlipHorizontal() {
- return this.$$.ctx[103];
- }
- set cropEnableButtonFlipHorizontal(cropEnableButtonFlipHorizontal) {
- this.$set({ cropEnableButtonFlipHorizontal });
- flush();
- }
- get cropEnableButtonFlipVertical() {
- return this.$$.ctx[104];
- }
- set cropEnableButtonFlipVertical(cropEnableButtonFlipVertical) {
- this.$set({ cropEnableButtonFlipVertical });
- flush();
- }
- get cropSelectPresetOptions() {
- return this.$$.ctx[105];
- }
- set cropSelectPresetOptions(cropSelectPresetOptions) {
- this.$set({ cropSelectPresetOptions });
- flush();
- }
- get cropEnableSelectPreset() {
- return this.$$.ctx[106];
- }
- set cropEnableSelectPreset(cropEnableSelectPreset) {
- this.$set({ cropEnableSelectPreset });
- flush();
- }
- get cropEnableButtonToggleCropLimit() {
- return this.$$.ctx[107];
- }
- set cropEnableButtonToggleCropLimit(cropEnableButtonToggleCropLimit) {
- this.$set({ cropEnableButtonToggleCropLimit });
- flush();
- }
- get cropWillRenderTools() {
- return this.$$.ctx[108];
- }
- set cropWillRenderTools(cropWillRenderTools) {
- this.$set({ cropWillRenderTools });
- flush();
- }
- get locale() {
- return this.$$.ctx[4];
- }
- set locale(locale) {
- this.$set({ locale });
- flush();
- }
- get tools() {
- return this.$$.ctx[0];
- }
- set tools(tools) {
- this.$set({ tools });
- flush();
- }
- }
- // @ts-ignore
- var _plugin_crop = { util: ['crop', Crop] };
- /* src/core/ui/plugins/filter/index.svelte generated by Svelte v3.37.0 */
- function create_option_slot$2(ctx) {
- let div1;
- let div0;
- let option = /*option*/ ctx[68];
- let t0;
- let span;
- let t1_value = (isFunction(/*option*/ ctx[68].label)
- ? /*option*/ ctx[68].label(/*locale*/ ctx[2])
- : /*option*/ ctx[68].label) + "";
- let t1;
- let mounted;
- let dispose;
- function measure_handler_1(...args) {
- return /*measure_handler_1*/ ctx[48](/*option*/ ctx[68], ...args);
- }
- const assign_div0 = () => /*div0_binding*/ ctx[49](div0, option);
- const unassign_div0 = () => /*div0_binding*/ ctx[49](null, option);
- return {
- c() {
- div1 = element("div");
- div0 = element("div");
- t0 = space();
- span = element("span");
- t1 = text(t1_value);
- attr(div0, "class", FILTER_PREVIEW_CLASS_NAME);
- attr(div1, "slot", "option");
- attr(div1, "class", "PinturaFilterOption");
- },
- m(target, anchor) {
- insert(target, div1, anchor);
- append(div1, div0);
- assign_div0();
- append(div1, t0);
- append(div1, span);
- append(span, t1);
- if (!mounted) {
- dispose = [
- listen(div0, "measure", measure_handler_1),
- action_destroyer(measurable.call(null, div0))
- ];
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- if (option !== /*option*/ ctx[68]) {
- unassign_div0();
- option = /*option*/ ctx[68];
- assign_div0();
- }
- if (dirty[0] & /*locale*/ 4 | dirty[2] & /*option*/ 64 && t1_value !== (t1_value = (isFunction(/*option*/ ctx[68].label)
- ? /*option*/ ctx[68].label(/*locale*/ ctx[2])
- : /*option*/ ctx[68].label) + "")) set_data(t1, t1_value);
- },
- d(detaching) {
- if (detaching) detach(div1);
- unassign_div0();
- mounted = false;
- run_all(dispose);
- }
- };
- }
- // (357:8) <Scrollable elasticity={elasticityMultiplier * scrollElasticity} onscroll={(offset) => (tileScrollOffset = offset)} bind:maskFeatherStartOpacity={tileLeftOpacity} bind:maskFeatherEndOpacity={tileRightOpacity} bind:maskFeatherSize={tileMargin} on:measure={(e) => (tileScrollContainerRect = e.detail)} >
- function create_default_slot$8(ctx) {
- let radiogroup;
- let current;
- radiogroup = new RadioGroup({
- props: {
- locale: /*locale*/ ctx[2],
- layout: "row",
- options: /*filterOptions*/ ctx[3],
- selectedIndex: /*selectedFilterIndex*/ ctx[10],
- onchange: /*handleChangeFilter*/ ctx[29],
- $$slots: {
- option: [
- create_option_slot$2,
- ({ option }) => ({ 68: option }),
- ({ option }) => [0, 0, option ? 64 : 0]
- ]
- },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(radiogroup.$$.fragment);
- },
- m(target, anchor) {
- mount_component(radiogroup, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const radiogroup_changes = {};
- if (dirty[0] & /*locale*/ 4) radiogroup_changes.locale = /*locale*/ ctx[2];
- if (dirty[0] & /*filterOptions*/ 8) radiogroup_changes.options = /*filterOptions*/ ctx[3];
- if (dirty[0] & /*selectedFilterIndex*/ 1024) radiogroup_changes.selectedIndex = /*selectedFilterIndex*/ ctx[10];
- if (dirty[0] & /*locale, tileElements*/ 516 | dirty[2] & /*$$scope, option*/ 192) {
- radiogroup_changes.$$scope = { dirty, ctx };
- }
- radiogroup.$set(radiogroup_changes);
- },
- i(local) {
- if (current) return;
- transition_in(radiogroup.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(radiogroup.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(radiogroup, detaching);
- }
- };
- }
- // (356:4)
- function create_footer_slot$4(ctx) {
- let div;
- let scrollable;
- let updating_maskFeatherStartOpacity;
- let updating_maskFeatherEndOpacity;
- let updating_maskFeatherSize;
- let current;
- let mounted;
- let dispose;
- function scrollable_maskFeatherStartOpacity_binding(value) {
- /*scrollable_maskFeatherStartOpacity_binding*/ ctx[51](value);
- }
- function scrollable_maskFeatherEndOpacity_binding(value) {
- /*scrollable_maskFeatherEndOpacity_binding*/ ctx[52](value);
- }
- function scrollable_maskFeatherSize_binding(value) {
- /*scrollable_maskFeatherSize_binding*/ ctx[53](value);
- }
- let scrollable_props = {
- elasticity: /*elasticityMultiplier*/ ctx[15] * /*scrollElasticity*/ ctx[16],
- onscroll: /*func*/ ctx[50],
- $$slots: { default: [create_default_slot$8] },
- $$scope: { ctx }
- };
- if (/*tileLeftOpacity*/ ctx[4] !== void 0) {
- scrollable_props.maskFeatherStartOpacity = /*tileLeftOpacity*/ ctx[4];
- }
- if (/*tileRightOpacity*/ ctx[5] !== void 0) {
- scrollable_props.maskFeatherEndOpacity = /*tileRightOpacity*/ ctx[5];
- }
- if (/*tileMargin*/ ctx[6] !== void 0) {
- scrollable_props.maskFeatherSize = /*tileMargin*/ ctx[6];
- }
- scrollable = new Scrollable({ props: scrollable_props });
- binding_callbacks.push(() => bind(scrollable, "maskFeatherStartOpacity", scrollable_maskFeatherStartOpacity_binding));
- binding_callbacks.push(() => bind(scrollable, "maskFeatherEndOpacity", scrollable_maskFeatherEndOpacity_binding));
- binding_callbacks.push(() => bind(scrollable, "maskFeatherSize", scrollable_maskFeatherSize_binding));
- scrollable.$on("measure", /*measure_handler_2*/ ctx[54]);
- return {
- c() {
- div = element("div");
- create_component(scrollable.$$.fragment);
- attr(div, "slot", "footer");
- attr(div, "style", /*footerStyle*/ ctx[11]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(scrollable, div, null);
- current = true;
- if (!mounted) {
- dispose = listen(div, "transitionend", /*handleTransitionEnd*/ ctx[27]);
- mounted = true;
- }
- },
- p(ctx, dirty) {
- const scrollable_changes = {};
- if (dirty[0] & /*tileScrollOffset*/ 128) scrollable_changes.onscroll = /*func*/ ctx[50];
- if (dirty[0] & /*locale, filterOptions, selectedFilterIndex, tileElements*/ 1548 | dirty[2] & /*$$scope*/ 128) {
- scrollable_changes.$$scope = { dirty, ctx };
- }
- if (!updating_maskFeatherStartOpacity && dirty[0] & /*tileLeftOpacity*/ 16) {
- updating_maskFeatherStartOpacity = true;
- scrollable_changes.maskFeatherStartOpacity = /*tileLeftOpacity*/ ctx[4];
- add_flush_callback(() => updating_maskFeatherStartOpacity = false);
- }
- if (!updating_maskFeatherEndOpacity && dirty[0] & /*tileRightOpacity*/ 32) {
- updating_maskFeatherEndOpacity = true;
- scrollable_changes.maskFeatherEndOpacity = /*tileRightOpacity*/ ctx[5];
- add_flush_callback(() => updating_maskFeatherEndOpacity = false);
- }
- if (!updating_maskFeatherSize && dirty[0] & /*tileMargin*/ 64) {
- updating_maskFeatherSize = true;
- scrollable_changes.maskFeatherSize = /*tileMargin*/ ctx[6];
- add_flush_callback(() => updating_maskFeatherSize = false);
- }
- scrollable.$set(scrollable_changes);
- if (!current || dirty[0] & /*footerStyle*/ 2048) {
- attr(div, "style", /*footerStyle*/ ctx[11]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(scrollable.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(scrollable.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(scrollable);
- mounted = false;
- dispose();
- }
- };
- }
- function create_fragment$j(ctx) {
- let util;
- let current;
- util = new Util({
- props: {
- $$slots: { footer: [create_footer_slot$4] },
- $$scope: { ctx }
- }
- });
- util.$on("measure", /*measure_handler*/ ctx[55]);
- return {
- c() {
- create_component(util.$$.fragment);
- },
- m(target, anchor) {
- mount_component(util, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const util_changes = {};
- if (dirty[0] & /*footerStyle, tileScrollOffset, tileLeftOpacity, tileRightOpacity, tileMargin, tileScrollContainerRect, locale, filterOptions, selectedFilterIndex, tileElements*/ 4092 | dirty[2] & /*$$scope*/ 128) {
- util_changes.$$scope = { dirty, ctx };
- }
- util.$set(util_changes);
- },
- i(local) {
- if (current) return;
- transition_in(util.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(util.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(util, detaching);
- }
- };
- }
- let FILTER_PREVIEW_CLASS_NAME = "PinturaFilterPreview";
- function instance$j($$self, $$props, $$invalidate) {
- let filterOptionsFlattened;
- let selectedFilterIndex;
- let footerStyle;
- let $imageColorMatrix;
- let $tileRects;
- let $canvasSize;
- let $imageTransforms;
- let $animation;
- let $isActive,
- $$unsubscribe_isActive = noop,
- $$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(40, $isActive = $$value)), isActive);
- let $utilRect;
- let $stageRect;
- let $imageGamma;
- let $imagePreview;
- let $imageSize;
- let $imageBackgroundColor;
- let $isActiveFraction,
- $$unsubscribe_isActiveFraction = noop,
- $$subscribe_isActiveFraction = () => ($$unsubscribe_isActiveFraction(), $$unsubscribe_isActiveFraction = subscribe(isActiveFraction, $$value => $$invalidate(45, $isActiveFraction = $$value)), isActiveFraction);
- let $footerOffset;
- let $imageTiles;
- $$self.$$.on_destroy.push(() => $$unsubscribe_isActive());
- $$self.$$.on_destroy.push(() => $$unsubscribe_isActiveFraction());
- const name = "filter";
- let { isActive } = $$props;
- $$subscribe_isActive();
- let { isActiveFraction } = $$props;
- $$subscribe_isActiveFraction();
- let { stores } = $$props;
- let { locale } = $$props;
- let { filterFunctions } = $$props;
- let { filterOptions } = $$props;
- // connect filter choice to stores
- const { history, interfaceImages, stageRect, utilRect, animation, elasticityMultiplier, scrollElasticity, imageSize, imagePreview, imageCropRect, imageRotation, imageFlipX, imageFlipY, imageBackgroundColor, imageGamma, imageColorMatrix } = stores;
- component_subscribe($$self, stageRect, value => $$invalidate(42, $stageRect = value));
- component_subscribe($$self, utilRect, value => $$invalidate(41, $utilRect = value));
- component_subscribe($$self, animation, value => $$invalidate(39, $animation = value));
- component_subscribe($$self, imageSize, value => $$invalidate(57, $imageSize = value));
- component_subscribe($$self, imagePreview, value => $$invalidate(44, $imagePreview = value));
- component_subscribe($$self, imageBackgroundColor, value => $$invalidate(58, $imageBackgroundColor = value));
- component_subscribe($$self, imageGamma, value => $$invalidate(43, $imageGamma = value));
- component_subscribe($$self, imageColorMatrix, value => $$invalidate(36, $imageColorMatrix = value));
- const getFilterIndex = (imageColorMatrix, filterOptionsFlattened) => {
- if (!imageColorMatrix || !imageColorMatrix["filter"] || !filterOptionsFlattened) return 0;
- const filterColorMatrix = imageColorMatrix["filter"];
- return filterOptionsFlattened.// get id and compare matrices
- findIndex(([id]) => {
- if (!filterFunctions[id]) return false;
- const matrix = filterFunctions[id]();
- return arrayEqual(matrix, filterColorMatrix);
- });
- };
- const tileRects = writable({});
- component_subscribe($$self, tileRects, value => $$invalidate(37, $tileRects = value));
- const handleTileResize = (item, rect) => set_store_value(tileRects, $tileRects[item.value] = rect, $tileRects);
- const canvasSize = derived(tileRects, $tileRects => {
- if (!$tileRects[undefined]) return;
- const tileRectFirst = $tileRects[undefined];
- if ($canvasSize && sizeEqual($canvasSize, tileRectFirst)) return $canvasSize;
- return sizeClone(tileRectFirst);
- });
- component_subscribe($$self, canvasSize, value => $$invalidate(56, $canvasSize = value));
- const imageTransforms = derived(
- [
- isActive,
- canvasSize,
- imageCropRect,
- imageSize,
- imageRotation,
- imageFlipX,
- imageFlipY
- ],
- ([
- $isActive,
- $canvasSize,
- $imageCropRect,
- $imageSize,
- $imageRotation,
- $imageFlipX,
- $imageFlipY
- ], set) => {
- if (!$isActive || !$canvasSize || !$imageSize) return $imageTransforms;
- const imageRect = rectCreateFromSize($imageSize);
- const imageCenter = rectCenter(imageRect);
- // get base crop rect so we can correctly apply transforms
- const cropRectBase = getBaseCropRect($imageSize, $imageCropRect, $imageRotation);
- const cropRectBaseCenter = rectCenter(cropRectBase);
- const imageTranslation = vectorSubtract(vectorClone(imageCenter), cropRectBaseCenter);
- const imageOrigin = vectorInvert(vectorClone(imageTranslation));
- // scalar
- const imageScalar = Math.max($canvasSize.width / $imageCropRect.width, $canvasSize.height / $imageCropRect.height);
- // update preview transforms
- set({
- origin: imageOrigin,
- translation: imageTranslation,
- rotation: {
- x: $imageFlipY ? Math.PI : 0,
- y: $imageFlipX ? Math.PI : 0,
- z: $imageRotation
- },
- perspective: vectorCreateEmpty(),
- scale: imageScalar
- });
- }
- );
- component_subscribe($$self, imageTransforms, value => $$invalidate(38, $imageTransforms = value));
- const cloneImageTransforms = imageTransforms => ({
- origin: vectorClone(imageTransforms.origin),
- translation: vectorClone(imageTransforms.translation),
- rotation: { ...imageTransforms.rotation },
- perspective: vectorClone(imageTransforms.perspective),
- scale: imageTransforms.scale
- });
- //
- // Footer
- //
- const footerOffset = spring($animation ? 20 : 0);
- component_subscribe($$self, footerOffset, value => $$invalidate(46, $footerOffset = value));
- let tileCornerRadius;
- const tileElements = {};
- const handleTransitionEnd = e => {
- if (e.target.className !== FILTER_PREVIEW_CLASS_NAME) return;
- $$invalidate(33, tileCornerRadius = Object.keys(tileElements).reduce(
- (prev, curr) => {
- const element = tileElements[curr];
- const style = getComputedStyle(element);
- const corners = ["top-left", "top-right", "bottom-left", "bottom-right"].map(corner => style.getPropertyValue(`border-${corner}-radius`)).map(unitToPixels).// this better aligns WebGL rounded corner with css rounded corner
- map(v => v * 1.25);
- prev[curr] = corners;
- return prev;
- },
- {}
- ));
- };
- let tileLeftOpacity; // set by Scrollable
- let tileRightOpacity; // set by Scrollable
- let tileMargin; // set by Scrollable
- let tileScrollOffset = { x: 0, y: 0 };
- let tileScrollContainerRect;
- let tileWrapperOffset;
- const imageTiles = writable([]);
- component_subscribe($$self, imageTiles, value => $$invalidate(47, $imageTiles = value));
- // clones an image tile for use in canvas
- const cloneImageTile = tile => {
- const clone = {
- // doesn't clone everything but should be enough
- ...tile,
- data: $imagePreview,
- size: $imageSize,
- offset: { ...tile.offset },
- mask: { ...tile.mask },
- backgroundColor: $imageBackgroundColor
- };
- clone.opacity = $isActiveFraction;
- clone.offset.y += $footerOffset;
- clone.mask.y += $footerOffset;
- return clone;
- };
- const handleChangeFilter = ({ value }) => {
- set_store_value(
- imageColorMatrix,
- $imageColorMatrix = {
- ...$imageColorMatrix,
- filter: isFunction(filterFunctions[value])
- ? filterFunctions[value]()
- : undefined
- },
- $imageColorMatrix
- );
- history.write();
- };
- // when destroyed we need to make sure all image previews are cleared
- onDestroy(() => {
- interfaceImages.set([]);
- });
- const measure_handler_1 = (option, e) => handleTileResize(option, e.detail);
- function div0_binding($$value, option) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- tileElements[option.value] = $$value;
- $$invalidate(9, tileElements);
- });
- }
- const func = offset => $$invalidate(7, tileScrollOffset = offset);
- function scrollable_maskFeatherStartOpacity_binding(value) {
- tileLeftOpacity = value;
- $$invalidate(4, tileLeftOpacity);
- }
- function scrollable_maskFeatherEndOpacity_binding(value) {
- tileRightOpacity = value;
- $$invalidate(5, tileRightOpacity);
- }
- function scrollable_maskFeatherSize_binding(value) {
- tileMargin = value;
- $$invalidate(6, tileMargin);
- }
- const measure_handler_2 = e => $$invalidate(8, tileScrollContainerRect = e.detail);
- function measure_handler(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("isActive" in $$props) $$subscribe_isActive($$invalidate(0, isActive = $$props.isActive));
- if ("isActiveFraction" in $$props) $$subscribe_isActiveFraction($$invalidate(1, isActiveFraction = $$props.isActiveFraction));
- if ("stores" in $$props) $$invalidate(31, stores = $$props.stores);
- if ("locale" in $$props) $$invalidate(2, locale = $$props.locale);
- if ("filterFunctions" in $$props) $$invalidate(32, filterFunctions = $$props.filterFunctions);
- if ("filterOptions" in $$props) $$invalidate(3, filterOptions = $$props.filterOptions);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*filterOptions*/ 8) {
- $$invalidate(35, filterOptionsFlattened = flattenOptions(filterOptions));
- }
- if ($$self.$$.dirty[1] & /*$imageColorMatrix, filterOptionsFlattened*/ 48) {
- $$invalidate(10, selectedFilterIndex = getFilterIndex($imageColorMatrix, filterOptionsFlattened));
- }
- if ($$self.$$.dirty[1] & /*$animation, $isActive*/ 768) {
- $animation && footerOffset.set($isActive ? 0 : 20);
- }
- if ($$self.$$.dirty[1] & /*$isActive, $utilRect, $stageRect*/ 3584) {
- if ($isActive && $utilRect && $stageRect) {
- const tileTopOffset = $stageRect.y + $stageRect.height + $utilRect.y;
- $$invalidate(34, tileWrapperOffset = {
- x: $stageRect.x - $utilRect.x,
- y: tileTopOffset
- });
- }
- }
- if ($$self.$$.dirty[0] & /*tileScrollOffset, tileScrollContainerRect, tileMargin, tileLeftOpacity, tileRightOpacity*/ 496 | $$self.$$.dirty[1] & /*$imageTransforms, tileWrapperOffset, tileCornerRadius, filterOptionsFlattened, $tileRects, $imageColorMatrix, filterFunctions, $imageGamma*/ 4350) {
- if ($imageTransforms && tileWrapperOffset && tileScrollOffset && tileScrollContainerRect && tileCornerRadius) {
- const boundsX = tileWrapperOffset.x + tileScrollContainerRect.x;
- const offsetX = boundsX + tileScrollOffset.x;
- const offsetY = tileWrapperOffset.y;
- const containerLeft = tileScrollContainerRect.x + tileWrapperOffset.x;
- const containerRight = containerLeft + tileScrollContainerRect.width;
- imageTiles.set(filterOptionsFlattened.map(([id], i) => {
- const tileRect = $tileRects[id];
- // test if is outside of view
- const tileLeft = tileScrollOffset.x + tileRect.x;
- const tileRight = tileLeft + tileRect.width;
- if (tileRight < 0 || tileLeft > tileScrollContainerRect.width) return false;
- const x = offsetX + tileRect.x;
- const y = offsetY + tileRect.y;
- const preview = cloneImageTransforms($imageTransforms);
- preview.offset = vectorCreate(tileRect.width * 0.5 + x, tileRect.height * 0.5 + y);
- let clipX = 0;
- let clipWidth = 0;
- preview.maskOpacity = 1;
- preview.mask = rectCreate(x + clipX, y, tileRect.width + clipWidth, tileRect.height);
- preview.maskFeather = [1, 0, 1, 0, 1, containerRight, 1, containerRight];
- if (tileLeft < tileMargin && tileLeftOpacity < 1) {
- preview.maskFeather[0] = tileLeftOpacity;
- preview.maskFeather[1] = containerLeft;
- preview.maskFeather[2] = 1;
- preview.maskFeather[3] = containerLeft + tileMargin;
- }
- if (tileRight > tileScrollContainerRect.width - tileMargin && tileRightOpacity < 1) {
- preview.maskFeather[4] = tileRightOpacity;
- preview.maskFeather[5] = containerRight - tileMargin;
- preview.maskFeather[6] = 1;
- preview.maskFeather[7] = containerRight;
- }
- preview.maskCornerRadius = tileCornerRadius[id];
- let colorMatrices = $imageColorMatrix && Object.keys($imageColorMatrix).filter(name => name != "filter").map(name => $imageColorMatrix[name]) || [];
- if (isFunction(filterFunctions[id])) {
- colorMatrices.push(filterFunctions[id]());
- }
- preview.colorMatrix = colorMatrices.length
- ? getColorMatrixFromColorMatrices(colorMatrices)
- : undefined;
- preview.gamma = $imageGamma;
- return preview;
- }).filter(Boolean));
- }
- }
- if ($$self.$$.dirty[1] & /*$isActiveFraction, $imageTiles, $footerOffset, $imagePreview*/ 122880) {
- // Will update `interfaceImages` store when
- // - $isActiveFraction is updated
- // - $imageTiles is updated
- // - $footerOffset is updated
- if ($isActiveFraction > 0 && $imageTiles) {
- // clone tiles
- interfaceImages.set($imageTiles.map(cloneImageTile));
- } else {
- interfaceImages.set([]);
- }
- }
- if ($$self.$$.dirty[1] & /*$footerOffset*/ 32768) {
- $$invalidate(11, footerStyle = $footerOffset
- ? `transform: translateY(${$footerOffset}px)`
- : undefined);
- }
- };
- return [
- isActive,
- isActiveFraction,
- locale,
- filterOptions,
- tileLeftOpacity,
- tileRightOpacity,
- tileMargin,
- tileScrollOffset,
- tileScrollContainerRect,
- tileElements,
- selectedFilterIndex,
- footerStyle,
- stageRect,
- utilRect,
- animation,
- elasticityMultiplier,
- scrollElasticity,
- imageSize,
- imagePreview,
- imageBackgroundColor,
- imageGamma,
- imageColorMatrix,
- tileRects,
- handleTileResize,
- canvasSize,
- imageTransforms,
- footerOffset,
- handleTransitionEnd,
- imageTiles,
- handleChangeFilter,
- name,
- stores,
- filterFunctions,
- tileCornerRadius,
- tileWrapperOffset,
- filterOptionsFlattened,
- $imageColorMatrix,
- $tileRects,
- $imageTransforms,
- $animation,
- $isActive,
- $utilRect,
- $stageRect,
- $imageGamma,
- $imagePreview,
- $isActiveFraction,
- $footerOffset,
- $imageTiles,
- measure_handler_1,
- div0_binding,
- func,
- scrollable_maskFeatherStartOpacity_binding,
- scrollable_maskFeatherEndOpacity_binding,
- scrollable_maskFeatherSize_binding,
- measure_handler_2,
- measure_handler
- ];
- }
- class Filter extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$j,
- create_fragment$j,
- safe_not_equal,
- {
- name: 30,
- isActive: 0,
- isActiveFraction: 1,
- stores: 31,
- locale: 2,
- filterFunctions: 32,
- filterOptions: 3
- },
- [-1, -1, -1]
- );
- }
- get name() {
- return this.$$.ctx[30];
- }
- get isActive() {
- return this.$$.ctx[0];
- }
- set isActive(isActive) {
- this.$set({ isActive });
- flush();
- }
- get isActiveFraction() {
- return this.$$.ctx[1];
- }
- set isActiveFraction(isActiveFraction) {
- this.$set({ isActiveFraction });
- flush();
- }
- get stores() {
- return this.$$.ctx[31];
- }
- set stores(stores) {
- this.$set({ stores });
- flush();
- }
- get locale() {
- return this.$$.ctx[2];
- }
- set locale(locale) {
- this.$set({ locale });
- flush();
- }
- get filterFunctions() {
- return this.$$.ctx[32];
- }
- set filterFunctions(filterFunctions) {
- this.$set({ filterFunctions });
- flush();
- }
- get filterOptions() {
- return this.$$.ctx[3];
- }
- set filterOptions(filterOptions) {
- this.$set({ filterOptions });
- flush();
- }
- }
- // @ts-ignore
- var _plugin_filter = { util: ['filter', Filter] };
- /* src/core/ui/plugins/finetune/index.svelte generated by Svelte v3.37.0 */
- function create_default_slot_2$1(ctx) {
- let span;
- let t_value = /*tab*/ ctx[37].label + "";
- let t;
- return {
- c() {
- span = element("span");
- t = text(t_value);
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- },
- p(ctx, dirty) {
- if (dirty[1] & /*tab*/ 64 && t_value !== (t_value = /*tab*/ ctx[37].label + "")) set_data(t, t_value);
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- // (145:8) <Scrollable elasticity={elasticityMultiplier * scrollElasticity} class="PinturaControlListScroller" >
- function create_default_slot_1$2(ctx) {
- let tablist;
- let current;
- const tablist_spread_levels = [
- { class: "PinturaControlList" },
- { tabs: /*tabs*/ ctx[1] },
- /*tabsConfig*/ ctx[3]
- ];
- let tablist_props = {
- $$slots: {
- default: [
- create_default_slot_2$1,
- ({ tab }) => ({ 37: tab }),
- ({ tab }) => [0, tab ? 64 : 0]
- ]
- },
- $$scope: { ctx }
- };
- for (let i = 0; i < tablist_spread_levels.length; i += 1) {
- tablist_props = assign(tablist_props, tablist_spread_levels[i]);
- }
- tablist = new TabList({ props: tablist_props });
- tablist.$on("select", /*select_handler*/ ctx[22]);
- return {
- c() {
- create_component(tablist.$$.fragment);
- },
- m(target, anchor) {
- mount_component(tablist, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const tablist_changes = (dirty[0] & /*tabs, tabsConfig*/ 10)
- ? get_spread_update(tablist_spread_levels, [
- tablist_spread_levels[0],
- dirty[0] & /*tabs*/ 2 && { tabs: /*tabs*/ ctx[1] },
- dirty[0] & /*tabsConfig*/ 8 && get_spread_object(/*tabsConfig*/ ctx[3])
- ])
- : {};
- if (dirty[1] & /*$$scope, tab*/ 192) {
- tablist_changes.$$scope = { dirty, ctx };
- }
- tablist.$set(tablist_changes);
- },
- i(local) {
- if (current) return;
- transition_in(tablist.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(tablist.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(tablist, detaching);
- }
- };
- }
- // (160:8) <TabPanels class="PinturaControlPanels" panelClass="PinturaControlPanel" {panels} {...tabsConfig} let:panel >
- function create_default_slot$7(ctx) {
- let rangeinput;
- let current;
- const rangeinput_spread_levels = [/*$rangeInputConfig*/ ctx[5][/*panel*/ ctx[36]]];
- let rangeinput_props = {};
- for (let i = 0; i < rangeinput_spread_levels.length; i += 1) {
- rangeinput_props = assign(rangeinput_props, rangeinput_spread_levels[i]);
- }
- rangeinput = new RangeInput({ props: rangeinput_props });
- return {
- c() {
- create_component(rangeinput.$$.fragment);
- },
- m(target, anchor) {
- mount_component(rangeinput, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const rangeinput_changes = (dirty[0] & /*$rangeInputConfig*/ 32 | dirty[1] & /*panel*/ 32)
- ? get_spread_update(rangeinput_spread_levels, [get_spread_object(/*$rangeInputConfig*/ ctx[5][/*panel*/ ctx[36]])])
- : {};
- rangeinput.$set(rangeinput_changes);
- },
- i(local) {
- if (current) return;
- transition_in(rangeinput.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(rangeinput.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(rangeinput, detaching);
- }
- };
- }
- // (144:4)
- function create_footer_slot$3(ctx) {
- let div;
- let scrollable;
- let t;
- let tabpanels;
- let current;
- scrollable = new Scrollable({
- props: {
- elasticity: /*elasticityMultiplier*/ ctx[9] * /*scrollElasticity*/ ctx[8],
- class: "PinturaControlListScroller",
- $$slots: { default: [create_default_slot_1$2] },
- $$scope: { ctx }
- }
- });
- const tabpanels_spread_levels = [
- { class: "PinturaControlPanels" },
- { panelClass: "PinturaControlPanel" },
- { panels: /*panels*/ ctx[4] },
- /*tabsConfig*/ ctx[3]
- ];
- let tabpanels_props = {
- $$slots: {
- default: [
- create_default_slot$7,
- ({ panel }) => ({ 36: panel }),
- ({ panel }) => [0, panel ? 32 : 0]
- ]
- },
- $$scope: { ctx }
- };
- for (let i = 0; i < tabpanels_spread_levels.length; i += 1) {
- tabpanels_props = assign(tabpanels_props, tabpanels_spread_levels[i]);
- }
- tabpanels = new TabPanels({ props: tabpanels_props });
- return {
- c() {
- div = element("div");
- create_component(scrollable.$$.fragment);
- t = space();
- create_component(tabpanels.$$.fragment);
- attr(div, "slot", "footer");
- attr(div, "style", /*footerStyle*/ ctx[6]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(scrollable, div, null);
- append(div, t);
- mount_component(tabpanels, div, null);
- current = true;
- },
- p(ctx, dirty) {
- const scrollable_changes = {};
- if (dirty[0] & /*tabs, tabsConfig, tabSelected*/ 14 | dirty[1] & /*$$scope*/ 128) {
- scrollable_changes.$$scope = { dirty, ctx };
- }
- scrollable.$set(scrollable_changes);
- const tabpanels_changes = (dirty[0] & /*panels, tabsConfig*/ 24)
- ? get_spread_update(tabpanels_spread_levels, [
- tabpanels_spread_levels[0],
- tabpanels_spread_levels[1],
- dirty[0] & /*panels*/ 16 && { panels: /*panels*/ ctx[4] },
- dirty[0] & /*tabsConfig*/ 8 && get_spread_object(/*tabsConfig*/ ctx[3])
- ])
- : {};
- if (dirty[0] & /*$rangeInputConfig*/ 32 | dirty[1] & /*$$scope, panel*/ 160) {
- tabpanels_changes.$$scope = { dirty, ctx };
- }
- tabpanels.$set(tabpanels_changes);
- if (!current || dirty[0] & /*footerStyle*/ 64) {
- attr(div, "style", /*footerStyle*/ ctx[6]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(scrollable.$$.fragment, local);
- transition_in(tabpanels.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(scrollable.$$.fragment, local);
- transition_out(tabpanels.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(scrollable);
- destroy_component(tabpanels);
- }
- };
- }
- function create_fragment$i(ctx) {
- let util;
- let current;
- util = new Util({
- props: {
- $$slots: { footer: [create_footer_slot$3] },
- $$scope: { ctx }
- }
- });
- util.$on("measure", /*measure_handler*/ ctx[23]);
- return {
- c() {
- create_component(util.$$.fragment);
- },
- m(target, anchor) {
- mount_component(util, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const util_changes = {};
- if (dirty[0] & /*footerStyle, panels, tabsConfig, $rangeInputConfig, tabs, tabSelected*/ 126 | dirty[1] & /*$$scope*/ 128) {
- util_changes.$$scope = { dirty, ctx };
- }
- util.$set(util_changes);
- },
- i(local) {
- if (current) return;
- transition_in(util.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(util.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(util, detaching);
- }
- };
- }
- function instance$i($$self, $$props, $$invalidate) {
- let tabs;
- let tabSelected;
- let tabsConfig;
- let panels;
- let footerStyle;
- let $rangeInputConfig;
- let $panelValues;
- let $animation;
- let $isActive,
- $$unsubscribe_isActive = noop,
- $$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(20, $isActive = $$value)), isActive);
- let $footerOffset;
- $$self.$$.on_destroy.push(() => $$unsubscribe_isActive());
- const name = "finetune";
- let { stores } = $$props;
- let { isActive } = $$props;
- $$subscribe_isActive();
- let { locale = {} } = $$props;
- let { finetuneControlConfiguration } = $$props;
- let { finetuneOptions } = $$props;
- const { history, animation, scrollElasticity, elasticityMultiplier, rangeInputElasticity, imageColorMatrix, imageConvolutionMatrix, imageGamma, imageVignette, imageNoise } = stores;
- component_subscribe($$self, animation, value => $$invalidate(19, $animation = value));
- const imageEffectStores = {
- imageColorMatrix,
- imageConvolutionMatrix,
- imageGamma,
- imageVignette,
- imageNoise
- };
- //
- // Tabs
- //
- const uid = `finetune-${getUniqueId()}`;
- //
- // Range inputs
- //
- const panelValues = writable({});
- component_subscribe($$self, panelValues, value => $$invalidate(18, $panelValues = value));
- const rangeInputConfig = writable({});
- component_subscribe($$self, rangeInputConfig, value => $$invalidate(5, $rangeInputConfig = value));
- const updateRangeInputState = () => {
- set_store_value(
- rangeInputConfig,
- $rangeInputConfig = Object.keys($panelValues).reduce(
- (config, id) => {
- const { base, min, max, getLabel, getStore, setValue = (store, v) => store.set(v) } = finetuneControlConfiguration[id];
- const store = getStore(imageEffectStores);
- const value = $panelValues[id] != null ? $panelValues[id] : base;
- config[id] = {
- base,
- min,
- max,
- value,
- valueLabel: getLabel
- ? getLabel(value, min, max, max - min)
- : Math.round(100 * value),
- oninputmove: v => {
- setValue(store, v);
- },
- oninputend: v => {
- setValue(store, v);
- history.write();
- },
- elasticity: elasticityMultiplier * rangeInputElasticity,
- labelReset: locale.labelReset
- };
- return config;
- },
- {}
- ),
- $rangeInputConfig
- );
- };
- // need to unsubscribe when redrawing vie
- let unsubs = [];
- const subscribePanelStores = config => {
- if (unsubs) unsubs.forEach(unsub => unsub());
- unsubs = panels.map(id => {
- const { getStore, getValue = passthrough } = config[id];
- const store = getStore(imageEffectStores);
- return store.subscribe(value => {
- const currentValue = value != null ? getValue(value) : value;
- set_store_value(panelValues, $panelValues = { ...$panelValues, [id]: currentValue }, $panelValues);
- });
- });
- };
- //
- // Footer
- //
- const footerOffset = spring($animation ? 20 : 0);
- component_subscribe($$self, footerOffset, value => $$invalidate(21, $footerOffset = value));
- const select_handler = ({ detail }) => $$invalidate(2, tabSelected = detail);
- function measure_handler(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("stores" in $$props) $$invalidate(14, stores = $$props.stores);
- if ("isActive" in $$props) $$subscribe_isActive($$invalidate(0, isActive = $$props.isActive));
- if ("locale" in $$props) $$invalidate(15, locale = $$props.locale);
- if ("finetuneControlConfiguration" in $$props) $$invalidate(16, finetuneControlConfiguration = $$props.finetuneControlConfiguration);
- if ("finetuneOptions" in $$props) $$invalidate(17, finetuneOptions = $$props.finetuneOptions);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*finetuneOptions, locale*/ 163840) {
- $$invalidate(1, tabs = finetuneOptions
- ? finetuneOptions.map(([id, label]) => ({
- id,
- label: isFunction(label) ? label(locale) : label
- }))
- : []);
- }
- if ($$self.$$.dirty[0] & /*tabs*/ 2) {
- $$invalidate(2, tabSelected = tabs.length && tabs[0].id);
- }
- if ($$self.$$.dirty[0] & /*tabSelected*/ 4) {
- $$invalidate(3, tabsConfig = { name: uid, selected: tabSelected });
- }
- if ($$self.$$.dirty[0] & /*tabs*/ 2) {
- $$invalidate(4, panels = tabs.map(tab => tab.id));
- }
- if ($$self.$$.dirty[0] & /*finetuneControlConfiguration*/ 65536) {
- finetuneControlConfiguration && subscribePanelStores(finetuneControlConfiguration);
- }
- if ($$self.$$.dirty[0] & /*finetuneControlConfiguration, $panelValues*/ 327680) {
- finetuneControlConfiguration && $panelValues && updateRangeInputState();
- }
- if ($$self.$$.dirty[0] & /*$animation, $isActive*/ 1572864) {
- $animation && footerOffset.set($isActive ? 0 : 20);
- }
- if ($$self.$$.dirty[0] & /*$footerOffset*/ 2097152) {
- $$invalidate(6, footerStyle = $footerOffset
- ? `transform: translateY(${$footerOffset}px)`
- : undefined);
- }
- };
- return [
- isActive,
- tabs,
- tabSelected,
- tabsConfig,
- panels,
- $rangeInputConfig,
- footerStyle,
- animation,
- scrollElasticity,
- elasticityMultiplier,
- panelValues,
- rangeInputConfig,
- footerOffset,
- name,
- stores,
- locale,
- finetuneControlConfiguration,
- finetuneOptions,
- $panelValues,
- $animation,
- $isActive,
- $footerOffset,
- select_handler,
- measure_handler
- ];
- }
- class Finetune extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$i,
- create_fragment$i,
- safe_not_equal,
- {
- name: 13,
- stores: 14,
- isActive: 0,
- locale: 15,
- finetuneControlConfiguration: 16,
- finetuneOptions: 17
- },
- [-1, -1]
- );
- }
- get name() {
- return this.$$.ctx[13];
- }
- get stores() {
- return this.$$.ctx[14];
- }
- set stores(stores) {
- this.$set({ stores });
- flush();
- }
- get isActive() {
- return this.$$.ctx[0];
- }
- set isActive(isActive) {
- this.$set({ isActive });
- flush();
- }
- get locale() {
- return this.$$.ctx[15];
- }
- set locale(locale) {
- this.$set({ locale });
- flush();
- }
- get finetuneControlConfiguration() {
- return this.$$.ctx[16];
- }
- set finetuneControlConfiguration(finetuneControlConfiguration) {
- this.$set({ finetuneControlConfiguration });
- flush();
- }
- get finetuneOptions() {
- return this.$$.ctx[17];
- }
- set finetuneOptions(finetuneOptions) {
- this.$set({ finetuneOptions });
- flush();
- }
- }
- // @ts-ignore
- var _plugin_finetune = { util: ['finetune', Finetune] };
- /* src/core/ui/components/ShapeManipulator.svelte generated by Svelte v3.37.0 */
- function get_each_context$4(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[47] = list[i].key;
- child_ctx[48] = list[i].index;
- child_ctx[49] = list[i].translate;
- child_ctx[50] = list[i].scale;
- child_ctx[14] = list[i].rotate;
- child_ctx[51] = list[i].dir;
- child_ctx[52] = list[i].center;
- child_ctx[53] = list[i].type;
- return child_ctx;
- }
- // (247:4) {#if type === 'edge' && resizeAxis !== 'both'}
- function create_if_block_1$3(ctx) {
- let div;
- let div_style_value;
- return {
- c() {
- div = element("div");
- attr(div, "class", "PinturaShapeManipulator");
- attr(div, "data-control", "point");
- attr(div, "style", div_style_value = `pointer-events:none;transform: translate3d(${/*center*/ ctx[52].x}px, ${/*center*/ ctx[52].y}px, 0) scale(${/*$selectionScale*/ ctx[5]}, ${/*$selectionScale*/ ctx[5]}); opacity: ${/*$selectionOpacity*/ ctx[6]}`);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- },
- p(ctx, dirty) {
- if (dirty[0] & /*resizeControls, $selectionScale, $selectionOpacity*/ 104 && div_style_value !== (div_style_value = `pointer-events:none;transform: translate3d(${/*center*/ ctx[52].x}px, ${/*center*/ ctx[52].y}px, 0) scale(${/*$selectionScale*/ ctx[5]}, ${/*$selectionScale*/ ctx[5]}); opacity: ${/*$selectionOpacity*/ ctx[6]}`)) {
- attr(div, "style", div_style_value);
- }
- },
- d(detaching) {
- if (detaching) detach(div);
- }
- };
- }
- // (226:0) {#each resizeControls as { key, index, translate, scale, rotate, dir, center, type }
- function create_each_block$4(key_1, ctx) {
- let div;
- let div_aria_label_value;
- let div_tabindex_value;
- let div_data_control_value;
- let div_style_value;
- let t;
- let if_block_anchor;
- let mounted;
- let dispose;
- function nudge_handler(...args) {
- return /*nudge_handler*/ ctx[18](/*index*/ ctx[48], ...args);
- }
- let if_block = /*type*/ ctx[53] === "edge" && /*resizeAxis*/ ctx[2] !== "both" && create_if_block_1$3(ctx);
- return {
- key: key_1,
- first: null,
- c() {
- div = element("div");
- t = space();
- if (if_block) if_block.c();
- if_block_anchor = empty();
- attr(div, "role", "button");
- attr(div, "aria-label", div_aria_label_value = `Drag ${/*type*/ ctx[53]} ${/*key*/ ctx[47]}`);
- attr(div, "tabindex", div_tabindex_value = /*type*/ ctx[53] === "edge" ? -1 : 0);
- attr(div, "class", "PinturaShapeManipulator");
- attr(div, "data-control", div_data_control_value = /*type*/ ctx[53]);
- attr(div, "style", div_style_value = `cursor: ${/*dir*/ ctx[51] ? /*dir*/ ctx[51] + "-resize" : "move"}; transform: translate3d(${/*translate*/ ctx[49].x}px, ${/*translate*/ ctx[49].y}px, 0)${/*type*/ ctx[53] === "edge"
- ? ` rotate(${/*rotate*/ ctx[14]}rad)`
- : ""} scale(${/*type*/ ctx[53] === "point"
- ? /*$selectionScale*/ ctx[5]
- : /*scale*/ ctx[50].x}, ${/*type*/ ctx[53] === "point"
- ? /*$selectionScale*/ ctx[5]
- : /*scale*/ ctx[50].y}); opacity: ${/*$selectionOpacity*/ ctx[6]}`);
- this.first = div;
- },
- m(target, anchor) {
- insert(target, div, anchor);
- insert(target, t, anchor);
- if (if_block) if_block.m(target, anchor);
- insert(target, if_block_anchor, anchor);
- if (!mounted) {
- dispose = [
- listen(div, "keydown", /*handleKeyDown*/ ctx[7]),
- listen(div, "keyup", /*handleKeyUp*/ ctx[8]),
- listen(div, "nudge", nudge_handler),
- action_destroyer(nudgeable.call(null, div)),
- listen(div, "interactionstart", function () {
- if (is_function(/*resize*/ ctx[11]("start", /*index*/ ctx[48]))) /*resize*/ ctx[11]("start", /*index*/ ctx[48]).apply(this, arguments);
- }),
- listen(div, "interactionupdate", function () {
- if (is_function(/*resize*/ ctx[11]("move", /*index*/ ctx[48]))) /*resize*/ ctx[11]("move", /*index*/ ctx[48]).apply(this, arguments);
- }),
- listen(div, "interactionend", function () {
- if (is_function(/*resize*/ ctx[11]("end", /*index*/ ctx[48]))) /*resize*/ ctx[11]("end", /*index*/ ctx[48]).apply(this, arguments);
- }),
- action_destroyer(interactable.call(null, div))
- ];
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- if (dirty[0] & /*resizeControls*/ 8 && div_aria_label_value !== (div_aria_label_value = `Drag ${/*type*/ ctx[53]} ${/*key*/ ctx[47]}`)) {
- attr(div, "aria-label", div_aria_label_value);
- }
- if (dirty[0] & /*resizeControls*/ 8 && div_tabindex_value !== (div_tabindex_value = /*type*/ ctx[53] === "edge" ? -1 : 0)) {
- attr(div, "tabindex", div_tabindex_value);
- }
- if (dirty[0] & /*resizeControls*/ 8 && div_data_control_value !== (div_data_control_value = /*type*/ ctx[53])) {
- attr(div, "data-control", div_data_control_value);
- }
- if (dirty[0] & /*resizeControls, $selectionScale, $selectionOpacity*/ 104 && div_style_value !== (div_style_value = `cursor: ${/*dir*/ ctx[51] ? /*dir*/ ctx[51] + "-resize" : "move"}; transform: translate3d(${/*translate*/ ctx[49].x}px, ${/*translate*/ ctx[49].y}px, 0)${/*type*/ ctx[53] === "edge"
- ? ` rotate(${/*rotate*/ ctx[14]}rad)`
- : ""} scale(${/*type*/ ctx[53] === "point"
- ? /*$selectionScale*/ ctx[5]
- : /*scale*/ ctx[50].x}, ${/*type*/ ctx[53] === "point"
- ? /*$selectionScale*/ ctx[5]
- : /*scale*/ ctx[50].y}); opacity: ${/*$selectionOpacity*/ ctx[6]}`)) {
- attr(div, "style", div_style_value);
- }
- if (/*type*/ ctx[53] === "edge" && /*resizeAxis*/ ctx[2] !== "both") {
- if (if_block) {
- if_block.p(ctx, dirty);
- } else {
- if_block = create_if_block_1$3(ctx);
- if_block.c();
- if_block.m(if_block_anchor.parentNode, if_block_anchor);
- }
- } else if (if_block) {
- if_block.d(1);
- if_block = null;
- }
- },
- d(detaching) {
- if (detaching) detach(div);
- if (detaching) detach(t);
- if (if_block) if_block.d(detaching);
- if (detaching) detach(if_block_anchor);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- // (255:0) {#if enableRotating && rotationControlActive}
- function create_if_block$3(ctx) {
- let div;
- let div_style_value;
- let mounted;
- let dispose;
- return {
- c() {
- div = element("div");
- attr(div, "role", "button");
- attr(div, "aria-label", "Drag rotator");
- attr(div, "tabindex", "0");
- attr(div, "class", "PinturaShapeManipulator");
- attr(div, "data-control", "rotate");
- attr(div, "style", div_style_value = `transform: translate3d(${/*rotatorPoint*/ ctx[0].x}px, ${/*rotatorPoint*/ ctx[0].y}px, 0) scale(${/*$selectionScale*/ ctx[5]}, ${/*$selectionScale*/ ctx[5]}); opacity: ${/*$selectionOpacity*/ ctx[6]}`);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (!mounted) {
- dispose = [
- listen(div, "keydown", /*handleKeyDown*/ ctx[7]),
- listen(div, "keyup", /*handleKeyUp*/ ctx[8]),
- listen(div, "nudge", /*handleRotateNudge*/ ctx[13]),
- action_destroyer(nudgeable.call(null, div)),
- listen(div, "interactionstart", /*rotate*/ ctx[14]("start")),
- listen(div, "interactionupdate", /*rotate*/ ctx[14]("move")),
- listen(div, "interactionend", /*rotate*/ ctx[14]("end")),
- action_destroyer(interactable.call(null, div))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- if (dirty[0] & /*rotatorPoint, $selectionScale, $selectionOpacity*/ 97 && div_style_value !== (div_style_value = `transform: translate3d(${/*rotatorPoint*/ ctx[0].x}px, ${/*rotatorPoint*/ ctx[0].y}px, 0) scale(${/*$selectionScale*/ ctx[5]}, ${/*$selectionScale*/ ctx[5]}); opacity: ${/*$selectionOpacity*/ ctx[6]}`)) {
- attr(div, "style", div_style_value);
- }
- },
- d(detaching) {
- if (detaching) detach(div);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function create_fragment$h(ctx) {
- let each_blocks = [];
- let each_1_lookup = new Map();
- let t;
- let if_block_anchor;
- let each_value = /*resizeControls*/ ctx[3];
- const get_key = ctx => /*key*/ ctx[47];
- for (let i = 0; i < each_value.length; i += 1) {
- let child_ctx = get_each_context$4(ctx, each_value, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block$4(key, child_ctx));
- }
- let if_block = /*enableRotating*/ ctx[1] && /*rotationControlActive*/ ctx[4] && create_if_block$3(ctx);
- return {
- c() {
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- t = space();
- if (if_block) if_block.c();
- if_block_anchor = empty();
- },
- m(target, anchor) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].m(target, anchor);
- }
- insert(target, t, anchor);
- if (if_block) if_block.m(target, anchor);
- insert(target, if_block_anchor, anchor);
- },
- p(ctx, dirty) {
- if (dirty[0] & /*resizeControls, $selectionScale, $selectionOpacity, resizeAxis, handleKeyDown, handleKeyUp, handleResizeNudge, resize*/ 6636) {
- each_value = /*resizeControls*/ ctx[3];
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, t.parentNode, destroy_block, create_each_block$4, t, get_each_context$4);
- }
- if (/*enableRotating*/ ctx[1] && /*rotationControlActive*/ ctx[4]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- } else {
- if_block = create_if_block$3(ctx);
- if_block.c();
- if_block.m(if_block_anchor.parentNode, if_block_anchor);
- }
- } else if (if_block) {
- if_block.d(1);
- if_block = null;
- }
- },
- i: noop,
- o: noop,
- d(detaching) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d(detaching);
- }
- if (detaching) detach(t);
- if (if_block) if_block.d(detaching);
- if (detaching) detach(if_block_anchor);
- }
- };
- }
- function instance$h($$self, $$props, $$invalidate) {
- let resizeAxis;
- let resizeControls;
- let rotationControlActive;
- let $selectionScale;
- let $selectionOpacity;
- const dispatch = createEventDispatcher();
- // which cursor to render
- const EIGTH_PI = QUART_PI * 0.5;
- const N = HALF_PI;
- const N0 = N - EIGTH_PI;
- const N1 = N + EIGTH_PI;
- const S = -HALF_PI;
- const S0 = S - EIGTH_PI;
- const S1 = S + EIGTH_PI;
- const E = PI;
- const E0 = E - EIGTH_PI;
- const E1 = -PI + EIGTH_PI;
- const W0 = EIGTH_PI;
- const W1 = -EIGTH_PI;
- const NW = N - QUART_PI;
- const NW0 = NW - EIGTH_PI;
- const NW1 = NW + EIGTH_PI;
- const NE = PI - QUART_PI;
- const NE0 = NE - EIGTH_PI;
- const NE1 = NE + EIGTH_PI;
- const SE = S - QUART_PI;
- const SE0 = SE + EIGTH_PI;
- const SE1 = SE - EIGTH_PI;
- const SW = S + QUART_PI;
- const SW0 = SW + EIGTH_PI;
- const SW1 = SW - EIGTH_PI;
- let { points = [] } = $$props;
- let { rotatorPoint = undefined } = $$props;
- let { visible = false } = $$props;
- let { enableResizing = true } = $$props;
- let { enableRotating = true } = $$props;
- // // internal
- let shiftKey = false;
- const handleKeyDown = e => shiftKey = e.shiftKey;
- const handleKeyUp = e => shiftKey = false;
- // state
- const selectionScale = spring(0.5, {
- precision: 0.0001,
- stiffness: 0.3,
- damping: 0.7
- });
- component_subscribe($$self, selectionScale, value => $$invalidate(5, $selectionScale = value));
- const selectionOpacity = spring(0, {
- precision: 0.001,
- stiffness: 0.3,
- damping: 0.7
- });
- component_subscribe($$self, selectionOpacity, value => $$invalidate(6, $selectionOpacity = value));
- const rotate = type => ({ detail }) => {
- // always make sure we have a translation to work with
- const translation = detail && detail.translation
- ? detail.translation
- : vectorCreate(0, 0);
- dispatch(`rotate${type}`, { translation, shiftKey });
- };
- const resize = (type, indexes) => ({ detail }) => {
- // always make sure we have a translation to work with
- const translation = detail && detail.translation
- ? detail.translation
- : vectorCreate(0, 0);
- // done transforming the points
- dispatch(`resize${type}`, { indexes, translation, shiftKey });
- };
- // https://en.wikipedia.org/wiki/Radian#/media/File:Degree-Radian_Conversion.svg
- const getDirectionByAngle = angle => {
- let dir = "";
- const isNorth = angle <= N1 && angle >= N0;
- const isSouth = angle >= S0 && angle <= S1;
- const isEast = angle <= E1 || angle >= E0;
- const isWest = angle >= W1 && angle <= W0;
- const isNorthEast = angle >= NE0 && angle <= NE1;
- const isNorthWest = angle >= NW0 && angle <= NW1;
- const isSouthEast = angle <= SE0 && angle >= SE1;
- const isSouthWest = angle <= SW0 && angle >= SW1;
- if (isNorth || isSouth) dir = "ns";
- if (isEast || isWest) dir = "ew";
- if (isNorthEast || isSouthWest) dir = "nesw";
- if (isNorthWest || isSouthEast) dir = "nwse";
- return dir;
- };
- // 2 points -> [corner, corner]
- // 3 points => [corner, edge, corner, edge, corner, edge],
- // 4 points => [corner, edge, corner, edge, corner, edge, corner, edge]
- const mapPointsToControls = (points, axis) => {
- let i = 0;
- const center = vectorCenter(points);
- const out = [];
- const l = points.length;
- const isLine = l === 2;
- const isAxisLimited = axis !== "both";
- for (; i < l; i++) {
- const p0 = points[i - 1] || points[points.length - 1];
- const p1 = points[i];
- const p2 = points[i + 1] || points[0];
- const dir = Math.atan2(p2.y - p1.y, p2.x - p1.x);
- // create corner, only allowed if axis equal 'both'
- if (!isAxisLimited) {
- const a = vectorNormalize(vectorCreate(p0.x - p1.x, p0.y - p1.y));
- const b = vectorNormalize(vectorCreate(p2.x - p1.x, p2.y - p1.y));
- const cornerVector = vectorCreate(a.x + b.x, a.y + b.y);
- out.push({
- index: [i],
- key: `point-${i}`,
- type: "point",
- scale: { x: 1, y: 1 },
- translate: { x: p1.x, y: p1.y },
- angle: undefined,
- rotate: isLine ? 0 : dir,
- center: p1,
- dir: isLine
- ? undefined
- : getDirectionByAngle(Math.atan2(cornerVector.y, cornerVector.x))
- });
- }
- // if only two points, skip edge
- if (isLine) continue;
- const mid = vectorCreate(p1.x + (p2.x - p1.x) * 0.5, p1.y + (p2.y - p1.y) * 0.5);
- // only allow horizontal controls
- if (axis === "horizontal" && i % 2 === 0) continue;
- // only allow vertical controls
- if (axis === "vertical" && i % 2 !== 0) continue;
- // create edge
- out.push({
- index: [i, i + 1 === l ? 0 : i + 1],
- key: `edge-${i}`,
- type: "edge",
- scale: { x: vectorDistance(p1, p2), y: 1 },
- translate: { x: p1.x, y: p1.y },
- angle: dir,
- rotate: dir,
- center: mid,
- dir: getDirectionByAngle(Math.atan2(center.y - mid.y, center.x - mid.x))
- });
- }
- return out;
- };
- const handleResizeNudge = (indexes, translation) => {
- dispatch(`resizestart`, {
- indexes,
- translation: vectorCreateEmpty()
- });
- dispatch(`resizemove`, { indexes, translation });
- dispatch(`resizeend`, {
- indexes,
- translation: vectorCreateEmpty()
- });
- };
- const handleRotateNudge = ({ detail }) => {
- dispatch(`rotatestart`, { translation: vectorCreateEmpty() });
- dispatch(`rotatemove`, { translation: detail });
- dispatch(`rotateend`, { translation: vectorCreateEmpty() });
- };
- const nudge_handler = (index, { detail }) => handleResizeNudge(index, detail);
- $$self.$$set = $$props => {
- if ("points" in $$props) $$invalidate(15, points = $$props.points);
- if ("rotatorPoint" in $$props) $$invalidate(0, rotatorPoint = $$props.rotatorPoint);
- if ("visible" in $$props) $$invalidate(16, visible = $$props.visible);
- if ("enableResizing" in $$props) $$invalidate(17, enableResizing = $$props.enableResizing);
- if ("enableRotating" in $$props) $$invalidate(1, enableRotating = $$props.enableRotating);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*visible*/ 65536) {
- selectionScale.set(visible ? 1 : 0.5);
- }
- if ($$self.$$.dirty[0] & /*visible*/ 65536) {
- selectionOpacity.set(visible ? 1 : 0);
- }
- if ($$self.$$.dirty[0] & /*enableResizing*/ 131072) {
- $$invalidate(2, resizeAxis = !enableResizing
- ? false
- : isString(enableResizing) ? enableResizing : "both");
- }
- if ($$self.$$.dirty[0] & /*resizeAxis, points*/ 32772) {
- $$invalidate(3, resizeControls = resizeAxis && mapPointsToControls(points, resizeAxis) || []);
- }
- if ($$self.$$.dirty[0] & /*points*/ 32768) {
- $$invalidate(4, rotationControlActive = points.length > 2);
- }
- };
- return [
- rotatorPoint,
- enableRotating,
- resizeAxis,
- resizeControls,
- rotationControlActive,
- $selectionScale,
- $selectionOpacity,
- handleKeyDown,
- handleKeyUp,
- selectionScale,
- selectionOpacity,
- resize,
- handleResizeNudge,
- handleRotateNudge,
- rotate,
- points,
- visible,
- enableResizing,
- nudge_handler
- ];
- }
- class ShapeManipulator extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$h,
- create_fragment$h,
- safe_not_equal,
- {
- points: 15,
- rotatorPoint: 0,
- visible: 16,
- enableResizing: 17,
- enableRotating: 1
- },
- [-1, -1]
- );
- }
- }
- var getEventPositionInEditor = (e, viewOffset) => {
- const positionInViewport = getEventPositionInViewport(e);
- return vectorSubtract(positionInViewport, viewOffset);
- };
- let result$1 = null;
- var isAndroid = () => {
- if (result$1 === null)
- result$1 = isUserAgent(/Android/);
- return result$1;
- };
- var cursorMoveToEnd = (field) => (field.selectionStart = field.selectionEnd = field.value.length);
- let result = null;
- var supportsVisualViewport = () => {
- if (result === null) {
- result = isBrowser() && 'visualViewport' in window;
- }
- return result;
- };
- var createSoftKeyboardObserver = (cb) => {
- if (!supportsVisualViewport())
- return false;
- const heightNormal = visualViewport.height;
- const testState = () => {
- cb(visualViewport.height < heightNormal ? 'visible' : 'hidden');
- };
- visualViewport.addEventListener('resize', testState);
- return () => visualViewport.removeEventListener('resize', testState);
- };
- /* src/core/ui/components/InputForm.svelte generated by Svelte v3.37.0 */
- function create_fragment$g(ctx) {
- let div2;
- let div1;
- let button0;
- let t0;
- let div0;
- let t1;
- let button1;
- let current;
- let mounted;
- let dispose;
- button0 = new Button({
- props: {
- onclick: /*oncancel*/ ctx[1],
- label: /*labelCancel*/ ctx[5],
- icon: /*iconCancel*/ ctx[7],
- hideLabel: !/*labelCancelShow*/ ctx[6]
- }
- });
- const default_slot_template = /*#slots*/ ctx[20].default;
- const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[19], null);
- button1 = new Button({
- props: {
- onclick: /*onconfirm*/ ctx[0],
- label: /*labelConfirm*/ ctx[2],
- icon: /*iconConfirm*/ ctx[4],
- hideLabel: !/*labelConfirmShow*/ ctx[3],
- class: "PinturaInputFormButtonConfirm"
- }
- });
- return {
- c() {
- div2 = element("div");
- div1 = element("div");
- create_component(button0.$$.fragment);
- t0 = space();
- div0 = element("div");
- if (default_slot) default_slot.c();
- t1 = space();
- create_component(button1.$$.fragment);
- attr(div0, "class", "PinturaInputFormFields");
- attr(div1, "class", "PinturaInputFormInner");
- attr(div2, "class", "PinturaInputForm");
- attr(div2, "style", /*style*/ ctx[9]);
- },
- m(target, anchor) {
- insert(target, div2, anchor);
- append(div2, div1);
- mount_component(button0, div1, null);
- append(div1, t0);
- append(div1, div0);
- if (default_slot) {
- default_slot.m(div0, null);
- }
- append(div1, t1);
- mount_component(button1, div1, null);
- /*div2_binding*/ ctx[21](div2);
- current = true;
- if (!mounted) {
- dispose = [
- listen(div2, "focusin", /*handleFocusIn*/ ctx[10]),
- listen(div2, "focusout", /*handleFocusOut*/ ctx[11]),
- listen(div2, "measure", /*handleMeasure*/ ctx[12]),
- action_destroyer(measurable.call(null, div2))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- const button0_changes = {};
- if (dirty[0] & /*oncancel*/ 2) button0_changes.onclick = /*oncancel*/ ctx[1];
- if (dirty[0] & /*labelCancel*/ 32) button0_changes.label = /*labelCancel*/ ctx[5];
- if (dirty[0] & /*iconCancel*/ 128) button0_changes.icon = /*iconCancel*/ ctx[7];
- if (dirty[0] & /*labelCancelShow*/ 64) button0_changes.hideLabel = !/*labelCancelShow*/ ctx[6];
- button0.$set(button0_changes);
- if (default_slot) {
- if (default_slot.p && dirty[0] & /*$$scope*/ 524288) {
- update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[19], dirty, null, null);
- }
- }
- const button1_changes = {};
- if (dirty[0] & /*onconfirm*/ 1) button1_changes.onclick = /*onconfirm*/ ctx[0];
- if (dirty[0] & /*labelConfirm*/ 4) button1_changes.label = /*labelConfirm*/ ctx[2];
- if (dirty[0] & /*iconConfirm*/ 16) button1_changes.icon = /*iconConfirm*/ ctx[4];
- if (dirty[0] & /*labelConfirmShow*/ 8) button1_changes.hideLabel = !/*labelConfirmShow*/ ctx[3];
- button1.$set(button1_changes);
- if (!current || dirty[0] & /*style*/ 512) {
- attr(div2, "style", /*style*/ ctx[9]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(button0.$$.fragment, local);
- transition_in(default_slot, local);
- transition_in(button1.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(button0.$$.fragment, local);
- transition_out(default_slot, local);
- transition_out(button1.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div2);
- destroy_component(button0);
- if (default_slot) default_slot.d(detaching);
- destroy_component(button1);
- /*div2_binding*/ ctx[21](null);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- const panelDelay = 200;
- function instance$g($$self, $$props, $$invalidate) {
- let computedStyle;
- let shouldStickToKeyboard;
- let style;
- let { $$slots: slots = {}, $$scope } = $$props;
- let { onconfirm } = $$props;
- let { oncancel } = $$props;
- let { autoFocus = true } = $$props;
- let { autoPositionCursor = true } = $$props;
- let { labelConfirm } = $$props;
- let { labelConfirmShow = true } = $$props;
- let { iconConfirm } = $$props;
- let { labelCancel } = $$props;
- let { labelCancelShow = false } = $$props;
- let { iconCancel } = $$props;
- let { panelOffset = vectorCreateEmpty() } = $$props;
- let panelVisible = false;
- let panelHeight = undefined;
- let panelRevealTimeout = undefined;
- let panelPosition = "";
- let panelOpacity = 0;
- let root;
- const isTextarea = element => (/textarea/i).test(element);
- const preventTextAreaScrollingOnIOS = element => {
- // preventsDefault on textarea events when can no longer scroll up or down in textarea
- let lastScreenY;
- const handleTouchStart = e => lastScreenY = e.touches[0].screenY;
- const handleTouchMove = e => {
- const currentScreenY = e.touches[0].screenY;
- const target = e.target;
- if ((/textarea/i).test(target.nodeName)) {
- // moving down
- if (currentScreenY > lastScreenY) {
- if (target.scrollTop == 0) {
- e.preventDefault();
- }
- } else // moving up
- if (currentScreenY < lastScreenY) {
- if (target.scrollTop + target.offsetHeight == target.scrollHeight) {
- e.preventDefault();
- }
- } else {
- e.preventDefault();
- }
- lastScreenY = currentScreenY;
- } else {
- e.preventDefault();
- }
- };
- element.addEventListener("touchstart", handleTouchStart);
- element.addEventListener("touchmove", handleTouchMove);
- return () => {
- element.removeEventListener("touchstart", handleTouchStart);
- element.removeEventListener("touchmove", handleTouchMove);
- };
- };
- const focus = () => {
- const field = root.querySelector("input, textarea");
- field.focus();
- field.select();
- };
- const show = () => {
- panelVisible = true;
- // browser does not support keyboard listener, place modal at top of view
- if (!unsubSoftKeyboardListener && (isIOS() || isAndroid())) {
- $$invalidate(16, panelPosition = "top:1em;bottom:auto;");
- }
- // prevent interacting with the root element
- if (isIOS()) preventTextAreaScrollingOnIOS(root);
- // reveal
- $$invalidate(17, panelOpacity = 1);
- };
- const hide = () => {
- panelVisible = false;
- $$invalidate(17, panelOpacity = 0);
- };
- const handleSoftKeyboard = keyboardState => {
- // shouldn't stick, we'll stick it to the top of the viewport so the keyboard doesn't obscure the input field
- if (!shouldStickToKeyboard) {
- $$invalidate(16, panelPosition = `top: 4.5em; bottom: auto`);
- return;
- }
- // no need to continue, already hidden
- if (keyboardState === "hidden" && !panelVisible) {
- focus();
- return;
- }
- // gonna update position here
- clearTimeout(panelRevealTimeout);
- panelRevealTimeout = undefined;
- // position
- $$invalidate(16, panelPosition = `top:${visualViewport.height - panelHeight - panelOffset.y}px`);
- // if a soft keyboard is detected, turn into modal mode
- if (keyboardState === "visible") {
- // stick to keyboard
- $$invalidate(8, root.dataset.layout = "stick", root);
- // need to refocus
- focus();
- // place above keyboard
- show();
- } else // keyboard is hidden
- {
- hide();
- }
- };
- let focusDateTime;
- const handleFocusIn = e => {
- if (!isTextarea(e.target)) return;
- // we need to remember focus time so we can detect unrealistic blur event caused by soft keyboard shenanigans
- focusDateTime = Date.now();
- // move cursor
- if (autoPositionCursor) cursorMoveToEnd(e.target);
- // wait a couple milliseconds
- clearTimeout(panelRevealTimeout);
- panelRevealTimeout = setTimeout(show, panelDelay);
- };
- const handleFocusOut = e => {
- const focusDuration = Date.now() - focusDateTime;
- if (focusDuration > 50) return;
- // unrealistic blur, refocus
- e.stopPropagation();
- focus();
- };
- const unsubSoftKeyboardListener = createSoftKeyboardObserver(handleSoftKeyboard);
- const handleMeasure = ({ detail }) => {
- panelHeight = detail.height;
- };
- onMount(() => {
- if (!autoFocus) return;
- focus();
- });
- onDestroy(() => {
- unsubSoftKeyboardListener && unsubSoftKeyboardListener();
- });
- function div2_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- root = $$value;
- $$invalidate(8, root);
- });
- }
- $$self.$$set = $$props => {
- if ("onconfirm" in $$props) $$invalidate(0, onconfirm = $$props.onconfirm);
- if ("oncancel" in $$props) $$invalidate(1, oncancel = $$props.oncancel);
- if ("autoFocus" in $$props) $$invalidate(13, autoFocus = $$props.autoFocus);
- if ("autoPositionCursor" in $$props) $$invalidate(14, autoPositionCursor = $$props.autoPositionCursor);
- if ("labelConfirm" in $$props) $$invalidate(2, labelConfirm = $$props.labelConfirm);
- if ("labelConfirmShow" in $$props) $$invalidate(3, labelConfirmShow = $$props.labelConfirmShow);
- if ("iconConfirm" in $$props) $$invalidate(4, iconConfirm = $$props.iconConfirm);
- if ("labelCancel" in $$props) $$invalidate(5, labelCancel = $$props.labelCancel);
- if ("labelCancelShow" in $$props) $$invalidate(6, labelCancelShow = $$props.labelCancelShow);
- if ("iconCancel" in $$props) $$invalidate(7, iconCancel = $$props.iconCancel);
- if ("panelOffset" in $$props) $$invalidate(15, panelOffset = $$props.panelOffset);
- if ("$$scope" in $$props) $$invalidate(19, $$scope = $$props.$$scope);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*root*/ 256) {
- $$invalidate(18, computedStyle = root && getComputedStyle(root));
- }
- if ($$self.$$.dirty[0] & /*computedStyle*/ 262144) {
- shouldStickToKeyboard = computedStyle && computedStyle.getPropertyValue("--editor-modal") === "1";
- }
- if ($$self.$$.dirty[0] & /*panelOpacity, panelPosition*/ 196608) {
- $$invalidate(9, style = `opacity:${panelOpacity};${panelPosition}`);
- }
- };
- return [
- onconfirm,
- oncancel,
- labelConfirm,
- labelConfirmShow,
- iconConfirm,
- labelCancel,
- labelCancelShow,
- iconCancel,
- root,
- style,
- handleFocusIn,
- handleFocusOut,
- handleMeasure,
- autoFocus,
- autoPositionCursor,
- panelOffset,
- panelPosition,
- panelOpacity,
- computedStyle,
- $$scope,
- slots,
- div2_binding
- ];
- }
- class InputForm extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$g,
- create_fragment$g,
- safe_not_equal,
- {
- onconfirm: 0,
- oncancel: 1,
- autoFocus: 13,
- autoPositionCursor: 14,
- labelConfirm: 2,
- labelConfirmShow: 3,
- iconConfirm: 4,
- labelCancel: 5,
- labelCancelShow: 6,
- iconCancel: 7,
- panelOffset: 15
- },
- [-1, -1]
- );
- }
- }
- /* src/core/ui/components/ShapeLayoutEditor.svelte generated by Svelte v3.37.0 */
- function get_each_context$3(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[178] = list[i];
- child_ctx[180] = i;
- return child_ctx;
- }
- // (2627:12) {#each shapeNavList as item, index (item.id)}
- function create_each_block$3(key_1, ctx) {
- let li;
- let button;
- let colorpreview;
- let t0;
- let span;
- let t1_value = /*item*/ ctx[178].name + "";
- let t1;
- let button_aria_label_value;
- let t2;
- let current;
- let mounted;
- let dispose;
- colorpreview = new ColorPreview({
- props: { color: /*item*/ ctx[178].color }
- });
- function click_handler(...args) {
- return /*click_handler*/ ctx[124](/*index*/ ctx[180], ...args);
- }
- return {
- key: key_1,
- first: null,
- c() {
- li = element("li");
- button = element("button");
- create_component(colorpreview.$$.fragment);
- t0 = space();
- span = element("span");
- t1 = text(t1_value);
- t2 = space();
- attr(button, "class", "PinturaShapeListItem");
- attr(button, "type", "button");
- attr(button, "aria-label", button_aria_label_value = "Select shape " + /*item*/ ctx[178].name);
- this.first = li;
- },
- m(target, anchor) {
- insert(target, li, anchor);
- append(li, button);
- mount_component(colorpreview, button, null);
- append(button, t0);
- append(button, span);
- append(span, t1);
- append(li, t2);
- current = true;
- if (!mounted) {
- dispose = listen(button, "click", click_handler);
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- const colorpreview_changes = {};
- if (dirty[0] & /*shapeNavList*/ 524288) colorpreview_changes.color = /*item*/ ctx[178].color;
- colorpreview.$set(colorpreview_changes);
- if ((!current || dirty[0] & /*shapeNavList*/ 524288) && t1_value !== (t1_value = /*item*/ ctx[178].name + "")) set_data(t1, t1_value);
- if (!current || dirty[0] & /*shapeNavList*/ 524288 && button_aria_label_value !== (button_aria_label_value = "Select shape " + /*item*/ ctx[178].name)) {
- attr(button, "aria-label", button_aria_label_value);
- }
- },
- i(local) {
- if (current) return;
- transition_in(colorpreview.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(colorpreview.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(li);
- destroy_component(colorpreview);
- mounted = false;
- dispose();
- }
- };
- }
- // (2643:4) {#if shouldRenderShapeManipulator}
- function create_if_block_2$2(ctx) {
- let shapemanipulator;
- let current;
- shapemanipulator = new ShapeManipulator({
- props: {
- visible: true,
- points: /*shapeManipulatorPoints*/ ctx[8],
- rotatorPoint: /*shapeManipulatorRotationPointPosition*/ ctx[14],
- enableResizing: /*allowedResizeControls*/ ctx[13],
- enableRotating: /*allowRotateControls*/ ctx[6]
- }
- });
- shapemanipulator.$on("resizestart", /*handleManipulatorResizeGrab*/ ctx[25]);
- shapemanipulator.$on("resizemove", /*handleManipulatorResizeDrag*/ ctx[26]);
- shapemanipulator.$on("resizeend", /*handleManipulatorResizeEnd*/ ctx[27]);
- shapemanipulator.$on("rotatestart", /*handleManipulatorRotateGrab*/ ctx[28]);
- shapemanipulator.$on("rotatemove", /*handleManipulatorRotateDrag*/ ctx[29]);
- shapemanipulator.$on("rotateend", /*handleManipulatorRotateEnd*/ ctx[30]);
- return {
- c() {
- create_component(shapemanipulator.$$.fragment);
- },
- m(target, anchor) {
- mount_component(shapemanipulator, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const shapemanipulator_changes = {};
- if (dirty[0] & /*shapeManipulatorPoints*/ 256) shapemanipulator_changes.points = /*shapeManipulatorPoints*/ ctx[8];
- if (dirty[0] & /*shapeManipulatorRotationPointPosition*/ 16384) shapemanipulator_changes.rotatorPoint = /*shapeManipulatorRotationPointPosition*/ ctx[14];
- if (dirty[0] & /*allowedResizeControls*/ 8192) shapemanipulator_changes.enableResizing = /*allowedResizeControls*/ ctx[13];
- if (dirty[0] & /*allowRotateControls*/ 64) shapemanipulator_changes.enableRotating = /*allowRotateControls*/ ctx[6];
- shapemanipulator.$set(shapemanipulator_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapemanipulator.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapemanipulator.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(shapemanipulator, detaching);
- }
- };
- }
- // (2659:4) {#if shouldRenderTextInput}
- function create_if_block_1$2(ctx) {
- let inputform;
- let current;
- inputform = new InputForm({
- props: {
- panelOffset: /*offset*/ ctx[1],
- onconfirm: /*handleTextConfirm*/ ctx[36],
- oncancel: /*handleTextCancel*/ ctx[37],
- labelCancel: /*locale*/ ctx[3].shapeLabelInputCancel,
- iconCancel: /*locale*/ ctx[3].shapeIconInputCancel,
- labelConfirm: /*locale*/ ctx[3].shapeLabelInputConfirm,
- iconConfirm: /*locale*/ ctx[3].shapeIconInputConfirm,
- $$slots: { default: [create_default_slot$6] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(inputform.$$.fragment);
- },
- m(target, anchor) {
- mount_component(inputform, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const inputform_changes = {};
- if (dirty[0] & /*offset*/ 2) inputform_changes.panelOffset = /*offset*/ ctx[1];
- if (dirty[0] & /*locale*/ 8) inputform_changes.labelCancel = /*locale*/ ctx[3].shapeLabelInputCancel;
- if (dirty[0] & /*locale*/ 8) inputform_changes.iconCancel = /*locale*/ ctx[3].shapeIconInputCancel;
- if (dirty[0] & /*locale*/ 8) inputform_changes.labelConfirm = /*locale*/ ctx[3].shapeLabelInputConfirm;
- if (dirty[0] & /*locale*/ 8) inputform_changes.iconConfirm = /*locale*/ ctx[3].shapeIconInputConfirm;
- if (dirty[0] & /*markupTextInputStyle, textInput, textInputText*/ 100352 | dirty[5] & /*$$scope*/ 67108864) {
- inputform_changes.$$scope = { dirty, ctx };
- }
- inputform.$set(inputform_changes);
- },
- i(local) {
- if (current) return;
- transition_in(inputform.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(inputform.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(inputform, detaching);
- }
- };
- }
- // (2660:8) <InputForm panelOffset={offset} onconfirm={handleTextConfirm} oncancel={handleTextCancel} labelCancel={locale.shapeLabelInputCancel} iconCancel={locale.shapeIconInputCancel} labelConfirm={locale.shapeLabelInputConfirm} iconConfirm={locale.shapeIconInputConfirm} >
- function create_default_slot$6(ctx) {
- let textarea;
- let mounted;
- let dispose;
- return {
- c() {
- textarea = element("textarea");
- attr(textarea, "style", /*markupTextInputStyle*/ ctx[16]);
- attr(textarea, "spellcheck", "false");
- attr(textarea, "autocorrect", "off");
- attr(textarea, "autocapitalize", "off");
- },
- m(target, anchor) {
- insert(target, textarea, anchor);
- /*textarea_binding*/ ctx[125](textarea);
- set_input_value(textarea, /*textInputText*/ ctx[15]);
- if (!mounted) {
- dispose = [
- listen(textarea, "keydown", /*handleTextInputKeyDown*/ ctx[34]),
- listen(textarea, "keypress", /*handleTextInputAttempt*/ ctx[33]),
- listen(textarea, "keyup", /*handleTextInputKeyUp*/ ctx[35]),
- listen(textarea, "input", /*handleTextInput*/ ctx[32]),
- listen(textarea, "input", /*textarea_input_handler*/ ctx[126])
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- if (dirty[0] & /*markupTextInputStyle*/ 65536) {
- attr(textarea, "style", /*markupTextInputStyle*/ ctx[16]);
- }
- if (dirty[0] & /*textInputText*/ 32768) {
- set_input_value(textarea, /*textInputText*/ ctx[15]);
- }
- },
- d(detaching) {
- if (detaching) detach(textarea);
- /*textarea_binding*/ ctx[125](null);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- // (2684:4) {#if $markupControlsOpacity > 0}
- function create_if_block$2(ctx) {
- let div;
- let dynamiccomponenttree;
- let current;
- let mounted;
- let dispose;
- dynamiccomponenttree = new DynamicComponentTree_1({
- props: { items: /*shapeControls*/ ctx[18] }
- });
- return {
- c() {
- div = element("div");
- create_component(dynamiccomponenttree.$$.fragment);
- attr(div, "class", "PinturaShapeControls");
- attr(div, "style", /*markupControlsStyle*/ ctx[17]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(dynamiccomponenttree, div, null);
- current = true;
- if (!mounted) {
- dispose = [
- listen(div, "measure", /*measure_handler_1*/ ctx[127]),
- action_destroyer(measurable.call(null, div))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- const dynamiccomponenttree_changes = {};
- if (dirty[0] & /*shapeControls*/ 262144) dynamiccomponenttree_changes.items = /*shapeControls*/ ctx[18];
- dynamiccomponenttree.$set(dynamiccomponenttree_changes);
- if (!current || dirty[0] & /*markupControlsStyle*/ 131072) {
- attr(div, "style", /*markupControlsStyle*/ ctx[17]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(dynamiccomponenttree.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(dynamiccomponenttree.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(dynamiccomponenttree);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function create_fragment$f(ctx) {
- let div;
- let nav;
- let ul;
- let each_blocks = [];
- let each_1_lookup = new Map();
- let t0;
- let t1;
- let t2;
- let interactable_action;
- let current;
- let mounted;
- let dispose;
- let each_value = /*shapeNavList*/ ctx[19];
- const get_key = ctx => /*item*/ ctx[178].id;
- for (let i = 0; i < each_value.length; i += 1) {
- let child_ctx = get_each_context$3(ctx, each_value, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block$3(key, child_ctx));
- }
- let if_block0 = /*shouldRenderShapeManipulator*/ ctx[7] && create_if_block_2$2(ctx);
- let if_block1 = /*shouldRenderTextInput*/ ctx[9] && create_if_block_1$2(ctx);
- let if_block2 = /*$markupControlsOpacity*/ ctx[10] > 0 && create_if_block$2(ctx);
- return {
- c() {
- div = element("div");
- nav = element("nav");
- ul = element("ul");
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- t0 = space();
- if (if_block0) if_block0.c();
- t1 = space();
- if (if_block1) if_block1.c();
- t2 = space();
- if (if_block2) if_block2.c();
- attr(nav, "class", "PinturaShapeList");
- attr(nav, "data-visible", /*showShapeList*/ ctx[12]);
- attr(div, "class", "PinturaShapeEditor");
- attr(div, "tabindex", "0");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- append(div, nav);
- append(nav, ul);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].m(ul, null);
- }
- append(div, t0);
- if (if_block0) if_block0.m(div, null);
- append(div, t1);
- if (if_block1) if_block1.m(div, null);
- append(div, t2);
- if (if_block2) if_block2.m(div, null);
- current = true;
- if (!mounted) {
- dispose = [
- listen(nav, "focusin", /*handleFocusIn*/ ctx[40]),
- listen(nav, "focusout", /*handleFocusOut*/ ctx[41]),
- listen(div, "keydown", /*handleKey*/ ctx[31]),
- listen(div, "nudge", /*handleNudge*/ ctx[39]),
- listen(div, "measure", /*measure_handler*/ ctx[123]),
- action_destroyer(measurable.call(null, div)),
- action_destroyer(nudgeable.call(null, div)),
- listen(div, "interactionstart", /*handleInteractionStart*/ ctx[21]),
- listen(div, "interactionupdate", /*handleInteractionUpdate*/ ctx[22]),
- listen(div, "interactionrelease", /*handleInteractionRelease*/ ctx[23]),
- listen(div, "interactionend", /*handleInteractionEnd*/ ctx[24]),
- action_destroyer(interactable_action = interactable.call(null, div, {
- drag: true,
- pinch: true,
- inertia: true,
- matchTarget: true,
- getEventPosition: /*interactable_function*/ ctx[128]
- }))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- if (dirty[0] & /*shapeNavList, selectShape, markup*/ 524305) {
- each_value = /*shapeNavList*/ ctx[19];
- group_outros();
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, ul, outro_and_destroy_block, create_each_block$3, null, get_each_context$3);
- check_outros();
- }
- if (!current || dirty[0] & /*showShapeList*/ 4096) {
- attr(nav, "data-visible", /*showShapeList*/ ctx[12]);
- }
- if (/*shouldRenderShapeManipulator*/ ctx[7]) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty[0] & /*shouldRenderShapeManipulator*/ 128) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_2$2(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(div, t1);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (/*shouldRenderTextInput*/ ctx[9]) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- if (dirty[0] & /*shouldRenderTextInput*/ 512) {
- transition_in(if_block1, 1);
- }
- } else {
- if_block1 = create_if_block_1$2(ctx);
- if_block1.c();
- transition_in(if_block1, 1);
- if_block1.m(div, t2);
- }
- } else if (if_block1) {
- group_outros();
- transition_out(if_block1, 1, 1, () => {
- if_block1 = null;
- });
- check_outros();
- }
- if (/*$markupControlsOpacity*/ ctx[10] > 0) {
- if (if_block2) {
- if_block2.p(ctx, dirty);
- if (dirty[0] & /*$markupControlsOpacity*/ 1024) {
- transition_in(if_block2, 1);
- }
- } else {
- if_block2 = create_if_block$2(ctx);
- if_block2.c();
- transition_in(if_block2, 1);
- if_block2.m(div, null);
- }
- } else if (if_block2) {
- group_outros();
- transition_out(if_block2, 1, 1, () => {
- if_block2 = null;
- });
- check_outros();
- }
- if (interactable_action && is_function(interactable_action.update) && dirty[0] & /*rootRect*/ 4) interactable_action.update.call(null, {
- drag: true,
- pinch: true,
- inertia: true,
- matchTarget: true,
- getEventPosition: /*interactable_function*/ ctx[128]
- });
- },
- i(local) {
- if (current) return;
- for (let i = 0; i < each_value.length; i += 1) {
- transition_in(each_blocks[i]);
- }
- transition_in(if_block0);
- transition_in(if_block1);
- transition_in(if_block2);
- current = true;
- },
- o(local) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- transition_out(each_blocks[i]);
- }
- transition_out(if_block0);
- transition_out(if_block1);
- transition_out(if_block2);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d();
- }
- if (if_block0) if_block0.d();
- if (if_block1) if_block1.d();
- if (if_block2) if_block2.d();
- mounted = false;
- run_all(dispose);
- }
- };
- }
- const ROTATION_CONTROL_OFFSET = 20;
- const MIN_TEXT_MARKUP_WIDTH = 10;
- const shapeControlDist = 16;
- function instance$f($$self, $$props, $$invalidate) {
- let activeMarkup;
- let activeShapeId;
- let activeMarkupComputed;
- let activeMarkupItemIsDraft;
- let shapeProps;
- let shapeActivePoints;
- let allowResizeControls;
- let allowRotateControls;
- let allowedResizeControls;
- let shouldRenderShapeManipulator;
- let shapeActiveScreenPoints;
- let shapeManipulatorPoints;
- let shapeManipulatorRotationPoint;
- let shapeManipulatorRotationPointPosition;
- let isTextMarkupSelected;
- let shouldRenderTextInput;
- let textShapeOrigin;
- let textShapeDisplayOrigin;
- let textSizeDisplayOrigin;
- let textRectDisplayOrigin;
- let textInputText;
- let markupTextInputStyle;
- let controlledMarkupItem;
- let allowShapeFlip;
- let allowShapeChangeTextLayout;
- let allowShapeDuplicate;
- let allowShapeRemove;
- let allowShapeReorder;
- let allowShapeInput;
- let allowShapeAdjustOpacity;
- let markupControlsAnchorPosition;
- let shapeControlsPosition;
- let markupControlsStyle;
- let shapeControls;
- let shapeNavList;
- let $keysPressedStored;
- let $markupControlsOpacity;
- let { uid = getUniqueId() } = $$props; // used to control manipulator lines
- let { ui } = $$props;
- let { markup } = $$props;
- let { offset } = $$props;
- let { contextRotation = 0 } = $$props;
- let { contextFlipX = false } = $$props;
- let { contextFlipY = false } = $$props;
- let { contextScale } = $$props;
- let { active = false } = $$props;
- let { opacity = 1 } = $$props;
- let { parentRect } = $$props;
- let { rootRect } = $$props;
- let { utilRect } = $$props;
- let { oninteractionstart = noop$1 } = $$props;
- let { oninteractionupdate = noop$1 } = $$props;
- let { oninteractionrelease = noop$1 } = $$props;
- let { oninteractionend = noop$1 } = $$props;
- let { onaddshape = noop$1 } = $$props;
- let { onupdateshape = noop$1 } = $$props;
- let { onselectshape = noop$1 } = $$props;
- let { onremoveshape = noop$1 } = $$props;
- let { beforeSelectShape = () => true } = $$props;
- let { beforeDeselectShape = () => true } = $$props;
- let { beforeRemoveShape = () => true } = $$props;
- let { beforeUpdateShape = (shape, props) => props } = $$props;
- let { willRenderShapeControls = passthrough } = $$props;
- let { mapEditorPointToImagePoint } = $$props;
- let { mapImagePointToEditorPoint } = $$props;
- let { eraseRadius = undefined } = $$props;
- let { selectRadius = undefined } = $$props;
- let { enableButtonFlipVertical = false } = $$props;
- let { enableTapToAddText = true } = $$props;
- let { locale } = $$props;
- //
- // Cache
- //
- const updateShape = (shape, props, parentRect) => {
- let propsToUpdate = beforeUpdateShape({ ...shape }, props, { ...parentRect });
- shapeUpdateProps(shape, propsToUpdate, parentRect);
- };
- //
- // Helpers
- //
- const circleOverlapsWithLine = (point, radius, from, to) => {
- const ac = vectorCreate(point.x - from.x, point.y - from.y);
- const ab = vectorCreate(to.x - from.x, to.y - from.y);
- const ab2 = vectorDot(ab, ab);
- const acab = vectorDot(ac, ab);
- let t = acab / ab2;
- t = t < 0 ? 0 : t;
- t = t > 1 ? 1 : t;
- const h = vectorCreate(ab.x * t + from.x - point.x, ab.y * t + from.y - point.y);
- const h2 = vectorDot(h, h);
- return h2 <= radius * radius;
- };
- const circleOverlapsWithPath = (position, radius, points) => {
- const l = points.length;
- for (let i = 0; i < l - 1; i++) {
- if (circleOverlapsWithLine(position, radius, points[i], points[i + 1])) return true;
- }
- return false;
- };
- const circleOverlapsWithPolygon = (position, radius, points) => {
- // if center is in polygon
- if (pointInPoly(position, points)) return true;
- if (circleOverlapsWithPath(position, radius, points)) return true;
- return circleOverlapsWithLine(position, radius, points[0], points[points.length - 1]);
- };
- const circleOverlapsWithEllipse = (position, radius, ellipse, rotation, flipX, flipY) => {
- const points = ellipseToPolygon(vectorCreate(ellipse.x, ellipse.y), ellipse.rx, ellipse.ry, rotation, flipX, flipY, 12);
- return circleOverlapsWithPolygon(position, radius, points);
- };
- const circleOverlapsWithRect = (position, radius, rect, rotation, pivot) => circleOverlapsWithPolygon(position, radius, rectRotate(rect, rotation, pivot || rectCenter(rect)));
- const shapeToPoly = (computedShape, resolution = 12) => {
- if (shapeIsRect(computedShape)) {
- return rectRotate(computedShape, computedShape.rotation, rectCenter(computedShape));
- } else if (shapeIsText(computedShape)) {
- const computedRect = getMarkupShapeRect(computedShape);
- return rectRotate(computedRect, computedShape.rotation, rectCenter(computedRect));
- } else if (shapeIsEllipse(computedShape)) {
- return ellipseToPolygon(vectorCreate(computedShape.x, computedShape.y), computedShape.rx, computedShape.ry, computedShape.rotation, computedShape.flipX, computedShape.flipY, resolution);
- }
- return [];
- };
- //
- // Shape creator
- //
- const keysPressedStored = getContext("keysPressed");
- component_subscribe($$self, keysPressedStored, value => $$invalidate(137, $keysPressedStored = value));
- const getShapeUpdateRotation = (rotation, flipX, flipY) => {
- if (rotation === 0) return rotation;
- if (flipX && flipY) return rotation;
- if (flipX) return -rotation;
- if (flipY) return -rotation;
- return rotation;
- };
- const createShape = (shapeDefault, options = {}) => {
- // state
- let interactionOrigin;
- let interactionRadius;
- let interactionPosition;
- let isEllipse = shapeIsEllipse(shapeDefault);
- let isText = shapeIsText(shapeDefault);
- let isRelative = options.position === "relative";
- if (shapeIsPath(shapeDefault)) {
- return {
- start: e => {
- const { origin } = e.detail;
- interactionRadius = 4;
- interactionOrigin = vectorClone(origin);
- interactionPosition = vectorClone(origin);
- const originPoint = mapEditorPointToImagePoint(origin);
- if (isRelative) {
- originPoint.x = isRelative
- ? toPercentage(originPoint.x, parentRect.width)
- : originPoint.x;
- originPoint.y = isRelative
- ? toPercentage(originPoint.y, parentRect.height)
- : originPoint.y;
- }
- // add to markup so it's drawn
- addMarkupItemDraft({ ...shapeDefault, points: [originPoint] });
- },
- update: e => {
- const draft = getMarkupItemDraft();
- const { translation } = e.detail;
- // position
- const pointerPosition = vectorCreate(interactionOrigin.x + translation.x, interactionOrigin.y + translation.y);
- // distance between interaction and pointer if it's too close, we don't draw this point
- const dist = vectorDistance(interactionPosition, pointerPosition);
- if (fixPrecision(dist, 5) <= interactionRadius) return;
- // get angle between interaction and pointer
- const angle = vectorAngleBetween(pointerPosition, interactionPosition);
- // move brush towards pointer at angle
- const moveDist = interactionRadius - dist;
- interactionPosition.x += moveDist * Math.cos(angle);
- interactionPosition.y += moveDist * Math.sin(angle);
- // create point
- const point = mapEditorPointToImagePoint(interactionPosition);
- if (point) {
- point.x = isRelative
- ? toPercentage(point.x, parentRect.width)
- : point.x;
- point.y = isRelative
- ? toPercentage(point.y, parentRect.height)
- : point.y;
- }
- draft.points = draft.points.concat(point);
- syncShapes();
- },
- release: e => e.detail.preventInertia(),
- end: e => {
- if (e.detail.isTap) return discardMarkupItemDraft();
- const shape = confirmMarkupItemDraft();
- onaddshape(shape);
- }
- };
- } else if (isEllipse || isText || shapeIsRect(shapeDefault)) {
- return {
- start: e => {
- const { origin } = e.detail;
- // need to remember origin so we can correctly apply interaction translation
- interactionOrigin = vectorClone(origin);
- const mappedOriginPosition = mapEditorPointToImagePoint(interactionOrigin);
- // add to markup so it's drawn
- const draft = {
- ...shapeDefault,
- rotation: -1 * getShapeUpdateRotation(contextRotation, contextFlipX, contextFlipY),
- x: isRelative
- ? toPercentage(mappedOriginPosition.x, parentRect.width)
- : mappedOriginPosition.x,
- y: isRelative
- ? toPercentage(mappedOriginPosition.y, parentRect.height)
- : mappedOriginPosition.y
- };
- // de-flip shape
- draft.flipX = contextFlipX;
- draft.flipY = contextFlipY;
- // remove position
- delete draft.position;
- // hide initially
- draft.opacity = 0;
- //
- if (isEllipse) {
- draft.rx = isRelative ? toPercentage(0) : 0;
- draft.ry = isRelative ? toPercentage(0) : 0;
- } else {
- draft.width = isRelative ? toPercentage(0) : 0;
- draft.height = isRelative ? toPercentage(0) : 0;
- }
- addMarkupItemDraft(draft);
- },
- update: e => {
- const draft = getMarkupItemDraft();
- draft.opacity = 1;
- const { aspectRatio } = draft;
- let { translation } = e.detail;
- // limit to aspect ratio
- if (aspectRatio) {
- const t = Math.abs(translation.x) * aspectRatio;
- translation.x = translation.x;
- translation.y = t * Math.sign(translation.y);
- }
- // position
- const pointerPosition = vectorCreate(interactionOrigin.x + translation.x, interactionOrigin.y + translation.y);
- const mappedOriginPosition = mapEditorPointToImagePoint(interactionOrigin);
- const mappedPointerPosition = mapEditorPointToImagePoint(pointerPosition);
- const pivot = {
- x: mappedOriginPosition.x + (mappedPointerPosition.x - mappedOriginPosition.x) * 0.5,
- y: mappedOriginPosition.y + (mappedPointerPosition.y - mappedOriginPosition.y) * 0.5
- };
- const rotation = getShapeUpdateRotation(contextRotation, contextFlipX, contextFlipY);
- vectorRotate(mappedOriginPosition, rotation, pivot);
- vectorRotate(mappedPointerPosition, rotation, pivot);
- const l = Math.min(mappedOriginPosition.x, mappedPointerPosition.x);
- const t = Math.min(mappedOriginPosition.y, mappedPointerPosition.y);
- const r = Math.max(mappedOriginPosition.x, mappedPointerPosition.x);
- const b = Math.max(mappedOriginPosition.y, mappedPointerPosition.y);
- let width = r - l;
- let height = b - t;
- let props = {};
- if (isEllipse) {
- props.x = l + width * 0.5;
- props.y = t + height * 0.5;
- props.rx = width * 0.5;
- props.ry = height * 0.5;
- } else {
- props.x = l;
- props.y = t;
- props.width = width;
- props.height = height;
- }
- updateShape(draft, props, parentRect);
- syncShapes();
- },
- release: e => {
- e.detail.preventInertia();
- },
- end: e => {
- const draft = getMarkupItemDraft();
- if (e.detail.isTap) {
- // will cancel if is not text shape
- if (!shapeIsText(draft) || !enableTapToAddText || interactionTarget) return discardMarkupItemDraft();
- // will add 'auto' text shape if not targetting other shape
- delete draft.width;
- delete draft.height;
- delete draft.textAlign;
- // position the shape correctly
- const draftComputedShape = shapeComputeDisplay({ ...draft }, parentRect);
- const size = textSize(draft.text, draftComputedShape);
- size.width *= contextScale;
- size.height *= contextScale;
- const mappedOriginPosition = mapEditorPointToImagePoint({
- x: interactionOrigin.x,
- y: interactionOrigin.y - size.height * 0.5
- });
- const mappedPointerPosition = mapEditorPointToImagePoint({
- x: interactionOrigin.x + size.width,
- y: interactionOrigin.y + size.height * 0.5
- });
- const pivot = {
- x: mappedOriginPosition.x + (mappedPointerPosition.x - mappedOriginPosition.x) * 0.5,
- y: mappedOriginPosition.y + (mappedPointerPosition.y - mappedOriginPosition.y) * 0.5
- };
- const rotation = getShapeUpdateRotation(contextRotation, contextFlipX, contextFlipY);
- vectorRotate(mappedOriginPosition, rotation, pivot);
- vectorRotate(mappedPointerPosition, rotation, pivot);
- const l = Math.min(mappedOriginPosition.x, mappedPointerPosition.x);
- const t = Math.min(mappedOriginPosition.y, mappedPointerPosition.y);
- draft.x = isString(draft.x)
- ? toPercentage(l, parentRect.width)
- : l;
- draft.y = isString(draft.y)
- ? toPercentage(t, parentRect.height)
- : t;
- }
- // reveal
- draft.opacity = 1;
- // finish markup
- if (!shapeIsText(draft)) {
- const shape = confirmMarkupItemDraft();
- onaddshape(shape);
- }
- // select the draft
- selectShape(draft);
- // also enable editing the text
- if (shapeIsText(draft)) editMarkupItem(draft);
- }
- };
- } else if (shapeIsLine(shapeDefault)) {
- return {
- start: e => {
- const { origin } = e.detail;
- const originMapped = mapEditorPointToImagePoint(origin);
- const originSnapped = vectorApply(originMapped, snapToPixel);
- interactionOrigin = vectorClone(origin);
- // add to markup so it's drawn
- addMarkupItemDraft({
- ...shapeDefault,
- x1: isRelative
- ? toPercentage(originSnapped.x, parentRect.width)
- : originSnapped.x,
- y1: isRelative
- ? toPercentage(originSnapped.y, parentRect.height)
- : originSnapped.y,
- x2: isRelative
- ? toPercentage(originSnapped.x, parentRect.width)
- : originSnapped.x,
- y2: isRelative
- ? toPercentage(originSnapped.y, parentRect.height)
- : originSnapped.y,
- opacity: 0
- });
- },
- update: e => {
- const draft = getMarkupItemDraft();
- const { translation } = e.detail;
- const interactionTarget = vectorAdd(vectorClone(interactionOrigin), translation);
- // shift pressed
- if ($keysPressedStored.includes(16)) {
- const length = vectorDistance(interactionOrigin, interactionTarget);
- const angle = vectorAngleBetween(interactionOrigin, interactionTarget);
- const angleSnapInterval = Math.PI / 4;
- const angleSnapped = angleSnapInterval * Math.round(angle / angleSnapInterval);
- interactionTarget.x = interactionOrigin.x + length * Math.cos(angleSnapped);
- interactionTarget.y = interactionOrigin.y + length * Math.sin(angleSnapped);
- }
- // update line end position
- const point = mapEditorPointToImagePoint(interactionTarget);
- updateMarkupShape(draft, {
- x2: isRelative
- ? toPercentage(point.x, parentRect.width)
- : point.x,
- y2: isRelative
- ? toPercentage(point.y, parentRect.height)
- : point.y,
- opacity: 1
- });
- syncShapes();
- },
- release: e => e.detail.preventInertia(),
- end: e => {
- const draft = getMarkupItemDraft();
- if (e.detail.isTap) return discardMarkupItemDraft();
- draft.opacity = 1;
- // finish markup
- const shape = confirmMarkupItemDraft();
- onaddshape(shape);
- // select the draft
- selectShape(shape);
- }
- };
- }
- };
- const eraseShape = () => {
- let origin;
- let positionPrevious;
- return {
- start: e => {
- origin = e.detail.origin;
- positionPrevious = origin;
- },
- update: e => {
- const { translation } = e.detail;
- const positionCurrent = vectorCreate(origin.x + translation.x, origin.y + translation.y);
- const shapesThatCanBeErased = markup.filter(shape => !shape.disableErase);
- const shapesFound = getShapesBetweenPoints(shapesThatCanBeErased, mapEditorPointToImagePoint(positionPrevious), mapEditorPointToImagePoint(positionCurrent), eraseRadius);
- const shapesRemoved = removeMarkupItems(shapesFound);
- shapesRemoved.forEach(onremoveshape);
- positionPrevious = vectorClone(positionCurrent);
- },
- release: e => e.detail.preventInertia(),
- end: () => {
-
- }
- };
- };
- //
- // Mapping coordinates
- //
- const getImagePointWithScreenTranslation = (point, translation) => {
- const pointInScreenSpace = mapImagePointToEditorPoint(point);
- return mapEditorPointToImagePoint(vectorAdd(pointInScreenSpace, translation));
- };
- //
- // Interaction
- //
- // image zoom
- // const handleWheel = (e) => {
- // TODO: ZOOM image
- // }
- // image pan
- // const handleImagePan = (e) => {
- // TODO: PAN image
- // }
- //
- // markup manipulate
- //
- const translateShape = (shapeCurrent, shapeOriginComputed, translation) => {
- if (shapeIsLine(shapeCurrent)) {
- const beginImageOffset = getImagePointWithScreenTranslation(shapeLineGetStartPoint(shapeOriginComputed), translation);
- const endImageOffset = getImagePointWithScreenTranslation(shapeLineGetEndPoint(shapeOriginComputed), translation);
- updateShape(
- shapeCurrent,
- {
- x1: beginImageOffset.x,
- y1: beginImageOffset.y,
- x2: endImageOffset.x,
- y2: endImageOffset.y
- },
- parentRect
- );
- } else if (shapeIsRect(shapeCurrent) || shapeIsText(shapeCurrent) || shapeIsEllipse(shapeCurrent)) {
- const imagePoint = getImagePointWithScreenTranslation(shapeOriginComputed, translation);
- updateShape(shapeCurrent, imagePoint, parentRect);
- }
- syncShapes();
- };
- const IndexFlipXMap = { 0: 1, 1: 0, 2: 3, 3: 2 };
- const IndexFlipYMap = { 0: 3, 1: 2, 2: 1, 3: 0 };
- const resizeMarkup = (shapeCurrent, shapeOriginComputed, indexes, translation, options) => {
- if (shapeIsLine(shapeCurrent)) {
- const [targetIndex] = indexes;
- const snap = $keysPressedStored.includes(16)
- ? (origin, target) => {
- const length = vectorDistance(origin, target);
- const angle = vectorAngleBetween(origin, target);
- const angleSnapInterval = Math.PI / 4;
- const angleSnapped = angleSnapInterval * Math.round(angle / angleSnapInterval) - contextRotation % angleSnapInterval;
- target.x = origin.x + length * Math.cos(angleSnapped);
- target.y = origin.y + length * Math.sin(angleSnapped);
- }
- : (origin, target) => target;
- if (targetIndex === 0) {
- const point = getImagePointWithScreenTranslation(shapeLineGetStartPoint(shapeOriginComputed), translation);
- snap(vectorCreate(shapeOriginComputed.x2, shapeOriginComputed.y2), point);
- updateShape(shapeCurrent, { x1: point.x, y1: point.y }, parentRect);
- } else if (targetIndex === 1) {
- const point = getImagePointWithScreenTranslation(shapeLineGetEndPoint(shapeOriginComputed), translation);
- snap(vectorCreate(shapeOriginComputed.x1, shapeOriginComputed.y1), point);
- updateShape(shapeCurrent, { x2: point.x, y2: point.y }, parentRect);
- }
- } else if (shapeHasSize(shapeCurrent) || shapeIsEllipse(shapeCurrent) || shapeIsTextBox(shapeCurrent)) {
- let hasAutoHeight = false;
- let shapeOriginRect;
- if (shapeIsEllipse(shapeCurrent)) {
- shapeOriginRect = rectCreateFromEllipse(shapeOriginComputed);
- } else if (shapeHasSize(shapeCurrent)) {
- shapeOriginRect = rectCreateFromAny(shapeOriginComputed);
- } else {
- // is text with 'width' only
- hasAutoHeight = true;
- shapeOriginRect = rectCreateFromAny(shapeOriginComputed);
- const size = textSize(shapeOriginComputed.text, shapeOriginComputed);
- shapeOriginRect.height = size.height;
- }
- let shapeAspectRatio;
- if (shapeCurrent.aspectRatio) {
- shapeAspectRatio = shapeCurrent.aspectRatio;
- } else if (options.shiftKey && !hasAutoHeight) {
- shapeAspectRatio = shapeOriginRect.width / shapeOriginRect.height;
- }
- // current shape
- const rectAligned = rectCreateFromAny(shapeOriginRect);
- const rectAlignedCenterPosition = rectCenter(rectAligned);
- const rectRotation = shapeCurrent.rotation;
- const rectAlignedCorners = rectGetCorners(rectAligned);
- const rectCorners = rectRotate(rectAligned, rectRotation);
- // is translating one corner
- if (indexes.length === 1) {
- // corner
- let cornerIndex = indexes[0];
- if (shapeCurrent.flipX) cornerIndex = IndexFlipXMap[cornerIndex];
- if (shapeCurrent.flipY) cornerIndex = IndexFlipYMap[cornerIndex];
- const [tl, tr, br, bl] = rectAlignedCorners;
- const screenTargetPosition = mapImagePointToEditorPoint(rectCorners[cornerIndex]);
- vectorAdd(screenTargetPosition, translation);
- const imageTargetPosition = mapEditorPointToImagePoint(screenTargetPosition);
- const imageTargetTranslation = vectorCreate(imageTargetPosition.x - rectCorners[cornerIndex].x, imageTargetPosition.y - rectCorners[cornerIndex].y);
- // if (shapeCurrent.flipX) imageTargetTranslation.x = -imageTargetTranslation.x;
- // if (shapeCurrent.flipY) imageTargetTranslation.y = -imageTargetTranslation.y;
- const imageTargetTranslationAligned = vectorRotate(vectorClone(imageTargetTranslation), -rectRotation);
- const imageTargetPositionAligned = vectorCreate(rectAlignedCorners[cornerIndex].x + imageTargetTranslationAligned.x, rectAlignedCorners[cornerIndex].y + imageTargetTranslationAligned.y);
- let anchor;
- if (cornerIndex === 0) anchor = br;
- if (cornerIndex === 1) anchor = bl;
- if (cornerIndex === 2) anchor = tl;
- if (cornerIndex === 3) anchor = tr;
- // create an aligned and updated rectangle
- const rectAlignedResized = rectCreateFromPoints(anchor, imageTargetPositionAligned);
- // limit rect
- if (shapeAspectRatio) {
- // get size that adheres to aspect ratio but still fits current rectangle
- const { width, height } = rectContainRect(rectAlignedResized, shapeAspectRatio);
- const [t, r, b, l] = rectToBounds(rectAlignedResized);
- // update size
- rectAlignedResized.width = width;
- rectAlignedResized.height = height;
- // align to anchor
- if (imageTargetPositionAligned.y < anchor.y) {
- rectAlignedResized.y = b - height;
- }
- if (imageTargetPositionAligned.x < anchor.x) {
- rectAlignedResized.x = r - width;
- }
- }
- // rotate the aligned rectangle around it's original pivot point
- const rr = rectRotate(rectAlignedResized, rectRotation, rectAlignedCenterPosition);
- // now calculate the new center and then rotate the tl and br corners around that center to find their new positions
- const rrc = vectorCenter(rr);
- const p1 = vectorRotate(rr[0], -rectRotation, rrc);
- const p2 = vectorRotate(rr[2], -rectRotation, rrc);
- // if (shapeCurrent.flipX || shapeCurrent.flipY) {
- // vectorsFlip([p1, p2], shapeCurrent.flipX, shapeCurrent.flipY, rectAlignedCenterPosition.x, rectAlignedCenterPosition.y)
- // }
- const rectUpdated = rectCreateFromPoints(p1, p2);
- updateShape(
- shapeCurrent,
- shapeIsEllipse(shapeCurrent)
- ? ellipseCreateFromRect(rectUpdated)
- : rectUpdated,
- parentRect
- );
- } else // is translating two corner points
- {
- // 0-1 -> 2-3
- // 1-2 -> 3-0
- // 2-3 -> 0-1
- // 3-0 -> 1-2
- indexes = indexes.map(index => {
- if (shapeCurrent.flipX) index = IndexFlipXMap[index];
- if (shapeCurrent.flipY) index = IndexFlipYMap[index];
- return index;
- });
- const [cornerA, cornerB] = indexes.map(index => rectCorners[index]);
- const mid = {
- x: cornerA.x + (cornerB.x - cornerA.x) * 0.5,
- y: cornerA.y + (cornerB.y - cornerA.y) * 0.5
- };
- const [cornerAlignedA, cornerAlignedB] = indexes.map(index => rectAlignedCorners[index]);
- const [cornerAlignedC, cornerAlignedD] = indexes.map(index => {
- const mappedIndex = index + 2;
- if (mappedIndex < 4) return rectAlignedCorners[mappedIndex];
- return rectAlignedCorners[mappedIndex - 4];
- });
- // const midAligned = {
- // x: cornerAlignedA.x + (cornerAlignedB.x - cornerAlignedA.x) * .5,
- // y: cornerAlignedA.y + (cornerAlignedB.y - cornerAlignedA.y) * .5
- // };
- const midAnchorAligned = {
- x: cornerAlignedC.x + (cornerAlignedD.x - cornerAlignedC.x) * 0.5,
- y: cornerAlignedC.y + (cornerAlignedD.y - cornerAlignedC.y) * 0.5
- };
- const screenTargetPosition = mapImagePointToEditorPoint(mid);
- vectorAdd(screenTargetPosition, translation);
- const imageTargetPosition = mapEditorPointToImagePoint(screenTargetPosition);
- const imageTargetTranslation = vectorCreate(imageTargetPosition.x - mid.x, imageTargetPosition.y - mid.y);
- // if (shapeCurrent.flipX) imageTargetTranslation.x = -imageTargetTranslation.x;
- // if (shapeCurrent.flipY) imageTargetTranslation.y = -imageTargetTranslation.y;
- const imageTargetTranslationAligned = vectorRotate(vectorClone(imageTargetTranslation), -rectRotation);
- // const imageTargetPositionAligned = vectorCreate(
- // midAligned.x + imageTargetTranslationAligned.x,
- // midAligned.y + imageTargetTranslationAligned.y,
- // );
- const d = vectorSubtract(vectorClone(cornerAlignedA), cornerAlignedB);
- const f = vectorApply(d, v => 1 - Math.abs(Math.sign(v)));
- const t = vectorCreate(imageTargetTranslationAligned.x * f.x, imageTargetTranslationAligned.y * f.y);
- vectorAdd(cornerAlignedA, t);
- vectorAdd(cornerAlignedB, t);
- const rectAlignedResized = rectCreateFromPoints(rectAlignedCorners);
- // limit rect
- if (shapeAspectRatio) {
- let width = rectAlignedResized.width;
- let height = rectAlignedResized.height;
- if (f.y === 0) {
- height = width / shapeAspectRatio;
- } else {
- width = height * shapeAspectRatio;
- }
- // update size
- rectAlignedResized.width = width;
- rectAlignedResized.height = height;
- // align to anchor
- if (f.y === 0) {
- rectAlignedResized.y = midAnchorAligned.y - height * 0.5;
- } else {
- rectAlignedResized.x = midAnchorAligned.x - width * 0.5;
- }
- }
- // rotate the aligned rectangle around it's original pivot point
- const rr = rectRotate(rectAlignedResized, rectRotation, rectAlignedCenterPosition);
- // now calculate the new center and then rotate the tl and br corners around that center to find their new positions
- const rrc = vectorCenter(rr);
- const p1 = vectorRotate(rr[0], -rectRotation, rrc);
- const p2 = vectorRotate(rr[2], -rectRotation, rrc);
- // if (shapeCurrent.flipX || shapeCurrent.flipY) {
- // vectorsFlip([p1, p2], shapeCurrent.flipX, shapeCurrent.flipY, rectAlignedCenterPosition.x, rectAlignedCenterPosition.y)
- // }
- const rectUpdated = rectCreateFromPoints(p1, p2);
- let props;
- if (shapeIsEllipse(shapeCurrent)) {
- props = ellipseCreateFromRect(rectUpdated);
- } else if (shapeHasSize(shapeCurrent)) {
- props = rectUpdated;
- } else if (hasAutoHeight) {
- props = {
- x: rectUpdated.x,
- y: rectUpdated.y,
- width: rectUpdated.width
- };
- }
- updateShape(shapeCurrent, props, parentRect);
- }
- }
- syncShapes();
- };
- let rotatorInitialPosition;
- const rotateMarkup = (shapeCurrent, shapeOriginComputed, translation, options) => {
- // calculate angle between translated rotation control and origin
- const shapeRect = getMarkupShapeRect(shapeComputeDisplay(shapeDeepCopy(shapeCurrent), parentRect));
- const shapeCenter = rectCenter(shapeRect);
- const p = getImagePointWithScreenTranslation(rotatorInitialPosition, translation);
- let shapeRotation = vectorAngleBetween(p, shapeCenter) + Math.PI / 2;
- if (options.shiftKey) {
- const rotatorSnapInterval = Math.PI / 16;
- shapeRotation = rotatorSnapInterval * Math.round(shapeRotation / rotatorSnapInterval) - contextRotation % rotatorSnapInterval;
- }
- updateShape(shapeCurrent, { rotation: shapeRotation }, parentRect);
- syncShapes();
- };
- const getMarkupItemDraft = () => {
- if (!markup.length) return;
- return markup.find(shapeIsDraft);
- };
- const getMarkupItemDraftIndex = () => {
- if (!markup.length) return;
- return markup.findIndex(shapeIsDraft);
- };
- const addMarkupItemDraft = (shape, sync = true) => {
- if (getMarkupItemDraft()) return;
- shapeMakeDraft(shape);
- return addShape(shape, sync);
- };
- const confirmMarkupItemDraft = () => {
- const markupItem = getMarkupItemDraft();
- if (!markupItem) return;
- shapeMakeFinal(markupItem);
- syncShapes();
- return markupItem;
- };
- const discardMarkupItemDraft = () => {
- if (!getMarkupItemDraft()) return;
- markup.splice(getMarkupItemDraftIndex(), 1);
- syncShapes();
- };
- const createMarkupItem = (props = {}) => ({ id: getUniqueId(), ...props });
- const syncShapes = () => $$invalidate(0, markup);
- const addShape = (shape, sync = true) => {
- markup.push(shape);
- // sync markup array
- if (sync) syncShapes();
- return shape;
- };
- const removeMarkupShapeProps = (shape, props = [], sync = true) => {
- props.forEach(prop => delete shape[prop]);
- // sync markup array
- if (!sync) return;
- syncShapes();
- };
- const updateMarkupShape = (shape, props, sync = true) => {
- // update markup
- shape = Object.assign(shape, props);
- // sync markup array
- if (!sync) return;
- syncShapes();
- };
- const updateMarkupShapeProperty = (shape, name, value, sync = true) => {
- shape[name] = value;
- // sync markup array
- if (!sync) return;
- syncShapes();
- };
- const updateMarkupItemsShapeProperty = (name, value, sync = true) => {
- markup.forEach(shape => updateMarkupShapeProperty(shape, name, value, false));
- // sync markup array
- if (!sync) return;
- syncShapes();
- };
- const updateMarkupShapeItems = (props, sync = true) => {
- markup.forEach(markupItem => updateMarkupShape(markupItem, props, false));
- // sync markup array
- if (!sync) return;
- syncShapes();
- };
- const getActiveMarkupItem = () => [...markup].reverse().find(shapeIsSelected);
- const hasActiveMarkupItem = () => !!getActiveMarkupItem();
- const removeShape = shapeToRemove => {
- if (!beforeRemoveShape(shapeToRemove)) return false;
- $$invalidate(0, markup = markup.filter(shape => shape !== shapeToRemove));
- onremoveshape(shapeToRemove);
- };
- const removeActiveMarkupItem = () => {
- const activeShape = getActiveMarkupItem();
- if (!activeShape) return;
- // get removable markup items,
- const removableShapes = markup.filter(shape => shapeCanRemove(shape) && shapeCanSelect(shape));
- // find index of active shape so we can select the next active shape on removal
- const index = removableShapes.findIndex(shape => shape === activeShape);
- // remove the active ship from the shape array
- const didRemove = removeShape(activeShape);
- if (didRemove === false) return;
- // remember selection
- previousSelectedShape = activeShape;
- // if no more markup items, release active shape
- if (removableShapes.length - 1 <= 0) return blurShapes();
- // select next active markup item
- const indexNext = index - 1 < 0 ? removableShapes.length - 1 : index - 1;
- selectShape(removableShapes[indexNext]);
- };
- let previousSelectedShape = undefined;
- const blurShapes = () => {
- // clear text state cache, when a text shape is blurred the changes are confirmed
- Object.keys(ShapeTextStateCache).forEach(key => ShapeTextStateCache[key] = {});
- // remember shape
- previousSelectedShape = getSelectedShape();
- updateMarkupShapeItems({ isSelected: false, isEditing: false });
- };
- const getSelectedShape = () => markup.find(shapeIsSelected);
- const selectShape = (shape, sync = true) => {
- // can't select draft
- if (shapeIsDraft(shape)) return;
- // get currently selected shape
- const selectedShape = getSelectedShape() || previousSelectedShape;
- // reset previous selected shape
- previousSelectedShape = undefined;
- // if is returned false will cancel select operation
- if (!beforeSelectShape(selectedShape, shape)) return;
- // remove selected state from other markup
- blurShapes();
- // select
- shapeSelect(shape);
- // selected this shape
- onselectshape(shape);
- // sync
- if (!sync) return;
- syncShapes();
- };
- const deselectMarkupItem = markupItem => {
- updateMarkupShape(markupItem, { isSelected: false, isEditing: false });
- };
- const editMarkupItem = markupItem => {
- updateMarkupShape(markupItem, { isSelected: true, isEditing: true });
- };
- const finishEditMarkupItem = markupItem => {
- updateMarkupShape(markupItem, { isSelected: true, isEditing: false });
- };
- const removeMarkupItems = shapesToRemove => {
- const shapesToRemoveFiltered = shapesToRemove.filter(beforeRemoveShape);
- $$invalidate(0, markup = markup.filter(shape => !shapesToRemoveFiltered.includes(shape)));
- return shapesToRemoveFiltered;
- };
- const getTextShapeRect = shape => {
- const size = textSize(shape.text, shape);
- return rectCreate(
- shape.x,
- shape.y,
- shape.width
- ? Math.min(shape.width, size.width)
- : size.width,
- shape.height
- ? Math.min(shape.height, size.height)
- : size.height
- );
- };
- const getMarkupShapeRect = shape => {
- // has own rect
- if (shapeHasSize(shape)) return rectCreateFromAny(shape);
- if (shapeIsEllipse(shape)) return rectCreateFromEllipse(shape);
- // calculate the size on canvas
- const rect = getTextShapeRect(shape);
- rect.width = Math.max(MIN_TEXT_MARKUP_WIDTH, shape.width || rect.width);
- return rect;
- };
- const getShapesNearPosition = (position, range = 0) => [...markup].// reverse the array, want to select from top to bottom
- reverse().map(shape => ({ shape, priority: 1 })).// can't select paths
- filter(result => shapeCanSelect(result.shape)).// find markup near pointer
- filter(result => {
- // get shape
- const { shape } = result;
- // we need to know where the shape will end up
- const computedShape = shapeComputeDisplay(shapeDeepCopy(shape), parentRect);
- // add stroke width to range
- const r = range + (computedShape.strokeWidth || 0);
- // test if clicked in rect
- if (shapeIsRect(computedShape)) {
- return circleOverlapsWithRect(position, r, computedShape, shape.rotation);
- } else if (shapeIsText(computedShape)) {
- const shapeRect = getMarkupShapeRect(computedShape);
- const isPositionInBounds = circleOverlapsWithRect(position, r, shapeRect, shape.rotation);
- let isPositionInVisual = false;
- if (isPositionInBounds && !shapeIsSelected(shape)) {
- const visualRect = getTextShapeRect(computedShape);
- if (shape.textAlign === "right" && !shape.flipX) {
- visualRect.x = shapeRect.x + shapeRect.width - visualRect.width;
- }
- if (shape.textAlign === "center") {
- visualRect.x = shapeRect.x + shapeRect.width * 0.5 - visualRect.width * 0.5;
- }
- isPositionInVisual = circleOverlapsWithRect(position, r, visualRect, shape.rotation, rectCenter(shapeRect));
- if (!isPositionInVisual) result.priority = -1;
- }
- return isPositionInBounds;
- } else // test if is ellipse
- if (shapeIsEllipse(computedShape)) {
- return circleOverlapsWithEllipse(position, r, computedShape, shape.rotation, shape.flipX, shape.flipY);
- } else // test if clicked on line
- if (shapeIsLine(computedShape)) {
- // radius around click position, test if line intersects
- return circleOverlapsWithLine(position, Math.max(16, r), shapeLineGetStartPoint(computedShape), shapeLineGetEndPoint(computedShape)); // always increase range when selecting lines
- } else if (shapeIsPath(computedShape)) {
- // radius around click position, test if line intersects
- return circleOverlapsWithPath(position, Math.max(16, r), computedShape.points); // always increase range when selecting lines
- }
- return false;
- }).sort((a, b) => {
- if (a.priority < b.priority) return 1;
- if (a.priority > b.priority) return -1;
- return 0;
- });
- const getShapesBetweenPoints = (shapes, a, b, range = 0) => {
- // make sure range is not negative
- const r = Math.abs(range);
- // eraseLine should be in image space
- const eraseLine = lineExtend(lineCreate(a, b), r);
- // create line polygon
- const erasePoly = lineExtrude(eraseLine, r);
- // loop over shapes and find intersecting shapes
- return shapes.// .filter(shapeCanErase)
- filter(shape => {
- const computedShape = shapeComputeDisplay(shapeDeepCopy(shape), parentRect);
- // if shape is line or path
- if (shapeIsLine(computedShape) || shapeIsPath(computedShape)) {
- const points = computedShape.points
- ? [...computedShape.points]
- : [
- shapeLineGetStartPoint(computedShape),
- shapeLineGetEndPoint(computedShape)
- ];
- return !!linePointsIntersection(eraseLine, points);
- }
- // else turn into polygon and compare polygons
- return polyIntersectsWithPoly(erasePoly, shapeToPoly(computedShape));
- });
- };
- //
- // Generic interaction
- //
- let interactionTimer = undefined;
- let interactionTarget = undefined;
- let interactionShape = undefined;
- let interactionShapeOrigin = undefined;
- let interactionShapeOriginComputed = undefined;
- let isInteracting = false;
- const handleInteractionStart = e => {
- const { origin } = e.detail;
- interactionShape = undefined;
- interactionShapeOrigin = undefined;
- interactionShapeOriginComputed = undefined;
- interactionTarget = undefined;
- clearTimeout(interactionTimer);
- interactionTimer = setTimeout(() => $$invalidate(99, isInteracting = true), 250);
- // if is editing text
- const draft = getMarkupItemDraft();
- if (draft) confirmMarkupItemDraft();
- // test if target is a shape, if not, run interaction handler
- const point = mapEditorPointToImagePoint(vectorClone(origin));
- const foundShapes = getShapesNearPosition(point, selectRadius);
- const targettedMarkupItem = foundShapes.length && foundShapes.shift().shape;
- // check if markup was targetted
- if (targettedMarkupItem && shapeIsSelected(targettedMarkupItem)) {
- interactionShape = targettedMarkupItem;
- // create a deep copy so we can check on end interaction if the shape was changed
- interactionShapeOrigin = shapeDeepCopy(interactionShape);
- // clone shape we're interacting with so we can update it properly
- interactionShapeOriginComputed = shapeComputeDisplay(shapeDeepCopy(interactionShape), parentRect);
- return;
- }
- // set target
- interactionTarget = targettedMarkupItem;
- // started interacting
- const didStartInteraction = oninteractionstart(e);
- // drag current targetted it as fallback interaction, helps make sticker interaction easier
- if (!didStartInteraction && targettedMarkupItem) {
- selectShape(targettedMarkupItem);
- interactionShape = targettedMarkupItem;
- // create a deep copy so we can check on end interaction if the shape was changed
- interactionShapeOrigin = shapeDeepCopy(interactionShape);
- // clone shape we're interacting with so we can update it properly
- interactionShapeOriginComputed = shapeComputeDisplay(shapeDeepCopy(interactionShape), parentRect);
- }
- };
- const handleInteractionUpdate = e => {
- // is interacting with shape
- if (interactionShape) {
- // prevent moving if not allowed
- if (!shapeCanMove(interactionShape)) return;
- // prevent moving if is editing text
- if (shapeIsTextEditing(interactionShape)) return;
- return translateShape(interactionShape, interactionShapeOriginComputed, e.detail.translation);
- }
- oninteractionupdate(e);
- };
- const handleInteractionRelease = e => {
- clearTimeout(interactionTimer);
- $$invalidate(99, isInteracting = false);
- // test if is text and if we double tapped, if so, switch to text edit mode
- if (interactionShape) {
- if (interactionShape.isEditing) {
- handleTextCancel();
- } else if (e.detail.isDoubleTap && shapeIsText(interactionShape) && shapeCanInput(interactionShape) !== false) {
- editMarkupItem(interactionShape);
- }
- return;
- }
- oninteractionrelease(e);
- };
- const handleInteractionEnd = e => {
- const isSelectInteraction = interactionTarget && e.detail.isTap;
- // shape remains active so user can resize, rotate
- if (interactionShape) {
- if (!shapeEqual(interactionShape, interactionShapeOrigin)) onupdateshape(interactionShape);
- interactionShape = undefined;
- return;
- }
- // can we deselect the current shape?
- const currentSelectedShape = getSelectedShape();
- const allowDeselectShape = currentSelectedShape
- ? beforeDeselectShape(currentSelectedShape, interactionTarget)
- : true;
- if (allowDeselectShape) {
- blurShapes();
- }
- oninteractionend(e);
- if (allowDeselectShape && isSelectInteraction) {
- selectShape(interactionTarget);
- }
- };
- //
- // Shape manipulation
- //
- const getMarkupShapePoints = shape => {
- let points;
- if (shapeIsRect(shape)) {
- const center = rectCenter(shape);
- points = rectGetCorners(shape);
- if (shape.flipX || shape.flipY) vectorsFlip(points, shape.flipX, shape.flipY, center.x, center.y);
- points = vectorsRotate(points, shape.rotation, center.x, center.y);
- } else if (shapeIsEllipse(shape)) {
- const center = shape;
- points = rectGetCorners(rectCreateFromEllipse(shape));
- if (shape.flipX || shape.flipY) vectorsFlip(points, shape.flipX, shape.flipY, center.x, center.y);
- points = vectorsRotate(points, shape.rotation, center.x, center.y);
- } else if (shapeIsLine(shape)) {
- points = [shapeLineGetStartPoint(shape), shapeLineGetEndPoint(shape)];
- } else if (shapeIsPath(shape)) {
- points = [...shape.points];
- } else if (shapeIsText(shape)) {
- const rect = getMarkupShapeRect(shape);
- rect.width = Math.max(MIN_TEXT_MARKUP_WIDTH, rect.width);
- const center = rectCenter(rect);
- points = rectGetCorners(rect);
- if (shape.flipX || shape.flipY) vectorsFlip(points, shape.flipX, shape.flipY, center.x, center.y);
- points = vectorsRotate(points, shape.rotation, center.x, center.y);
- }
- return points;
- };
- const getShapeRotationPoint = shape => {
- const points = getMarkupShapePoints(shape);
- let origin;
- let dir;
- if (shape.flipY) {
- origin = vectorCenter([points[0], points[1]]);
- dir = vectorNormalize(vectorCreate(points[1].x - points[2].x, points[1].y - points[2].y));
- } else {
- origin = vectorCenter([points[2], points[3]]);
- dir = vectorNormalize(vectorCreate(points[2].x - points[1].x, points[2].y - points[1].y));
- }
- vectorMultiply(dir, ROTATION_CONTROL_OFFSET / contextScale);
- return { origin, dir };
- };
- const getShapeRotationPointOnScreen = shape => {
- const markupPoint = getShapeRotationPoint(shape);
- const screenPosition = mapImagePointToEditorPoint({
- x: markupPoint.origin.x + markupPoint.dir.x,
- y: markupPoint.origin.y + markupPoint.dir.y
- });
- const screenOrigin = mapImagePointToEditorPoint(markupPoint.origin);
- return {
- origin: screenOrigin,
- position: screenPosition
- };
- };
- // draw shape manipulator edges
- let shapeManipulatorUid = `markup-manipulator-segment`;
- const claimManipulatorLines = () => {
- $$invalidate(42, ui = ui.map(shape => {
- if (shape.id !== shapeManipulatorUid) return shape;
- shape._group = uid;
- return shape;
- }));
- };
- const shouldManipulateLines = () => !!ui.find(segment => segment._group === uid);
- const redrawManipulatorLines = opacity => {
- // get current line opacity
- const current = ui.find(segment => segment.id === shapeManipulatorUid);
- const manipulatorOpacity = current ? Math.max(current.opacity, opacity) : opacity;
- // create manipulator outline segments
- const segments = [];
- const shadowOpacity = 0.1 * manipulatorOpacity;
- const lineOpacity = manipulatorOpacity;
- const strokeColorShadow = [0, 0, 0];
- const strokeColor = [1, 1, 1];
- const strokeWidth = 1.5;
- const pathClose = shapeIsPath(activeMarkup) || shapeIsLine(activeMarkup)
- ? false
- : true;
- // shadows
- segments.push({
- id: shapeManipulatorUid,
- points: shapeActiveScreenPoints.map(p => vectorCreate(p.x + 1, p.y + 1)),
- pathClose,
- strokeColor: strokeColorShadow,
- strokeWidth: 2,
- opacity: shadowOpacity,
- _group: uid
- });
- if (shapeManipulatorRotationPoint) {
- // add rotator line shadow
- segments.push({
- id: shapeManipulatorUid,
- points: [
- vectorCreate(shapeManipulatorRotationPoint.origin.x + 1, shapeManipulatorRotationPoint.origin.y + 1),
- vectorCreate(shapeManipulatorRotationPoint.position.x + 1, shapeManipulatorRotationPoint.position.y + 1)
- ],
- strokeColor: strokeColorShadow,
- strokeWidth: 2,
- opacity: shadowOpacity,
- _group: uid
- });
- }
- // lines
- segments.push({
- id: shapeManipulatorUid,
- points: shapeActiveScreenPoints,
- pathClose,
- strokeColor,
- strokeWidth,
- opacity: lineOpacity,
- _group: uid
- });
- if (shapeManipulatorRotationPoint) {
- // add rotator line
- segments.push({
- id: shapeManipulatorUid,
- points: [
- {
- x: shapeManipulatorRotationPoint.origin.x,
- y: shapeManipulatorRotationPoint.origin.y
- },
- {
- x: shapeManipulatorRotationPoint.position.x,
- y: shapeManipulatorRotationPoint.position.y
- }
- ],
- strokeColor,
- strokeWidth,
- opacity: lineOpacity,
- _group: uid
- });
- }
- // replace existing segments
- $$invalidate(42, ui = [...ui.filter(guide => guide.id !== shapeManipulatorUid), ...segments]);
- };
- const removeMarkupManipulatorLines = () => {
- $$invalidate(42, ui = ui.filter(guide => guide.opacity === 0 && guide.id !== shapeManipulatorUid));
- };
- onDestroy(() => {
- // clean up invisible lines
- removeMarkupManipulatorLines();
- });
- const handleManipulatorResizeGrab = e => {
- $$invalidate(99, isInteracting = true);
- interactionShape = activeMarkup;
- interactionShapeOriginComputed = activeMarkupComputed;
- };
- const handleManipulatorResizeDrag = e => {
- const { translation, indexes, shiftKey } = e.detail;
- resizeMarkup(interactionShape, interactionShapeOriginComputed, indexes, translation, { shiftKey });
- };
- const handleManipulatorResizeEnd = e => {
- selectShape(interactionShape);
- interactionShape = undefined;
- $$invalidate(99, isInteracting = false);
- onupdateshape(activeMarkup);
- };
- const handleManipulatorRotateGrab = e => {
- rotatorInitialPosition = getShapeRotationPoint(activeMarkupComputed).origin;
- $$invalidate(99, isInteracting = true);
- interactionShape = activeMarkup;
- interactionShapeOriginComputed = activeMarkupComputed;
- };
- const handleManipulatorRotateDrag = e => {
- const { translation, shiftKey } = e.detail;
- rotateMarkup(interactionShape, interactionShapeOriginComputed, translation, { shiftKey });
- };
- const handleManipulatorRotateEnd = () => {
- selectShape(interactionShape);
- interactionShape = undefined;
- $$invalidate(99, isInteracting = false);
- onupdateshape(activeMarkup);
- };
- //
- // Keyboard
- //
- const handleKey = e => {
- // only handle key input if a shape has been selected
- if (!hasActiveMarkupItem()) return;
- // get key type
- const { key } = e;
- // if is escape deselect active item
- if ((/escape/i).test(key)) {
- return deselectMarkupItem(activeMarkup);
- }
- // if is tab, select next markup item
- /*
- if (/arrow/i.test(key)) {
- const success = e.shiftKey
- ? selectPreviousMarkupItem(activeMarkup)
- : selectNextMarkupItem(activeMarkup);
- if (success) {
- e.preventDefault();
- e.stopPropagation();
- }
- }
- */
- // if is remove active
- if ((/backspace/i).test(key) && !(/input|textarea/i).test(e.target.nodeName)) {
- // prevent back navigation on Firefox
- e.preventDefault();
- // remove the item
- removeActiveMarkupItem();
- }
- };
- //
- // Text input
- //
- let textInput;
- const getTextShapeOriginSnapshot = () => ({ ...activeMarkup });
- const handleTextInput = () => {
- const value = shapeIsTextLine(activeMarkup)
- ? filterNewlines(textInput.value)
- : textInput.value;
- const canInput = shapeCanInput(activeMarkup, value);
- const text = canInput === true ? value : canInput;
- let x = textShapeDisplayOrigin.x;
- let y = textShapeDisplayOrigin.y;
- // if does not have height we need to adjust offset if is rotated
- if (!activeMarkup.height) {
- // draw origin rect
- const originRotatedRect = rectRotate({ ...textRectDisplayOrigin }, activeMarkup.rotation);
- // draw current rect
- const size = textSize(text, activeMarkupComputed);
- const currentRotatedRect = rectRotate({ x, y, ...size }, activeMarkup.rotation);
- const [originTopLeft, ,originBottomRight] = originRotatedRect;
- const [currentTopLeft, ,currentBottomRight] = currentRotatedRect;
- let a = originTopLeft;
- let b = currentTopLeft;
- // if flipped we need to 'extend' the text field in the opposite direction
- if (activeMarkup.flipX) {
- a = originBottomRight;
- b = currentBottomRight;
- }
- // move
- const d = vectorSubtract(vectorClone(a), b);
- x += d.x;
- y += d.y;
- }
- updateMarkupShape(activeMarkup, {
- x: isString(textShapeOrigin.x)
- ? toPercentage(x, parentRect.width)
- : x,
- y: isString(textShapeOrigin.y)
- ? toPercentage(y, parentRect.height)
- : y,
- text
- });
- };
- const getShapeSizeTranslation = (originRect, targetRect, { flipX, flipY, rotation }, anchor = "top left") => {
- let a, b;
- // draw origin rect
- const [originTopLeft, originTopRight, originBottomRight, originBottomLeft] = rectRotate(originRect, rotation);
- // draw target rect
- const [targetTopLeft, targetTopRight, targetBottomRight, targetBottomLeft] = rectRotate(targetRect, rotation);
- if (anchor === "top center") {
- // for now doesn't matter if it's flipped horizontal
- const originMid = vectorCenter(flipY
- ? [originBottomLeft, originBottomRight]
- : [originTopLeft, originTopRight]);
- const targetMid = vectorCenter(flipY
- ? [targetBottomLeft, targetBottomRight]
- : [targetTopLeft, targetTopRight]);
- a = originMid;
- b = targetMid;
- } else if (anchor === "top right" && !flipX || anchor === "top left" && flipX) {
- // tr
- a = flipY ? originBottomRight : originTopRight;
- b = flipY ? targetBottomRight : targetTopRight;
- } else {
- // tl
- a = flipY ? originBottomLeft : originTopLeft;
- b = flipY ? targetBottomLeft : targetTopLeft;
- }
- return vectorSubtract(vectorClone(a), b);
- };
- const translateRelative = (current, position, translation) => vectorCreate(
- isString(current.x)
- ? toPercentage(position.x + translation.x, parentRect.width)
- : position.x + translation.x,
- isString(current.y)
- ? toPercentage(position.y + translation.y, parentRect.height)
- : position.y + translation.y
- );
- const ShapeTextStateCache = {};
- const handleTextSwitchLayout = () => {
- const shapeTextSize = textSize(activeMarkup.text, activeMarkupComputed);
- const isFixedBox = hasProp(activeMarkup, "height");
- const isAutoHeightBox = !isFixedBox && hasProp(activeMarkup, "width");
- // set/get cache entries for this text shapw
- const key = activeMarkup.id;
- let cache = ShapeTextStateCache[key];
- if (!cache) {
- ShapeTextStateCache[key] = {};
- cache = ShapeTextStateCache[key];
- }
- const toAutoWidth = sizeFrom => {
- const { width, ...autoSizeProps } = activeMarkupComputed;
- const sizeTo = textSize(activeMarkup.text, autoSizeProps);
- // this will change dimensions so if rotated we have to calculate new position
- const translation = getShapeSizeTranslation(rectCreate(activeMarkupComputed.x, activeMarkupComputed.y, sizeFrom.width, sizeFrom.height), rectCreate(activeMarkupComputed.x, activeMarkupComputed.y, sizeTo.width, sizeTo.height), activeMarkupComputed, `top ${activeMarkup.textAlign}`);
- // switch to auto mode
- removeMarkupShapeProps(activeMarkup, ["width", "height", "textAlign"]);
- // update position based on size translation
- updateMarkupShape(activeMarkup, {
- ...translateRelative(activeMarkup, activeMarkupComputed, translation)
- });
- };
- const toAutoHeight = sizeFrom => {
- // -> switch to auto height mode
- const sizeTo = sizeCreate(cache.width || activeMarkupComputed.width || shapeTextSize.width, shapeTextSize.height);
- const textAlign = cache.textAlign || "left";
- // this will change dimensions so if rotated we have to calculate new position
- const translation = getShapeSizeTranslation(rectCreate(activeMarkupComputed.x, activeMarkupComputed.y, sizeFrom.width, sizeFrom.height), rectCreate(activeMarkupComputed.x, activeMarkupComputed.y, sizeTo.width, sizeTo.height), activeMarkupComputed, `top ${textAlign}`);
- // switch to auto-height mode
- removeMarkupShapeProps(activeMarkup, ["height"]);
- // update position based on size translation
- updateMarkupShape(activeMarkup, {
- ...translateRelative(activeMarkup, activeMarkupComputed, translation),
- width: isString(activeMarkup.width)
- ? toPercentage(sizeTo.width, parentRect.width)
- : sizeTo.width,
- textAlign
- });
- };
- const toFixedSize = sizeFrom => {
- // this can change dimensions so we need to recalculate position
- const sizeTo = sizeCreate(cache.width || shapeTextSize.width, cache.height || shapeTextSize.height);
- const textAlign = cache.textAlign || "left";
- // this will change dimensions so if rotated we have to calculate new position
- const translation = getShapeSizeTranslation(rectCreate(activeMarkupComputed.x, activeMarkupComputed.y, sizeFrom.width, sizeFrom.height), rectCreate(activeMarkupComputed.x, activeMarkupComputed.y, sizeTo.width, sizeTo.height), activeMarkupComputed, `top ${textAlign}`);
- // switch to fixed box, use stored alignment or default to left text align
- updateMarkupShape(activeMarkup, {
- ...translateRelative(activeMarkup, activeMarkupComputed, translation),
- width: isString(activeMarkup.width)
- ? toPercentage(sizeTo.width, parentRect.width)
- : sizeTo.width,
- height: isString(activeMarkup.width)
- ? toPercentage(sizeTo.height, parentRect.height)
- : sizeTo.height,
- textAlign
- });
- };
- if (isFixedBox) {
- // store size so we can restore it later
- cache.textAlign = activeMarkup.textAlign;
- cache.width = activeMarkupComputed.width;
- cache.height = activeMarkupComputed.height;
- const sizeFrom = sizeCreate(activeMarkupComputed.width, activeMarkupComputed.height);
- if (shapeCanChangeTextLayout(activeMarkup, "auto-height")) {
- toAutoHeight(sizeFrom);
- } else if (shapeCanChangeTextLayout(activeMarkup, "auto-width")) {
- toAutoWidth(sizeFrom);
- }
- } else if (isAutoHeightBox) {
- // store alignment so we can restore it later
- cache.textAlign = activeMarkup.textAlign;
- cache.width = activeMarkupComputed.width;
- // -> switch to auto width
- const sizeFrom = sizeCreate(activeMarkupComputed.width, shapeTextSize.height);
- if (shapeCanChangeTextLayout(activeMarkup, "auto-width")) {
- toAutoWidth(sizeFrom);
- } else if (shapeCanChangeTextLayout(activeMarkup, "fixed-size")) {
- toFixedSize(sizeFrom);
- }
- } else {
- // -> switch to fixed size or auto height
- const sizeFrom = sizeCreate(shapeTextSize.width, shapeTextSize.height);
- if (shapeCanChangeTextLayout(activeMarkup, "fixed-size")) {
- toFixedSize(sizeFrom);
- } else if (shapeCanChangeTextLayout(activeMarkup, "auto-height")) {
- toAutoHeight(sizeFrom);
- }
- }
- };
- const handleEditTextActiveMarkup = () => editMarkupItem(activeMarkup);
- const handleTextInputAttempt = e => {
- const currentValue = e.target.value;
- const selectionStart = e.target.selectionStart;
- const selectionEnd = e.target.selectionEnd;
- const currentValueStart = currentValue.substring(0, selectionStart);
- const currentValueEnd = currentValue.substring(selectionEnd);
- const intendedValue = currentValueStart + e.key + currentValueEnd;
- const filteredValue = shapeCanInput(activeMarkup, intendedValue);
- if (filteredValue !== intendedValue) return e.preventDefault();
- };
- const filterNewlines = value => value.// split on lines so we can create compressed normal line of text
- split(/[\n\r]/g).// rempve spaces around lines
- map(str => str.trim()).// remove empty strings
- filter(str => str.length).// create new line
- join(" ");
- // prevent moving shape when focusing text field, and close field if escape pressed
- const handleTextInputKeyDown = e => {
- if (shapeIsTextLine(activeMarkup) && (/enter/i).test(e.code)) return e.preventDefault();
- if ((/arrow/i).test(e.code)) return e.stopPropagation();
- if ((/escape/i).test(e.key)) return handleTextCancel();
- };
- // handle alt/ctrl/cmd + return
- const handleTextInputKeyUp = e => {
- // get key type
- const { key, ctrlKey, altKey } = e;
- // confirm multi line text elements
- if ((/enter/i).test(key) && ctrlKey | altKey) return handleTextConfirm();
- };
- const handleTextConfirm = () => {
- // if was draft, now need to confirm
- let wasDraft = shapeIsDraft(activeMarkup);
- if (shapeIsDraft(activeMarkup)) confirmMarkupItemDraft();
- // final text input check
- handleTextInput();
- // done
- finishEditMarkupItem(activeMarkup);
- if (wasDraft) onaddshape(activeMarkup); else onupdateshape(activeMarkup);
- };
- const handleTextCancel = () => {
- if (shapeIsDraft(activeMarkup)) {
- discardMarkupItemDraft();
- } else {
- updateMarkupShape(activeMarkup, {
- text: textShapeOrigin.text,
- x: textShapeOrigin.x,
- y: textShapeOrigin.y
- });
- finishEditMarkupItem(activeMarkup);
- }
- };
- //
- // Controls
- //
- const handleFlipX = e => {
- e.stopPropagation();
- const flipX = activeMarkup.flipX || false;
- updateMarkupShapeProperty(activeMarkup, "flipX", !flipX);
- onupdateshape(activeMarkup);
- };
- const handleFlipY = e => {
- e.stopPropagation();
- const flipY = activeMarkup.flipY || false;
- updateMarkupShapeProperty(activeMarkup, "flipY", !flipY);
- onupdateshape(activeMarkup);
- };
- const handleAdjustOpacity = value => {
- updateMarkupShapeProperty(activeMarkup, "opacity", value);
- onupdateshape(activeMarkup);
- };
- const handleRemoveActiveMarkup = e => {
- e.stopPropagation();
- e.target.blur(); // cancels focus of remove button
- removeActiveMarkupItem();
- };
- const handleMoveToFrontActiveMarkup = e => {
- e.stopPropagation();
- // test if is not already at top of stack, if so, exit
- const index = markup.findIndex(shape => shape === activeMarkup);
- if (index === markup.length - 1) return;
- // add to last index
- $$invalidate(0, markup = markup.filter(markupItem => markupItem !== activeMarkup).concat([activeMarkup]));
- onupdateshape(activeMarkup);
- };
- const handleDuplicateActiveMarkup = e => {
- e.stopPropagation();
- // create clone
- const clone = shapeDeepCopy(activeMarkup);
- clone.id = getUniqueId();
- const duplicationOffset = vectorCreate(50, -50);
- // offset
- if (shapeIsLine(clone)) {
- const linePosition = shapeGetPropsPixelValues(clone, ["x1", "y1", "x2", "y2"], parentRect);
- linePosition.x1 += duplicationOffset.x;
- linePosition.y1 += duplicationOffset.y;
- linePosition.x2 += duplicationOffset.x;
- linePosition.y2 += duplicationOffset.y;
- shapeUpdateProps(clone, linePosition, parentRect);
- } else {
- const currentPosition = shapeGetPropsPixelValues(clone, ["x", "y"], parentRect);
- currentPosition.x += 50;
- currentPosition.y -= 50;
- shapeUpdateProps(clone, currentPosition, parentRect);
- }
- // add clone
- markup.push(clone);
- // added
- onaddshape(clone);
- // select clone
- selectShape(clone);
- };
- const getMarkupControlsAnchorPosition = rect => vectorApply(vectorCreate(rect.x + rect.width * 0.5, rect.y), snapToPixel);
- //
- // show & position markup controls panel
- //
- const markupControlsOpacity = spring(0, { stiffness: 0.2, damping: 0.7 });
- component_subscribe($$self, markupControlsOpacity, value => $$invalidate(10, $markupControlsOpacity = value));
- let shapeControlsSize;
- const getShapeControlPositionOnCanvas = position => {
- const left = utilRect.x;
- const top = utilRect.y;
- const right = left + utilRect.width;
- let x = Math.max(position.x - shapeControlsSize.width * 0.5, left);
- let y = Math.max(position.y - shapeControlsSize.height - shapeControlDist, top);
- if (x + shapeControlsSize.width > right) x = right - shapeControlsSize.width;
- return vectorCreate(x, y);
- };
- const TextLayoutChangeIcon = (locale, shape) => {
- const { disableTextLayout = [] } = shape;
- // is fixed size
- if ("height" in shape) {
- if (disableTextLayout.includes("auto-height")) {
- // next is auto-width, no need to set as is empty
- return locale.shapeIconButtonTextLayoutAutoWidth;
- } else {
- // next is auto-height
- return locale.shapeIconButtonTextLayoutAutoHeight;
- }
- } else // is auto-height
- if ("width" in shape) {
- if (disableTextLayout.includes("auto-width")) {
- // next is fixed-size
- return locale.shapeIconButtonTextLayoutFixedSize;
- } else {
- // next is auto-width, no need to set as is empty
- return locale.shapeIconButtonTextLayoutAutoWidth;
- }
- } else // is auto-width
- {
- // next is fixed-size
- if (disableTextLayout.includes("fixed-size")) {
- // next is fixed-size
- return locale.shapeIconButtonTextLayoutAutoHeight;
- } else {
- // next is auto-width, no need to set as is empty
- return locale.shapeIconButtonTextLayoutFixedSize;
- }
- }
- };
- const TextLayoutChangeLabel = (locale, shape) => {
- const { disableTextLayout = [] } = shape;
- // is fixed size
- if ("height" in shape) {
- if (disableTextLayout.includes("auto-height")) {
- // next is auto-width, no need to set as is empty
- return locale.shapeTitleButtonTextLayoutAutoWidth;
- } else {
- // next is auto-height
- return locale.shapeTitleButtonTextLayoutAutoHeight;
- }
- } else // is auto-height
- if ("width" in shape) {
- if (disableTextLayout.includes("auto-width")) {
- // next is fixed-size
- return locale.shapeTitleButtonTextLayoutFixedSize;
- } else {
- // next is auto-width, no need to set as is empty
- return locale.shapeTitleButtonTextLayoutAutoWidth;
- }
- } else // is auto-width
- {
- // next is fixed-size
- if (disableTextLayout.includes("fixed-size")) {
- // next is fixed-size
- return locale.shapeTitleButtonTextLayoutAutoHeight;
- } else {
- // next is auto-width, no need to set as is empty
- return locale.shapeTitleButtonTextLayoutFixedSize;
- }
- }
- };
- const handleNudge = e => {
- const shape = getActiveMarkupItem();
- if (!shape) return;
- if (!shapeCanMove(shape)) return;
- interactionShape = shape;
- interactionShapeOriginComputed = shapeComputeDisplay(shapeDeepCopy(interactionShape), parentRect);
- translateShape(interactionShape, interactionShapeOriginComputed, e.detail);
- };
- // shape navigator
- let showShapeList = false;
- const handleFocusIn = e => {
- $$invalidate(12, showShapeList = true);
- };
- const handleFocusOut = ({ relatedTarget }) => {
- // still in list
- if (relatedTarget && relatedTarget.classList.contains("shape-selector__button")) return;
- $$invalidate(12, showShapeList = false);
- };
- function measure_handler(event) {
- bubble($$self, event);
- }
- const click_handler = (index, e) => selectShape(markup[index]);
- function textarea_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- textInput = $$value;
- $$invalidate(11, textInput);
- });
- }
- function textarea_input_handler() {
- textInputText = this.value;
- (((($$invalidate(15, textInputText), $$invalidate(9, shouldRenderTextInput)), $$invalidate(100, activeMarkup)), $$invalidate(109, isTextMarkupSelected)), $$invalidate(0, markup));
- }
- const measure_handler_1 = e => $$invalidate(5, shapeControlsSize = e.detail);
- const interactable_function = e => getEventPositionInEditor(e, rootRect);
- $$self.$$set = $$props => {
- if ("uid" in $$props) $$invalidate(43, uid = $$props.uid);
- if ("ui" in $$props) $$invalidate(42, ui = $$props.ui);
- if ("markup" in $$props) $$invalidate(0, markup = $$props.markup);
- if ("offset" in $$props) $$invalidate(1, offset = $$props.offset);
- if ("contextRotation" in $$props) $$invalidate(44, contextRotation = $$props.contextRotation);
- if ("contextFlipX" in $$props) $$invalidate(45, contextFlipX = $$props.contextFlipX);
- if ("contextFlipY" in $$props) $$invalidate(46, contextFlipY = $$props.contextFlipY);
- if ("contextScale" in $$props) $$invalidate(47, contextScale = $$props.contextScale);
- if ("active" in $$props) $$invalidate(48, active = $$props.active);
- if ("opacity" in $$props) $$invalidate(49, opacity = $$props.opacity);
- if ("parentRect" in $$props) $$invalidate(50, parentRect = $$props.parentRect);
- if ("rootRect" in $$props) $$invalidate(2, rootRect = $$props.rootRect);
- if ("utilRect" in $$props) $$invalidate(51, utilRect = $$props.utilRect);
- if ("oninteractionstart" in $$props) $$invalidate(52, oninteractionstart = $$props.oninteractionstart);
- if ("oninteractionupdate" in $$props) $$invalidate(53, oninteractionupdate = $$props.oninteractionupdate);
- if ("oninteractionrelease" in $$props) $$invalidate(54, oninteractionrelease = $$props.oninteractionrelease);
- if ("oninteractionend" in $$props) $$invalidate(55, oninteractionend = $$props.oninteractionend);
- if ("onaddshape" in $$props) $$invalidate(56, onaddshape = $$props.onaddshape);
- if ("onupdateshape" in $$props) $$invalidate(57, onupdateshape = $$props.onupdateshape);
- if ("onselectshape" in $$props) $$invalidate(58, onselectshape = $$props.onselectshape);
- if ("onremoveshape" in $$props) $$invalidate(59, onremoveshape = $$props.onremoveshape);
- if ("beforeSelectShape" in $$props) $$invalidate(60, beforeSelectShape = $$props.beforeSelectShape);
- if ("beforeDeselectShape" in $$props) $$invalidate(61, beforeDeselectShape = $$props.beforeDeselectShape);
- if ("beforeRemoveShape" in $$props) $$invalidate(62, beforeRemoveShape = $$props.beforeRemoveShape);
- if ("beforeUpdateShape" in $$props) $$invalidate(63, beforeUpdateShape = $$props.beforeUpdateShape);
- if ("willRenderShapeControls" in $$props) $$invalidate(64, willRenderShapeControls = $$props.willRenderShapeControls);
- if ("mapEditorPointToImagePoint" in $$props) $$invalidate(65, mapEditorPointToImagePoint = $$props.mapEditorPointToImagePoint);
- if ("mapImagePointToEditorPoint" in $$props) $$invalidate(66, mapImagePointToEditorPoint = $$props.mapImagePointToEditorPoint);
- if ("eraseRadius" in $$props) $$invalidate(67, eraseRadius = $$props.eraseRadius);
- if ("selectRadius" in $$props) $$invalidate(68, selectRadius = $$props.selectRadius);
- if ("enableButtonFlipVertical" in $$props) $$invalidate(69, enableButtonFlipVertical = $$props.enableButtonFlipVertical);
- if ("enableTapToAddText" in $$props) $$invalidate(70, enableTapToAddText = $$props.enableTapToAddText);
- if ("locale" in $$props) $$invalidate(3, locale = $$props.locale);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*markup*/ 1) {
- $$invalidate(100, activeMarkup = markup && (getMarkupItemDraft() || getActiveMarkupItem()));
- }
- if ($$self.$$.dirty[3] & /*activeMarkup*/ 128) {
- $$invalidate(101, activeShapeId = activeMarkup && !shapeIsDraft(activeMarkup)
- ? activeMarkup.id
- : undefined);
- }
- if ($$self.$$.dirty[0] & /*rootRect*/ 4 | $$self.$$.dirty[1] & /*parentRect*/ 524288 | $$self.$$.dirty[3] & /*activeMarkup*/ 128) {
- // rootRect is in there so it recomputes the shape when the editor is resized
- $$invalidate(102, activeMarkupComputed = rootRect && activeMarkup && shapeComputeDisplay(shapeDeepCopy(activeMarkup), parentRect));
- }
- if ($$self.$$.dirty[3] & /*activeMarkup*/ 128) {
- $$invalidate(103, activeMarkupItemIsDraft = !!(activeMarkup && shapeIsDraft(activeMarkup)));
- }
- if ($$self.$$.dirty[3] & /*activeMarkup*/ 128) {
- $$invalidate(104, shapeProps = activeMarkup || undefined);
- }
- if ($$self.$$.dirty[1] & /*opacity*/ 262144 | $$self.$$.dirty[3] & /*activeMarkup, activeMarkupComputed*/ 640) {
- // TODO: we use opacity to trigger a redraw of the active points, this should be changed to the image zoom factor in a future release
- // && !shapeIsPath(activeMarkupComputed)
- $$invalidate(105, shapeActivePoints = activeMarkup && opacity && getMarkupShapePoints(activeMarkupComputed) || []);
- }
- if ($$self.$$.dirty[3] & /*activeMarkup*/ 128) {
- $$invalidate(106, allowResizeControls = activeMarkup && shapeCanResize(activeMarkup) && !shapeIsTextEditing(activeMarkup));
- }
- if ($$self.$$.dirty[3] & /*activeMarkup*/ 128) {
- $$invalidate(6, allowRotateControls = activeMarkup && shapeCanRotate(activeMarkup) && !shapeIsTextEditing(activeMarkup));
- }
- if ($$self.$$.dirty[3] & /*allowResizeControls, activeMarkup*/ 8320) {
- $$invalidate(13, allowedResizeControls = allowResizeControls && hasProp(activeMarkup, "text") && !activeMarkup.height
- ? "horizontal"
- : allowResizeControls);
- }
- if ($$self.$$.dirty[3] & /*activeMarkup, shapeActivePoints*/ 4224) {
- $$invalidate(7, shouldRenderShapeManipulator = activeMarkup && shapeActivePoints.length > 1);
- }
- if ($$self.$$.dirty[2] & /*mapImagePointToEditorPoint*/ 16 | $$self.$$.dirty[3] & /*shapeActivePoints*/ 4096) {
- $$invalidate(107, shapeActiveScreenPoints = shapeActivePoints.map(mapImagePointToEditorPoint));
- }
- if ($$self.$$.dirty[0] & /*offset*/ 2 | $$self.$$.dirty[3] & /*shapeActiveScreenPoints*/ 16384) {
- $$invalidate(8, shapeManipulatorPoints = shapeActiveScreenPoints.map(point => vectorCreate(point.x - offset.x, point.y - offset.y)));
- }
- if ($$self.$$.dirty[0] & /*shouldRenderShapeManipulator, allowRotateControls*/ 192 | $$self.$$.dirty[1] & /*opacity*/ 262144 | $$self.$$.dirty[3] & /*activeMarkupComputed*/ 512) {
- // TODO: we use opacity to trigger a redraw of the active points, this should be changed to the image zoom factor in a future release
- $$invalidate(108, shapeManipulatorRotationPoint = shouldRenderShapeManipulator && allowRotateControls && opacity && getShapeRotationPointOnScreen(activeMarkupComputed));
- }
- if ($$self.$$.dirty[0] & /*offset*/ 2 | $$self.$$.dirty[3] & /*shapeManipulatorRotationPoint*/ 32768) {
- $$invalidate(14, shapeManipulatorRotationPointPosition = shapeManipulatorRotationPoint && vectorCreate(shapeManipulatorRotationPoint.position.x - offset.x, shapeManipulatorRotationPoint.position.y - offset.y));
- }
- if ($$self.$$.dirty[0] & /*shapeManipulatorPoints*/ 256 | $$self.$$.dirty[1] & /*active, opacity*/ 393216 | $$self.$$.dirty[3] & /*activeMarkup*/ 128) {
- if (active) {
- // show when something selected
- if (opacity > 0) {
- claimManipulatorLines();
- // don't draw for line
- const isPathDraft = activeMarkup && shapeIsDraft(activeMarkup) && shapeIsPath(activeMarkup);
- if (shapeManipulatorPoints.length > 2 && !isPathDraft) {
- redrawManipulatorLines(opacity);
- } else {
- removeMarkupManipulatorLines();
- }
- } else // hide when nothing selected
- if (!activeMarkup) {
- redrawManipulatorLines(opacity);
- }
- } else if (shouldManipulateLines()) {
- redrawManipulatorLines(opacity);
- }
- }
- if ($$self.$$.dirty[3] & /*activeMarkup*/ 128) {
- $$invalidate(109, isTextMarkupSelected = activeMarkup && shapeIsText(activeMarkup));
- }
- if ($$self.$$.dirty[3] & /*isTextMarkupSelected, activeMarkup*/ 65664) {
- $$invalidate(9, shouldRenderTextInput = isTextMarkupSelected && shapeCanInput(activeMarkup) !== false && activeMarkup.isEditing);
- }
- if ($$self.$$.dirty[0] & /*shouldRenderTextInput*/ 512) {
- $$invalidate(110, textShapeOrigin = shouldRenderTextInput
- ? getTextShapeOriginSnapshot()
- : undefined);
- }
- if ($$self.$$.dirty[1] & /*parentRect*/ 524288 | $$self.$$.dirty[3] & /*textShapeOrigin*/ 131072) {
- $$invalidate(111, textShapeDisplayOrigin = textShapeOrigin && shapeComputeDisplay({ ...textShapeOrigin }, parentRect));
- }
- if ($$self.$$.dirty[3] & /*textShapeDisplayOrigin*/ 262144) {
- $$invalidate(112, textSizeDisplayOrigin = textShapeDisplayOrigin && textSize(textShapeDisplayOrigin.text, textShapeDisplayOrigin));
- }
- if ($$self.$$.dirty[3] & /*textShapeDisplayOrigin, textSizeDisplayOrigin*/ 786432) {
- textRectDisplayOrigin = textShapeDisplayOrigin && rectCreate(textShapeDisplayOrigin.x, textShapeDisplayOrigin.y, textSizeDisplayOrigin.width, textSizeDisplayOrigin.height);
- }
- if ($$self.$$.dirty[0] & /*shouldRenderTextInput*/ 512 | $$self.$$.dirty[3] & /*activeMarkup*/ 128) {
- $$invalidate(15, textInputText = shouldRenderTextInput ? activeMarkup.text : "");
- }
- if ($$self.$$.dirty[0] & /*shouldRenderTextInput*/ 512 | $$self.$$.dirty[3] & /*shapeProps*/ 2048) {
- $$invalidate(16, markupTextInputStyle = shouldRenderTextInput && `
- text-align: ${shapeProps.textAlign || "left"};
- font-family: ${shapeProps.fontFamily || "sans-serif"};
- `);
- }
- if ($$self.$$.dirty[3] & /*activeMarkup, activeMarkupItemIsDraft, controlledMarkupItem*/ 1049728) {
- $$invalidate(113, controlledMarkupItem = activeMarkup && !activeMarkupItemIsDraft
- ? activeMarkup
- : controlledMarkupItem);
- }
- if ($$self.$$.dirty[3] & /*controlledMarkupItem*/ 1048576) {
- $$invalidate(114, allowShapeFlip = controlledMarkupItem && shapeCanFlip(controlledMarkupItem));
- }
- if ($$self.$$.dirty[3] & /*controlledMarkupItem*/ 1048576) {
- $$invalidate(115, allowShapeChangeTextLayout = controlledMarkupItem && shapeCanChangeTextLayout(controlledMarkupItem));
- }
- if ($$self.$$.dirty[3] & /*controlledMarkupItem*/ 1048576) {
- $$invalidate(116, allowShapeDuplicate = controlledMarkupItem && shapeCanDuplicate(controlledMarkupItem));
- }
- if ($$self.$$.dirty[3] & /*controlledMarkupItem*/ 1048576) {
- $$invalidate(117, allowShapeRemove = controlledMarkupItem && shapeCanRemove(controlledMarkupItem));
- }
- if ($$self.$$.dirty[3] & /*controlledMarkupItem*/ 1048576) {
- $$invalidate(118, allowShapeReorder = controlledMarkupItem && shapeCanReorder(controlledMarkupItem));
- }
- if ($$self.$$.dirty[3] & /*controlledMarkupItem*/ 1048576) {
- $$invalidate(119, allowShapeInput = controlledMarkupItem && shapeCanInput(controlledMarkupItem) !== false);
- }
- if ($$self.$$.dirty[3] & /*controlledMarkupItem*/ 1048576) {
- $$invalidate(120, allowShapeAdjustOpacity = controlledMarkupItem && hasProp(controlledMarkupItem, "backgroundImage") && shapeCanStyle(controlledMarkupItem, "opacity"));
- }
- if ($$self.$$.dirty[0] & /*shouldRenderTextInput*/ 512 | $$self.$$.dirty[3] & /*activeMarkup, activeMarkupItemIsDraft, isInteracting*/ 1216) {
- markupControlsOpacity.set(activeMarkup && !activeMarkupItemIsDraft && !isInteracting && !shouldRenderTextInput
- ? 1
- : 0);
- }
- if ($$self.$$.dirty[0] & /*shapeManipulatorPoints*/ 256 | $$self.$$.dirty[3] & /*activeMarkup, activeMarkupItemIsDraft, markupControlsAnchorPosition*/ 268436608) {
- $$invalidate(121, markupControlsAnchorPosition = activeMarkup && !activeMarkupItemIsDraft
- ? getMarkupControlsAnchorPosition(rectCreateFromPoints(shapeManipulatorPoints))
- : markupControlsAnchorPosition);
- }
- if ($$self.$$.dirty[0] & /*shapeControlsSize*/ 32 | $$self.$$.dirty[1] & /*utilRect*/ 1048576 | $$self.$$.dirty[3] & /*markupControlsAnchorPosition*/ 268435456) {
- $$invalidate(122, shapeControlsPosition = markupControlsAnchorPosition && shapeControlsSize && utilRect && getShapeControlPositionOnCanvas(markupControlsAnchorPosition));
- }
- if ($$self.$$.dirty[0] & /*$markupControlsOpacity*/ 1024 | $$self.$$.dirty[3] & /*shapeControlsPosition*/ 536870912) {
- $$invalidate(17, markupControlsStyle = shapeControlsPosition && `transform: translate(${shapeControlsPosition.x}px, ${shapeControlsPosition.y}px);opacity:${$markupControlsOpacity}`);
- }
- if ($$self.$$.dirty[0] & /*locale*/ 8 | $$self.$$.dirty[2] & /*willRenderShapeControls, enableButtonFlipVertical*/ 132 | $$self.$$.dirty[3] & /*activeShapeId, allowShapeAdjustOpacity, activeMarkup, allowShapeFlip, allowShapeReorder, allowShapeDuplicate, allowShapeRemove, allowShapeInput, allowShapeChangeTextLayout*/ 266338688) {
- $$invalidate(18, shapeControls = activeShapeId && willRenderShapeControls(
- [
- allowShapeAdjustOpacity && [
- "div",
- "alpha",
- { class: "PinturaShapeControlsGroup" },
- [
- [
- "Slider",
- "adjust-opacity",
- {
- onchange: handleAdjustOpacity,
- step: 0.01,
- value: hasProp(activeMarkup, "opacity")
- ? activeMarkup.opacity
- : 1,
- label: (value, min, max) => `${Math.round(value / max * 100)}%`,
- min: 0,
- max: 1,
- direction: "x"
- }
- ]
- ]
- ],
- [
- "div",
- "beta",
- { class: "PinturaShapeControlsGroup" },
- [
- allowShapeFlip && [
- "Button",
- "flip-horizontal",
- {
- onclick: handleFlipX,
- label: locale.shapeTitleButtonFlipHorizontal,
- icon: locale.shapeIconButtonFlipHorizontal,
- hideLabel: true
- }
- ],
- allowShapeFlip && enableButtonFlipVertical && [
- "Button",
- "flip-vertical",
- {
- onclick: handleFlipY,
- label: locale.shapeTitleButtonFlipVertical,
- icon: locale.shapeIconButtonFlipVertical,
- hideLabel: true
- }
- ],
- allowShapeReorder && [
- "Button",
- "to-front",
- {
- onclick: handleMoveToFrontActiveMarkup,
- label: locale.shapeTitleButtonMoveToFront,
- icon: locale.shapeIconButtonMoveToFront,
- hideLabel: true
- }
- ],
- allowShapeDuplicate && [
- "Button",
- "duplicate",
- {
- onclick: handleDuplicateActiveMarkup,
- label: locale.shapeTitleButtonDuplicate,
- icon: locale.shapeIconButtonDuplicate,
- hideLabel: true
- }
- ],
- allowShapeRemove && [
- "Button",
- "remove",
- {
- onclick: handleRemoveActiveMarkup,
- label: locale.shapeTitleButtonRemove,
- icon: locale.shapeIconButtonRemove,
- hideLabel: true
- }
- ]
- ].filter(Boolean)
- ],
- allowShapeInput && allowShapeChangeTextLayout && [
- "div",
- "gamma",
- { class: "PinturaShapeControlsGroup" },
- [
- [
- "Button",
- "text-layout",
- {
- onclick: handleTextSwitchLayout,
- label: localize(TextLayoutChangeLabel, locale, activeMarkup),
- icon: localize(TextLayoutChangeIcon, locale, activeMarkup),
- hideLabel: true
- }
- ]
- ]
- ],
- allowShapeInput && [
- "div",
- "delta",
- { class: "PinturaShapeControlsGroup" },
- [
- [
- "Button",
- "edit-text",
- {
- label: locale.shapeLabelInputText,
- onclick: handleEditTextActiveMarkup
- }
- ]
- ]
- ]
- ].filter(Boolean),
- activeShapeId
- ));
- }
- if ($$self.$$.dirty[0] & /*markup, locale*/ 9) {
- $$invalidate(19, shapeNavList = markup.filter(shapeCanSelect).filter(shape => !shapeIsDraft(shape)).map(shape => ({
- id: shape.id,
- color: shapeIsText(shape)
- ? shape.color
- : shapeIsLine(shape)
- ? shape.strokeColor
- : shape.backgroundColor,
- name: shape.name || locale[`shapeLabelTool${capitalizeFirstLetter(shapeGetDescription(shape))}`]
- })));
- }
- };
- return [
- markup,
- offset,
- rootRect,
- locale,
- selectShape,
- shapeControlsSize,
- allowRotateControls,
- shouldRenderShapeManipulator,
- shapeManipulatorPoints,
- shouldRenderTextInput,
- $markupControlsOpacity,
- textInput,
- showShapeList,
- allowedResizeControls,
- shapeManipulatorRotationPointPosition,
- textInputText,
- markupTextInputStyle,
- markupControlsStyle,
- shapeControls,
- shapeNavList,
- keysPressedStored,
- handleInteractionStart,
- handleInteractionUpdate,
- handleInteractionRelease,
- handleInteractionEnd,
- handleManipulatorResizeGrab,
- handleManipulatorResizeDrag,
- handleManipulatorResizeEnd,
- handleManipulatorRotateGrab,
- handleManipulatorRotateDrag,
- handleManipulatorRotateEnd,
- handleKey,
- handleTextInput,
- handleTextInputAttempt,
- handleTextInputKeyDown,
- handleTextInputKeyUp,
- handleTextConfirm,
- handleTextCancel,
- markupControlsOpacity,
- handleNudge,
- handleFocusIn,
- handleFocusOut,
- ui,
- uid,
- contextRotation,
- contextFlipX,
- contextFlipY,
- contextScale,
- active,
- opacity,
- parentRect,
- utilRect,
- oninteractionstart,
- oninteractionupdate,
- oninteractionrelease,
- oninteractionend,
- onaddshape,
- onupdateshape,
- onselectshape,
- onremoveshape,
- beforeSelectShape,
- beforeDeselectShape,
- beforeRemoveShape,
- beforeUpdateShape,
- willRenderShapeControls,
- mapEditorPointToImagePoint,
- mapImagePointToEditorPoint,
- eraseRadius,
- selectRadius,
- enableButtonFlipVertical,
- enableTapToAddText,
- createShape,
- eraseShape,
- getMarkupItemDraft,
- getMarkupItemDraftIndex,
- addMarkupItemDraft,
- confirmMarkupItemDraft,
- discardMarkupItemDraft,
- createMarkupItem,
- syncShapes,
- addShape,
- removeMarkupShapeProps,
- updateMarkupShape,
- updateMarkupShapeProperty,
- updateMarkupItemsShapeProperty,
- updateMarkupShapeItems,
- getActiveMarkupItem,
- hasActiveMarkupItem,
- removeShape,
- removeActiveMarkupItem,
- blurShapes,
- deselectMarkupItem,
- editMarkupItem,
- finishEditMarkupItem,
- removeMarkupItems,
- getTextShapeRect,
- getMarkupShapeRect,
- getShapesNearPosition,
- getShapesBetweenPoints,
- isInteracting,
- activeMarkup,
- activeShapeId,
- activeMarkupComputed,
- activeMarkupItemIsDraft,
- shapeProps,
- shapeActivePoints,
- allowResizeControls,
- shapeActiveScreenPoints,
- shapeManipulatorRotationPoint,
- isTextMarkupSelected,
- textShapeOrigin,
- textShapeDisplayOrigin,
- textSizeDisplayOrigin,
- controlledMarkupItem,
- allowShapeFlip,
- allowShapeChangeTextLayout,
- allowShapeDuplicate,
- allowShapeRemove,
- allowShapeReorder,
- allowShapeInput,
- allowShapeAdjustOpacity,
- markupControlsAnchorPosition,
- shapeControlsPosition,
- measure_handler,
- click_handler,
- textarea_binding,
- textarea_input_handler,
- measure_handler_1,
- interactable_function
- ];
- }
- class ShapeLayoutEditor extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$f,
- create_fragment$f,
- safe_not_equal,
- {
- uid: 43,
- ui: 42,
- markup: 0,
- offset: 1,
- contextRotation: 44,
- contextFlipX: 45,
- contextFlipY: 46,
- contextScale: 47,
- active: 48,
- opacity: 49,
- parentRect: 50,
- rootRect: 2,
- utilRect: 51,
- oninteractionstart: 52,
- oninteractionupdate: 53,
- oninteractionrelease: 54,
- oninteractionend: 55,
- onaddshape: 56,
- onupdateshape: 57,
- onselectshape: 58,
- onremoveshape: 59,
- beforeSelectShape: 60,
- beforeDeselectShape: 61,
- beforeRemoveShape: 62,
- beforeUpdateShape: 63,
- willRenderShapeControls: 64,
- mapEditorPointToImagePoint: 65,
- mapImagePointToEditorPoint: 66,
- eraseRadius: 67,
- selectRadius: 68,
- enableButtonFlipVertical: 69,
- enableTapToAddText: 70,
- locale: 3,
- createShape: 71,
- eraseShape: 72,
- getMarkupItemDraft: 73,
- getMarkupItemDraftIndex: 74,
- addMarkupItemDraft: 75,
- confirmMarkupItemDraft: 76,
- discardMarkupItemDraft: 77,
- createMarkupItem: 78,
- syncShapes: 79,
- addShape: 80,
- removeMarkupShapeProps: 81,
- updateMarkupShape: 82,
- updateMarkupShapeProperty: 83,
- updateMarkupItemsShapeProperty: 84,
- updateMarkupShapeItems: 85,
- getActiveMarkupItem: 86,
- hasActiveMarkupItem: 87,
- removeShape: 88,
- removeActiveMarkupItem: 89,
- blurShapes: 90,
- selectShape: 4,
- deselectMarkupItem: 91,
- editMarkupItem: 92,
- finishEditMarkupItem: 93,
- removeMarkupItems: 94,
- getTextShapeRect: 95,
- getMarkupShapeRect: 96,
- getShapesNearPosition: 97,
- getShapesBetweenPoints: 98
- },
- [-1, -1, -1, -1, -1, -1]
- );
- }
- get createShape() {
- return this.$$.ctx[71];
- }
- get eraseShape() {
- return this.$$.ctx[72];
- }
- get getMarkupItemDraft() {
- return this.$$.ctx[73];
- }
- get getMarkupItemDraftIndex() {
- return this.$$.ctx[74];
- }
- get addMarkupItemDraft() {
- return this.$$.ctx[75];
- }
- get confirmMarkupItemDraft() {
- return this.$$.ctx[76];
- }
- get discardMarkupItemDraft() {
- return this.$$.ctx[77];
- }
- get createMarkupItem() {
- return this.$$.ctx[78];
- }
- get syncShapes() {
- return this.$$.ctx[79];
- }
- get addShape() {
- return this.$$.ctx[80];
- }
- get removeMarkupShapeProps() {
- return this.$$.ctx[81];
- }
- get updateMarkupShape() {
- return this.$$.ctx[82];
- }
- get updateMarkupShapeProperty() {
- return this.$$.ctx[83];
- }
- get updateMarkupItemsShapeProperty() {
- return this.$$.ctx[84];
- }
- get updateMarkupShapeItems() {
- return this.$$.ctx[85];
- }
- get getActiveMarkupItem() {
- return this.$$.ctx[86];
- }
- get hasActiveMarkupItem() {
- return this.$$.ctx[87];
- }
- get removeShape() {
- return this.$$.ctx[88];
- }
- get removeActiveMarkupItem() {
- return this.$$.ctx[89];
- }
- get blurShapes() {
- return this.$$.ctx[90];
- }
- get selectShape() {
- return this.$$.ctx[4];
- }
- get deselectMarkupItem() {
- return this.$$.ctx[91];
- }
- get editMarkupItem() {
- return this.$$.ctx[92];
- }
- get finishEditMarkupItem() {
- return this.$$.ctx[93];
- }
- get removeMarkupItems() {
- return this.$$.ctx[94];
- }
- get getTextShapeRect() {
- return this.$$.ctx[95];
- }
- get getMarkupShapeRect() {
- return this.$$.ctx[96];
- }
- get getShapesNearPosition() {
- return this.$$.ctx[97];
- }
- get getShapesBetweenPoints() {
- return this.$$.ctx[98];
- }
- }
- /* src/core/ui/components/ShapeStyleControls.svelte generated by Svelte v3.37.0 */
- function get_each_context$2(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[7] = list[i];
- return child_ctx;
- }
- // (21:12) {#each controls as control (control.id)}
- function create_each_block$2(key_1, ctx) {
- let li;
- let span;
- let t0_value = localize(/*control*/ ctx[7].componentProps.title, /*locale*/ ctx[1]) + "";
- let t0;
- let t1;
- let switch_instance;
- let t2;
- let current;
- const switch_instance_spread_levels = [/*control*/ ctx[7].componentProps];
- var switch_value = /*control*/ ctx[7].component;
- function switch_props(ctx) {
- let switch_instance_props = {};
- for (let i = 0; i < switch_instance_spread_levels.length; i += 1) {
- switch_instance_props = assign(switch_instance_props, switch_instance_spread_levels[i]);
- }
- return { props: switch_instance_props };
- }
- if (switch_value) {
- switch_instance = new switch_value(switch_props());
- }
- return {
- key: key_1,
- first: null,
- c() {
- li = element("li");
- span = element("span");
- t0 = text(t0_value);
- t1 = space();
- if (switch_instance) create_component(switch_instance.$$.fragment);
- t2 = space();
- attr(span, "class", "PinturaShapeStyleLabel");
- attr(li, "class", "PinturaShapeStyle");
- this.first = li;
- },
- m(target, anchor) {
- insert(target, li, anchor);
- append(li, span);
- append(span, t0);
- append(li, t1);
- if (switch_instance) {
- mount_component(switch_instance, li, null);
- }
- append(li, t2);
- current = true;
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- if ((!current || dirty & /*controls, locale*/ 3) && t0_value !== (t0_value = localize(/*control*/ ctx[7].componentProps.title, /*locale*/ ctx[1]) + "")) set_data(t0, t0_value);
- const switch_instance_changes = (dirty & /*controls*/ 1)
- ? get_spread_update(switch_instance_spread_levels, [get_spread_object(/*control*/ ctx[7].componentProps)])
- : {};
- if (switch_value !== (switch_value = /*control*/ ctx[7].component)) {
- if (switch_instance) {
- group_outros();
- const old_component = switch_instance;
- transition_out(old_component.$$.fragment, 1, 0, () => {
- destroy_component(old_component, 1);
- });
- check_outros();
- }
- if (switch_value) {
- switch_instance = new switch_value(switch_props());
- create_component(switch_instance.$$.fragment);
- transition_in(switch_instance.$$.fragment, 1);
- mount_component(switch_instance, li, t2);
- } else {
- switch_instance = null;
- }
- } else if (switch_value) {
- switch_instance.$set(switch_instance_changes);
- }
- },
- i(local) {
- if (current) return;
- if (switch_instance) transition_in(switch_instance.$$.fragment, local);
- current = true;
- },
- o(local) {
- if (switch_instance) transition_out(switch_instance.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(li);
- if (switch_instance) destroy_component(switch_instance);
- }
- };
- }
- // (19:4) <Scrollable class="PinturaShapeStyles" elasticity={scrollElasticity}>
- function create_default_slot$5(ctx) {
- let ul;
- let each_blocks = [];
- let each_1_lookup = new Map();
- let current;
- let each_value = /*controls*/ ctx[0];
- const get_key = ctx => /*control*/ ctx[7].id;
- for (let i = 0; i < each_value.length; i += 1) {
- let child_ctx = get_each_context$2(ctx, each_value, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block$2(key, child_ctx));
- }
- return {
- c() {
- ul = element("ul");
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- attr(ul, "class", "PinturaShapeStyleList");
- },
- m(target, anchor) {
- insert(target, ul, anchor);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].m(ul, null);
- }
- current = true;
- },
- p(ctx, dirty) {
- if (dirty & /*controls, localize, locale*/ 3) {
- each_value = /*controls*/ ctx[0];
- group_outros();
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, ul, outro_and_destroy_block, create_each_block$2, null, get_each_context$2);
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- for (let i = 0; i < each_value.length; i += 1) {
- transition_in(each_blocks[i]);
- }
- current = true;
- },
- o(local) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- transition_out(each_blocks[i]);
- }
- current = false;
- },
- d(detaching) {
- if (detaching) detach(ul);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d();
- }
- }
- };
- }
- function create_fragment$e(ctx) {
- let div;
- let scrollable;
- let current;
- scrollable = new Scrollable({
- props: {
- class: "PinturaShapeStyles",
- elasticity: /*scrollElasticity*/ ctx[2],
- $$slots: { default: [create_default_slot$5] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- div = element("div");
- create_component(scrollable.$$.fragment);
- attr(div, "style", /*style*/ ctx[3]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(scrollable, div, null);
- current = true;
- },
- p(ctx, [dirty]) {
- const scrollable_changes = {};
- if (dirty & /*scrollElasticity*/ 4) scrollable_changes.elasticity = /*scrollElasticity*/ ctx[2];
- if (dirty & /*$$scope, controls, locale*/ 1027) {
- scrollable_changes.$$scope = { dirty, ctx };
- }
- scrollable.$set(scrollable_changes);
- if (!current || dirty & /*style*/ 8) {
- attr(div, "style", /*style*/ ctx[3]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(scrollable.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(scrollable.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(scrollable);
- }
- };
- }
- function instance$e($$self, $$props, $$invalidate) {
- let style;
- let $opacity;
- let { isActive = false } = $$props;
- let { controls = [] } = $$props;
- let { locale } = $$props;
- let { scrollElasticity } = $$props;
- const opacity = spring(0);
- component_subscribe($$self, opacity, value => $$invalidate(6, $opacity = value));
- $$self.$$set = $$props => {
- if ("isActive" in $$props) $$invalidate(5, isActive = $$props.isActive);
- if ("controls" in $$props) $$invalidate(0, controls = $$props.controls);
- if ("locale" in $$props) $$invalidate(1, locale = $$props.locale);
- if ("scrollElasticity" in $$props) $$invalidate(2, scrollElasticity = $$props.scrollElasticity);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*isActive*/ 32) {
- opacity.set(isActive ? 1 : 0);
- }
- if ($$self.$$.dirty & /*$opacity, isActive*/ 96) {
- $$invalidate(3, style = `opacity:${$opacity};${!isActive ? "pointer-events:none;" : ""}${$opacity <= 0 ? "visibility:hidden" : ""}`);
- }
- };
- return [controls, locale, scrollElasticity, style, opacity, isActive, $opacity];
- }
- class ShapeStyleControls extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$e, create_fragment$e, safe_not_equal, {
- isActive: 5,
- controls: 0,
- locale: 1,
- scrollElasticity: 2
- });
- }
- }
- /* src/core/ui/components/ShapeStyleEditor.svelte generated by Svelte v3.37.0 */
- function get_each_context$1(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[11] = list[i].key;
- child_ctx[2] = list[i].controls;
- child_ctx[12] = list[i].isActive;
- return child_ctx;
- }
- // (132:4) {#each currentStyleControlSets as { key, controls, isActive }
- function create_each_block$1(key_1, ctx) {
- let first;
- let shapestylecontrols;
- let current;
- shapestylecontrols = new ShapeStyleControls({
- props: {
- isActive: /*isActive*/ ctx[12],
- controls: /*controls*/ ctx[2],
- locale: /*locale*/ ctx[0],
- scrollElasticity: /*scrollElasticity*/ ctx[1]
- }
- });
- return {
- key: key_1,
- first: null,
- c() {
- first = empty();
- create_component(shapestylecontrols.$$.fragment);
- this.first = first;
- },
- m(target, anchor) {
- insert(target, first, anchor);
- mount_component(shapestylecontrols, target, anchor);
- current = true;
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- const shapestylecontrols_changes = {};
- if (dirty & /*currentStyleControlSets*/ 8) shapestylecontrols_changes.isActive = /*isActive*/ ctx[12];
- if (dirty & /*currentStyleControlSets*/ 8) shapestylecontrols_changes.controls = /*controls*/ ctx[2];
- if (dirty & /*locale*/ 1) shapestylecontrols_changes.locale = /*locale*/ ctx[0];
- if (dirty & /*scrollElasticity*/ 2) shapestylecontrols_changes.scrollElasticity = /*scrollElasticity*/ ctx[1];
- shapestylecontrols.$set(shapestylecontrols_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapestylecontrols.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapestylecontrols.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(first);
- destroy_component(shapestylecontrols, detaching);
- }
- };
- }
- function create_fragment$d(ctx) {
- let div;
- let each_blocks = [];
- let each_1_lookup = new Map();
- let current;
- let each_value = /*currentStyleControlSets*/ ctx[3];
- const get_key = ctx => /*key*/ ctx[11];
- for (let i = 0; i < each_value.length; i += 1) {
- let child_ctx = get_each_context$1(ctx, each_value, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block$1(key, child_ctx));
- }
- return {
- c() {
- div = element("div");
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- attr(div, "class", "PinturaShapeStyleEditor");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].m(div, null);
- }
- current = true;
- },
- p(ctx, [dirty]) {
- if (dirty & /*currentStyleControlSets, locale, scrollElasticity*/ 11) {
- each_value = /*currentStyleControlSets*/ ctx[3];
- group_outros();
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, div, outro_and_destroy_block, create_each_block$1, null, get_each_context$1);
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- for (let i = 0; i < each_value.length; i += 1) {
- transition_in(each_blocks[i]);
- }
- current = true;
- },
- o(local) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- transition_out(each_blocks[i]);
- }
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d();
- }
- }
- };
- }
- function instance$d($$self, $$props, $$invalidate) {
- let controlKeys;
- let activeControls;
- let currentStyleControlSets;
- let { controls = {} } = $$props;
- let { shape = undefined } = $$props;
- let { onchange } = $$props;
- let { locale } = $$props;
- let { scrollElasticity } = $$props;
- const getShapeControls = shape => {
- const shapeId = shape.id || "tool";
- const activeControls = controlKeys.filter(styleKey => styleKey.split("_").every(styleKey => // shape needs to have the property
- hasProp(shape, styleKey) && // shape needs to be able to style the property
- shapeCanStyle(shape, styleKey))).map(styleKey => {
- const styleKeys = styleKey.split("_");
- const currentValue = styleKeys.length > 1
- ? styleKeys.map(key => shape[key])
- : shape[styleKey];
- let [component, componentProps] = controls[styleKey];
- // is reference to other control
- if (isString(component)) {
- // exif if not a valid default control
- if (!controls[component]) return;
- // create component based on reference
- const componentCustomProps = { ...componentProps };
- [component, componentProps] = controls[component];
- componentProps = {
- ...componentProps,
- ...componentCustomProps
- };
- }
- const options = isFunction(componentProps.options)
- ? componentProps.options(shape)
- : componentProps.options;
- return {
- id: `${shapeId}_${styleKey}`,
- component,
- componentProps: {
- ...componentProps,
- // set the options prop
- options,
- // defaults
- locale,
- value: currentValue,
- optionLabelClass: "PinturaButtonLabel",
- onchange: detail => {
- const value = isObject(detail) && !isArray(detail)
- ? detail.value
- : detail;
- // allow custom changes
- if (componentProps.onchange) componentProps.onchange(value, shape);
- // internal change
- const props = styleKeys.length > 1
- ? styleKeys.reduce(
- (prev, key, index) => {
- return {
- ...prev,
- [key]: Array.isArray(value) ? value[index] : value
- };
- },
- {}
- )
- : { [styleKey]: value };
- onchange(props);
- }
- }
- };
- }).filter(Boolean);
- return activeControls;
- };
- const styleControlSets = [];
- const getStyleControlSets = (key, controls) => {
- let controlSet = styleControlSets.find(controlSet => controlSet.key === key);
- if (!controlSet) {
- // create
- controlSet = { key, controls };
- // add
- styleControlSets.push(controlSet);
- }
- // hide all
- styleControlSets.forEach(controlSet => controlSet.isActive = false);
- // update active controls
- controlSet.controls = controls;
- // show active
- controlSet.isActive = true;
- return styleControlSets;
- };
- $$self.$$set = $$props => {
- if ("controls" in $$props) $$invalidate(2, controls = $$props.controls);
- if ("shape" in $$props) $$invalidate(4, shape = $$props.shape);
- if ("onchange" in $$props) $$invalidate(5, onchange = $$props.onchange);
- if ("locale" in $$props) $$invalidate(0, locale = $$props.locale);
- if ("scrollElasticity" in $$props) $$invalidate(1, scrollElasticity = $$props.scrollElasticity);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*controls*/ 4) {
- // finds the controls needed to style the selected shape
- $$invalidate(6, controlKeys = Object.keys(controls).filter(key => controls[key]));
- }
- if ($$self.$$.dirty & /*shape, controlKeys*/ 80) {
- $$invalidate(7, activeControls = shape && controlKeys && shapeCanStyle(shape)
- ? getShapeControls(shape)
- : []);
- }
- if ($$self.$$.dirty & /*shape, activeControls*/ 144) {
- $$invalidate(3, currentStyleControlSets = shape
- ? getStyleControlSets(Object.keys(shape).join("_"), activeControls)
- : []);
- }
- };
- return [
- locale,
- scrollElasticity,
- controls,
- currentStyleControlSets,
- shape,
- onchange,
- controlKeys,
- activeControls
- ];
- }
- class ShapeStyleEditor extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$d, create_fragment$d, safe_not_equal, {
- controls: 2,
- shape: 4,
- onchange: 5,
- locale: 0,
- scrollElasticity: 1
- });
- }
- }
- /* src/core/ui/components/DragButton.svelte generated by Svelte v3.37.0 */
- function create_fragment$c(ctx) {
- let button;
- let mounted;
- let dispose;
- return {
- c() {
- button = element("button");
- attr(button, "class", "PinturaDragButton");
- attr(button, "title", /*title*/ ctx[1]);
- button.disabled = /*disabled*/ ctx[2];
- },
- m(target, anchor) {
- insert(target, button, anchor);
- button.innerHTML = /*html*/ ctx[0];
- /*button_binding*/ ctx[9](button);
- if (!mounted) {
- dispose = listen(button, "pointerdown", /*handleDown*/ ctx[4]);
- mounted = true;
- }
- },
- p(ctx, [dirty]) {
- if (dirty & /*html*/ 1) button.innerHTML = /*html*/ ctx[0];
- if (dirty & /*title*/ 2) {
- attr(button, "title", /*title*/ ctx[1]);
- }
- if (dirty & /*disabled*/ 4) {
- button.disabled = /*disabled*/ ctx[2];
- }
- },
- i: noop,
- o: noop,
- d(detaching) {
- if (detaching) detach(button);
- /*button_binding*/ ctx[9](null);
- mounted = false;
- dispose();
- }
- };
- }
- function instance$c($$self, $$props, $$invalidate) {
- let { html } = $$props;
- let { title } = $$props;
- let { onclick } = $$props;
- let { disabled = false } = $$props;
- let { ongrab = noop$1 } = $$props;
- let { ondrag = noop$1 } = $$props;
- let { ondrop = noop$1 } = $$props;
- let element;
- const isOverButton = e => vectorDistanceSquared(downPosition, vectorCreate(e.pageX, e.pageY)) < 256;
- let downPosition;
- const handleDown = e => {
- downPosition = vectorCreate(e.pageX, e.pageY);
- ongrab(e);
- document.documentElement.addEventListener("pointermove", handleMove);
- document.documentElement.addEventListener("pointerup", handleUp);
- };
- const handleUp = e => {
- document.documentElement.removeEventListener("pointermove", handleMove);
- document.documentElement.removeEventListener("pointerup", handleUp);
- const upPosition = vectorCreate(e.pageX, e.pageY);
- // must have moved enough distance to drop
- if (vectorDistanceSquared(downPosition, upPosition) < 32) return onclick(e);
- // cant drop in button /
- if (isOverButton(e)) return;
- // was dragging
- ondrop(e);
- };
- const handleMove = e => {
- // must have moved enough distance from button
- if (isOverButton(e)) return;
- // dragging out of button
- ondrag(e);
- };
- function button_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- element = $$value;
- $$invalidate(3, element);
- });
- }
- $$self.$$set = $$props => {
- if ("html" in $$props) $$invalidate(0, html = $$props.html);
- if ("title" in $$props) $$invalidate(1, title = $$props.title);
- if ("onclick" in $$props) $$invalidate(5, onclick = $$props.onclick);
- if ("disabled" in $$props) $$invalidate(2, disabled = $$props.disabled);
- if ("ongrab" in $$props) $$invalidate(6, ongrab = $$props.ongrab);
- if ("ondrag" in $$props) $$invalidate(7, ondrag = $$props.ondrag);
- if ("ondrop" in $$props) $$invalidate(8, ondrop = $$props.ondrop);
- };
- return [
- html,
- title,
- disabled,
- element,
- handleDown,
- onclick,
- ongrab,
- ondrag,
- ondrop,
- button_binding
- ];
- }
- class DragButton extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$c, create_fragment$c, safe_not_equal, {
- html: 0,
- title: 1,
- onclick: 5,
- disabled: 2,
- ongrab: 6,
- ondrag: 7,
- ondrop: 8
- });
- }
- }
- /* src/core/ui/components/ShapePresetsList.svelte generated by Svelte v3.37.0 */
- function get_each_context(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[14] = list[i];
- return child_ctx;
- }
- // (25:4) {#each presets as preset (preset.id)}
- function create_each_block(key_1, ctx) {
- let li;
- let dragbutton;
- let t;
- let didMountPresetThumb_action;
- let current;
- let mounted;
- let dispose;
- function func() {
- return /*func*/ ctx[10](/*preset*/ ctx[14]);
- }
- function func_1(...args) {
- return /*func_1*/ ctx[11](/*preset*/ ctx[14], ...args);
- }
- function func_2(...args) {
- return /*func_2*/ ctx[12](/*preset*/ ctx[14], ...args);
- }
- function func_3(...args) {
- return /*func_3*/ ctx[13](/*preset*/ ctx[14], ...args);
- }
- dragbutton = new DragButton({
- props: {
- onclick: func,
- ongrab: func_1,
- ondrag: func_2,
- ondrop: func_3,
- disabled: /*disabled*/ ctx[1] || /*preset*/ ctx[14].disabled,
- title: /*preset*/ ctx[14].title,
- html: /*preset*/ ctx[14].thumb
- }
- });
- return {
- key: key_1,
- first: null,
- c() {
- li = element("li");
- create_component(dragbutton.$$.fragment);
- t = space();
- attr(li, "class", "PinturaShapePreset");
- attr(li, "style", /*style*/ ctx[6]);
- this.first = li;
- },
- m(target, anchor) {
- insert(target, li, anchor);
- mount_component(dragbutton, li, null);
- append(li, t);
- current = true;
- if (!mounted) {
- dispose = action_destroyer(didMountPresetThumb_action = /*didMountPresetThumb*/ ctx[8].call(null, li, /*preset*/ ctx[14]));
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- const dragbutton_changes = {};
- if (dirty & /*onclickpreset, presets*/ 5) dragbutton_changes.onclick = func;
- if (dirty & /*ongrabpreset, presets*/ 9) dragbutton_changes.ongrab = func_1;
- if (dirty & /*ondragpreset, presets*/ 17) dragbutton_changes.ondrag = func_2;
- if (dirty & /*ondroppreset, presets*/ 33) dragbutton_changes.ondrop = func_3;
- if (dirty & /*disabled, presets*/ 3) dragbutton_changes.disabled = /*disabled*/ ctx[1] || /*preset*/ ctx[14].disabled;
- if (dirty & /*presets*/ 1) dragbutton_changes.title = /*preset*/ ctx[14].title;
- if (dirty & /*presets*/ 1) dragbutton_changes.html = /*preset*/ ctx[14].thumb;
- dragbutton.$set(dragbutton_changes);
- if (!current || dirty & /*style*/ 64) {
- attr(li, "style", /*style*/ ctx[6]);
- }
- if (didMountPresetThumb_action && is_function(didMountPresetThumb_action.update) && dirty & /*presets*/ 1) didMountPresetThumb_action.update.call(null, /*preset*/ ctx[14]);
- },
- i(local) {
- if (current) return;
- transition_in(dragbutton.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(dragbutton.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(li);
- destroy_component(dragbutton);
- mounted = false;
- dispose();
- }
- };
- }
- function create_fragment$b(ctx) {
- let ul;
- let each_blocks = [];
- let each_1_lookup = new Map();
- let current;
- let each_value = /*presets*/ ctx[0];
- const get_key = ctx => /*preset*/ ctx[14].id;
- for (let i = 0; i < each_value.length; i += 1) {
- let child_ctx = get_each_context(ctx, each_value, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block(key, child_ctx));
- }
- return {
- c() {
- ul = element("ul");
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- attr(ul, "class", "PinturaShapePresetsList");
- },
- m(target, anchor) {
- insert(target, ul, anchor);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].m(ul, null);
- }
- current = true;
- },
- p(ctx, [dirty]) {
- if (dirty & /*style, presets, onclickpreset, ongrabpreset, ondragpreset, ondroppreset, disabled*/ 127) {
- each_value = /*presets*/ ctx[0];
- group_outros();
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, ul, outro_and_destroy_block, create_each_block, null, get_each_context);
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- for (let i = 0; i < each_value.length; i += 1) {
- transition_in(each_blocks[i]);
- }
- current = true;
- },
- o(local) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- transition_out(each_blocks[i]);
- }
- current = false;
- },
- d(detaching) {
- if (detaching) detach(ul);
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d();
- }
- }
- };
- }
- function instance$b($$self, $$props, $$invalidate) {
- let style;
- let $anim;
- let { presets } = $$props;
- let { disabled = undefined } = $$props;
- let { onclickpreset } = $$props;
- let { ongrabpreset = undefined } = $$props;
- let { ondragpreset = undefined } = $$props;
- let { ondroppreset = undefined } = $$props;
- const anim = tweened(0, { duration: 300 });
- component_subscribe($$self, anim, value => $$invalidate(9, $anim = value));
- const didMountPresetThumb = (element, item) => item.mount && item.mount(element.firstChild, item);
- onMount(() => anim.set(1));
- const func = preset => onclickpreset(preset.id);
- const func_1 = (preset, e) => ongrabpreset && ongrabpreset(preset.id, e);
- const func_2 = (preset, e) => ondragpreset && ondragpreset(preset.id, e);
- const func_3 = (preset, e) => ondroppreset && ondroppreset(preset.id, e);
- $$self.$$set = $$props => {
- if ("presets" in $$props) $$invalidate(0, presets = $$props.presets);
- if ("disabled" in $$props) $$invalidate(1, disabled = $$props.disabled);
- if ("onclickpreset" in $$props) $$invalidate(2, onclickpreset = $$props.onclickpreset);
- if ("ongrabpreset" in $$props) $$invalidate(3, ongrabpreset = $$props.ongrabpreset);
- if ("ondragpreset" in $$props) $$invalidate(4, ondragpreset = $$props.ondragpreset);
- if ("ondroppreset" in $$props) $$invalidate(5, ondroppreset = $$props.ondroppreset);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*$anim*/ 512) {
- $$invalidate(6, style = `opacity:${$anim}`);
- }
- };
- return [
- presets,
- disabled,
- onclickpreset,
- ongrabpreset,
- ondragpreset,
- ondroppreset,
- style,
- anim,
- didMountPresetThumb,
- $anim,
- func,
- func_1,
- func_2,
- func_3
- ];
- }
- class ShapePresetsList extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$b, create_fragment$b, safe_not_equal, {
- presets: 0,
- disabled: 1,
- onclickpreset: 2,
- ongrabpreset: 3,
- ondragpreset: 4,
- ondroppreset: 5
- });
- }
- }
- var isSVGMarkup = (str) => /<svg /.test(str);
- /* src/core/ui/components/ShapePresetsPalette.svelte generated by Svelte v3.37.0 */
- function create_if_block_6(ctx) {
- let dynamiccomponenttree;
- let current;
- dynamiccomponenttree = new DynamicComponentTree_1({
- props: { items: /*presetToolbar*/ ctx[13] }
- });
- return {
- c() {
- create_component(dynamiccomponenttree.$$.fragment);
- },
- m(target, anchor) {
- mount_component(dynamiccomponenttree, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const dynamiccomponenttree_changes = {};
- if (dirty & /*presetToolbar*/ 8192) dynamiccomponenttree_changes.items = /*presetToolbar*/ ctx[13];
- dynamiccomponenttree.$set(dynamiccomponenttree_changes);
- },
- i(local) {
- if (current) return;
- transition_in(dynamiccomponenttree.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(dynamiccomponenttree.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(dynamiccomponenttree, detaching);
- }
- };
- }
- // (171:4) {#if shouldRenderPresets}
- function create_if_block$1(ctx) {
- let current_block_type_index;
- let if_block;
- let if_block_anchor;
- let current;
- const if_block_creators = [create_if_block_1$1, create_else_block$1];
- const if_blocks = [];
- function select_block_type_1(ctx, dirty) {
- if (/*shouldGroupPresets*/ ctx[7]) return 0;
- return 1;
- }
- current_block_type_index = select_block_type_1(ctx);
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- return {
- c() {
- if_block.c();
- if_block_anchor = empty();
- },
- m(target, anchor) {
- if_blocks[current_block_type_index].m(target, anchor);
- insert(target, if_block_anchor, anchor);
- current = true;
- },
- p(ctx, dirty) {
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type_1(ctx);
- if (current_block_type_index === previous_block_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- } else {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- if_block = if_blocks[current_block_type_index];
- if (!if_block) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block.c();
- } else {
- if_block.p(ctx, dirty);
- }
- transition_in(if_block, 1);
- if_block.m(if_block_anchor.parentNode, if_block_anchor);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if_blocks[current_block_type_index].d(detaching);
- if (detaching) detach(if_block_anchor);
- }
- };
- }
- // (221:8) {:else}
- function create_else_block$1(ctx) {
- let div;
- let t;
- let scrollable;
- let current;
- let if_block = /*presetToolbar*/ ctx[13] && create_if_block_5$1(ctx);
- scrollable = new Scrollable({
- props: {
- scrollAutoCancel: /*shouldRenderPresets*/ ctx[6],
- elasticity: /*scrollElasticity*/ ctx[0],
- $$slots: { default: [create_default_slot_4] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- div = element("div");
- if (if_block) if_block.c();
- t = space();
- create_component(scrollable.$$.fragment);
- attr(div, "class", "PinturaShapePresetsFlat");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (if_block) if_block.m(div, null);
- append(div, t);
- mount_component(scrollable, div, null);
- current = true;
- },
- p(ctx, dirty) {
- if (/*presetToolbar*/ ctx[13]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty & /*presetToolbar*/ 8192) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block_5$1(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(div, t);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- const scrollable_changes = {};
- if (dirty & /*shouldRenderPresets*/ 64) scrollable_changes.scrollAutoCancel = /*shouldRenderPresets*/ ctx[6];
- if (dirty & /*scrollElasticity*/ 1) scrollable_changes.elasticity = /*scrollElasticity*/ ctx[0];
- if (dirty & /*$$scope, presetsMapped, onaddpreset, ongrabpreset, ondragpreset, ondroppreset*/ 536870974) {
- scrollable_changes.$$scope = { dirty, ctx };
- }
- scrollable.$set(scrollable_changes);
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- transition_in(scrollable.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- transition_out(scrollable.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (if_block) if_block.d();
- destroy_component(scrollable);
- }
- };
- }
- // (173:8) {#if shouldGroupPresets}
- function create_if_block_1$1(ctx) {
- let div1;
- let div0;
- let t0;
- let tablist;
- let t1;
- let tabpanels;
- let current;
- let if_block = /*presetToolbar*/ ctx[13] && create_if_block_4$1(ctx);
- const tablist_spread_levels = [
- { class: "PinturaControlList" },
- { tabs: /*tabs*/ ctx[8] },
- /*tabsConfig*/ ctx[11],
- { layout: "compact" }
- ];
- let tablist_props = {
- $$slots: {
- default: [
- create_default_slot_2,
- ({ tab }) => ({ 28: tab }),
- ({ tab }) => tab ? 268435456 : 0
- ]
- },
- $$scope: { ctx }
- };
- for (let i = 0; i < tablist_spread_levels.length; i += 1) {
- tablist_props = assign(tablist_props, tablist_spread_levels[i]);
- }
- tablist = new TabList({ props: tablist_props });
- tablist.$on("select", /*select_handler*/ ctx[18]);
- const tabpanels_spread_levels = [
- { class: "PinturaControlPanels" },
- { panelClass: "PinturaControlPanel" },
- { panels: /*panels*/ ctx[12] },
- /*tabsConfig*/ ctx[11]
- ];
- let tabpanels_props = {
- $$slots: {
- default: [
- create_default_slot$4,
- ({ panel, panelIsActive }) => ({ 26: panel, 27: panelIsActive }),
- ({ panel, panelIsActive }) => (panel ? 67108864 : 0) | (panelIsActive ? 134217728 : 0)
- ]
- },
- $$scope: { ctx }
- };
- for (let i = 0; i < tabpanels_spread_levels.length; i += 1) {
- tabpanels_props = assign(tabpanels_props, tabpanels_spread_levels[i]);
- }
- tabpanels = new TabPanels({ props: tabpanels_props });
- return {
- c() {
- div1 = element("div");
- div0 = element("div");
- if (if_block) if_block.c();
- t0 = space();
- create_component(tablist.$$.fragment);
- t1 = space();
- create_component(tabpanels.$$.fragment);
- attr(div0, "class", "PinturaShapePresetsGroups");
- attr(div1, "class", "PinturaShapePresetsGrouped");
- },
- m(target, anchor) {
- insert(target, div1, anchor);
- append(div1, div0);
- if (if_block) if_block.m(div0, null);
- append(div0, t0);
- mount_component(tablist, div0, null);
- append(div1, t1);
- mount_component(tabpanels, div1, null);
- current = true;
- },
- p(ctx, dirty) {
- if (/*presetToolbar*/ ctx[13]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty & /*presetToolbar*/ 8192) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block_4$1(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(div0, t0);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- const tablist_changes = (dirty & /*tabs, tabsConfig*/ 2304)
- ? get_spread_update(tablist_spread_levels, [
- tablist_spread_levels[0],
- dirty & /*tabs*/ 256 && { tabs: /*tabs*/ ctx[8] },
- dirty & /*tabsConfig*/ 2048 && get_spread_object(/*tabsConfig*/ ctx[11]),
- tablist_spread_levels[3]
- ])
- : {};
- if (dirty & /*$$scope, tab*/ 805306368) {
- tablist_changes.$$scope = { dirty, ctx };
- }
- tablist.$set(tablist_changes);
- const tabpanels_changes = (dirty & /*panels, tabsConfig*/ 6144)
- ? get_spread_update(tabpanels_spread_levels, [
- tabpanels_spread_levels[0],
- tabpanels_spread_levels[1],
- dirty & /*panels*/ 4096 && { panels: /*panels*/ ctx[12] },
- dirty & /*tabsConfig*/ 2048 && get_spread_object(/*tabsConfig*/ ctx[11])
- ])
- : {};
- if (dirty & /*$$scope, panelIsActive, shouldRenderPresets, scrollElasticity, presetTabs, panel, onaddpreset, ongrabpreset, ondragpreset, ondroppreset*/ 738198623) {
- tabpanels_changes.$$scope = { dirty, ctx };
- }
- tabpanels.$set(tabpanels_changes);
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- transition_in(tablist.$$.fragment, local);
- transition_in(tabpanels.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- transition_out(tablist.$$.fragment, local);
- transition_out(tabpanels.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div1);
- if (if_block) if_block.d();
- destroy_component(tablist);
- destroy_component(tabpanels);
- }
- };
- }
- // (224:16) {#if presetToolbar}
- function create_if_block_5$1(ctx) {
- let dynamiccomponenttree;
- let current;
- dynamiccomponenttree = new DynamicComponentTree_1({
- props: { items: /*presetToolbar*/ ctx[13] }
- });
- return {
- c() {
- create_component(dynamiccomponenttree.$$.fragment);
- },
- m(target, anchor) {
- mount_component(dynamiccomponenttree, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const dynamiccomponenttree_changes = {};
- if (dirty & /*presetToolbar*/ 8192) dynamiccomponenttree_changes.items = /*presetToolbar*/ ctx[13];
- dynamiccomponenttree.$set(dynamiccomponenttree_changes);
- },
- i(local) {
- if (current) return;
- transition_in(dynamiccomponenttree.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(dynamiccomponenttree.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(dynamiccomponenttree, detaching);
- }
- };
- }
- // (228:16) <Scrollable scrollAutoCancel={shouldRenderPresets} elasticity={scrollElasticity}>
- function create_default_slot_4(ctx) {
- let shapepresetslist;
- let current;
- shapepresetslist = new ShapePresetsList({
- props: {
- presets: /*presetsMapped*/ ctx[5],
- onclickpreset: /*onaddpreset*/ ctx[1],
- ongrabpreset: /*ongrabpreset*/ ctx[2],
- ondragpreset: /*ondragpreset*/ ctx[3],
- ondroppreset: /*ondroppreset*/ ctx[4]
- }
- });
- return {
- c() {
- create_component(shapepresetslist.$$.fragment);
- },
- m(target, anchor) {
- mount_component(shapepresetslist, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const shapepresetslist_changes = {};
- if (dirty & /*presetsMapped*/ 32) shapepresetslist_changes.presets = /*presetsMapped*/ ctx[5];
- if (dirty & /*onaddpreset*/ 2) shapepresetslist_changes.onclickpreset = /*onaddpreset*/ ctx[1];
- if (dirty & /*ongrabpreset*/ 4) shapepresetslist_changes.ongrabpreset = /*ongrabpreset*/ ctx[2];
- if (dirty & /*ondragpreset*/ 8) shapepresetslist_changes.ondragpreset = /*ondragpreset*/ ctx[3];
- if (dirty & /*ondroppreset*/ 16) shapepresetslist_changes.ondroppreset = /*ondroppreset*/ ctx[4];
- shapepresetslist.$set(shapepresetslist_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapepresetslist.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapepresetslist.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(shapepresetslist, detaching);
- }
- };
- }
- // (176:20) {#if presetToolbar}
- function create_if_block_4$1(ctx) {
- let dynamiccomponenttree;
- let current;
- dynamiccomponenttree = new DynamicComponentTree_1({
- props: { items: /*presetToolbar*/ ctx[13] }
- });
- return {
- c() {
- create_component(dynamiccomponenttree.$$.fragment);
- },
- m(target, anchor) {
- mount_component(dynamiccomponenttree, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const dynamiccomponenttree_changes = {};
- if (dirty & /*presetToolbar*/ 8192) dynamiccomponenttree_changes.items = /*presetToolbar*/ ctx[13];
- dynamiccomponenttree.$set(dynamiccomponenttree_changes);
- },
- i(local) {
- if (current) return;
- transition_in(dynamiccomponenttree.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(dynamiccomponenttree.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(dynamiccomponenttree, detaching);
- }
- };
- }
- // (188:24) {#if tab.icon}
- function create_if_block_3$1(ctx) {
- let icon;
- let current;
- icon = new Icon({
- props: {
- $$slots: { default: [create_default_slot_3] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(icon.$$.fragment);
- },
- m(target, anchor) {
- mount_component(icon, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const icon_changes = {};
- if (dirty & /*$$scope, tab*/ 805306368) {
- icon_changes.$$scope = { dirty, ctx };
- }
- icon.$set(icon_changes);
- },
- i(local) {
- if (current) return;
- transition_in(icon.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(icon, detaching);
- }
- };
- }
- // (189:28) <Icon>
- function create_default_slot_3(ctx) {
- let g;
- let raw_value = /*tab*/ ctx[28].icon + "";
- return {
- c() {
- g = svg_element("g");
- },
- m(target, anchor) {
- insert(target, g, anchor);
- g.innerHTML = raw_value;
- },
- p(ctx, dirty) {
- if (dirty & /*tab*/ 268435456 && raw_value !== (raw_value = /*tab*/ ctx[28].icon + "")) g.innerHTML = raw_value; },
- d(detaching) {
- if (detaching) detach(g);
- }
- };
- }
- // (191:24) {#if !tab.hideLabel}
- function create_if_block_2$1(ctx) {
- let span;
- let t_value = /*tab*/ ctx[28].label + "";
- let t;
- return {
- c() {
- span = element("span");
- t = text(t_value);
- },
- m(target, anchor) {
- insert(target, span, anchor);
- append(span, t);
- },
- p(ctx, dirty) {
- if (dirty & /*tab*/ 268435456 && t_value !== (t_value = /*tab*/ ctx[28].label + "")) set_data(t, t_value);
- },
- d(detaching) {
- if (detaching) detach(span);
- }
- };
- }
- // (180:20) <TabList class="PinturaControlList" {tabs} {...tabsConfig} layout="compact" on:select={({ detail }) => (tabSelected = detail)} let:tab >
- function create_default_slot_2(ctx) {
- let t;
- let if_block1_anchor;
- let current;
- let if_block0 = /*tab*/ ctx[28].icon && create_if_block_3$1(ctx);
- let if_block1 = !/*tab*/ ctx[28].hideLabel && create_if_block_2$1(ctx);
- return {
- c() {
- if (if_block0) if_block0.c();
- t = space();
- if (if_block1) if_block1.c();
- if_block1_anchor = empty();
- },
- m(target, anchor) {
- if (if_block0) if_block0.m(target, anchor);
- insert(target, t, anchor);
- if (if_block1) if_block1.m(target, anchor);
- insert(target, if_block1_anchor, anchor);
- current = true;
- },
- p(ctx, dirty) {
- if (/*tab*/ ctx[28].icon) {
- if (if_block0) {
- if_block0.p(ctx, dirty);
- if (dirty & /*tab*/ 268435456) {
- transition_in(if_block0, 1);
- }
- } else {
- if_block0 = create_if_block_3$1(ctx);
- if_block0.c();
- transition_in(if_block0, 1);
- if_block0.m(t.parentNode, t);
- }
- } else if (if_block0) {
- group_outros();
- transition_out(if_block0, 1, 1, () => {
- if_block0 = null;
- });
- check_outros();
- }
- if (!/*tab*/ ctx[28].hideLabel) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- } else {
- if_block1 = create_if_block_2$1(ctx);
- if_block1.c();
- if_block1.m(if_block1_anchor.parentNode, if_block1_anchor);
- }
- } else if (if_block1) {
- if_block1.d(1);
- if_block1 = null;
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- current = false;
- },
- d(detaching) {
- if (if_block0) if_block0.d(detaching);
- if (detaching) detach(t);
- if (if_block1) if_block1.d(detaching);
- if (detaching) detach(if_block1_anchor);
- }
- };
- }
- // (205:20) <Scrollable scroll={panelIsActive ? { scrollOffset: 0, animate: false } : undefined} scrollAutoCancel={shouldRenderPresets} elasticity={scrollElasticity} >
- function create_default_slot_1$1(ctx) {
- let shapepresetslist;
- let current;
- shapepresetslist = new ShapePresetsList({
- props: {
- presets: /*presetTabs*/ ctx[10][/*panel*/ ctx[26]].items,
- disabled: /*presetTabs*/ ctx[10][/*panel*/ ctx[26]].disabled,
- onclickpreset: /*onaddpreset*/ ctx[1],
- ongrabpreset: /*ongrabpreset*/ ctx[2],
- ondragpreset: /*ondragpreset*/ ctx[3],
- ondroppreset: /*ondroppreset*/ ctx[4]
- }
- });
- return {
- c() {
- create_component(shapepresetslist.$$.fragment);
- },
- m(target, anchor) {
- mount_component(shapepresetslist, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const shapepresetslist_changes = {};
- if (dirty & /*presetTabs, panel*/ 67109888) shapepresetslist_changes.presets = /*presetTabs*/ ctx[10][/*panel*/ ctx[26]].items;
- if (dirty & /*presetTabs, panel*/ 67109888) shapepresetslist_changes.disabled = /*presetTabs*/ ctx[10][/*panel*/ ctx[26]].disabled;
- if (dirty & /*onaddpreset*/ 2) shapepresetslist_changes.onclickpreset = /*onaddpreset*/ ctx[1];
- if (dirty & /*ongrabpreset*/ 4) shapepresetslist_changes.ongrabpreset = /*ongrabpreset*/ ctx[2];
- if (dirty & /*ondragpreset*/ 8) shapepresetslist_changes.ondragpreset = /*ondragpreset*/ ctx[3];
- if (dirty & /*ondroppreset*/ 16) shapepresetslist_changes.ondroppreset = /*ondroppreset*/ ctx[4];
- shapepresetslist.$set(shapepresetslist_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapepresetslist.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapepresetslist.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(shapepresetslist, detaching);
- }
- };
- }
- // (197:16) <TabPanels class="PinturaControlPanels" panelClass="PinturaControlPanel" {panels} {...tabsConfig} let:panel let:panelIsActive >
- function create_default_slot$4(ctx) {
- let scrollable;
- let current;
- scrollable = new Scrollable({
- props: {
- scroll: /*panelIsActive*/ ctx[27]
- ? { scrollOffset: 0, animate: false }
- : undefined,
- scrollAutoCancel: /*shouldRenderPresets*/ ctx[6],
- elasticity: /*scrollElasticity*/ ctx[0],
- $$slots: { default: [create_default_slot_1$1] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(scrollable.$$.fragment);
- },
- m(target, anchor) {
- mount_component(scrollable, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const scrollable_changes = {};
- if (dirty & /*panelIsActive*/ 134217728) scrollable_changes.scroll = /*panelIsActive*/ ctx[27]
- ? { scrollOffset: 0, animate: false }
- : undefined;
- if (dirty & /*shouldRenderPresets*/ 64) scrollable_changes.scrollAutoCancel = /*shouldRenderPresets*/ ctx[6];
- if (dirty & /*scrollElasticity*/ 1) scrollable_changes.elasticity = /*scrollElasticity*/ ctx[0];
- if (dirty & /*$$scope, presetTabs, panel, onaddpreset, ongrabpreset, ondragpreset, ondroppreset*/ 603980830) {
- scrollable_changes.$$scope = { dirty, ctx };
- }
- scrollable.$set(scrollable_changes);
- },
- i(local) {
- if (current) return;
- transition_in(scrollable.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(scrollable.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(scrollable, detaching);
- }
- };
- }
- function create_fragment$a(ctx) {
- let div;
- let current_block_type_index;
- let if_block;
- let current;
- const if_block_creators = [create_if_block$1, create_if_block_6];
- const if_blocks = [];
- function select_block_type(ctx, dirty) {
- if (/*shouldRenderPresets*/ ctx[6]) return 0;
- if (/*presetToolbar*/ ctx[13]) return 1;
- return -1;
- }
- if (~(current_block_type_index = select_block_type(ctx))) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- }
- return {
- c() {
- div = element("div");
- if (if_block) if_block.c();
- attr(div, "class", "PinturaShapePresetsPalette");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].m(div, null);
- }
- current = true;
- },
- p(ctx, [dirty]) {
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type(ctx);
- if (current_block_type_index === previous_block_index) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- }
- } else {
- if (if_block) {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- }
- if (~current_block_type_index) {
- if_block = if_blocks[current_block_type_index];
- if (!if_block) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block.c();
- } else {
- if_block.p(ctx, dirty);
- }
- transition_in(if_block, 1);
- if_block.m(div, null);
- } else {
- if_block = null;
- }
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].d();
- }
- }
- };
- }
- function instance$a($$self, $$props, $$invalidate) {
- let presetsMapped;
- let shouldRenderPresets;
- let shouldGroupPresets;
- let tabs;
- let presetTabs;
- let tabSelected;
- let tabsConfig;
- let panels;
- let presetToolbar;
- let { locale } = $$props;
- let { presets } = $$props;
- let { scrollElasticity } = $$props;
- let { enableSelectImage = true } = $$props;
- let { willRenderPresetToolbar = passthrough } = $$props;
- let { onaddpreset = noop$1 } = $$props;
- let { ongrabpreset = undefined } = $$props;
- let { ondragpreset = undefined } = $$props;
- let { ondroppreset = undefined } = $$props;
- const uid = `presets-${getUniqueId()}`;
- const isPresetGroup = item => isArray(item) && isString(item[0]) && isArray(item[1]);
- const getPresetThumb = (value, alt = "") => {
- // could be svg
- if (isSVGMarkup(value)) return value;
- // test if is emoji
- if (isEmoji(value)) return getEmojiSVG(value, alt);
- // must be URL
- return `<img src="${value}" alt="${alt}"/>`;
- };
- const getAltFromSrc = src => getFilenameWithoutExtension(getFilenameFromURL(src));
- const excludedStickerItemProps = ["src", "alt", "thumb", "shape", "id", "mount", "disabled"];
- const mapPreset = item => {
- let id = item;
- let src;
- let shape;
- let shapeProps;
- let thumb;
- let alt;
- let mount;
- let disabled;
- // if item is a string, it's either an emoji or a URL
- if (isString(item)) {
- // is emoji
- if (isEmoji(item)) {
- src = item;
- alt = item;
- thumb = getPresetThumb(src, alt);
- } else // must be URL
- {
- src = item;
- alt = getAltFromSrc(src);
- thumb = getPresetThumb(src, alt);
- }
- } else {
- // set custom thumbnail if defined
- src = item.src;
- alt = item.alt || (isString(src)
- ? getAltFromSrc(src)
- : isString(item.thumb)
- ? getAltFromSrc(item.thumb)
- : undefined);
- thumb = getPresetThumb(item.thumb || src, alt);
- shape = item.shape;
- mount = item.mount;
- disabled = item.disabled;
- shapeProps = Object.keys(item).reduce(
- (prev, curr) => {
- if (excludedStickerItemProps.includes(curr)) return prev;
- prev[curr] = item[curr];
- return prev;
- },
- {}
- );
- }
- return {
- id,
- src,
- thumb,
- shape,
- shapeProps,
- alt,
- title: alt,
- mount,
- disabled
- };
- };
- const mapPresets = items => items.map(item => {
- if (isPresetGroup(item)) {
- return {
- ...item[2],
- id: `${uid}-${item[0].toLowerCase()}`,
- label: item[0],
- items: mapPresets(item[1])
- };
- }
- return mapPreset(item);
- });
- const select_handler = ({ detail }) => $$invalidate(9, tabSelected = detail);
- $$self.$$set = $$props => {
- if ("locale" in $$props) $$invalidate(14, locale = $$props.locale);
- if ("presets" in $$props) $$invalidate(15, presets = $$props.presets);
- if ("scrollElasticity" in $$props) $$invalidate(0, scrollElasticity = $$props.scrollElasticity);
- if ("enableSelectImage" in $$props) $$invalidate(16, enableSelectImage = $$props.enableSelectImage);
- if ("willRenderPresetToolbar" in $$props) $$invalidate(17, willRenderPresetToolbar = $$props.willRenderPresetToolbar);
- if ("onaddpreset" in $$props) $$invalidate(1, onaddpreset = $$props.onaddpreset);
- if ("ongrabpreset" in $$props) $$invalidate(2, ongrabpreset = $$props.ongrabpreset);
- if ("ondragpreset" in $$props) $$invalidate(3, ondragpreset = $$props.ondragpreset);
- if ("ondroppreset" in $$props) $$invalidate(4, ondroppreset = $$props.ondroppreset);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*presets*/ 32768) {
- $$invalidate(5, presetsMapped = mapPresets(presets));
- }
- if ($$self.$$.dirty & /*presetsMapped*/ 32) {
- //
- // handle file input
- //
- $$invalidate(6, shouldRenderPresets = presetsMapped.length);
- }
- if ($$self.$$.dirty & /*shouldRenderPresets, presetsMapped*/ 96) {
- $$invalidate(7, shouldGroupPresets = shouldRenderPresets && presetsMapped.some(preset => !!preset.items));
- }
- if ($$self.$$.dirty & /*shouldGroupPresets, presetsMapped*/ 160) {
- $$invalidate(8, tabs = shouldGroupPresets && presetsMapped);
- }
- if ($$self.$$.dirty & /*shouldGroupPresets, presetsMapped*/ 160) {
- $$invalidate(10, presetTabs = shouldGroupPresets && presetsMapped.reduce(
- (prev, curr) => {
- prev[curr.id] = curr;
- return prev;
- },
- {}
- ));
- }
- if ($$self.$$.dirty & /*tabSelected, tabs*/ 768) {
- $$invalidate(9, tabSelected = tabSelected || tabs && (tabs.find(tab => !tab.disabled) || {}).id);
- }
- if ($$self.$$.dirty & /*tabSelected*/ 512) {
- $$invalidate(11, tabsConfig = { name: uid, selected: tabSelected });
- }
- if ($$self.$$.dirty & /*tabs*/ 256) {
- $$invalidate(12, panels = tabs && tabs.map(tab => tab.id));
- }
- if ($$self.$$.dirty & /*locale, willRenderPresetToolbar, enableSelectImage, onaddpreset*/ 212994) {
- $$invalidate(13, presetToolbar = locale && willRenderPresetToolbar([
- enableSelectImage && [
- "Button",
- "browse",
- {
- label: locale.shapeLabelButtonSelectSticker,
- icon: locale.shapeIconButtonSelectSticker,
- onclick: () => {
- // create file input box
- const fileInput = h("input", {
- type: "file",
- accept: "image/*",
- onchange: () => {
- const [file] = fileInput.files;
- if (!file) return;
- onaddpreset(file);
- }
- });
- // open browse window
- fileInput.click();
- }
- }
- ]
- ]));
- }
- };
- return [
- scrollElasticity,
- onaddpreset,
- ongrabpreset,
- ondragpreset,
- ondroppreset,
- presetsMapped,
- shouldRenderPresets,
- shouldGroupPresets,
- tabs,
- tabSelected,
- presetTabs,
- tabsConfig,
- panels,
- presetToolbar,
- locale,
- presets,
- enableSelectImage,
- willRenderPresetToolbar,
- select_handler
- ];
- }
- class ShapePresetsPalette extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$a, create_fragment$a, safe_not_equal, {
- locale: 14,
- presets: 15,
- scrollElasticity: 0,
- enableSelectImage: 16,
- willRenderPresetToolbar: 17,
- onaddpreset: 1,
- ongrabpreset: 2,
- ondragpreset: 3,
- ondroppreset: 4
- });
- }
- }
- var createPingDispatcher = (node) => (type, data) => {
- node.dispatchEvent(createPing(type, data));
- };
- /* src/core/ui/components/ShapeUtil.svelte generated by Svelte v3.37.0 */
- function create_if_block_5(ctx) {
- let shapelayouteditor;
- let updating_markup;
- let updating_ui;
- let current;
- const shapelayouteditor_spread_levels = [
- { locale: /*locale*/ ctx[4] },
- { uid: /*utilKey*/ ctx[13] },
- { parentRect: /*$parentRect*/ ctx[23] },
- { rootRect: /*$rootRect*/ ctx[31] },
- { utilRect: /*$utilRect*/ ctx[25] },
- { offset: /*markupOffset*/ ctx[33] },
- {
- contextScale: /*$presentationScalar*/ ctx[42]
- },
- {
- contextRotation: /*imageRotation*/ ctx[16]
- },
- { contextFlipX: /*imageFlipX*/ ctx[17] },
- { contextFlipY: /*imageFlipY*/ ctx[18] },
- { active: /*$isActive*/ ctx[24] },
- { opacity: /*$isActiveFraction*/ ctx[28] },
- { eraseRadius: /*toolEraseRadius*/ ctx[34] },
- {
- selectRadius: /*toolSelectRadius*/ ctx[6]
- },
- {
- enableButtonFlipVertical: /*enableButtonFlipVertical*/ ctx[8]
- },
- {
- mapEditorPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[14]
- },
- {
- mapImagePointToEditorPoint: /*mapImagePointToScreenPoint*/ ctx[15]
- },
- {
- enableTapToAddText: /*enableTapToAddText*/ ctx[11]
- },
- {
- oninteractionstart: /*handleInteractionStart*/ ctx[54]
- },
- {
- oninteractionupdate: /*handleInteractionUpdate*/ ctx[55]
- },
- {
- oninteractionrelease: /*handleInteractionRelease*/ ctx[56]
- },
- {
- oninteractionend: /*handleInteractionEnd*/ ctx[57]
- },
- { onaddshape: /*func_1*/ ctx[89] },
- { onselectshape: /*func_2*/ ctx[90] },
- { onupdateshape: /*func_3*/ ctx[91] },
- { onremoveshape: /*func_4*/ ctx[92] },
- /*layoutEditorHooks*/ ctx[39]
- ];
- function shapelayouteditor_markup_binding(value) {
- /*shapelayouteditor_markup_binding*/ ctx[94](value);
- }
- function shapelayouteditor_ui_binding(value) {
- /*shapelayouteditor_ui_binding*/ ctx[95](value);
- }
- let shapelayouteditor_props = {};
- for (let i = 0; i < shapelayouteditor_spread_levels.length; i += 1) {
- shapelayouteditor_props = assign(shapelayouteditor_props, shapelayouteditor_spread_levels[i]);
- }
- if (/*$shapes*/ ctx[26] !== void 0) {
- shapelayouteditor_props.markup = /*$shapes*/ ctx[26];
- }
- if (/*$imageOverlayMarkup*/ ctx[41] !== void 0) {
- shapelayouteditor_props.ui = /*$imageOverlayMarkup*/ ctx[41];
- }
- shapelayouteditor = new ShapeLayoutEditor({ props: shapelayouteditor_props });
- /*shapelayouteditor_binding*/ ctx[93](shapelayouteditor);
- binding_callbacks.push(() => bind(shapelayouteditor, "markup", shapelayouteditor_markup_binding));
- binding_callbacks.push(() => bind(shapelayouteditor, "ui", shapelayouteditor_ui_binding));
- return {
- c() {
- create_component(shapelayouteditor.$$.fragment);
- },
- m(target, anchor) {
- mount_component(shapelayouteditor, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const shapelayouteditor_changes = (dirty[0] & /*locale, utilKey, $parentRect, $utilRect, imageRotation, imageFlipX, imageFlipY, $isActive, $isActiveFraction, toolSelectRadius, enableButtonFlipVertical, mapScreenPointToImagePoint, mapImagePointToScreenPoint, enableTapToAddText*/ 327674192 | dirty[1] & /*$rootRect, markupOffset, $presentationScalar, toolEraseRadius, handleInteractionStart, handleInteractionUpdate, handleInteractionRelease, handleInteractionEnd, ping, layoutEditorHooks*/ 125831469 | dirty[2] & /*handleMarkupUpdate*/ 4)
- ? get_spread_update(shapelayouteditor_spread_levels, [
- dirty[0] & /*locale*/ 16 && { locale: /*locale*/ ctx[4] },
- dirty[0] & /*utilKey*/ 8192 && { uid: /*utilKey*/ ctx[13] },
- dirty[0] & /*$parentRect*/ 8388608 && { parentRect: /*$parentRect*/ ctx[23] },
- dirty[1] & /*$rootRect*/ 1 && { rootRect: /*$rootRect*/ ctx[31] },
- dirty[0] & /*$utilRect*/ 33554432 && { utilRect: /*$utilRect*/ ctx[25] },
- dirty[1] & /*markupOffset*/ 4 && { offset: /*markupOffset*/ ctx[33] },
- dirty[1] & /*$presentationScalar*/ 2048 && {
- contextScale: /*$presentationScalar*/ ctx[42]
- },
- dirty[0] & /*imageRotation*/ 65536 && {
- contextRotation: /*imageRotation*/ ctx[16]
- },
- dirty[0] & /*imageFlipX*/ 131072 && { contextFlipX: /*imageFlipX*/ ctx[17] },
- dirty[0] & /*imageFlipY*/ 262144 && { contextFlipY: /*imageFlipY*/ ctx[18] },
- dirty[0] & /*$isActive*/ 16777216 && { active: /*$isActive*/ ctx[24] },
- dirty[0] & /*$isActiveFraction*/ 268435456 && { opacity: /*$isActiveFraction*/ ctx[28] },
- dirty[1] & /*toolEraseRadius*/ 8 && { eraseRadius: /*toolEraseRadius*/ ctx[34] },
- dirty[0] & /*toolSelectRadius*/ 64 && {
- selectRadius: /*toolSelectRadius*/ ctx[6]
- },
- dirty[0] & /*enableButtonFlipVertical*/ 256 && {
- enableButtonFlipVertical: /*enableButtonFlipVertical*/ ctx[8]
- },
- dirty[0] & /*mapScreenPointToImagePoint*/ 16384 && {
- mapEditorPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[14]
- },
- dirty[0] & /*mapImagePointToScreenPoint*/ 32768 && {
- mapImagePointToEditorPoint: /*mapImagePointToScreenPoint*/ ctx[15]
- },
- dirty[0] & /*enableTapToAddText*/ 2048 && {
- enableTapToAddText: /*enableTapToAddText*/ ctx[11]
- },
- dirty[1] & /*handleInteractionStart*/ 8388608 && {
- oninteractionstart: /*handleInteractionStart*/ ctx[54]
- },
- dirty[1] & /*handleInteractionUpdate*/ 16777216 && {
- oninteractionupdate: /*handleInteractionUpdate*/ ctx[55]
- },
- dirty[1] & /*handleInteractionRelease*/ 33554432 && {
- oninteractionrelease: /*handleInteractionRelease*/ ctx[56]
- },
- dirty[1] & /*handleInteractionEnd*/ 67108864 && {
- oninteractionend: /*handleInteractionEnd*/ ctx[57]
- },
- dirty[1] & /*ping*/ 32 | dirty[2] & /*handleMarkupUpdate*/ 4 && { onaddshape: /*func_1*/ ctx[89] },
- dirty[1] & /*ping*/ 32 && { onselectshape: /*func_2*/ ctx[90] },
- dirty[1] & /*ping*/ 32 | dirty[2] & /*handleMarkupUpdate*/ 4 && { onupdateshape: /*func_3*/ ctx[91] },
- dirty[1] & /*ping*/ 32 | dirty[2] & /*handleMarkupUpdate*/ 4 && { onremoveshape: /*func_4*/ ctx[92] },
- dirty[1] & /*layoutEditorHooks*/ 256 && get_spread_object(/*layoutEditorHooks*/ ctx[39])
- ])
- : {};
- if (!updating_markup && dirty[0] & /*$shapes*/ 67108864) {
- updating_markup = true;
- shapelayouteditor_changes.markup = /*$shapes*/ ctx[26];
- add_flush_callback(() => updating_markup = false);
- }
- if (!updating_ui && dirty[1] & /*$imageOverlayMarkup*/ 1024) {
- updating_ui = true;
- shapelayouteditor_changes.ui = /*$imageOverlayMarkup*/ ctx[41];
- add_flush_callback(() => updating_ui = false);
- }
- shapelayouteditor.$set(shapelayouteditor_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapelayouteditor.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapelayouteditor.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- /*shapelayouteditor_binding*/ ctx[93](null);
- destroy_component(shapelayouteditor, detaching);
- }
- };
- }
- // (559:4)
- function create_main_slot(ctx) {
- let div;
- let current;
- let mounted;
- let dispose;
- let if_block = /*shouldRenderShapeEditor*/ ctx[32] && create_if_block_5(ctx);
- return {
- c() {
- div = element("div");
- if (if_block) if_block.c();
- attr(div, "slot", "main");
- set_style(div, "cursor", "crosshair");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (if_block) if_block.m(div, null);
- /*div_binding*/ ctx[96](div);
- current = true;
- if (!mounted) {
- dispose = [
- action_destroyer(dropable.call(null, div)),
- listen(div, "dropfiles", function () {
- if (is_function(/*enablePresetDropImage*/ ctx[10]
- ? /*handleDropFiles*/ ctx[63]
- : noop$1)) (/*enablePresetDropImage*/ ctx[10]
- ? /*handleDropFiles*/ ctx[63]
- : noop$1).apply(this, arguments);
- }),
- action_destroyer(measurable.call(null, div)),
- listen(div, "measure", /*measure_handler_1*/ ctx[87])
- ];
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- if (/*shouldRenderShapeEditor*/ ctx[32]) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty[1] & /*shouldRenderShapeEditor*/ 2) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block_5(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(div, null);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (if_block) if_block.d();
- /*div_binding*/ ctx[96](null);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- // (681:38)
- function create_if_block_4(ctx) {
- let shapepresetspalette;
- let current;
- shapepresetspalette = new ShapePresetsPalette({
- props: {
- locale: /*locale*/ ctx[4],
- presets: /*shapePresets*/ ctx[12],
- enableSelectImage: /*enablePresetSelectImage*/ ctx[9],
- willRenderPresetToolbar: /*runWillRenderPresetToolbarHook*/ ctx[38],
- onaddpreset: /*handleAddPreset*/ ctx[62],
- ongrabpreset: /*handleGrabPreset*/ ctx[59],
- ondragpreset: /*handleDragPreset*/ ctx[60],
- ondroppreset: /*handleDropPreset*/ ctx[61],
- scrollElasticity: /*computedScrollElasticity*/ ctx[37]
- }
- });
- return {
- c() {
- create_component(shapepresetspalette.$$.fragment);
- },
- m(target, anchor) {
- mount_component(shapepresetspalette, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const shapepresetspalette_changes = {};
- if (dirty[0] & /*locale*/ 16) shapepresetspalette_changes.locale = /*locale*/ ctx[4];
- if (dirty[0] & /*shapePresets*/ 4096) shapepresetspalette_changes.presets = /*shapePresets*/ ctx[12];
- if (dirty[0] & /*enablePresetSelectImage*/ 512) shapepresetspalette_changes.enableSelectImage = /*enablePresetSelectImage*/ ctx[9];
- if (dirty[1] & /*runWillRenderPresetToolbarHook*/ 128) shapepresetspalette_changes.willRenderPresetToolbar = /*runWillRenderPresetToolbarHook*/ ctx[38];
- if (dirty[1] & /*computedScrollElasticity*/ 64) shapepresetspalette_changes.scrollElasticity = /*computedScrollElasticity*/ ctx[37];
- shapepresetspalette.$set(shapepresetspalette_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapepresetspalette.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapepresetspalette.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(shapepresetspalette, detaching);
- }
- };
- }
- // (616:8) {#if shouldRenderControls}
- function create_if_block(ctx) {
- let div;
- let current_block_type_index;
- let if_block0;
- let t;
- let if_block1_anchor;
- let current;
- const if_block_creators = [create_if_block_3, create_else_block];
- const if_blocks = [];
- function select_block_type_1(ctx, dirty) {
- if (/*shouldRenderPresets*/ ctx[35]) return 0;
- return 1;
- }
- current_block_type_index = select_block_type_1(ctx);
- if_block0 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- let if_block1 = /*showToolbar*/ ctx[22] && create_if_block_1(ctx);
- return {
- c() {
- div = element("div");
- if_block0.c();
- t = space();
- if (if_block1) if_block1.c();
- if_block1_anchor = empty();
- attr(div, "class", "PinturaControlPanels");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if_blocks[current_block_type_index].m(div, null);
- insert(target, t, anchor);
- if (if_block1) if_block1.m(target, anchor);
- insert(target, if_block1_anchor, anchor);
- current = true;
- },
- p(ctx, dirty) {
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type_1(ctx);
- if (current_block_type_index === previous_block_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- } else {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- if_block0 = if_blocks[current_block_type_index];
- if (!if_block0) {
- if_block0 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block0.c();
- } else {
- if_block0.p(ctx, dirty);
- }
- transition_in(if_block0, 1);
- if_block0.m(div, null);
- }
- if (/*showToolbar*/ ctx[22]) {
- if (if_block1) {
- if_block1.p(ctx, dirty);
- if (dirty[0] & /*showToolbar*/ 4194304) {
- transition_in(if_block1, 1);
- }
- } else {
- if_block1 = create_if_block_1(ctx);
- if_block1.c();
- transition_in(if_block1, 1);
- if_block1.m(if_block1_anchor.parentNode, if_block1_anchor);
- }
- } else if (if_block1) {
- group_outros();
- transition_out(if_block1, 1, 1, () => {
- if_block1 = null;
- });
- check_outros();
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block0);
- transition_in(if_block1);
- current = true;
- },
- o(local) {
- transition_out(if_block0);
- transition_out(if_block1);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if_blocks[current_block_type_index].d();
- if (detaching) detach(t);
- if (if_block1) if_block1.d(detaching);
- if (detaching) detach(if_block1_anchor);
- }
- };
- }
- // (632:16) {:else}
- function create_else_block(ctx) {
- let div;
- let shapestyleeditor;
- let current;
- shapestyleeditor = new ShapeStyleEditor({
- props: {
- locale: /*locale*/ ctx[4],
- shape: /*markupShapeSelected*/ ctx[27],
- onchange: /*handleUpdateSelectedMarkupShape*/ ctx[58],
- controls: /*shapeControls*/ ctx[7],
- scrollElasticity: /*computedScrollElasticity*/ ctx[37]
- }
- });
- return {
- c() {
- div = element("div");
- create_component(shapestyleeditor.$$.fragment);
- attr(div, "class", "PinturaControlPanel");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(shapestyleeditor, div, null);
- current = true;
- },
- p(ctx, dirty) {
- const shapestyleeditor_changes = {};
- if (dirty[0] & /*locale*/ 16) shapestyleeditor_changes.locale = /*locale*/ ctx[4];
- if (dirty[0] & /*markupShapeSelected*/ 134217728) shapestyleeditor_changes.shape = /*markupShapeSelected*/ ctx[27];
- if (dirty[0] & /*shapeControls*/ 128) shapestyleeditor_changes.controls = /*shapeControls*/ ctx[7];
- if (dirty[1] & /*computedScrollElasticity*/ 64) shapestyleeditor_changes.scrollElasticity = /*computedScrollElasticity*/ ctx[37];
- shapestyleeditor.$set(shapestyleeditor_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapestyleeditor.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapestyleeditor.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(shapestyleeditor);
- }
- };
- }
- // (618:16) {#if shouldRenderPresets}
- function create_if_block_3(ctx) {
- let div;
- let shapepresetspalette;
- let current;
- shapepresetspalette = new ShapePresetsPalette({
- props: {
- locale: /*locale*/ ctx[4],
- presets: /*shapePresets*/ ctx[12],
- enableSelectImage: /*enablePresetSelectImage*/ ctx[9],
- willRenderPresetToolbar: /*runWillRenderPresetToolbarHook*/ ctx[38],
- onaddpreset: /*handleAddPreset*/ ctx[62],
- ongrabpreset: /*handleGrabPreset*/ ctx[59],
- ondragpreset: /*handleDragPreset*/ ctx[60],
- ondroppreset: /*handleDropPreset*/ ctx[61],
- scrollElasticity: /*computedScrollElasticity*/ ctx[37]
- }
- });
- return {
- c() {
- div = element("div");
- create_component(shapepresetspalette.$$.fragment);
- attr(div, "class", "PinturaControlPanel");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(shapepresetspalette, div, null);
- current = true;
- },
- p(ctx, dirty) {
- const shapepresetspalette_changes = {};
- if (dirty[0] & /*locale*/ 16) shapepresetspalette_changes.locale = /*locale*/ ctx[4];
- if (dirty[0] & /*shapePresets*/ 4096) shapepresetspalette_changes.presets = /*shapePresets*/ ctx[12];
- if (dirty[0] & /*enablePresetSelectImage*/ 512) shapepresetspalette_changes.enableSelectImage = /*enablePresetSelectImage*/ ctx[9];
- if (dirty[1] & /*runWillRenderPresetToolbarHook*/ 128) shapepresetspalette_changes.willRenderPresetToolbar = /*runWillRenderPresetToolbarHook*/ ctx[38];
- if (dirty[1] & /*computedScrollElasticity*/ 64) shapepresetspalette_changes.scrollElasticity = /*computedScrollElasticity*/ ctx[37];
- shapepresetspalette.$set(shapepresetspalette_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapepresetspalette.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapepresetspalette.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(shapepresetspalette);
- }
- };
- }
- // (645:12) {#if showToolbar}
- function create_if_block_1(ctx) {
- let scrollable;
- let current;
- scrollable = new Scrollable({
- props: {
- class: "PinturaControlListScroller",
- elasticity: /*computedScrollElasticity*/ ctx[37],
- $$slots: { default: [create_default_slot$3] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(scrollable.$$.fragment);
- },
- m(target, anchor) {
- mount_component(scrollable, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const scrollable_changes = {};
- if (dirty[1] & /*computedScrollElasticity*/ 64) scrollable_changes.elasticity = /*computedScrollElasticity*/ ctx[37];
- if (dirty[0] & /*locale, toolsFiltered, toolActive*/ 2097169 | dirty[3] & /*$$scope*/ 4194304) {
- scrollable_changes.$$scope = { dirty, ctx };
- }
- scrollable.$set(scrollable_changes);
- },
- i(local) {
- if (current) return;
- transition_in(scrollable.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(scrollable.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(scrollable, detaching);
- }
- };
- }
- // (663:28) {#if option.icon}
- function create_if_block_2(ctx) {
- let icon;
- let current;
- icon = new Icon({
- props: {
- $$slots: { default: [create_default_slot_1] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(icon.$$.fragment);
- },
- m(target, anchor) {
- mount_component(icon, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const icon_changes = {};
- if (dirty[0] & /*locale*/ 16 | dirty[3] & /*$$scope, option*/ 6291456) {
- icon_changes.$$scope = { dirty, ctx };
- }
- icon.$set(icon_changes);
- },
- i(local) {
- if (current) return;
- transition_in(icon.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(icon, detaching);
- }
- };
- }
- // (664:32) <Icon >
- function create_default_slot_1(ctx) {
- let g;
- let raw_value = (isFunction(/*option*/ ctx[114].icon)
- ? /*option*/ ctx[114].icon(/*locale*/ ctx[4])
- : /*option*/ ctx[114].icon) + "";
- return {
- c() {
- g = svg_element("g");
- },
- m(target, anchor) {
- insert(target, g, anchor);
- g.innerHTML = raw_value;
- },
- p(ctx, dirty) {
- if (dirty[0] & /*locale*/ 16 | dirty[3] & /*option*/ 2097152 && raw_value !== (raw_value = (isFunction(/*option*/ ctx[114].icon)
- ? /*option*/ ctx[114].icon(/*locale*/ ctx[4])
- : /*option*/ ctx[114].icon) + "")) g.innerHTML = raw_value; },
- d(detaching) {
- if (detaching) detach(g);
- }
- };
- }
- // (662:24)
- function create_option_slot$1(ctx) {
- let div;
- let t0;
- let span;
- let t1_value = (isFunction(/*option*/ ctx[114].label)
- ? /*option*/ ctx[114].label(/*locale*/ ctx[4])
- : /*option*/ ctx[114].label) + "";
- let t1;
- let current;
- let if_block = /*option*/ ctx[114].icon && create_if_block_2(ctx);
- return {
- c() {
- div = element("div");
- if (if_block) if_block.c();
- t0 = space();
- span = element("span");
- t1 = text(t1_value);
- attr(div, "slot", "option");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (if_block) if_block.m(div, null);
- append(div, t0);
- append(div, span);
- append(span, t1);
- current = true;
- },
- p(ctx, dirty) {
- if (/*option*/ ctx[114].icon) {
- if (if_block) {
- if_block.p(ctx, dirty);
- if (dirty[3] & /*option*/ 2097152) {
- transition_in(if_block, 1);
- }
- } else {
- if_block = create_if_block_2(ctx);
- if_block.c();
- transition_in(if_block, 1);
- if_block.m(div, t0);
- }
- } else if (if_block) {
- group_outros();
- transition_out(if_block, 1, 1, () => {
- if_block = null;
- });
- check_outros();
- }
- if ((!current || dirty[0] & /*locale*/ 16 | dirty[3] & /*option*/ 2097152) && t1_value !== (t1_value = (isFunction(/*option*/ ctx[114].label)
- ? /*option*/ ctx[114].label(/*locale*/ ctx[4])
- : /*option*/ ctx[114].label) + "")) set_data(t1, t1_value);
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (if_block) if_block.d();
- }
- };
- }
- // (646:16) <Scrollable class="PinturaControlListScroller" elasticity={computedScrollElasticity} >
- function create_default_slot$3(ctx) {
- let radiogroup;
- let current;
- radiogroup = new RadioGroup({
- props: {
- locale: /*locale*/ ctx[4],
- class: "PinturaControlList",
- optionClass: "PinturaControlListOption",
- layout: "row",
- options: /*toolsFiltered*/ ctx[21],
- selectedIndex: /*toolsFiltered*/ ctx[21].findIndex(/*func*/ ctx[88]),
- onchange: /*updateActiveTool*/ ctx[53],
- $$slots: {
- option: [
- create_option_slot$1,
- ({ option }) => ({ 114: option }),
- ({ option }) => [0, 0, 0, option ? 2097152 : 0]
- ]
- },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(radiogroup.$$.fragment);
- },
- m(target, anchor) {
- mount_component(radiogroup, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const radiogroup_changes = {};
- if (dirty[0] & /*locale*/ 16) radiogroup_changes.locale = /*locale*/ ctx[4];
- if (dirty[0] & /*toolsFiltered*/ 2097152) radiogroup_changes.options = /*toolsFiltered*/ ctx[21];
- if (dirty[0] & /*toolsFiltered, toolActive*/ 2097153) radiogroup_changes.selectedIndex = /*toolsFiltered*/ ctx[21].findIndex(/*func*/ ctx[88]);
- if (dirty[0] & /*locale*/ 16 | dirty[3] & /*$$scope, option*/ 6291456) {
- radiogroup_changes.$$scope = { dirty, ctx };
- }
- radiogroup.$set(radiogroup_changes);
- },
- i(local) {
- if (current) return;
- transition_in(radiogroup.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(radiogroup.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(radiogroup, detaching);
- }
- };
- }
- // (615:4)
- function create_footer_slot$2(ctx) {
- let div;
- let current_block_type_index;
- let if_block;
- let current;
- const if_block_creators = [create_if_block, create_if_block_4];
- const if_blocks = [];
- function select_block_type(ctx, dirty) {
- if (/*shouldRenderControls*/ ctx[30]) return 0;
- if (/*shouldRenderPresets*/ ctx[35]) return 1;
- return -1;
- }
- if (~(current_block_type_index = select_block_type(ctx))) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- }
- return {
- c() {
- div = element("div");
- if (if_block) if_block.c();
- attr(div, "slot", "footer");
- attr(div, "style", /*footerStyle*/ ctx[40]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].m(div, null);
- }
- current = true;
- },
- p(ctx, dirty) {
- let previous_block_index = current_block_type_index;
- current_block_type_index = select_block_type(ctx);
- if (current_block_type_index === previous_block_index) {
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].p(ctx, dirty);
- }
- } else {
- if (if_block) {
- group_outros();
- transition_out(if_blocks[previous_block_index], 1, 1, () => {
- if_blocks[previous_block_index] = null;
- });
- check_outros();
- }
- if (~current_block_type_index) {
- if_block = if_blocks[current_block_type_index];
- if (!if_block) {
- if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
- if_block.c();
- } else {
- if_block.p(ctx, dirty);
- }
- transition_in(if_block, 1);
- if_block.m(div, null);
- } else {
- if_block = null;
- }
- }
- if (!current || dirty[1] & /*footerStyle*/ 512) {
- attr(div, "style", /*footerStyle*/ ctx[40]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(if_block);
- current = true;
- },
- o(local) {
- transition_out(if_block);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- if (~current_block_type_index) {
- if_blocks[current_block_type_index].d();
- }
- }
- };
- }
- function create_fragment$9(ctx) {
- let util;
- let current;
- util = new Util({
- props: {
- $$slots: {
- footer: [create_footer_slot$2],
- main: [create_main_slot]
- },
- $$scope: { ctx }
- }
- });
- util.$on("measure", /*measure_handler*/ ctx[97]);
- return {
- c() {
- create_component(util.$$.fragment);
- },
- m(target, anchor) {
- mount_component(util, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const util_changes = {};
- if (dirty[0] & /*locale, toolsFiltered, toolActive, showToolbar, shapePresets, enablePresetSelectImage, markupShapeSelected, shapeControls, shouldRenderControls, pingHub, enablePresetDropImage, utilKey, $parentRect, $utilRect, imageRotation, imageFlipX, imageFlipY, $isActive, $isActiveFraction, toolSelectRadius, enableButtonFlipVertical, mapScreenPointToImagePoint, mapImagePointToScreenPoint, enableTapToAddText, markupEditor, $shapes*/ 2146959313 | dirty[1] & /*footerStyle, computedScrollElasticity, runWillRenderPresetToolbarHook, shouldRenderPresets, $rootRect, markupOffset, $presentationScalar, toolEraseRadius, ping, layoutEditorHooks, $imageOverlayMarkup, shouldRenderShapeEditor*/ 4095 | dirty[3] & /*$$scope*/ 4194304) {
- util_changes.$$scope = { dirty, ctx };
- }
- util.$set(util_changes);
- },
- i(local) {
- if (current) return;
- transition_in(util.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(util.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(util, detaching);
- }
- };
- }
- function instance$9($$self, $$props, $$invalidate) {
- let toolsFiltered;
- let hasShapeControls;
- let showToolbar;
- let hasTools;
- let hasActiveTool;
- let shouldRenderControls;
- let shouldRenderShapeEditor;
- let markupOffset;
- let markupShapeKeys;
- let markupSelected;
- let markupToolShape;
- let markupToolStylesComputed;
- let markupShapeSelected;
- let toolEraseRadius;
- let shouldRenderPresets;
- let shouldStickToImage;
- let ping;
- let computedScrollElasticity;
- let runWillRenderPresetToolbarHook;
- let layoutEditorHooks;
- let footerStyle;
- let $parentRect,
- $$unsubscribe_parentRect = noop,
- $$subscribe_parentRect = () => ($$unsubscribe_parentRect(), $$unsubscribe_parentRect = subscribe(parentRect, $$value => $$invalidate(23, $parentRect = $$value)), parentRect);
- let $rootRect;
- let $isActive,
- $$unsubscribe_isActive = noop,
- $$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(24, $isActive = $$value)), isActive);
- let $imagePreviewModifiers;
- let $isVisible,
- $$unsubscribe_isVisible = noop,
- $$subscribe_isVisible = () => ($$unsubscribe_isVisible(), $$unsubscribe_isVisible = subscribe(isVisible, $$value => $$invalidate(78, $isVisible = $$value)), isVisible);
- let $utilRect;
- let $stageRect;
- let $shapes,
- $$unsubscribe_shapes = noop,
- $$subscribe_shapes = () => ($$unsubscribe_shapes(), $$unsubscribe_shapes = subscribe(shapes, $$value => $$invalidate(26, $shapes = $$value)), shapes);
- let $shapePreprocessor;
- let $isActiveFraction,
- $$unsubscribe_isActiveFraction = noop,
- $$subscribe_isActiveFraction = () => ($$unsubscribe_isActiveFraction(), $$unsubscribe_isActiveFraction = subscribe(isActiveFraction, $$value => $$invalidate(28, $isActiveFraction = $$value)), isActiveFraction);
- let $imageCropRect;
- let $env;
- let $animation;
- let $footerOffset;
- let $imageOverlayMarkup;
- let $presentationScalar;
- $$self.$$.on_destroy.push(() => $$unsubscribe_parentRect());
- $$self.$$.on_destroy.push(() => $$unsubscribe_isActive());
- $$self.$$.on_destroy.push(() => $$unsubscribe_isVisible());
- $$self.$$.on_destroy.push(() => $$unsubscribe_shapes());
- $$self.$$.on_destroy.push(() => $$unsubscribe_isActiveFraction());
- let { isActive } = $$props;
- $$subscribe_isActive();
- let { isActiveFraction } = $$props;
- $$subscribe_isActiveFraction();
- let { isVisible } = $$props;
- $$subscribe_isVisible();
- let { stores } = $$props;
- let { locale = {} } = $$props;
- let { shapes } = $$props;
- $$subscribe_shapes();
- let { tools = [] } = $$props;
- let { toolShapes = [] } = $$props;
- let { toolActive = undefined } = $$props;
- let { toolSelectRadius = undefined } = $$props;
- let { shapeControls = {} } = $$props;
- let { enableButtonFlipVertical = false } = $$props;
- let { enablePresetSelectImage = true } = $$props;
- let { enablePresetDropImage = true } = $$props;
- let { enableSelectToolToAddShape = false } = $$props;
- let { enableTapToAddText = false } = $$props;
- let { willRenderPresetToolbar = undefined } = $$props;
- let { shapePresets = [] } = $$props;
- let { utilKey } = $$props;
- let { mapScreenPointToImagePoint } = $$props;
- let { mapImagePointToScreenPoint } = $$props;
- let { imageRotation = 0 } = $$props;
- let { imageFlipX = false } = $$props;
- let { imageFlipY = false } = $$props;
- let { parentRect } = $$props;
- $$subscribe_parentRect();
- let { hooks = {} } = $$props;
- const { env, animation, history, rootRect, stageRect, utilRect, elasticityMultiplier, scrollElasticity, imageOverlayMarkup, imagePreviewModifiers, imageCropRect, presentationScalar, shapePreprocessor, // for panning / scaling the image
- imagePresentationScale, imagePresentationPan } = stores;
- component_subscribe($$self, env, value => $$invalidate(84, $env = value));
- component_subscribe($$self, animation, value => $$invalidate(85, $animation = value));
- component_subscribe($$self, rootRect, value => $$invalidate(31, $rootRect = value));
- component_subscribe($$self, stageRect, value => $$invalidate(79, $stageRect = value));
- component_subscribe($$self, utilRect, value => $$invalidate(25, $utilRect = value));
- component_subscribe($$self, imageOverlayMarkup, value => $$invalidate(41, $imageOverlayMarkup = value));
- component_subscribe($$self, imagePreviewModifiers, value => $$invalidate(76, $imagePreviewModifiers = value));
- component_subscribe($$self, imageCropRect, value => $$invalidate(101, $imageCropRect = value));
- component_subscribe($$self, presentationScalar, value => $$invalidate(42, $presentationScalar = value));
- component_subscribe($$self, shapePreprocessor, value => $$invalidate(83, $shapePreprocessor = value));
- const updateActiveTool = ({ value }, event) => {
- $$invalidate(0, toolActive = value);
- // if is keyboard navigating or should add shape
- if (enableSelectToolToAddShape || isConfirmKey(event.key)) {
- AddToolDefaultShape(value);
- }
- };
- const AddToolDefaultShape = tool => {
- const [shape, options] = toolShapes[tool];
- let isRelative = options.position === "relative";
- let shapeToAdd;
- const size = isRelative ? "20%" : $parentRect.width * 0.2;
- const x = isRelative ? "0%" : 0;
- const y = isRelative ? "0%" : 0;
- if (shapeIsRect(shape) || shapeIsText(shape)) {
- shapeToAdd = shapeDeepCopy(shape);
- shapeToAdd.x = x;
- shapeToAdd.y = y;
- shapeUpdateProps(shapeToAdd, { width: size, height: size }, $parentRect);
- } else if (shapeIsEllipse(shape)) {
- shapeToAdd = shapeDeepCopy(shape);
- shapeToAdd.x = x;
- shapeToAdd.y = y;
- shapeUpdateProps(shapeToAdd, { rx: size, ry: size }, $parentRect);
- } else if (shapeIsLine(shape)) {
- shapeToAdd = shapeDeepCopy(shape);
- shapeToAdd.x1 = x;
- shapeToAdd.y1 = y;
- shapeToAdd.x2 = x;
- shapeToAdd.y2 = y;
- }
- if (!shapeToAdd) return;
- Promise.resolve().then(() => {
- addShape(createShapeAtPosition(shapeToAdd, undefined, size));
- });
- };
- const mapScreenEventToImagePoint = e => mapScreenPointToImagePoint(getEventPositionInEditor(e, $rootRect));
- // A reference to the markup editor, we need this so we can call exported functions
- let markupEditor;
- // the current tool styles
- let markupToolStyles = {};
- //
- // Create new shape
- //
- let interactionHandler;
- const handleInteractionStart = e => {
- if (toolActive === "eraser") {
- interactionHandler = markupEditor.eraseShape();
- } else if (toolActive && toolShapes[toolActive]) {
- const [shape, options] = toolShapes[toolActive];
- interactionHandler = markupEditor.createShape({ ...shape, ...markupToolStylesComputed }, options);
- } else {
- interactionHandler = undefined;
- }
- if (!interactionHandler) return false;
- interactionHandler.start(e);
- return true;
- };
- const handleInteractionUpdate = e => {
- if (!interactionHandler) return false;
- interactionHandler.update(e);
- return true;
- };
- const handleInteractionRelease = e => {
- if (!interactionHandler) return false;
- interactionHandler.release(e);
- return true;
- };
- const handleInteractionEnd = e => {
- if (!interactionHandler) return false;
- interactionHandler.end(e);
- interactionHandler = undefined;
- return true;
- };
- const blurOnToolSwitch = () => {
- if (!markupEditor) return;
- markupEditor.blurShapes();
- };
- function handleUpdateSelectedMarkupShape(props) {
- // remember style for when creating or styling other element
- Object.keys(props).forEach(key => $$invalidate(72, markupToolStyles[key] = props[key], markupToolStyles));
- // it's possible we're only updating default styles
- if (!markupSelected) return;
- // update element
- markupEditor.updateMarkupShape(markupSelected, props);
- // update markup style
- handleMarkupUpdate();
- }
- const createShapeAtPosition = (shape, position, size) => {
- // position defaults to crop center
- let positionIsCenter = false;
- if (!position) {
- // is centering to stage
- positionIsCenter = true;
- // calculate image or rect position
- position = shouldStickToImage
- ? mapScreenPointToImagePoint(rectCenter($stageRect))
- : rectCenter($imageCropRect);
- }
- // adjust offset if parent rect is image crop rect
- position.x -= $parentRect.x || 0;
- position.y -= $parentRect.y || 0;
- // de-flip shape
- if (imageFlipX || imageFlipY) {
- shape.flipX = imageFlipX;
- shape.flipY = imageFlipY;
- }
- // reposition if there's already shapes at position and shape isn't full screen
- const shapesAlreadyAtPosition = markupEditor.getShapesNearPosition(position);
- if (positionIsCenter && shapesAlreadyAtPosition.length) {
- const dist = Math.min($imageCropRect.width, $imageCropRect.height) * 0.1;
- position.x += Math.round(-dist + Math.random() * dist * 2);
- position.y += Math.round(-dist + Math.random() * dist * 2);
- }
- // de-rotate shape
- if (imageRotation !== 0) {
- if (imageFlipX && imageFlipY) shape.rotation = -imageRotation; else if (imageFlipX) shape.rotation = imageRotation; else if (imageFlipY) shape.rotation = imageRotation; else shape.rotation = -imageRotation;
- }
- if (hasProp(shape, "width") && hasProp(shape, "height")) {
- const { width, height } = shapeGetPropsPixelValues(shape, ["width", "height"], $parentRect);
- shapeUpdateProps(
- shape,
- {
- x: position.x - width * 0.5,
- y: position.y - height * 0.5
- },
- $parentRect
- );
- } else if (shapeIsEllipse(shape)) {
- shapeUpdateProps(shape, { x: position.x, y: position.y }, $parentRect);
- } else if (shapeIsLine(shape)) {
- const { x1, y1, x2, y2 } = shapeGetPropsPixelValues(shape, ["x1", "y1", "x2", "y2"], $parentRect);
- const dist = vectorDistance(vectorCreate(x1, y1), vectorCreate(x2, y2));
- const l = dist || isString(size)
- ? toPixelValue(size, $parentRect.width)
- : size;
- shapeUpdateProps(
- shape,
- {
- x1: position.x - l,
- y1: position.y + l,
- x2: position.x + l,
- y2: position.y - l
- },
- $parentRect
- );
- }
- return shape;
- };
- const addPreset = (preset, position) => {
- const shape = createShapeAtPosition(shapeCreateFromPreset(preset, $imageCropRect), position);
- return addShape(shape);
- };
- const addShape = shape => {
- const { beforeAddShape = () => true } = hooks;
- if (!beforeAddShape(shape)) return;
- markupEditor.addShape(shape);
- markupEditor.selectShape(shape);
- history.write();
- return shape;
- };
- let dragCancelled = false;
- const handleGrabPreset = () => {
- dragCancelled = false;
- };
- const handleDragPreset = (preset, e) => {
- if (dragCancelled) return;
- const { beforeAddShape = () => true } = hooks;
- const position = mapScreenEventToImagePoint(e);
- // create or update if is inside image
- const draft = markupEditor.getMarkupItemDraft();
- const inCropRect = rectContainsPoint($imageCropRect, {
- // adjust offset if parent rect is image crop rect
- x: position.x + ($parentRect.x || 0),
- y: position.y + ($parentRect.y || 0)
- });
- // remove draft if not dragging inside image
- if (draft && !inCropRect) markupEditor.discardMarkupItemDraft();
- // stop here if we're not in the crop rect
- if (!inCropRect) return;
- // create draft shape
- if (!draft) {
- const shape = createShapeAtPosition(shapeCreateFromPreset(preset, $imageCropRect), position);
- if (!beforeAddShape(shape)) {
- dragCancelled = true;
- e.preventDefault();
- return;
- }
- shapeMakeDraft(shape);
- markupEditor.addShape(shape);
- return;
- }
- // center shape on pointer if it has dimensions
- if (shapeIsRect(draft)) {
- position.x -= draft.width * 0.5;
- position.y -= draft.height * 0.5;
- }
- // update the draft shape
- markupEditor.updateMarkupShape(draft, position);
- };
- const handleDropPreset = (_, e) => {
- if (dragCancelled) return;
- const position = mapScreenEventToImagePoint(e);
- if (!rectContainsPoint($imageCropRect, {
- x: position.x + ($parentRect.x || 0),
- y: position.y + ($parentRect.y || 0)
- })) {
- markupEditor.discardMarkupItemDraft();
- return;
- }
- // confirm shape
- const shape = markupEditor.confirmMarkupItemDraft();
- markupEditor.selectShape(shape);
- // update history
- history.write();
- };
- const handleAddPreset = preset => addPreset(preset);
- const handleAddFiles = (files, position) => files.forEach(file => addPreset(file, position));
- const handleDropFiles = e => handleAddFiles(e.detail.resources, mapScreenEventToImagePoint(e.detail.event));
- //
- // Zoom
- //
- // const handleWheel = (e) => {
- // // don't run default actions, prevent other actions from running
- // e.preventDefault();
- // e.stopPropagation();
- // // convert wheel delta to scalar
- // const delta = getWheelDelta(e);
- // const scalar = 1 + (delta / 100);
- // // update image zoom
- // imagePresentationScale.update(v => v * scalar)
- // }
- // on:wheel|nonpassive={handleWheel}
- //
- // History
- //
- const handleMarkupUpdate = () => history.write();
- // used to fire ping events from
- let pingHub;
- //
- // Footer style
- //
- const footerOffset = spring($animation ? 20 : 0);
- component_subscribe($$self, footerOffset, value => $$invalidate(86, $footerOffset = value));
- function measure_handler_1(event) {
- bubble($$self, event);
- }
- const func = option => option[0] === toolActive;
- const func_1 = shape => {
- ping("addshape", shape);
- handleMarkupUpdate();
- };
- const func_2 = shape => {
- ping("selectshape", shape);
- };
- const func_3 = shape => {
- ping("updateshape", shape);
- handleMarkupUpdate();
- };
- const func_4 = shape => {
- ping("removeshape", shape);
- handleMarkupUpdate();
- };
- function shapelayouteditor_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- markupEditor = $$value;
- $$invalidate(29, markupEditor);
- });
- }
- function shapelayouteditor_markup_binding(value) {
- $shapes = value;
- shapes.set($shapes);
- }
- function shapelayouteditor_ui_binding(value) {
- $imageOverlayMarkup = value;
- imageOverlayMarkup.set($imageOverlayMarkup);
- }
- function div_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- pingHub = $$value;
- $$invalidate(20, pingHub);
- });
- }
- function measure_handler(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("isActive" in $$props) $$subscribe_isActive($$invalidate(1, isActive = $$props.isActive));
- if ("isActiveFraction" in $$props) $$subscribe_isActiveFraction($$invalidate(2, isActiveFraction = $$props.isActiveFraction));
- if ("isVisible" in $$props) $$subscribe_isVisible($$invalidate(3, isVisible = $$props.isVisible));
- if ("stores" in $$props) $$invalidate(66, stores = $$props.stores);
- if ("locale" in $$props) $$invalidate(4, locale = $$props.locale);
- if ("shapes" in $$props) $$subscribe_shapes($$invalidate(5, shapes = $$props.shapes));
- if ("tools" in $$props) $$invalidate(67, tools = $$props.tools);
- if ("toolShapes" in $$props) $$invalidate(68, toolShapes = $$props.toolShapes);
- if ("toolActive" in $$props) $$invalidate(0, toolActive = $$props.toolActive);
- if ("toolSelectRadius" in $$props) $$invalidate(6, toolSelectRadius = $$props.toolSelectRadius);
- if ("shapeControls" in $$props) $$invalidate(7, shapeControls = $$props.shapeControls);
- if ("enableButtonFlipVertical" in $$props) $$invalidate(8, enableButtonFlipVertical = $$props.enableButtonFlipVertical);
- if ("enablePresetSelectImage" in $$props) $$invalidate(9, enablePresetSelectImage = $$props.enablePresetSelectImage);
- if ("enablePresetDropImage" in $$props) $$invalidate(10, enablePresetDropImage = $$props.enablePresetDropImage);
- if ("enableSelectToolToAddShape" in $$props) $$invalidate(69, enableSelectToolToAddShape = $$props.enableSelectToolToAddShape);
- if ("enableTapToAddText" in $$props) $$invalidate(11, enableTapToAddText = $$props.enableTapToAddText);
- if ("willRenderPresetToolbar" in $$props) $$invalidate(70, willRenderPresetToolbar = $$props.willRenderPresetToolbar);
- if ("shapePresets" in $$props) $$invalidate(12, shapePresets = $$props.shapePresets);
- if ("utilKey" in $$props) $$invalidate(13, utilKey = $$props.utilKey);
- if ("mapScreenPointToImagePoint" in $$props) $$invalidate(14, mapScreenPointToImagePoint = $$props.mapScreenPointToImagePoint);
- if ("mapImagePointToScreenPoint" in $$props) $$invalidate(15, mapImagePointToScreenPoint = $$props.mapImagePointToScreenPoint);
- if ("imageRotation" in $$props) $$invalidate(16, imageRotation = $$props.imageRotation);
- if ("imageFlipX" in $$props) $$invalidate(17, imageFlipX = $$props.imageFlipX);
- if ("imageFlipY" in $$props) $$invalidate(18, imageFlipY = $$props.imageFlipY);
- if ("parentRect" in $$props) $$subscribe_parentRect($$invalidate(19, parentRect = $$props.parentRect));
- if ("hooks" in $$props) $$invalidate(71, hooks = $$props.hooks);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*shapePresets*/ 4096 | $$self.$$.dirty[2] & /*tools*/ 32) {
- // remove presets tool if no shape presets defined
- $$invalidate(21, toolsFiltered = shapePresets.length === 0
- ? tools.filter(tool => tool[0] !== "preset")
- : tools);
- }
- if ($$self.$$.dirty[0] & /*shapeControls*/ 128) {
- $$invalidate(73, hasShapeControls = Object.keys(shapeControls).length);
- }
- if ($$self.$$.dirty[0] & /*toolsFiltered*/ 2097152) {
- $$invalidate(22, showToolbar = toolsFiltered.length > 1);
- }
- if ($$self.$$.dirty[0] & /*toolsFiltered*/ 2097152) {
- $$invalidate(74, hasTools = !!toolsFiltered.length);
- }
- if ($$self.$$.dirty[0] & /*showToolbar, toolActive, toolsFiltered*/ 6291457) {
- // set to first tool in tools list if not defined
- if (showToolbar && toolActive === undefined) $$invalidate(0, toolActive = toolsFiltered[0][0]);
- }
- if ($$self.$$.dirty[0] & /*toolActive*/ 1) {
- $$invalidate(75, hasActiveTool = toolActive !== undefined);
- }
- if ($$self.$$.dirty[2] & /*hasActiveTool, hasTools, hasShapeControls*/ 14336) {
- $$invalidate(30, shouldRenderControls = (!hasActiveTool || hasTools) && hasShapeControls);
- }
- if ($$self.$$.dirty[0] & /*$isActive, utilKey*/ 16785408 | $$self.$$.dirty[2] & /*$imagePreviewModifiers*/ 16384) {
- //
- // enable seeing the markup outlines outside of the crop area
- //
- if ($isActive) {
- set_store_value(imagePreviewModifiers, $imagePreviewModifiers[utilKey] = { maskMarkupOpacity: 0.85 }, $imagePreviewModifiers);
- } else {
- delete $imagePreviewModifiers[utilKey];
- }
- }
- if ($$self.$$.dirty[0] & /*toolActive*/ 1) {
- if (toolActive) blurOnToolSwitch();
- }
- if ($$self.$$.dirty[2] & /*$isVisible*/ 65536) {
- $$invalidate(32, shouldRenderShapeEditor = $isVisible);
- }
- if ($$self.$$.dirty[0] & /*$utilRect*/ 33554432 | $$self.$$.dirty[2] & /*$stageRect*/ 131072) {
- $$invalidate(33, markupOffset = $utilRect && vectorCreate($stageRect.x - $utilRect.x, $stageRect.y - $utilRect.y));
- }
- if ($$self.$$.dirty[0] & /*shapeControls*/ 128) {
- $$invalidate(80, markupShapeKeys = Object.keys(shapeControls));
- }
- if ($$self.$$.dirty[0] & /*$shapes*/ 67108864) {
- $$invalidate(81, markupSelected = $shapes.filter(shapeIsSelected)[0]);
- }
- if ($$self.$$.dirty[0] & /*$isActive, toolActive*/ 16777217 | $$self.$$.dirty[2] & /*toolShapes*/ 64) {
- $$invalidate(82, markupToolShape = $isActive && (toolShapes[toolActive]
- ? shapeFormat(shapeDeepCopy(toolShapes[toolActive][0]))
- : {}));
- }
- if ($$self.$$.dirty[2] & /*markupToolShape, markupShapeKeys, markupToolStyles*/ 1311744) {
- $$invalidate(77, markupToolStylesComputed = markupToolShape && Object.keys(markupToolShape).reduce(
- (prev, key) => {
- const isDisableStyleProp = key === "disableStyle";
- const isStylableProp = markupShapeKeys.find(shapeKey => shapeKey.split("_").includes(key));
- // skip props that can't be styled, but keep all `disable` props
- if (!isDisableStyleProp && !isStylableProp) return prev;
- // skip props that are set to undefined, this means they won't auto-inherit current styles (line won't inherit line ends)
- if (markupToolShape[key] === undefined) return prev;
- // apply this style
- prev[key] = markupToolStyles[key] || markupToolShape[key];
- return prev;
- },
- {}
- ));
- }
- if ($$self.$$.dirty[2] & /*markupSelected, markupToolStylesComputed*/ 557056) {
- $$invalidate(27, markupShapeSelected = markupSelected || markupToolStylesComputed);
- }
- if ($$self.$$.dirty[0] & /*markupShapeSelected*/ 134217728 | $$self.$$.dirty[2] & /*$shapePreprocessor*/ 2097152) {
- // TODO: remove temporary warning while everyone switches to 8.7.0+
- if (markupShapeSelected && markupShapeSelected.lineEnd && !$shapePreprocessor) {
- console.warn(`Set shapePreprocessor property to draw lineStart and lineEnd styles.\nhttps://pqina.nl/pintura/docs/v8/api/exports/#createshapepreprocessor`);
- }
- }
- if ($$self.$$.dirty[2] & /*markupToolShape*/ 1048576) {
- $$invalidate(34, toolEraseRadius = markupToolShape && isNumber(markupToolShape.eraseRadius)
- ? markupToolShape.eraseRadius
- : undefined);
- }
- if ($$self.$$.dirty[0] & /*$isActiveFraction, toolActive, shapePresets, enablePresetSelectImage*/ 268440065) {
- //
- // presets
- //
- $$invalidate(35, shouldRenderPresets = $isActiveFraction > 0 && toolActive === "preset" && (shapePresets.length > 0 || enablePresetSelectImage));
- }
- if ($$self.$$.dirty[0] & /*$parentRect*/ 8388608) {
- // if parent rect is a `Size` we're sticking presets to the image context
- shouldStickToImage = !hasProp($parentRect, "x") && !hasProp($parentRect, "y");
- }
- if ($$self.$$.dirty[0] & /*pingHub*/ 1048576) {
- $$invalidate(36, ping = pingHub && createPingDispatcher(pingHub));
- }
- if ($$self.$$.dirty[2] & /*willRenderPresetToolbar, $env*/ 4194560) {
- //
- //
- //
- $$invalidate(38, runWillRenderPresetToolbarHook = willRenderPresetToolbar
- ? toolbar => willRenderPresetToolbar(toolbar, addPreset, { ...$env })
- : passthrough);
- }
- if ($$self.$$.dirty[2] & /*hooks*/ 512) {
- //
- // filter out beforeAdd hook
- //
- $$invalidate(39, layoutEditorHooks = Object.keys(hooks).reduce(
- (prev, curr) => {
- if (curr === "beforeAddShape") return prev;
- prev[curr] = hooks[curr];
- return prev;
- },
- {}
- ));
- }
- if ($$self.$$.dirty[0] & /*$isActive*/ 16777216 | $$self.$$.dirty[2] & /*$animation*/ 8388608) {
- $animation && footerOffset.set($isActive ? 0 : 20);
- }
- if ($$self.$$.dirty[2] & /*$footerOffset*/ 16777216) {
- $$invalidate(40, footerStyle = $footerOffset
- ? `transform: translateY(${$footerOffset}px)`
- : undefined);
- }
- };
- $$invalidate(37, computedScrollElasticity = elasticityMultiplier * scrollElasticity);
- return [
- toolActive,
- isActive,
- isActiveFraction,
- isVisible,
- locale,
- shapes,
- toolSelectRadius,
- shapeControls,
- enableButtonFlipVertical,
- enablePresetSelectImage,
- enablePresetDropImage,
- enableTapToAddText,
- shapePresets,
- utilKey,
- mapScreenPointToImagePoint,
- mapImagePointToScreenPoint,
- imageRotation,
- imageFlipX,
- imageFlipY,
- parentRect,
- pingHub,
- toolsFiltered,
- showToolbar,
- $parentRect,
- $isActive,
- $utilRect,
- $shapes,
- markupShapeSelected,
- $isActiveFraction,
- markupEditor,
- shouldRenderControls,
- $rootRect,
- shouldRenderShapeEditor,
- markupOffset,
- toolEraseRadius,
- shouldRenderPresets,
- ping,
- computedScrollElasticity,
- runWillRenderPresetToolbarHook,
- layoutEditorHooks,
- footerStyle,
- $imageOverlayMarkup,
- $presentationScalar,
- env,
- animation,
- rootRect,
- stageRect,
- utilRect,
- imageOverlayMarkup,
- imagePreviewModifiers,
- imageCropRect,
- presentationScalar,
- shapePreprocessor,
- updateActiveTool,
- handleInteractionStart,
- handleInteractionUpdate,
- handleInteractionRelease,
- handleInteractionEnd,
- handleUpdateSelectedMarkupShape,
- handleGrabPreset,
- handleDragPreset,
- handleDropPreset,
- handleAddPreset,
- handleDropFiles,
- handleMarkupUpdate,
- footerOffset,
- stores,
- tools,
- toolShapes,
- enableSelectToolToAddShape,
- willRenderPresetToolbar,
- hooks,
- markupToolStyles,
- hasShapeControls,
- hasTools,
- hasActiveTool,
- $imagePreviewModifiers,
- markupToolStylesComputed,
- $isVisible,
- $stageRect,
- markupShapeKeys,
- markupSelected,
- markupToolShape,
- $shapePreprocessor,
- $env,
- $animation,
- $footerOffset,
- measure_handler_1,
- func,
- func_1,
- func_2,
- func_3,
- func_4,
- shapelayouteditor_binding,
- shapelayouteditor_markup_binding,
- shapelayouteditor_ui_binding,
- div_binding,
- measure_handler
- ];
- }
- class ShapeUtil extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$9,
- create_fragment$9,
- safe_not_equal,
- {
- isActive: 1,
- isActiveFraction: 2,
- isVisible: 3,
- stores: 66,
- locale: 4,
- shapes: 5,
- tools: 67,
- toolShapes: 68,
- toolActive: 0,
- toolSelectRadius: 6,
- shapeControls: 7,
- enableButtonFlipVertical: 8,
- enablePresetSelectImage: 9,
- enablePresetDropImage: 10,
- enableSelectToolToAddShape: 69,
- enableTapToAddText: 11,
- willRenderPresetToolbar: 70,
- shapePresets: 12,
- utilKey: 13,
- mapScreenPointToImagePoint: 14,
- mapImagePointToScreenPoint: 15,
- imageRotation: 16,
- imageFlipX: 17,
- imageFlipY: 18,
- parentRect: 19,
- hooks: 71
- },
- [-1, -1, -1, -1]
- );
- }
- get isActive() {
- return this.$$.ctx[1];
- }
- set isActive(isActive) {
- this.$set({ isActive });
- flush();
- }
- get isActiveFraction() {
- return this.$$.ctx[2];
- }
- set isActiveFraction(isActiveFraction) {
- this.$set({ isActiveFraction });
- flush();
- }
- get isVisible() {
- return this.$$.ctx[3];
- }
- set isVisible(isVisible) {
- this.$set({ isVisible });
- flush();
- }
- get stores() {
- return this.$$.ctx[66];
- }
- set stores(stores) {
- this.$set({ stores });
- flush();
- }
- get locale() {
- return this.$$.ctx[4];
- }
- set locale(locale) {
- this.$set({ locale });
- flush();
- }
- get shapes() {
- return this.$$.ctx[5];
- }
- set shapes(shapes) {
- this.$set({ shapes });
- flush();
- }
- get tools() {
- return this.$$.ctx[67];
- }
- set tools(tools) {
- this.$set({ tools });
- flush();
- }
- get toolShapes() {
- return this.$$.ctx[68];
- }
- set toolShapes(toolShapes) {
- this.$set({ toolShapes });
- flush();
- }
- get toolActive() {
- return this.$$.ctx[0];
- }
- set toolActive(toolActive) {
- this.$set({ toolActive });
- flush();
- }
- get toolSelectRadius() {
- return this.$$.ctx[6];
- }
- set toolSelectRadius(toolSelectRadius) {
- this.$set({ toolSelectRadius });
- flush();
- }
- get shapeControls() {
- return this.$$.ctx[7];
- }
- set shapeControls(shapeControls) {
- this.$set({ shapeControls });
- flush();
- }
- get enableButtonFlipVertical() {
- return this.$$.ctx[8];
- }
- set enableButtonFlipVertical(enableButtonFlipVertical) {
- this.$set({ enableButtonFlipVertical });
- flush();
- }
- get enablePresetSelectImage() {
- return this.$$.ctx[9];
- }
- set enablePresetSelectImage(enablePresetSelectImage) {
- this.$set({ enablePresetSelectImage });
- flush();
- }
- get enablePresetDropImage() {
- return this.$$.ctx[10];
- }
- set enablePresetDropImage(enablePresetDropImage) {
- this.$set({ enablePresetDropImage });
- flush();
- }
- get enableSelectToolToAddShape() {
- return this.$$.ctx[69];
- }
- set enableSelectToolToAddShape(enableSelectToolToAddShape) {
- this.$set({ enableSelectToolToAddShape });
- flush();
- }
- get enableTapToAddText() {
- return this.$$.ctx[11];
- }
- set enableTapToAddText(enableTapToAddText) {
- this.$set({ enableTapToAddText });
- flush();
- }
- get willRenderPresetToolbar() {
- return this.$$.ctx[70];
- }
- set willRenderPresetToolbar(willRenderPresetToolbar) {
- this.$set({ willRenderPresetToolbar });
- flush();
- }
- get shapePresets() {
- return this.$$.ctx[12];
- }
- set shapePresets(shapePresets) {
- this.$set({ shapePresets });
- flush();
- }
- get utilKey() {
- return this.$$.ctx[13];
- }
- set utilKey(utilKey) {
- this.$set({ utilKey });
- flush();
- }
- get mapScreenPointToImagePoint() {
- return this.$$.ctx[14];
- }
- set mapScreenPointToImagePoint(mapScreenPointToImagePoint) {
- this.$set({ mapScreenPointToImagePoint });
- flush();
- }
- get mapImagePointToScreenPoint() {
- return this.$$.ctx[15];
- }
- set mapImagePointToScreenPoint(mapImagePointToScreenPoint) {
- this.$set({ mapImagePointToScreenPoint });
- flush();
- }
- get imageRotation() {
- return this.$$.ctx[16];
- }
- set imageRotation(imageRotation) {
- this.$set({ imageRotation });
- flush();
- }
- get imageFlipX() {
- return this.$$.ctx[17];
- }
- set imageFlipX(imageFlipX) {
- this.$set({ imageFlipX });
- flush();
- }
- get imageFlipY() {
- return this.$$.ctx[18];
- }
- set imageFlipY(imageFlipY) {
- this.$set({ imageFlipY });
- flush();
- }
- get parentRect() {
- return this.$$.ctx[19];
- }
- set parentRect(parentRect) {
- this.$set({ parentRect });
- flush();
- }
- get hooks() {
- return this.$$.ctx[71];
- }
- set hooks(hooks) {
- this.$set({ hooks });
- flush();
- }
- }
- var _mapImagePointToScreenPoint = (imagePoint, canvasSize, imageSize, imageOrigin, imageTranslation, imageRotation, imageScalar, imageFlipX, imageFlipY) => {
- const mappedPoint = vectorClone(imagePoint);
- const imageCenterX = imageSize.width * 0.5;
- const imageCenterY = imageSize.height * 0.5;
- const canvasCenterX = canvasSize.width * 0.5;
- const canvasCenterY = canvasSize.height * 0.5;
- const imageOffsetX = imageTranslation.x + imageOrigin.x;
- const imageOffsetY = imageTranslation.y + imageOrigin.y;
- if (imageFlipX)
- mappedPoint.x = imageSize.width - mappedPoint.x;
- if (imageFlipY)
- mappedPoint.y = imageSize.height - mappedPoint.y;
- // rotate around image center based on if image is rotated
- const c = Math.cos(imageRotation);
- const s = Math.sin(imageRotation);
- mappedPoint.x -= imageCenterX;
- mappedPoint.y -= imageCenterY;
- const rx = mappedPoint.x * c - mappedPoint.y * s;
- const ry = mappedPoint.x * s + mappedPoint.y * c;
- mappedPoint.x = imageCenterX + rx;
- mappedPoint.y = imageCenterY + ry;
- // position based on screen transforms
- mappedPoint.x *= imageScalar;
- mappedPoint.y *= imageScalar;
- mappedPoint.x += canvasCenterX;
- mappedPoint.y += canvasCenterY;
- mappedPoint.x += imageOffsetX;
- mappedPoint.y += imageOffsetY;
- mappedPoint.x -= imageCenterX * imageScalar;
- mappedPoint.y -= imageCenterY * imageScalar;
- const tx = (imageTranslation.x - imageOffsetX) * imageScalar;
- const ty = (imageTranslation.y - imageOffsetY) * imageScalar;
- const rtx = tx * c - ty * s;
- const rty = tx * s + ty * c;
- mappedPoint.x += rtx;
- mappedPoint.y += rty;
- return mappedPoint;
- };
- var _mapScreenPointToImagePoint = (screenPoint, canvasSize, imageSize, imageOrigin, imageTranslation, imageRotation, imageScalar, imageFlipX, imageFlipY) => {
- const mappedPoint = vectorClone(screenPoint);
- const imageCenter = sizeCenter(imageSize);
- const canvasCenter = sizeCenter(canvasSize);
- const imageOffset = vectorCreate(imageTranslation.x + imageOrigin.x, imageTranslation.y + imageOrigin.y);
- const c = Math.cos(imageRotation);
- const s = Math.sin(imageRotation);
- mappedPoint.x -= canvasCenter.x;
- mappedPoint.y -= canvasCenter.y;
- const tx = (imageTranslation.x - imageOffset.x) * imageScalar;
- const ty = (imageTranslation.y - imageOffset.y) * imageScalar;
- const rtx = tx * c - ty * s;
- const rty = tx * s + ty * c;
- mappedPoint.x -= rtx;
- mappedPoint.y -= rty;
- mappedPoint.x -= imageOffset.x;
- mappedPoint.y -= imageOffset.y;
- mappedPoint.x /= imageScalar;
- mappedPoint.y /= imageScalar;
- const rx = mappedPoint.x * c + mappedPoint.y * s;
- const ry = mappedPoint.x * s - mappedPoint.y * c;
- mappedPoint.x = rx;
- mappedPoint.y = -ry;
- mappedPoint.x += imageCenter.x;
- mappedPoint.y += imageCenter.y;
- if (imageFlipX)
- mappedPoint.x = imageSize.width - mappedPoint.x;
- if (imageFlipY)
- mappedPoint.y = imageSize.height - mappedPoint.y;
- return mappedPoint;
- };
- /* src/core/ui/plugins/annotate/index.svelte generated by Svelte v3.37.0 */
- function create_fragment$8(ctx) {
- let shapeutil;
- let updating_toolActive;
- let current;
- function shapeutil_toolActive_binding(value) {
- /*shapeutil_toolActive_binding*/ ctx[39](value);
- }
- let shapeutil_props = {
- stores: /*stores*/ ctx[4],
- locale: /*locale*/ ctx[5],
- isActive: /*isActive*/ ctx[1],
- isActiveFraction: /*isActiveFraction*/ ctx[2],
- isVisible: /*isVisible*/ ctx[3],
- mapScreenPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[36],
- mapImagePointToScreenPoint: /*mapImagePointToScreenPoint*/ ctx[37],
- utilKey: "annotate",
- imageRotation: /*$imageRotation*/ ctx[28],
- imageFlipX: /*$imageFlipX*/ ctx[26],
- imageFlipY: /*$imageFlipY*/ ctx[27],
- shapes: /*imageAnnotation*/ ctx[30],
- tools: /*annotateTools*/ ctx[11] || /*markupEditorToolbar*/ ctx[6],
- toolShapes: /*annotateToolShapes*/ ctx[12] || /*markupEditorToolStyles*/ ctx[7],
- enableSelectToolToAddShape: /*enableSelectToolToAddShape*/ ctx[18],
- enableTapToAddText: /*enableTapToAddText*/ ctx[19],
- shapeControls: /*annotateShapeControls*/ ctx[13] || /*markupEditorShapeStyleControls*/ ctx[8],
- shapePresets: /*annotatePresets*/ ctx[16],
- enableButtonFlipVertical: /*annotateEnableButtonFlipVertical*/ ctx[14],
- parentRect: /*imageSize*/ ctx[31],
- enablePresetSelectImage: /*annotateEnableSelectImagePreset*/ ctx[15],
- toolSelectRadius: /*markupEditorToolSelectRadius*/ ctx[9],
- willRenderPresetToolbar: /*annotateWillRenderShapePresetToolbar*/ ctx[17] || /*willRenderShapePresetToolbar*/ ctx[10],
- hooks: {
- willRenderShapeControls: /*willRenderShapeControls*/ ctx[20],
- beforeAddShape: /*beforeAddShape*/ ctx[21],
- beforeRemoveShape: /*beforeRemoveShape*/ ctx[22],
- beforeDeselectShape: /*beforeDeselectShape*/ ctx[23],
- beforeSelectShape: /*beforeSelectShape*/ ctx[24],
- beforeUpdateShape: /*beforeUpdateShape*/ ctx[25]
- }
- };
- if (/*annotateActiveTool*/ ctx[0] !== void 0) {
- shapeutil_props.toolActive = /*annotateActiveTool*/ ctx[0];
- }
- shapeutil = new ShapeUtil({ props: shapeutil_props });
- binding_callbacks.push(() => bind(shapeutil, "toolActive", shapeutil_toolActive_binding));
- shapeutil.$on("measure", /*measure_handler*/ ctx[40]);
- return {
- c() {
- create_component(shapeutil.$$.fragment);
- },
- m(target, anchor) {
- mount_component(shapeutil, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const shapeutil_changes = {};
- if (dirty[0] & /*stores*/ 16) shapeutil_changes.stores = /*stores*/ ctx[4];
- if (dirty[0] & /*locale*/ 32) shapeutil_changes.locale = /*locale*/ ctx[5];
- if (dirty[0] & /*isActive*/ 2) shapeutil_changes.isActive = /*isActive*/ ctx[1];
- if (dirty[0] & /*isActiveFraction*/ 4) shapeutil_changes.isActiveFraction = /*isActiveFraction*/ ctx[2];
- if (dirty[0] & /*isVisible*/ 8) shapeutil_changes.isVisible = /*isVisible*/ ctx[3];
- if (dirty[0] & /*$imageRotation*/ 268435456) shapeutil_changes.imageRotation = /*$imageRotation*/ ctx[28];
- if (dirty[0] & /*$imageFlipX*/ 67108864) shapeutil_changes.imageFlipX = /*$imageFlipX*/ ctx[26];
- if (dirty[0] & /*$imageFlipY*/ 134217728) shapeutil_changes.imageFlipY = /*$imageFlipY*/ ctx[27];
- if (dirty[0] & /*annotateTools, markupEditorToolbar*/ 2112) shapeutil_changes.tools = /*annotateTools*/ ctx[11] || /*markupEditorToolbar*/ ctx[6];
- if (dirty[0] & /*annotateToolShapes, markupEditorToolStyles*/ 4224) shapeutil_changes.toolShapes = /*annotateToolShapes*/ ctx[12] || /*markupEditorToolStyles*/ ctx[7];
- if (dirty[0] & /*enableSelectToolToAddShape*/ 262144) shapeutil_changes.enableSelectToolToAddShape = /*enableSelectToolToAddShape*/ ctx[18];
- if (dirty[0] & /*enableTapToAddText*/ 524288) shapeutil_changes.enableTapToAddText = /*enableTapToAddText*/ ctx[19];
- if (dirty[0] & /*annotateShapeControls, markupEditorShapeStyleControls*/ 8448) shapeutil_changes.shapeControls = /*annotateShapeControls*/ ctx[13] || /*markupEditorShapeStyleControls*/ ctx[8];
- if (dirty[0] & /*annotatePresets*/ 65536) shapeutil_changes.shapePresets = /*annotatePresets*/ ctx[16];
- if (dirty[0] & /*annotateEnableButtonFlipVertical*/ 16384) shapeutil_changes.enableButtonFlipVertical = /*annotateEnableButtonFlipVertical*/ ctx[14];
- if (dirty[0] & /*annotateEnableSelectImagePreset*/ 32768) shapeutil_changes.enablePresetSelectImage = /*annotateEnableSelectImagePreset*/ ctx[15];
- if (dirty[0] & /*markupEditorToolSelectRadius*/ 512) shapeutil_changes.toolSelectRadius = /*markupEditorToolSelectRadius*/ ctx[9];
- if (dirty[0] & /*annotateWillRenderShapePresetToolbar, willRenderShapePresetToolbar*/ 132096) shapeutil_changes.willRenderPresetToolbar = /*annotateWillRenderShapePresetToolbar*/ ctx[17] || /*willRenderShapePresetToolbar*/ ctx[10];
- if (dirty[0] & /*willRenderShapeControls, beforeAddShape, beforeRemoveShape, beforeDeselectShape, beforeSelectShape, beforeUpdateShape*/ 66060288) shapeutil_changes.hooks = {
- willRenderShapeControls: /*willRenderShapeControls*/ ctx[20],
- beforeAddShape: /*beforeAddShape*/ ctx[21],
- beforeRemoveShape: /*beforeRemoveShape*/ ctx[22],
- beforeDeselectShape: /*beforeDeselectShape*/ ctx[23],
- beforeSelectShape: /*beforeSelectShape*/ ctx[24],
- beforeUpdateShape: /*beforeUpdateShape*/ ctx[25]
- };
- if (!updating_toolActive && dirty[0] & /*annotateActiveTool*/ 1) {
- updating_toolActive = true;
- shapeutil_changes.toolActive = /*annotateActiveTool*/ ctx[0];
- add_flush_callback(() => updating_toolActive = false);
- }
- shapeutil.$set(shapeutil_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapeutil.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapeutil.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(shapeutil, detaching);
- }
- };
- }
- function instance$8($$self, $$props, $$invalidate) {
- let $rootRect;
- let $imageSize;
- let $imageTransforms;
- let $imageFlipX;
- let $imageFlipY;
- let $imageRotation;
- const name = "annotate";
- let { isActive } = $$props;
- let { isActiveFraction } = $$props;
- let { isVisible } = $$props;
- let { stores } = $$props;
- let { locale = {} } = $$props;
- let { markupEditorToolbar = undefined } = $$props;
- let { markupEditorToolStyles = undefined } = $$props;
- let { markupEditorShapeStyleControls = undefined } = $$props;
- let { markupEditorToolSelectRadius = undefined } = $$props;
- let { willRenderShapePresetToolbar = undefined } = $$props;
- let { annotateTools = undefined } = $$props;
- let { annotateToolShapes = undefined } = $$props;
- let { annotateShapeControls = undefined } = $$props;
- let { annotateActiveTool = undefined } = $$props;
- let { annotateEnableButtonFlipVertical = false } = $$props;
- let { annotateEnableSelectImagePreset = false } = $$props;
- let { annotatePresets = [] } = $$props;
- let { annotateWillRenderShapePresetToolbar = undefined } = $$props;
- let { enableSelectToolToAddShape = undefined } = $$props;
- let { enableTapToAddText = undefined } = $$props;
- let { willRenderShapeControls = undefined } = $$props;
- let { beforeAddShape = undefined } = $$props;
- let { beforeRemoveShape = undefined } = $$props;
- let { beforeDeselectShape = undefined } = $$props;
- let { beforeSelectShape = undefined } = $$props;
- let { beforeUpdateShape = undefined } = $$props;
- // connect filter choice to stores
- const { rootRect, imageAnnotation, imageSize, imageTransforms, imageRotation, imageFlipX, imageFlipY } = stores;
- component_subscribe($$self, rootRect, value => $$invalidate(41, $rootRect = value));
- component_subscribe($$self, imageSize, value => $$invalidate(42, $imageSize = value));
- component_subscribe($$self, imageTransforms, value => $$invalidate(43, $imageTransforms = value));
- component_subscribe($$self, imageRotation, value => $$invalidate(28, $imageRotation = value));
- component_subscribe($$self, imageFlipX, value => $$invalidate(26, $imageFlipX = value));
- component_subscribe($$self, imageFlipY, value => $$invalidate(27, $imageFlipY = value));
- //
- // Mapping coordinates
- //
- const mapScreenPointToImagePoint = point => _mapScreenPointToImagePoint(point, $rootRect, $imageSize, $imageTransforms.origin, $imageTransforms.translation, $imageTransforms.rotation.z, $imageTransforms.scale, $imageFlipX, $imageFlipY);
- const mapImagePointToScreenPoint = point => _mapImagePointToScreenPoint(point, $rootRect, $imageSize, $imageTransforms.origin, $imageTransforms.translation, $imageTransforms.rotation.z, $imageTransforms.scale, $imageFlipX, $imageFlipY);
- function shapeutil_toolActive_binding(value) {
- annotateActiveTool = value;
- $$invalidate(0, annotateActiveTool);
- }
- function measure_handler(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("isActive" in $$props) $$invalidate(1, isActive = $$props.isActive);
- if ("isActiveFraction" in $$props) $$invalidate(2, isActiveFraction = $$props.isActiveFraction);
- if ("isVisible" in $$props) $$invalidate(3, isVisible = $$props.isVisible);
- if ("stores" in $$props) $$invalidate(4, stores = $$props.stores);
- if ("locale" in $$props) $$invalidate(5, locale = $$props.locale);
- if ("markupEditorToolbar" in $$props) $$invalidate(6, markupEditorToolbar = $$props.markupEditorToolbar);
- if ("markupEditorToolStyles" in $$props) $$invalidate(7, markupEditorToolStyles = $$props.markupEditorToolStyles);
- if ("markupEditorShapeStyleControls" in $$props) $$invalidate(8, markupEditorShapeStyleControls = $$props.markupEditorShapeStyleControls);
- if ("markupEditorToolSelectRadius" in $$props) $$invalidate(9, markupEditorToolSelectRadius = $$props.markupEditorToolSelectRadius);
- if ("willRenderShapePresetToolbar" in $$props) $$invalidate(10, willRenderShapePresetToolbar = $$props.willRenderShapePresetToolbar);
- if ("annotateTools" in $$props) $$invalidate(11, annotateTools = $$props.annotateTools);
- if ("annotateToolShapes" in $$props) $$invalidate(12, annotateToolShapes = $$props.annotateToolShapes);
- if ("annotateShapeControls" in $$props) $$invalidate(13, annotateShapeControls = $$props.annotateShapeControls);
- if ("annotateActiveTool" in $$props) $$invalidate(0, annotateActiveTool = $$props.annotateActiveTool);
- if ("annotateEnableButtonFlipVertical" in $$props) $$invalidate(14, annotateEnableButtonFlipVertical = $$props.annotateEnableButtonFlipVertical);
- if ("annotateEnableSelectImagePreset" in $$props) $$invalidate(15, annotateEnableSelectImagePreset = $$props.annotateEnableSelectImagePreset);
- if ("annotatePresets" in $$props) $$invalidate(16, annotatePresets = $$props.annotatePresets);
- if ("annotateWillRenderShapePresetToolbar" in $$props) $$invalidate(17, annotateWillRenderShapePresetToolbar = $$props.annotateWillRenderShapePresetToolbar);
- if ("enableSelectToolToAddShape" in $$props) $$invalidate(18, enableSelectToolToAddShape = $$props.enableSelectToolToAddShape);
- if ("enableTapToAddText" in $$props) $$invalidate(19, enableTapToAddText = $$props.enableTapToAddText);
- if ("willRenderShapeControls" in $$props) $$invalidate(20, willRenderShapeControls = $$props.willRenderShapeControls);
- if ("beforeAddShape" in $$props) $$invalidate(21, beforeAddShape = $$props.beforeAddShape);
- if ("beforeRemoveShape" in $$props) $$invalidate(22, beforeRemoveShape = $$props.beforeRemoveShape);
- if ("beforeDeselectShape" in $$props) $$invalidate(23, beforeDeselectShape = $$props.beforeDeselectShape);
- if ("beforeSelectShape" in $$props) $$invalidate(24, beforeSelectShape = $$props.beforeSelectShape);
- if ("beforeUpdateShape" in $$props) $$invalidate(25, beforeUpdateShape = $$props.beforeUpdateShape);
- };
- return [
- annotateActiveTool,
- isActive,
- isActiveFraction,
- isVisible,
- stores,
- locale,
- markupEditorToolbar,
- markupEditorToolStyles,
- markupEditorShapeStyleControls,
- markupEditorToolSelectRadius,
- willRenderShapePresetToolbar,
- annotateTools,
- annotateToolShapes,
- annotateShapeControls,
- annotateEnableButtonFlipVertical,
- annotateEnableSelectImagePreset,
- annotatePresets,
- annotateWillRenderShapePresetToolbar,
- enableSelectToolToAddShape,
- enableTapToAddText,
- willRenderShapeControls,
- beforeAddShape,
- beforeRemoveShape,
- beforeDeselectShape,
- beforeSelectShape,
- beforeUpdateShape,
- $imageFlipX,
- $imageFlipY,
- $imageRotation,
- rootRect,
- imageAnnotation,
- imageSize,
- imageTransforms,
- imageRotation,
- imageFlipX,
- imageFlipY,
- mapScreenPointToImagePoint,
- mapImagePointToScreenPoint,
- name,
- shapeutil_toolActive_binding,
- measure_handler
- ];
- }
- class Annotate extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$8,
- create_fragment$8,
- safe_not_equal,
- {
- name: 38,
- isActive: 1,
- isActiveFraction: 2,
- isVisible: 3,
- stores: 4,
- locale: 5,
- markupEditorToolbar: 6,
- markupEditorToolStyles: 7,
- markupEditorShapeStyleControls: 8,
- markupEditorToolSelectRadius: 9,
- willRenderShapePresetToolbar: 10,
- annotateTools: 11,
- annotateToolShapes: 12,
- annotateShapeControls: 13,
- annotateActiveTool: 0,
- annotateEnableButtonFlipVertical: 14,
- annotateEnableSelectImagePreset: 15,
- annotatePresets: 16,
- annotateWillRenderShapePresetToolbar: 17,
- enableSelectToolToAddShape: 18,
- enableTapToAddText: 19,
- willRenderShapeControls: 20,
- beforeAddShape: 21,
- beforeRemoveShape: 22,
- beforeDeselectShape: 23,
- beforeSelectShape: 24,
- beforeUpdateShape: 25
- },
- [-1, -1]
- );
- }
- get name() {
- return this.$$.ctx[38];
- }
- get isActive() {
- return this.$$.ctx[1];
- }
- set isActive(isActive) {
- this.$set({ isActive });
- flush();
- }
- get isActiveFraction() {
- return this.$$.ctx[2];
- }
- set isActiveFraction(isActiveFraction) {
- this.$set({ isActiveFraction });
- flush();
- }
- get isVisible() {
- return this.$$.ctx[3];
- }
- set isVisible(isVisible) {
- this.$set({ isVisible });
- flush();
- }
- get stores() {
- return this.$$.ctx[4];
- }
- set stores(stores) {
- this.$set({ stores });
- flush();
- }
- get locale() {
- return this.$$.ctx[5];
- }
- set locale(locale) {
- this.$set({ locale });
- flush();
- }
- get markupEditorToolbar() {
- return this.$$.ctx[6];
- }
- set markupEditorToolbar(markupEditorToolbar) {
- this.$set({ markupEditorToolbar });
- flush();
- }
- get markupEditorToolStyles() {
- return this.$$.ctx[7];
- }
- set markupEditorToolStyles(markupEditorToolStyles) {
- this.$set({ markupEditorToolStyles });
- flush();
- }
- get markupEditorShapeStyleControls() {
- return this.$$.ctx[8];
- }
- set markupEditorShapeStyleControls(markupEditorShapeStyleControls) {
- this.$set({ markupEditorShapeStyleControls });
- flush();
- }
- get markupEditorToolSelectRadius() {
- return this.$$.ctx[9];
- }
- set markupEditorToolSelectRadius(markupEditorToolSelectRadius) {
- this.$set({ markupEditorToolSelectRadius });
- flush();
- }
- get willRenderShapePresetToolbar() {
- return this.$$.ctx[10];
- }
- set willRenderShapePresetToolbar(willRenderShapePresetToolbar) {
- this.$set({ willRenderShapePresetToolbar });
- flush();
- }
- get annotateTools() {
- return this.$$.ctx[11];
- }
- set annotateTools(annotateTools) {
- this.$set({ annotateTools });
- flush();
- }
- get annotateToolShapes() {
- return this.$$.ctx[12];
- }
- set annotateToolShapes(annotateToolShapes) {
- this.$set({ annotateToolShapes });
- flush();
- }
- get annotateShapeControls() {
- return this.$$.ctx[13];
- }
- set annotateShapeControls(annotateShapeControls) {
- this.$set({ annotateShapeControls });
- flush();
- }
- get annotateActiveTool() {
- return this.$$.ctx[0];
- }
- set annotateActiveTool(annotateActiveTool) {
- this.$set({ annotateActiveTool });
- flush();
- }
- get annotateEnableButtonFlipVertical() {
- return this.$$.ctx[14];
- }
- set annotateEnableButtonFlipVertical(annotateEnableButtonFlipVertical) {
- this.$set({ annotateEnableButtonFlipVertical });
- flush();
- }
- get annotateEnableSelectImagePreset() {
- return this.$$.ctx[15];
- }
- set annotateEnableSelectImagePreset(annotateEnableSelectImagePreset) {
- this.$set({ annotateEnableSelectImagePreset });
- flush();
- }
- get annotatePresets() {
- return this.$$.ctx[16];
- }
- set annotatePresets(annotatePresets) {
- this.$set({ annotatePresets });
- flush();
- }
- get annotateWillRenderShapePresetToolbar() {
- return this.$$.ctx[17];
- }
- set annotateWillRenderShapePresetToolbar(annotateWillRenderShapePresetToolbar) {
- this.$set({ annotateWillRenderShapePresetToolbar });
- flush();
- }
- get enableSelectToolToAddShape() {
- return this.$$.ctx[18];
- }
- set enableSelectToolToAddShape(enableSelectToolToAddShape) {
- this.$set({ enableSelectToolToAddShape });
- flush();
- }
- get enableTapToAddText() {
- return this.$$.ctx[19];
- }
- set enableTapToAddText(enableTapToAddText) {
- this.$set({ enableTapToAddText });
- flush();
- }
- get willRenderShapeControls() {
- return this.$$.ctx[20];
- }
- set willRenderShapeControls(willRenderShapeControls) {
- this.$set({ willRenderShapeControls });
- flush();
- }
- get beforeAddShape() {
- return this.$$.ctx[21];
- }
- set beforeAddShape(beforeAddShape) {
- this.$set({ beforeAddShape });
- flush();
- }
- get beforeRemoveShape() {
- return this.$$.ctx[22];
- }
- set beforeRemoveShape(beforeRemoveShape) {
- this.$set({ beforeRemoveShape });
- flush();
- }
- get beforeDeselectShape() {
- return this.$$.ctx[23];
- }
- set beforeDeselectShape(beforeDeselectShape) {
- this.$set({ beforeDeselectShape });
- flush();
- }
- get beforeSelectShape() {
- return this.$$.ctx[24];
- }
- set beforeSelectShape(beforeSelectShape) {
- this.$set({ beforeSelectShape });
- flush();
- }
- get beforeUpdateShape() {
- return this.$$.ctx[25];
- }
- set beforeUpdateShape(beforeUpdateShape) {
- this.$set({ beforeUpdateShape });
- flush();
- }
- }
- // @ts-ignore
- var _plugin_annotate = { util: ['annotate', Annotate] };
- /* src/core/ui/plugins/decorate/index.svelte generated by Svelte v3.37.0 */
- function create_fragment$7(ctx) {
- let shapeutil;
- let updating_toolActive;
- let current;
- function shapeutil_toolActive_binding(value) {
- /*shapeutil_toolActive_binding*/ ctx[33](value);
- }
- let shapeutil_props = {
- stores: /*stores*/ ctx[4],
- locale: /*locale*/ ctx[5],
- isActive: /*isActive*/ ctx[1],
- isActiveFraction: /*isActiveFraction*/ ctx[2],
- isVisible: /*isVisible*/ ctx[3],
- mapScreenPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[30],
- mapImagePointToScreenPoint: /*mapImagePointToScreenPoint*/ ctx[31],
- utilKey: "decorate",
- shapes: /*imageDecoration*/ ctx[27],
- tools: /*decorateTools*/ ctx[11] || /*markupEditorToolbar*/ ctx[6],
- toolShapes: /*decorateToolShapes*/ ctx[12] || /*markupEditorToolStyles*/ ctx[7],
- shapeControls: /*decorateShapeControls*/ ctx[13] || /*markupEditorShapeStyleControls*/ ctx[8],
- shapePresets: /*decoratePresets*/ ctx[16],
- enableSelectToolToAddShape: /*enableSelectToolToAddShape*/ ctx[18],
- enableTapToAddText: /*enableTapToAddText*/ ctx[19],
- enablePresetSelectImage: /*decorateEnableSelectImagePreset*/ ctx[15],
- enableButtonFlipVertical: /*decorateEnableButtonFlipVertical*/ ctx[14],
- parentRect: /*imageCropRect*/ ctx[26],
- toolSelectRadius: /*markupEditorToolSelectRadius*/ ctx[9],
- willRenderPresetToolbar: /*decorateWillRenderShapePresetToolbar*/ ctx[17] || /*willRenderShapePresetToolbar*/ ctx[10],
- hooks: {
- willRenderShapeControls: /*willRenderShapeControls*/ ctx[20],
- beforeAddShape: /*beforeAddShape*/ ctx[21],
- beforeRemoveShape: /*beforeRemoveShape*/ ctx[22],
- beforeDeselectShape: /*beforeDeselectShape*/ ctx[23],
- beforeSelectShape: /*beforeSelectShape*/ ctx[24],
- beforeUpdateShape: /*beforeUpdateShape*/ ctx[25]
- }
- };
- if (/*decorateActiveTool*/ ctx[0] !== void 0) {
- shapeutil_props.toolActive = /*decorateActiveTool*/ ctx[0];
- }
- shapeutil = new ShapeUtil({ props: shapeutil_props });
- binding_callbacks.push(() => bind(shapeutil, "toolActive", shapeutil_toolActive_binding));
- shapeutil.$on("measure", /*measure_handler*/ ctx[34]);
- return {
- c() {
- create_component(shapeutil.$$.fragment);
- },
- m(target, anchor) {
- mount_component(shapeutil, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const shapeutil_changes = {};
- if (dirty[0] & /*stores*/ 16) shapeutil_changes.stores = /*stores*/ ctx[4];
- if (dirty[0] & /*locale*/ 32) shapeutil_changes.locale = /*locale*/ ctx[5];
- if (dirty[0] & /*isActive*/ 2) shapeutil_changes.isActive = /*isActive*/ ctx[1];
- if (dirty[0] & /*isActiveFraction*/ 4) shapeutil_changes.isActiveFraction = /*isActiveFraction*/ ctx[2];
- if (dirty[0] & /*isVisible*/ 8) shapeutil_changes.isVisible = /*isVisible*/ ctx[3];
- if (dirty[0] & /*decorateTools, markupEditorToolbar*/ 2112) shapeutil_changes.tools = /*decorateTools*/ ctx[11] || /*markupEditorToolbar*/ ctx[6];
- if (dirty[0] & /*decorateToolShapes, markupEditorToolStyles*/ 4224) shapeutil_changes.toolShapes = /*decorateToolShapes*/ ctx[12] || /*markupEditorToolStyles*/ ctx[7];
- if (dirty[0] & /*decorateShapeControls, markupEditorShapeStyleControls*/ 8448) shapeutil_changes.shapeControls = /*decorateShapeControls*/ ctx[13] || /*markupEditorShapeStyleControls*/ ctx[8];
- if (dirty[0] & /*decoratePresets*/ 65536) shapeutil_changes.shapePresets = /*decoratePresets*/ ctx[16];
- if (dirty[0] & /*enableSelectToolToAddShape*/ 262144) shapeutil_changes.enableSelectToolToAddShape = /*enableSelectToolToAddShape*/ ctx[18];
- if (dirty[0] & /*enableTapToAddText*/ 524288) shapeutil_changes.enableTapToAddText = /*enableTapToAddText*/ ctx[19];
- if (dirty[0] & /*decorateEnableSelectImagePreset*/ 32768) shapeutil_changes.enablePresetSelectImage = /*decorateEnableSelectImagePreset*/ ctx[15];
- if (dirty[0] & /*decorateEnableButtonFlipVertical*/ 16384) shapeutil_changes.enableButtonFlipVertical = /*decorateEnableButtonFlipVertical*/ ctx[14];
- if (dirty[0] & /*markupEditorToolSelectRadius*/ 512) shapeutil_changes.toolSelectRadius = /*markupEditorToolSelectRadius*/ ctx[9];
- if (dirty[0] & /*decorateWillRenderShapePresetToolbar, willRenderShapePresetToolbar*/ 132096) shapeutil_changes.willRenderPresetToolbar = /*decorateWillRenderShapePresetToolbar*/ ctx[17] || /*willRenderShapePresetToolbar*/ ctx[10];
- if (dirty[0] & /*willRenderShapeControls, beforeAddShape, beforeRemoveShape, beforeDeselectShape, beforeSelectShape, beforeUpdateShape*/ 66060288) shapeutil_changes.hooks = {
- willRenderShapeControls: /*willRenderShapeControls*/ ctx[20],
- beforeAddShape: /*beforeAddShape*/ ctx[21],
- beforeRemoveShape: /*beforeRemoveShape*/ ctx[22],
- beforeDeselectShape: /*beforeDeselectShape*/ ctx[23],
- beforeSelectShape: /*beforeSelectShape*/ ctx[24],
- beforeUpdateShape: /*beforeUpdateShape*/ ctx[25]
- };
- if (!updating_toolActive && dirty[0] & /*decorateActiveTool*/ 1) {
- updating_toolActive = true;
- shapeutil_changes.toolActive = /*decorateActiveTool*/ ctx[0];
- add_flush_callback(() => updating_toolActive = false);
- }
- shapeutil.$set(shapeutil_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapeutil.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapeutil.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(shapeutil, detaching);
- }
- };
- }
- function instance$7($$self, $$props, $$invalidate) {
- let $imageSelectionRectPresentation;
- let $presentationScalar;
- const name = "decorate";
- let { isActive } = $$props;
- let { isActiveFraction } = $$props;
- let { isVisible } = $$props;
- let { stores } = $$props;
- let { locale = {} } = $$props;
- let { markupEditorToolbar = undefined } = $$props;
- let { markupEditorToolStyles = undefined } = $$props;
- let { markupEditorShapeStyleControls = undefined } = $$props;
- let { markupEditorToolSelectRadius = undefined } = $$props;
- let { willRenderShapePresetToolbar = undefined } = $$props;
- let { decorateTools = undefined } = $$props;
- let { decorateToolShapes = undefined } = $$props;
- let { decorateShapeControls = undefined } = $$props;
- let { decorateActiveTool = undefined } = $$props;
- let { decorateEnableButtonFlipVertical = false } = $$props;
- let { decorateEnableSelectImagePreset = false } = $$props;
- let { decoratePresets = [] } = $$props;
- let { decorateWillRenderShapePresetToolbar = undefined } = $$props;
- let { enableSelectToolToAddShape = undefined } = $$props;
- let { enableTapToAddText = undefined } = $$props;
- let { willRenderShapeControls = undefined } = $$props;
- let { beforeAddShape = undefined } = $$props;
- let { beforeRemoveShape = undefined } = $$props;
- let { beforeDeselectShape = undefined } = $$props;
- let { beforeSelectShape = undefined } = $$props;
- let { beforeUpdateShape = undefined } = $$props;
- const { imageCropRect, imageDecoration, imageSelectionRectPresentation, presentationScalar } = stores;
- component_subscribe($$self, imageSelectionRectPresentation, value => $$invalidate(35, $imageSelectionRectPresentation = value));
- component_subscribe($$self, presentationScalar, value => $$invalidate(36, $presentationScalar = value));
- const mapScreenPointToImagePoint = screenPoint => {
- const mappedPoint = vectorClone(screenPoint);
- mappedPoint.x -= $imageSelectionRectPresentation.x;
- mappedPoint.y -= $imageSelectionRectPresentation.y;
- mappedPoint.x /= $presentationScalar;
- mappedPoint.y /= $presentationScalar;
- return mappedPoint;
- };
- const mapImagePointToScreenPoint = imagePoint => {
- const mappedPoint = vectorClone(imagePoint);
- mappedPoint.x *= $presentationScalar;
- mappedPoint.y *= $presentationScalar;
- mappedPoint.x += $imageSelectionRectPresentation.x;
- mappedPoint.y += $imageSelectionRectPresentation.y;
- return mappedPoint;
- };
- function shapeutil_toolActive_binding(value) {
- decorateActiveTool = value;
- $$invalidate(0, decorateActiveTool);
- }
- function measure_handler(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("isActive" in $$props) $$invalidate(1, isActive = $$props.isActive);
- if ("isActiveFraction" in $$props) $$invalidate(2, isActiveFraction = $$props.isActiveFraction);
- if ("isVisible" in $$props) $$invalidate(3, isVisible = $$props.isVisible);
- if ("stores" in $$props) $$invalidate(4, stores = $$props.stores);
- if ("locale" in $$props) $$invalidate(5, locale = $$props.locale);
- if ("markupEditorToolbar" in $$props) $$invalidate(6, markupEditorToolbar = $$props.markupEditorToolbar);
- if ("markupEditorToolStyles" in $$props) $$invalidate(7, markupEditorToolStyles = $$props.markupEditorToolStyles);
- if ("markupEditorShapeStyleControls" in $$props) $$invalidate(8, markupEditorShapeStyleControls = $$props.markupEditorShapeStyleControls);
- if ("markupEditorToolSelectRadius" in $$props) $$invalidate(9, markupEditorToolSelectRadius = $$props.markupEditorToolSelectRadius);
- if ("willRenderShapePresetToolbar" in $$props) $$invalidate(10, willRenderShapePresetToolbar = $$props.willRenderShapePresetToolbar);
- if ("decorateTools" in $$props) $$invalidate(11, decorateTools = $$props.decorateTools);
- if ("decorateToolShapes" in $$props) $$invalidate(12, decorateToolShapes = $$props.decorateToolShapes);
- if ("decorateShapeControls" in $$props) $$invalidate(13, decorateShapeControls = $$props.decorateShapeControls);
- if ("decorateActiveTool" in $$props) $$invalidate(0, decorateActiveTool = $$props.decorateActiveTool);
- if ("decorateEnableButtonFlipVertical" in $$props) $$invalidate(14, decorateEnableButtonFlipVertical = $$props.decorateEnableButtonFlipVertical);
- if ("decorateEnableSelectImagePreset" in $$props) $$invalidate(15, decorateEnableSelectImagePreset = $$props.decorateEnableSelectImagePreset);
- if ("decoratePresets" in $$props) $$invalidate(16, decoratePresets = $$props.decoratePresets);
- if ("decorateWillRenderShapePresetToolbar" in $$props) $$invalidate(17, decorateWillRenderShapePresetToolbar = $$props.decorateWillRenderShapePresetToolbar);
- if ("enableSelectToolToAddShape" in $$props) $$invalidate(18, enableSelectToolToAddShape = $$props.enableSelectToolToAddShape);
- if ("enableTapToAddText" in $$props) $$invalidate(19, enableTapToAddText = $$props.enableTapToAddText);
- if ("willRenderShapeControls" in $$props) $$invalidate(20, willRenderShapeControls = $$props.willRenderShapeControls);
- if ("beforeAddShape" in $$props) $$invalidate(21, beforeAddShape = $$props.beforeAddShape);
- if ("beforeRemoveShape" in $$props) $$invalidate(22, beforeRemoveShape = $$props.beforeRemoveShape);
- if ("beforeDeselectShape" in $$props) $$invalidate(23, beforeDeselectShape = $$props.beforeDeselectShape);
- if ("beforeSelectShape" in $$props) $$invalidate(24, beforeSelectShape = $$props.beforeSelectShape);
- if ("beforeUpdateShape" in $$props) $$invalidate(25, beforeUpdateShape = $$props.beforeUpdateShape);
- };
- return [
- decorateActiveTool,
- isActive,
- isActiveFraction,
- isVisible,
- stores,
- locale,
- markupEditorToolbar,
- markupEditorToolStyles,
- markupEditorShapeStyleControls,
- markupEditorToolSelectRadius,
- willRenderShapePresetToolbar,
- decorateTools,
- decorateToolShapes,
- decorateShapeControls,
- decorateEnableButtonFlipVertical,
- decorateEnableSelectImagePreset,
- decoratePresets,
- decorateWillRenderShapePresetToolbar,
- enableSelectToolToAddShape,
- enableTapToAddText,
- willRenderShapeControls,
- beforeAddShape,
- beforeRemoveShape,
- beforeDeselectShape,
- beforeSelectShape,
- beforeUpdateShape,
- imageCropRect,
- imageDecoration,
- imageSelectionRectPresentation,
- presentationScalar,
- mapScreenPointToImagePoint,
- mapImagePointToScreenPoint,
- name,
- shapeutil_toolActive_binding,
- measure_handler
- ];
- }
- class Decorate extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$7,
- create_fragment$7,
- safe_not_equal,
- {
- name: 32,
- isActive: 1,
- isActiveFraction: 2,
- isVisible: 3,
- stores: 4,
- locale: 5,
- markupEditorToolbar: 6,
- markupEditorToolStyles: 7,
- markupEditorShapeStyleControls: 8,
- markupEditorToolSelectRadius: 9,
- willRenderShapePresetToolbar: 10,
- decorateTools: 11,
- decorateToolShapes: 12,
- decorateShapeControls: 13,
- decorateActiveTool: 0,
- decorateEnableButtonFlipVertical: 14,
- decorateEnableSelectImagePreset: 15,
- decoratePresets: 16,
- decorateWillRenderShapePresetToolbar: 17,
- enableSelectToolToAddShape: 18,
- enableTapToAddText: 19,
- willRenderShapeControls: 20,
- beforeAddShape: 21,
- beforeRemoveShape: 22,
- beforeDeselectShape: 23,
- beforeSelectShape: 24,
- beforeUpdateShape: 25
- },
- [-1, -1]
- );
- }
- get name() {
- return this.$$.ctx[32];
- }
- get isActive() {
- return this.$$.ctx[1];
- }
- set isActive(isActive) {
- this.$set({ isActive });
- flush();
- }
- get isActiveFraction() {
- return this.$$.ctx[2];
- }
- set isActiveFraction(isActiveFraction) {
- this.$set({ isActiveFraction });
- flush();
- }
- get isVisible() {
- return this.$$.ctx[3];
- }
- set isVisible(isVisible) {
- this.$set({ isVisible });
- flush();
- }
- get stores() {
- return this.$$.ctx[4];
- }
- set stores(stores) {
- this.$set({ stores });
- flush();
- }
- get locale() {
- return this.$$.ctx[5];
- }
- set locale(locale) {
- this.$set({ locale });
- flush();
- }
- get markupEditorToolbar() {
- return this.$$.ctx[6];
- }
- set markupEditorToolbar(markupEditorToolbar) {
- this.$set({ markupEditorToolbar });
- flush();
- }
- get markupEditorToolStyles() {
- return this.$$.ctx[7];
- }
- set markupEditorToolStyles(markupEditorToolStyles) {
- this.$set({ markupEditorToolStyles });
- flush();
- }
- get markupEditorShapeStyleControls() {
- return this.$$.ctx[8];
- }
- set markupEditorShapeStyleControls(markupEditorShapeStyleControls) {
- this.$set({ markupEditorShapeStyleControls });
- flush();
- }
- get markupEditorToolSelectRadius() {
- return this.$$.ctx[9];
- }
- set markupEditorToolSelectRadius(markupEditorToolSelectRadius) {
- this.$set({ markupEditorToolSelectRadius });
- flush();
- }
- get willRenderShapePresetToolbar() {
- return this.$$.ctx[10];
- }
- set willRenderShapePresetToolbar(willRenderShapePresetToolbar) {
- this.$set({ willRenderShapePresetToolbar });
- flush();
- }
- get decorateTools() {
- return this.$$.ctx[11];
- }
- set decorateTools(decorateTools) {
- this.$set({ decorateTools });
- flush();
- }
- get decorateToolShapes() {
- return this.$$.ctx[12];
- }
- set decorateToolShapes(decorateToolShapes) {
- this.$set({ decorateToolShapes });
- flush();
- }
- get decorateShapeControls() {
- return this.$$.ctx[13];
- }
- set decorateShapeControls(decorateShapeControls) {
- this.$set({ decorateShapeControls });
- flush();
- }
- get decorateActiveTool() {
- return this.$$.ctx[0];
- }
- set decorateActiveTool(decorateActiveTool) {
- this.$set({ decorateActiveTool });
- flush();
- }
- get decorateEnableButtonFlipVertical() {
- return this.$$.ctx[14];
- }
- set decorateEnableButtonFlipVertical(decorateEnableButtonFlipVertical) {
- this.$set({ decorateEnableButtonFlipVertical });
- flush();
- }
- get decorateEnableSelectImagePreset() {
- return this.$$.ctx[15];
- }
- set decorateEnableSelectImagePreset(decorateEnableSelectImagePreset) {
- this.$set({ decorateEnableSelectImagePreset });
- flush();
- }
- get decoratePresets() {
- return this.$$.ctx[16];
- }
- set decoratePresets(decoratePresets) {
- this.$set({ decoratePresets });
- flush();
- }
- get decorateWillRenderShapePresetToolbar() {
- return this.$$.ctx[17];
- }
- set decorateWillRenderShapePresetToolbar(decorateWillRenderShapePresetToolbar) {
- this.$set({ decorateWillRenderShapePresetToolbar });
- flush();
- }
- get enableSelectToolToAddShape() {
- return this.$$.ctx[18];
- }
- set enableSelectToolToAddShape(enableSelectToolToAddShape) {
- this.$set({ enableSelectToolToAddShape });
- flush();
- }
- get enableTapToAddText() {
- return this.$$.ctx[19];
- }
- set enableTapToAddText(enableTapToAddText) {
- this.$set({ enableTapToAddText });
- flush();
- }
- get willRenderShapeControls() {
- return this.$$.ctx[20];
- }
- set willRenderShapeControls(willRenderShapeControls) {
- this.$set({ willRenderShapeControls });
- flush();
- }
- get beforeAddShape() {
- return this.$$.ctx[21];
- }
- set beforeAddShape(beforeAddShape) {
- this.$set({ beforeAddShape });
- flush();
- }
- get beforeRemoveShape() {
- return this.$$.ctx[22];
- }
- set beforeRemoveShape(beforeRemoveShape) {
- this.$set({ beforeRemoveShape });
- flush();
- }
- get beforeDeselectShape() {
- return this.$$.ctx[23];
- }
- set beforeDeselectShape(beforeDeselectShape) {
- this.$set({ beforeDeselectShape });
- flush();
- }
- get beforeSelectShape() {
- return this.$$.ctx[24];
- }
- set beforeSelectShape(beforeSelectShape) {
- this.$set({ beforeSelectShape });
- flush();
- }
- get beforeUpdateShape() {
- return this.$$.ctx[25];
- }
- set beforeUpdateShape(beforeUpdateShape) {
- this.$set({ beforeUpdateShape });
- flush();
- }
- }
- // @ts-ignore
- var _plugin_decorate = { util: ['decorate', Decorate] };
- /* src/core/ui/plugins/sticker/index.svelte generated by Svelte v3.37.0 */
- function create_fragment$6(ctx) {
- let shapeutil;
- let current;
- shapeutil = new ShapeUtil({
- props: {
- stores: /*stores*/ ctx[3],
- locale: /*locale*/ ctx[4],
- isActive: /*isActive*/ ctx[0],
- isActiveFraction: /*isActiveFraction*/ ctx[1],
- isVisible: /*isVisible*/ ctx[2],
- mapScreenPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[32],
- mapImagePointToScreenPoint: /*mapImagePointToScreenPoint*/ ctx[33],
- utilKey: "sticker",
- shapePresets: /*stickers*/ ctx[5],
- shapes: /*stickerStickToImage*/ ctx[6]
- ? /*imageAnnotation*/ ctx[25]
- : /*imageDecoration*/ ctx[26],
- toolActive: "preset",
- imageFlipX: /*stickerStickToImage*/ ctx[6]
- ? /*$imageFlipX*/ ctx[18]
- : false,
- imageFlipY: /*stickerStickToImage*/ ctx[6]
- ? /*$imageFlipY*/ ctx[19]
- : false,
- imageRotation: /*stickerStickToImage*/ ctx[6]
- ? /*$imageRotation*/ ctx[20]
- : 0,
- parentRect: /*stickerStickToImage*/ ctx[6]
- ? /*imageSize*/ ctx[27]
- : /*imageCropRect*/ ctx[23],
- enablePresetSelectImage: /*stickerEnableSelectImage*/ ctx[7],
- enableButtonFlipVertical: /*stickersEnableButtonFlipVertical*/ ctx[8],
- toolSelectRadius: /*markupEditorToolSelectRadius*/ ctx[11],
- willRenderPresetToolbar: /*stickersWillRenderShapePresetToolbar*/ ctx[9] || /*willRenderShapePresetToolbar*/ ctx[12],
- hooks: {
- willRenderShapeControls: /*willRenderShapeControls*/ ctx[10],
- beforeAddShape: /*beforeAddShape*/ ctx[13],
- beforeRemoveShape: /*beforeRemoveShape*/ ctx[14],
- beforeDeselectShape: /*beforeDeselectShape*/ ctx[15],
- beforeSelectShape: /*beforeSelectShape*/ ctx[16],
- beforeUpdateShape: /*beforeUpdateShape*/ ctx[17]
- }
- }
- });
- shapeutil.$on("measure", /*measure_handler*/ ctx[35]);
- return {
- c() {
- create_component(shapeutil.$$.fragment);
- },
- m(target, anchor) {
- mount_component(shapeutil, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const shapeutil_changes = {};
- if (dirty[0] & /*stores*/ 8) shapeutil_changes.stores = /*stores*/ ctx[3];
- if (dirty[0] & /*locale*/ 16) shapeutil_changes.locale = /*locale*/ ctx[4];
- if (dirty[0] & /*isActive*/ 1) shapeutil_changes.isActive = /*isActive*/ ctx[0];
- if (dirty[0] & /*isActiveFraction*/ 2) shapeutil_changes.isActiveFraction = /*isActiveFraction*/ ctx[1];
- if (dirty[0] & /*isVisible*/ 4) shapeutil_changes.isVisible = /*isVisible*/ ctx[2];
- if (dirty[0] & /*stickers*/ 32) shapeutil_changes.shapePresets = /*stickers*/ ctx[5];
- if (dirty[0] & /*stickerStickToImage*/ 64) shapeutil_changes.shapes = /*stickerStickToImage*/ ctx[6]
- ? /*imageAnnotation*/ ctx[25]
- : /*imageDecoration*/ ctx[26];
- if (dirty[0] & /*stickerStickToImage, $imageFlipX*/ 262208) shapeutil_changes.imageFlipX = /*stickerStickToImage*/ ctx[6]
- ? /*$imageFlipX*/ ctx[18]
- : false;
- if (dirty[0] & /*stickerStickToImage, $imageFlipY*/ 524352) shapeutil_changes.imageFlipY = /*stickerStickToImage*/ ctx[6]
- ? /*$imageFlipY*/ ctx[19]
- : false;
- if (dirty[0] & /*stickerStickToImage, $imageRotation*/ 1048640) shapeutil_changes.imageRotation = /*stickerStickToImage*/ ctx[6]
- ? /*$imageRotation*/ ctx[20]
- : 0;
- if (dirty[0] & /*stickerStickToImage*/ 64) shapeutil_changes.parentRect = /*stickerStickToImage*/ ctx[6]
- ? /*imageSize*/ ctx[27]
- : /*imageCropRect*/ ctx[23];
- if (dirty[0] & /*stickerEnableSelectImage*/ 128) shapeutil_changes.enablePresetSelectImage = /*stickerEnableSelectImage*/ ctx[7];
- if (dirty[0] & /*stickersEnableButtonFlipVertical*/ 256) shapeutil_changes.enableButtonFlipVertical = /*stickersEnableButtonFlipVertical*/ ctx[8];
- if (dirty[0] & /*markupEditorToolSelectRadius*/ 2048) shapeutil_changes.toolSelectRadius = /*markupEditorToolSelectRadius*/ ctx[11];
- if (dirty[0] & /*stickersWillRenderShapePresetToolbar, willRenderShapePresetToolbar*/ 4608) shapeutil_changes.willRenderPresetToolbar = /*stickersWillRenderShapePresetToolbar*/ ctx[9] || /*willRenderShapePresetToolbar*/ ctx[12];
- if (dirty[0] & /*willRenderShapeControls, beforeAddShape, beforeRemoveShape, beforeDeselectShape, beforeSelectShape, beforeUpdateShape*/ 254976) shapeutil_changes.hooks = {
- willRenderShapeControls: /*willRenderShapeControls*/ ctx[10],
- beforeAddShape: /*beforeAddShape*/ ctx[13],
- beforeRemoveShape: /*beforeRemoveShape*/ ctx[14],
- beforeDeselectShape: /*beforeDeselectShape*/ ctx[15],
- beforeSelectShape: /*beforeSelectShape*/ ctx[16],
- beforeUpdateShape: /*beforeUpdateShape*/ ctx[17]
- };
- shapeutil.$set(shapeutil_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapeutil.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapeutil.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(shapeutil, detaching);
- }
- };
- }
- function instance$6($$self, $$props, $$invalidate) {
- let $rootRect;
- let $imageSize;
- let $imageTransforms;
- let $imageFlipX;
- let $imageFlipY;
- let $imageSelectionRectPresentation;
- let $presentationScalar;
- let $imageRotation;
- const name = "sticker";
- let { isActive } = $$props;
- let { isActiveFraction } = $$props;
- let { isVisible } = $$props;
- let { stores } = $$props;
- let { locale = {} } = $$props;
- let { stickers = [] } = $$props;
- let { stickerStickToImage = false } = $$props;
- let { stickerEnableSelectImage = true } = $$props;
- let { stickersEnableButtonFlipVertical = false } = $$props;
- let { stickersWillRenderShapePresetToolbar = undefined } = $$props;
- let { willRenderShapeControls = undefined } = $$props;
- let { markupEditorToolSelectRadius = undefined } = $$props;
- let { willRenderShapePresetToolbar = undefined } = $$props;
- let { beforeAddShape = undefined } = $$props;
- let { beforeRemoveShape = undefined } = $$props;
- let { beforeDeselectShape = undefined } = $$props;
- let { beforeSelectShape = undefined } = $$props;
- let { beforeUpdateShape = undefined } = $$props;
- // connect filter choice to stores
- const { presentationScalar, rootRect, imageCropRect, imageSelectionRectPresentation, imageAnnotation, imageDecoration, imageSize, imageTransforms, imageRotation, imageFlipX, imageFlipY } = stores;
- component_subscribe($$self, presentationScalar, value => $$invalidate(40, $presentationScalar = value));
- component_subscribe($$self, rootRect, value => $$invalidate(36, $rootRect = value));
- component_subscribe($$self, imageSelectionRectPresentation, value => $$invalidate(39, $imageSelectionRectPresentation = value));
- component_subscribe($$self, imageSize, value => $$invalidate(37, $imageSize = value));
- component_subscribe($$self, imageTransforms, value => $$invalidate(38, $imageTransforms = value));
- component_subscribe($$self, imageRotation, value => $$invalidate(20, $imageRotation = value));
- component_subscribe($$self, imageFlipX, value => $$invalidate(18, $imageFlipX = value));
- component_subscribe($$self, imageFlipY, value => $$invalidate(19, $imageFlipY = value));
- //
- // Mapping coordinates
- //
- const mapScreenPointToImagePoint = stickerStickToImage
- ? point => _mapScreenPointToImagePoint(point, $rootRect, $imageSize, $imageTransforms.origin, $imageTransforms.translation, $imageTransforms.rotation.z, $imageTransforms.scale, $imageFlipX, $imageFlipY)
- : point => {
- const mappedPoint = vectorClone(point);
- mappedPoint.x -= $imageSelectionRectPresentation.x;
- mappedPoint.y -= $imageSelectionRectPresentation.y;
- mappedPoint.x /= $presentationScalar;
- mappedPoint.y /= $presentationScalar;
- return mappedPoint;
- };
- const mapImagePointToScreenPoint = stickerStickToImage
- ? point => _mapImagePointToScreenPoint(point, $rootRect, $imageSize, $imageTransforms.origin, $imageTransforms.translation, $imageTransforms.rotation.z, $imageTransforms.scale, $imageFlipX, $imageFlipY)
- : point => {
- const mappedPoint = vectorClone(point);
- mappedPoint.x *= $presentationScalar;
- mappedPoint.y *= $presentationScalar;
- mappedPoint.x += $imageSelectionRectPresentation.x;
- mappedPoint.y += $imageSelectionRectPresentation.y;
- return mappedPoint;
- };
- function measure_handler(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("isActive" in $$props) $$invalidate(0, isActive = $$props.isActive);
- if ("isActiveFraction" in $$props) $$invalidate(1, isActiveFraction = $$props.isActiveFraction);
- if ("isVisible" in $$props) $$invalidate(2, isVisible = $$props.isVisible);
- if ("stores" in $$props) $$invalidate(3, stores = $$props.stores);
- if ("locale" in $$props) $$invalidate(4, locale = $$props.locale);
- if ("stickers" in $$props) $$invalidate(5, stickers = $$props.stickers);
- if ("stickerStickToImage" in $$props) $$invalidate(6, stickerStickToImage = $$props.stickerStickToImage);
- if ("stickerEnableSelectImage" in $$props) $$invalidate(7, stickerEnableSelectImage = $$props.stickerEnableSelectImage);
- if ("stickersEnableButtonFlipVertical" in $$props) $$invalidate(8, stickersEnableButtonFlipVertical = $$props.stickersEnableButtonFlipVertical);
- if ("stickersWillRenderShapePresetToolbar" in $$props) $$invalidate(9, stickersWillRenderShapePresetToolbar = $$props.stickersWillRenderShapePresetToolbar);
- if ("willRenderShapeControls" in $$props) $$invalidate(10, willRenderShapeControls = $$props.willRenderShapeControls);
- if ("markupEditorToolSelectRadius" in $$props) $$invalidate(11, markupEditorToolSelectRadius = $$props.markupEditorToolSelectRadius);
- if ("willRenderShapePresetToolbar" in $$props) $$invalidate(12, willRenderShapePresetToolbar = $$props.willRenderShapePresetToolbar);
- if ("beforeAddShape" in $$props) $$invalidate(13, beforeAddShape = $$props.beforeAddShape);
- if ("beforeRemoveShape" in $$props) $$invalidate(14, beforeRemoveShape = $$props.beforeRemoveShape);
- if ("beforeDeselectShape" in $$props) $$invalidate(15, beforeDeselectShape = $$props.beforeDeselectShape);
- if ("beforeSelectShape" in $$props) $$invalidate(16, beforeSelectShape = $$props.beforeSelectShape);
- if ("beforeUpdateShape" in $$props) $$invalidate(17, beforeUpdateShape = $$props.beforeUpdateShape);
- };
- return [
- isActive,
- isActiveFraction,
- isVisible,
- stores,
- locale,
- stickers,
- stickerStickToImage,
- stickerEnableSelectImage,
- stickersEnableButtonFlipVertical,
- stickersWillRenderShapePresetToolbar,
- willRenderShapeControls,
- markupEditorToolSelectRadius,
- willRenderShapePresetToolbar,
- beforeAddShape,
- beforeRemoveShape,
- beforeDeselectShape,
- beforeSelectShape,
- beforeUpdateShape,
- $imageFlipX,
- $imageFlipY,
- $imageRotation,
- presentationScalar,
- rootRect,
- imageCropRect,
- imageSelectionRectPresentation,
- imageAnnotation,
- imageDecoration,
- imageSize,
- imageTransforms,
- imageRotation,
- imageFlipX,
- imageFlipY,
- mapScreenPointToImagePoint,
- mapImagePointToScreenPoint,
- name,
- measure_handler
- ];
- }
- class Sticker extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$6,
- create_fragment$6,
- safe_not_equal,
- {
- name: 34,
- isActive: 0,
- isActiveFraction: 1,
- isVisible: 2,
- stores: 3,
- locale: 4,
- stickers: 5,
- stickerStickToImage: 6,
- stickerEnableSelectImage: 7,
- stickersEnableButtonFlipVertical: 8,
- stickersWillRenderShapePresetToolbar: 9,
- willRenderShapeControls: 10,
- markupEditorToolSelectRadius: 11,
- willRenderShapePresetToolbar: 12,
- beforeAddShape: 13,
- beforeRemoveShape: 14,
- beforeDeselectShape: 15,
- beforeSelectShape: 16,
- beforeUpdateShape: 17
- },
- [-1, -1]
- );
- }
- get name() {
- return this.$$.ctx[34];
- }
- get isActive() {
- return this.$$.ctx[0];
- }
- set isActive(isActive) {
- this.$set({ isActive });
- flush();
- }
- get isActiveFraction() {
- return this.$$.ctx[1];
- }
- set isActiveFraction(isActiveFraction) {
- this.$set({ isActiveFraction });
- flush();
- }
- get isVisible() {
- return this.$$.ctx[2];
- }
- set isVisible(isVisible) {
- this.$set({ isVisible });
- flush();
- }
- get stores() {
- return this.$$.ctx[3];
- }
- set stores(stores) {
- this.$set({ stores });
- flush();
- }
- get locale() {
- return this.$$.ctx[4];
- }
- set locale(locale) {
- this.$set({ locale });
- flush();
- }
- get stickers() {
- return this.$$.ctx[5];
- }
- set stickers(stickers) {
- this.$set({ stickers });
- flush();
- }
- get stickerStickToImage() {
- return this.$$.ctx[6];
- }
- set stickerStickToImage(stickerStickToImage) {
- this.$set({ stickerStickToImage });
- flush();
- }
- get stickerEnableSelectImage() {
- return this.$$.ctx[7];
- }
- set stickerEnableSelectImage(stickerEnableSelectImage) {
- this.$set({ stickerEnableSelectImage });
- flush();
- }
- get stickersEnableButtonFlipVertical() {
- return this.$$.ctx[8];
- }
- set stickersEnableButtonFlipVertical(stickersEnableButtonFlipVertical) {
- this.$set({ stickersEnableButtonFlipVertical });
- flush();
- }
- get stickersWillRenderShapePresetToolbar() {
- return this.$$.ctx[9];
- }
- set stickersWillRenderShapePresetToolbar(stickersWillRenderShapePresetToolbar) {
- this.$set({ stickersWillRenderShapePresetToolbar });
- flush();
- }
- get willRenderShapeControls() {
- return this.$$.ctx[10];
- }
- set willRenderShapeControls(willRenderShapeControls) {
- this.$set({ willRenderShapeControls });
- flush();
- }
- get markupEditorToolSelectRadius() {
- return this.$$.ctx[11];
- }
- set markupEditorToolSelectRadius(markupEditorToolSelectRadius) {
- this.$set({ markupEditorToolSelectRadius });
- flush();
- }
- get willRenderShapePresetToolbar() {
- return this.$$.ctx[12];
- }
- set willRenderShapePresetToolbar(willRenderShapePresetToolbar) {
- this.$set({ willRenderShapePresetToolbar });
- flush();
- }
- get beforeAddShape() {
- return this.$$.ctx[13];
- }
- set beforeAddShape(beforeAddShape) {
- this.$set({ beforeAddShape });
- flush();
- }
- get beforeRemoveShape() {
- return this.$$.ctx[14];
- }
- set beforeRemoveShape(beforeRemoveShape) {
- this.$set({ beforeRemoveShape });
- flush();
- }
- get beforeDeselectShape() {
- return this.$$.ctx[15];
- }
- set beforeDeselectShape(beforeDeselectShape) {
- this.$set({ beforeDeselectShape });
- flush();
- }
- get beforeSelectShape() {
- return this.$$.ctx[16];
- }
- set beforeSelectShape(beforeSelectShape) {
- this.$set({ beforeSelectShape });
- flush();
- }
- get beforeUpdateShape() {
- return this.$$.ctx[17];
- }
- set beforeUpdateShape(beforeUpdateShape) {
- this.$set({ beforeUpdateShape });
- flush();
- }
- }
- // @ts-ignore
- var _plugin_sticker = { util: ['sticker', Sticker] };
- /* src/core/ui/plugins/frame/index.svelte generated by Svelte v3.37.0 */
- function create_option_slot(ctx) {
- let div;
- let html_tag;
- let raw_value = (/*getOptionThumb*/ ctx[13](/*option*/ ctx[27].value) || "") + "";
- let t0;
- let span;
- let t1_value = (isFunction(/*option*/ ctx[27].label)
- ? /*option*/ ctx[27].label(/*locale*/ ctx[1])
- : /*option*/ ctx[27].label) + "";
- let t1;
- return {
- c() {
- div = element("div");
- t0 = space();
- span = element("span");
- t1 = text(t1_value);
- html_tag = new HtmlTag(t0);
- attr(div, "slot", "option");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- html_tag.m(raw_value, div);
- append(div, t0);
- append(div, span);
- append(span, t1);
- },
- p(ctx, dirty) {
- if (dirty & /*option*/ 134217728 && raw_value !== (raw_value = (/*getOptionThumb*/ ctx[13](/*option*/ ctx[27].value) || "") + "")) html_tag.p(raw_value);
- if (dirty & /*option, locale*/ 134217730 && t1_value !== (t1_value = (isFunction(/*option*/ ctx[27].label)
- ? /*option*/ ctx[27].label(/*locale*/ ctx[1])
- : /*option*/ ctx[27].label) + "")) set_data(t1, t1_value);
- },
- d(detaching) {
- if (detaching) detach(div);
- }
- };
- }
- // (125:8) <Scrollable elasticity={scrollElasticity}>
- function create_default_slot$2(ctx) {
- let radiogroup;
- let current;
- radiogroup = new RadioGroup({
- props: {
- locale: /*locale*/ ctx[1],
- layout: "row",
- options: /*frameOptions*/ ctx[2],
- selectedIndex: /*selectedFrameIndex*/ ctx[10],
- onchange: /*handleChangeFrame*/ ctx[11],
- $$slots: {
- option: [
- create_option_slot,
- ({ option }) => ({ 27: option }),
- ({ option }) => option ? 134217728 : 0
- ]
- },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- create_component(radiogroup.$$.fragment);
- },
- m(target, anchor) {
- mount_component(radiogroup, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const radiogroup_changes = {};
- if (dirty & /*locale*/ 2) radiogroup_changes.locale = /*locale*/ ctx[1];
- if (dirty & /*frameOptions*/ 4) radiogroup_changes.options = /*frameOptions*/ ctx[2];
- if (dirty & /*$$scope, option, locale*/ 402653186) {
- radiogroup_changes.$$scope = { dirty, ctx };
- }
- radiogroup.$set(radiogroup_changes);
- },
- i(local) {
- if (current) return;
- transition_in(radiogroup.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(radiogroup.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(radiogroup, detaching);
- }
- };
- }
- // (116:4)
- function create_footer_slot$1(ctx) {
- let div;
- let shapestyleeditor;
- let t;
- let scrollable;
- let current;
- shapestyleeditor = new ShapeStyleEditor({
- props: {
- locale: /*locale*/ ctx[1],
- shape: /*$imageFrame*/ ctx[5],
- onchange: /*handleUpdateSelectedFrameShape*/ ctx[12],
- controls: /*markupEditorShapeStyleControls*/ ctx[3],
- scrollElasticity: /*computedScrollElasticity*/ ctx[4]
- }
- });
- scrollable = new Scrollable({
- props: {
- elasticity: /*scrollElasticity*/ ctx[8],
- $$slots: { default: [create_default_slot$2] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- div = element("div");
- create_component(shapestyleeditor.$$.fragment);
- t = space();
- create_component(scrollable.$$.fragment);
- attr(div, "slot", "footer");
- attr(div, "style", /*footerStyle*/ ctx[6]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(shapestyleeditor, div, null);
- append(div, t);
- mount_component(scrollable, div, null);
- current = true;
- },
- p(ctx, dirty) {
- const shapestyleeditor_changes = {};
- if (dirty & /*locale*/ 2) shapestyleeditor_changes.locale = /*locale*/ ctx[1];
- if (dirty & /*$imageFrame*/ 32) shapestyleeditor_changes.shape = /*$imageFrame*/ ctx[5];
- if (dirty & /*markupEditorShapeStyleControls*/ 8) shapestyleeditor_changes.controls = /*markupEditorShapeStyleControls*/ ctx[3];
- if (dirty & /*computedScrollElasticity*/ 16) shapestyleeditor_changes.scrollElasticity = /*computedScrollElasticity*/ ctx[4];
- shapestyleeditor.$set(shapestyleeditor_changes);
- const scrollable_changes = {};
- if (dirty & /*$$scope, locale, frameOptions*/ 268435462) {
- scrollable_changes.$$scope = { dirty, ctx };
- }
- scrollable.$set(scrollable_changes);
- if (!current || dirty & /*footerStyle*/ 64) {
- attr(div, "style", /*footerStyle*/ ctx[6]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(shapestyleeditor.$$.fragment, local);
- transition_in(scrollable.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapestyleeditor.$$.fragment, local);
- transition_out(scrollable.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(shapestyleeditor);
- destroy_component(scrollable);
- }
- };
- }
- function create_fragment$5(ctx) {
- let util;
- let current;
- util = new Util({
- props: {
- $$slots: { footer: [create_footer_slot$1] },
- $$scope: { ctx }
- }
- });
- util.$on("measure", /*measure_handler*/ ctx[21]);
- return {
- c() {
- create_component(util.$$.fragment);
- },
- m(target, anchor) {
- mount_component(util, target, anchor);
- current = true;
- },
- p(ctx, [dirty]) {
- const util_changes = {};
- if (dirty & /*$$scope, footerStyle, locale, frameOptions, $imageFrame, markupEditorShapeStyleControls, computedScrollElasticity*/ 268435582) {
- util_changes.$$scope = { dirty, ctx };
- }
- util.$set(util_changes);
- },
- i(local) {
- if (current) return;
- transition_in(util.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(util.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(util, detaching);
- }
- };
- }
- function instance$5($$self, $$props, $$invalidate) {
- let computedScrollElasticity;
- let footerStyle;
- let $imageFrame;
- let $animation;
- let $isActive,
- $$unsubscribe_isActive = noop,
- $$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(19, $isActive = $$value)), isActive);
- let $footerOffset;
- $$self.$$.on_destroy.push(() => $$unsubscribe_isActive());
- const name = "frame";
- let { isActive } = $$props;
- $$subscribe_isActive();
- let { stores } = $$props;
- let { locale = {} } = $$props;
- let { frameStyles = {} } = $$props;
- let { frameOptions = [] } = $$props;
- let { markupEditorShapeStyleControls = undefined } = $$props;
- // connect filter choice to stores
- const { animation, elasticityMultiplier, scrollElasticity, imageFrame } = stores;
- component_subscribe($$self, animation, value => $$invalidate(18, $animation = value));
- component_subscribe($$self, imageFrame, value => $$invalidate(5, $imageFrame = value));
- // current index in frame list
- let selectedFrameIndex = $imageFrame
- ? frameOptions.findIndex(([id]) => id === $imageFrame.id)
- : 0;
- // default frame styles
- let frameActiveStyles = { frameColor: [1, 1, 1] };
- const handleChangeFrame = ({ value }) => {
- // get new frame
- const frameBase = frameStyles[value];
- // no new frame selected
- if (!frameBase || !frameBase.shape) {
- imageFrame.set(undefined);
- return;
- }
- // create new base frame
- const frame = {
- id: value,
- // set base styles
- ...frameActiveStyles,
- // copy the frame base, it's possible that this frame has a different layout
- ...shapeDeepCopy(frameBase.shape)
- };
- imageFrame.set(frame);
- };
- function handleUpdateSelectedFrameShape(props) {
- // remember color style for when creating or styling other element
- if (hasProp(props, "frameColor")) frameActiveStyles.frameColor = props.frameColor;
- // it's possible we're only updating default styles
- if (!$imageFrame) return;
- // frameSelected
- shapeUpdateProps($imageFrame, props);
- // update shape so ui shape controls are updated
- imageFrame.set($imageFrame);
- }
- const isIncompleteSVGMarkup = str => (/rect|path|circle|line|<g>/i).test(str);
- const isHTML = str => (/div/i).test(str);
- const getThumb = value => {
- if (isHTML(value)) return value;
- // could be full svg
- if (isSVGMarkup(value)) return value;
- // could be a partial svg in which case we turn it into a full svg
- if (isIncompleteSVGMarkup(value)) return `<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" stroke-width="1" stroke="currentColor" fill="none" aria-hidden="true" focusable="false" stroke-linecap="round" stroke-linejoin="round">${value}</svg>`;
- // if not, must be URL
- return `<img src="${value}" alt=""/>`;
- };
- const getOptionThumb = key => {
- const frameStyle = frameStyles[key];
- if (!frameStyle || !frameStyle.thumb) return;
- return getThumb(frameStyle.thumb);
- };
- //
- // Footer style
- //
- const footerOffset = spring($animation ? 20 : 0);
- component_subscribe($$self, footerOffset, value => $$invalidate(20, $footerOffset = value));
- function measure_handler(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("isActive" in $$props) $$subscribe_isActive($$invalidate(0, isActive = $$props.isActive));
- if ("stores" in $$props) $$invalidate(16, stores = $$props.stores);
- if ("locale" in $$props) $$invalidate(1, locale = $$props.locale);
- if ("frameStyles" in $$props) $$invalidate(17, frameStyles = $$props.frameStyles);
- if ("frameOptions" in $$props) $$invalidate(2, frameOptions = $$props.frameOptions);
- if ("markupEditorShapeStyleControls" in $$props) $$invalidate(3, markupEditorShapeStyleControls = $$props.markupEditorShapeStyleControls);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*$animation, $isActive*/ 786432) {
- $animation && footerOffset.set($isActive ? 0 : 20);
- }
- if ($$self.$$.dirty & /*$footerOffset*/ 1048576) {
- $$invalidate(6, footerStyle = $footerOffset
- ? `transform: translateY(${$footerOffset}px)`
- : undefined);
- }
- };
- $$invalidate(4, computedScrollElasticity = elasticityMultiplier * scrollElasticity);
- return [
- isActive,
- locale,
- frameOptions,
- markupEditorShapeStyleControls,
- computedScrollElasticity,
- $imageFrame,
- footerStyle,
- animation,
- scrollElasticity,
- imageFrame,
- selectedFrameIndex,
- handleChangeFrame,
- handleUpdateSelectedFrameShape,
- getOptionThumb,
- footerOffset,
- name,
- stores,
- frameStyles,
- $animation,
- $isActive,
- $footerOffset,
- measure_handler
- ];
- }
- class Frame extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$5, create_fragment$5, safe_not_equal, {
- name: 15,
- isActive: 0,
- stores: 16,
- locale: 1,
- frameStyles: 17,
- frameOptions: 2,
- markupEditorShapeStyleControls: 3
- });
- }
- get name() {
- return this.$$.ctx[15];
- }
- get isActive() {
- return this.$$.ctx[0];
- }
- set isActive(isActive) {
- this.$set({ isActive });
- flush();
- }
- get stores() {
- return this.$$.ctx[16];
- }
- set stores(stores) {
- this.$set({ stores });
- flush();
- }
- get locale() {
- return this.$$.ctx[1];
- }
- set locale(locale) {
- this.$set({ locale });
- flush();
- }
- get frameStyles() {
- return this.$$.ctx[17];
- }
- set frameStyles(frameStyles) {
- this.$set({ frameStyles });
- flush();
- }
- get frameOptions() {
- return this.$$.ctx[2];
- }
- set frameOptions(frameOptions) {
- this.$set({ frameOptions });
- flush();
- }
- get markupEditorShapeStyleControls() {
- return this.$$.ctx[3];
- }
- set markupEditorShapeStyleControls(markupEditorShapeStyleControls) {
- this.$set({ markupEditorShapeStyleControls });
- flush();
- }
- }
- // @ts-ignore
- var _plugin_frame = { util: ['frame', Frame] };
- /* src/core/ui/plugins/resize/DimensionInput.svelte generated by Svelte v3.37.0 */
- function create_fragment$4(ctx) {
- let div;
- let label_1;
- let t0;
- let t1;
- let input;
- let input_value_value;
- let mounted;
- let dispose;
- return {
- c() {
- div = element("div");
- label_1 = element("label");
- t0 = text(/*label*/ ctx[1]);
- t1 = space();
- input = element("input");
- attr(label_1, "for", /*id*/ ctx[0]);
- attr(label_1, "title", /*title*/ ctx[2]);
- attr(label_1, "aria-label", /*title*/ ctx[2]);
- attr(input, "id", /*id*/ ctx[0]);
- attr(input, "type", "text");
- attr(input, "inputmode", "numeric");
- attr(input, "pattern", "[0-9]*");
- attr(input, "data-state", /*state*/ ctx[3]);
- attr(input, "autocomplete", "off");
- attr(input, "placeholder", /*placeholder*/ ctx[4]);
- input.value = input_value_value = /*value*/ ctx[5] === undefined
- ? ""
- : /*format*/ ctx[7](/*value*/ ctx[5] + "");
- attr(div, "class", "PinturaInputDimension");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- append(div, label_1);
- append(label_1, t0);
- append(div, t1);
- append(div, input);
- if (!mounted) {
- dispose = listen(input, "input", /*input_handler*/ ctx[8]);
- mounted = true;
- }
- },
- p(ctx, [dirty]) {
- if (dirty & /*label*/ 2) set_data(t0, /*label*/ ctx[1]);
- if (dirty & /*id*/ 1) {
- attr(label_1, "for", /*id*/ ctx[0]);
- }
- if (dirty & /*title*/ 4) {
- attr(label_1, "title", /*title*/ ctx[2]);
- }
- if (dirty & /*title*/ 4) {
- attr(label_1, "aria-label", /*title*/ ctx[2]);
- }
- if (dirty & /*id*/ 1) {
- attr(input, "id", /*id*/ ctx[0]);
- }
- if (dirty & /*state*/ 8) {
- attr(input, "data-state", /*state*/ ctx[3]);
- }
- if (dirty & /*placeholder*/ 16) {
- attr(input, "placeholder", /*placeholder*/ ctx[4]);
- }
- if (dirty & /*value, format*/ 160 && input_value_value !== (input_value_value = /*value*/ ctx[5] === undefined
- ? ""
- : /*format*/ ctx[7](/*value*/ ctx[5] + "")) && input.value !== input_value_value) {
- input.value = input_value_value;
- }
- },
- i: noop,
- o: noop,
- d(detaching) {
- if (detaching) detach(div);
- mounted = false;
- dispose();
- }
- };
- }
- function instance$4($$self, $$props, $$invalidate) {
- let { id } = $$props;
- let { label } = $$props;
- let { title } = $$props;
- let { state } = $$props;
- let { placeholder } = $$props;
- let { value } = $$props;
- let { onchange } = $$props;
- let { format = str => str.replace(/\D/g, "") } = $$props;
- const input_handler = e => onchange(format(e.currentTarget.value));
- $$self.$$set = $$props => {
- if ("id" in $$props) $$invalidate(0, id = $$props.id);
- if ("label" in $$props) $$invalidate(1, label = $$props.label);
- if ("title" in $$props) $$invalidate(2, title = $$props.title);
- if ("state" in $$props) $$invalidate(3, state = $$props.state);
- if ("placeholder" in $$props) $$invalidate(4, placeholder = $$props.placeholder);
- if ("value" in $$props) $$invalidate(5, value = $$props.value);
- if ("onchange" in $$props) $$invalidate(6, onchange = $$props.onchange);
- if ("format" in $$props) $$invalidate(7, format = $$props.format);
- };
- return [id, label, title, state, placeholder, value, onchange, format, input_handler];
- }
- class DimensionInput extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$4, create_fragment$4, safe_not_equal, {
- id: 0,
- label: 1,
- title: 2,
- state: 3,
- placeholder: 4,
- value: 5,
- onchange: 6,
- format: 7
- });
- }
- }
- /* src/core/ui/plugins/resize/DimensionLock.svelte generated by Svelte v3.37.0 */
- function create_default_slot$1(ctx) {
- let g;
- return {
- c() {
- g = svg_element("g");
- },
- m(target, anchor) {
- insert(target, g, anchor);
- g.innerHTML = /*icon*/ ctx[2];
- },
- p(ctx, dirty) {
- if (dirty & /*icon*/ 4) g.innerHTML = /*icon*/ ctx[2]; },
- d(detaching) {
- if (detaching) detach(g);
- }
- };
- }
- function create_fragment$3(ctx) {
- let div;
- let input;
- let t;
- let label;
- let icon_1;
- let current;
- let mounted;
- let dispose;
- icon_1 = new Icon({
- props: {
- $$slots: { default: [create_default_slot$1] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- div = element("div");
- input = element("input");
- t = space();
- label = element("label");
- create_component(icon_1.$$.fragment);
- attr(input, "id", /*id*/ ctx[0]);
- attr(input, "class", "implicit");
- attr(input, "type", "checkbox");
- input.checked = /*locked*/ ctx[1];
- attr(label, "for", /*id*/ ctx[0]);
- attr(label, "title", /*title*/ ctx[3]);
- },
- m(target, anchor) {
- insert(target, div, anchor);
- append(div, input);
- append(div, t);
- append(div, label);
- mount_component(icon_1, label, null);
- current = true;
- if (!mounted) {
- dispose = listen(input, "change", /*change_handler*/ ctx[5]);
- mounted = true;
- }
- },
- p(ctx, [dirty]) {
- if (!current || dirty & /*id*/ 1) {
- attr(input, "id", /*id*/ ctx[0]);
- }
- if (!current || dirty & /*locked*/ 2) {
- input.checked = /*locked*/ ctx[1];
- }
- const icon_1_changes = {};
- if (dirty & /*$$scope, icon*/ 68) {
- icon_1_changes.$$scope = { dirty, ctx };
- }
- icon_1.$set(icon_1_changes);
- if (!current || dirty & /*id*/ 1) {
- attr(label, "for", /*id*/ ctx[0]);
- }
- if (!current || dirty & /*title*/ 8) {
- attr(label, "title", /*title*/ ctx[3]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(icon_1.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(icon_1.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(div);
- destroy_component(icon_1);
- mounted = false;
- dispose();
- }
- };
- }
- function instance$3($$self, $$props, $$invalidate) {
- let { id } = $$props;
- let { locked } = $$props;
- let { icon } = $$props;
- let { title } = $$props;
- let { onchange } = $$props;
- const change_handler = e => onchange(e.currentTarget.checked);
- $$self.$$set = $$props => {
- if ("id" in $$props) $$invalidate(0, id = $$props.id);
- if ("locked" in $$props) $$invalidate(1, locked = $$props.locked);
- if ("icon" in $$props) $$invalidate(2, icon = $$props.icon);
- if ("title" in $$props) $$invalidate(3, title = $$props.title);
- if ("onchange" in $$props) $$invalidate(4, onchange = $$props.onchange);
- };
- return [id, locked, icon, title, onchange, change_handler];
- }
- class DimensionLock extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$3, create_fragment$3, safe_not_equal, {
- id: 0,
- locked: 1,
- icon: 2,
- title: 3,
- onchange: 4
- });
- }
- }
- /* src/core/ui/plugins/resize/index.svelte generated by Svelte v3.37.0 */
- function create_default_slot(ctx) {
- let t;
- return {
- c() {
- t = text("Save");
- },
- m(target, anchor) {
- insert(target, t, anchor);
- },
- d(detaching) {
- if (detaching) detach(t);
- }
- };
- }
- // (542:4)
- function create_footer_slot(ctx) {
- let form;
- let div1;
- let fieldset;
- let legend;
- let t0_value = /*locale*/ ctx[1].resizeLabelFormCaption + "";
- let t0;
- let t1;
- let div0;
- let dynamiccomponenttree;
- let t2;
- let button;
- let current;
- let mounted;
- let dispose;
- dynamiccomponenttree = new DynamicComponentTree_1({ props: { items: /*tools*/ ctx[3] } });
- button = new Button({
- props: {
- type: "submit",
- class: "implicit",
- $$slots: { default: [create_default_slot] },
- $$scope: { ctx }
- }
- });
- return {
- c() {
- form = element("form");
- div1 = element("div");
- fieldset = element("fieldset");
- legend = element("legend");
- t0 = text(t0_value);
- t1 = space();
- div0 = element("div");
- create_component(dynamiccomponenttree.$$.fragment);
- t2 = space();
- create_component(button.$$.fragment);
- attr(legend, "class", "implicit");
- attr(div0, "class", "PinturaFieldsetInner");
- attr(div1, "class", "PinturaFormInner");
- attr(form, "slot", "footer");
- attr(form, "style", /*footerStyle*/ ctx[4]);
- },
- m(target, anchor) {
- insert(target, form, anchor);
- append(form, div1);
- append(div1, fieldset);
- append(fieldset, legend);
- append(legend, t0);
- append(fieldset, t1);
- append(fieldset, div0);
- mount_component(dynamiccomponenttree, div0, null);
- /*div0_binding*/ ctx[62](div0);
- append(div1, t2);
- mount_component(button, div1, null);
- current = true;
- if (!mounted) {
- dispose = [
- listen(div0, "focusin", /*handleFocusIn*/ ctx[13]),
- listen(div0, "focusout", /*handleFocusOut*/ ctx[14]),
- listen(form, "submit", prevent_default(/*handleSubmit*/ ctx[15]))
- ];
- mounted = true;
- }
- },
- p(ctx, dirty) {
- if ((!current || dirty[0] & /*locale*/ 2) && t0_value !== (t0_value = /*locale*/ ctx[1].resizeLabelFormCaption + "")) set_data(t0, t0_value);
- const dynamiccomponenttree_changes = {};
- if (dirty[0] & /*tools*/ 8) dynamiccomponenttree_changes.items = /*tools*/ ctx[3];
- dynamiccomponenttree.$set(dynamiccomponenttree_changes);
- const button_changes = {};
- if (dirty[2] & /*$$scope*/ 524288) {
- button_changes.$$scope = { dirty, ctx };
- }
- button.$set(button_changes);
- if (!current || dirty[0] & /*footerStyle*/ 16) {
- attr(form, "style", /*footerStyle*/ ctx[4]);
- }
- },
- i(local) {
- if (current) return;
- transition_in(dynamiccomponenttree.$$.fragment, local);
- transition_in(button.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(dynamiccomponenttree.$$.fragment, local);
- transition_out(button.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) detach(form);
- destroy_component(dynamiccomponenttree);
- /*div0_binding*/ ctx[62](null);
- destroy_component(button);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function create_fragment$2(ctx) {
- let util;
- let current;
- util = new Util({
- props: {
- $$slots: { footer: [create_footer_slot] },
- $$scope: { ctx }
- }
- });
- util.$on("measure", /*measure_handler*/ ctx[63]);
- return {
- c() {
- create_component(util.$$.fragment);
- },
- m(target, anchor) {
- mount_component(util, target, anchor);
- current = true;
- },
- p(ctx, dirty) {
- const util_changes = {};
- if (dirty[0] & /*footerStyle, fieldsGroup, tools, locale*/ 30 | dirty[2] & /*$$scope*/ 524288) {
- util_changes.$$scope = { dirty, ctx };
- }
- util.$set(util_changes);
- },
- i(local) {
- if (current) return;
- transition_in(util.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(util.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(util, detaching);
- }
- };
- }
- function instance$2($$self, $$props, $$invalidate) {
- let sizePresetLabel;
- let widthPresetLabel;
- let heightPresetLabel;
- let canRenderSizePresets;
- let canRenderWidthPresets;
- let canRenderHeightPresets;
- let canRenderSizeInputs;
- let tools;
- let footerStyle;
- let $imageCropRectAspectRatio;
- let $imageOutputSize;
- let $imageCropAspectRatio;
- let $imageSize;
- let $formattedResizeSizePresetOptions;
- let $formattedResizeSizePresetOptionsFlattened;
- let $formattedResizeWidthPresetOptions;
- let $formattedResizeWidthPresetOptionsFlattened;
- let $formattedResizeHeightPresetOptions;
- let $formattedResizeHeightPresetOptionsFlattened;
- let $sizePresetSelectedIndex;
- let $widthPresetSelectedIndex;
- let $heightPresetSelectedIndex;
- let $imageCropRect;
- let $iconActiveFraction;
- let $env;
- let $animation;
- let $isActive,
- $$unsubscribe_isActive = noop,
- $$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(60, $isActive = $$value)), isActive);
- let $footerOffset;
- $$self.$$.on_destroy.push(() => $$unsubscribe_isActive());
- const formatValue = (value, min = 0, max = 9999) => {
- if (isString(value)) {
- value = value.replace(/\D/g, "");
- if (!value.length) return;
- }
- const v = Math.round(value);
- if (Number.isNaN(v)) return;
- return clamp(v, min, max);
- };
- const name = "resize";
- let { isActive } = $$props;
- $$subscribe_isActive();
- let { stores } = $$props;
- let { locale = {} } = $$props;
- let { resizeMinSize = sizeCreate(1, 1) } = $$props;
- let { resizeMaxSize = sizeCreate(9999, 9999) } = $$props;
- let { resizeSizePresetOptions = undefined } = $$props;
- let { resizeWidthPresetOptions = undefined } = $$props;
- let { resizeHeightPresetOptions = undefined } = $$props;
- let { resizeWillRenderFooter = passthrough } = $$props;
- // offset
- const iconActiveFraction = spring(0, { stiffness: 0.15, damping: 0.3 });
- component_subscribe($$self, iconActiveFraction, value => $$invalidate(57, $iconActiveFraction = value));
- const { animation, imageSize, imageCropRect, imageCropRectAspectRatio, imageCropAspectRatio, imageOutputSize, history, env } = stores;
- component_subscribe($$self, animation, value => $$invalidate(59, $animation = value));
- component_subscribe($$self, imageSize, value => $$invalidate(69, $imageSize = value));
- component_subscribe($$self, imageCropRect, value => $$invalidate(52, $imageCropRect = value));
- component_subscribe($$self, imageCropRectAspectRatio, value => $$invalidate(39, $imageCropRectAspectRatio = value));
- component_subscribe($$self, imageCropAspectRatio, value => $$invalidate(68, $imageCropAspectRatio = value));
- component_subscribe($$self, imageOutputSize, value => $$invalidate(67, $imageOutputSize = value));
- component_subscribe($$self, env, value => $$invalidate(58, $env = value));
- const formId = getUniqueId();
- let fieldsGroup;
- let maintainAspectRatio = false;
- let width;
- let height;
- let activeField;
- let lastActiveField;
- const getState = (value, field, activeField, resizeMinSize, resizeMaxSize) => value != null && activeField !== field
- ? value >= resizeMinSize[field] && value <= resizeMaxSize[field]
- ? "valid"
- : "invalid"
- : "undetermined";
- const getWidthPlaceholder = (value, cropAspectRatio, cropRect) => Math.round(value != null ? value * cropAspectRatio : cropRect.width);
- const getHeightPlaceholder = (value, cropAspectRatio, cropRect) => Math.round(value != null
- ? value / cropAspectRatio
- : cropRect.height);
- // populate active field
- const handleFocusIn = e => {
- const id = e.target.id;
- if ((/width/).test(id)) {
- $$invalidate(37, activeField = "width");
- } else if ((/height/).test(id)) {
- $$invalidate(37, activeField = "height");
- } else if ((/aspectRatio/i).test(id)) {
- $$invalidate(37, activeField = "lock");
- } else {
- $$invalidate(37, activeField = undefined);
- }
- };
- const handleFocusOut = e => {
- if (!fieldsGroup.contains(e.relatedTarget)) handleSubmit();
- $$invalidate(37, activeField = undefined);
- };
- // sync fields if one has a value and aspect ratio should be maintained
- const syncFields = () => {
- if (!maintainAspectRatio || !width || !height) return;
- if (activeField === "width") {
- // sync height field
- $$invalidate(36, height = Math.round(width / $imageCropRectAspectRatio));
- } else if (activeField === "height") {
- // sync width field
- $$invalidate(35, width = Math.round(height * $imageCropRectAspectRatio));
- } else {
- if (lastActiveField === "width") {
- $$invalidate(36, height = Math.round(width / $imageCropRectAspectRatio));
- } else if (lastActiveField === "height") {
- $$invalidate(35, width = Math.round(height * $imageCropRectAspectRatio));
- }
- consolidateSize();
- }
- };
- // $: if (maintainAspectRatio && width && height) syncFields()
- const consolidateSize = forcedAspectRatio => {
- // first need to limit values
- let inputWidth = formatValue(width);
- let inputHeight = formatValue(height);
- let currentWidth = inputWidth;
- let currentHeight = inputHeight;
- let bothAxisDefined = currentWidth && currentHeight;
- let aspectRatio = forcedAspectRatio || $imageCropRectAspectRatio;
- // done, no consolidation needed
- if (!currentWidth && !currentHeight) return;
- // need to fill in missing values
- if (currentWidth && !currentHeight) {
- currentHeight = Math.round(currentWidth / aspectRatio);
- } else if (currentHeight && !currentWidth) {
- currentWidth = Math.round(currentHeight * aspectRatio);
- }
- aspectRatio = forcedAspectRatio || bothAxisDefined
- ? getAspectRatio(currentWidth, currentHeight)
- : $imageCropRectAspectRatio;
- // now we have both width and height let's re-fit the min max size
- let currentSize = sizeCreate(currentWidth, currentHeight);
- if (!sizeContains(resizeMaxSize, currentSize)) {
- // too big
- currentSize = rectContainRect(resizeMaxSize, aspectRatio);
- }
- if (!sizeContains(currentSize, resizeMinSize)) {
- // too small
- currentSize = rectCoverRect(resizeMinSize, aspectRatio);
- }
- $$invalidate(35, width = inputWidth != null
- ? Math.round(currentSize.width)
- : undefined);
- $$invalidate(36, height = inputHeight != null
- ? Math.round(currentSize.height)
- : undefined);
- };
- const handleSubmit = () => {
- // calculate correct values
- consolidateSize();
- // get curent values so we can check if they were changed (if not, no need to write history or update)
- const { width: currentWidth, height: currentHeight } = $imageOutputSize || {};
- // no need to update
- if (currentWidth === width && currentHeight === height) return;
- // update state
- if (!width && !height) {
- // reset image crop
- set_store_value(imageCropAspectRatio, $imageCropAspectRatio = $imageSize.width / $imageSize.height, $imageCropAspectRatio);
- set_store_value(imageCropAspectRatio, $imageCropAspectRatio = undefined, $imageCropAspectRatio);
- // reset output size
- set_store_value(imageOutputSize, $imageOutputSize = undefined, $imageOutputSize);
- } else {
- if (width && height) set_store_value(imageCropAspectRatio, $imageCropAspectRatio = width / height, $imageCropAspectRatio);
- set_store_value(imageOutputSize, $imageOutputSize = sizeCreate(width, height), $imageOutputSize);
- }
- history.write();
- };
- // handle external updates to outputSize
- imageOutputSize.subscribe(size => {
- if (!size) {
- $$invalidate(35, width = undefined);
- $$invalidate(36, height = undefined);
- return;
- }
- $$invalidate(35, width = size.width);
- $$invalidate(36, height = size.height);
- // make sure the size conforms to min max
- consolidateSize();
- });
- // if the crop aspect ratio is changed we need to align width/height
- imageCropAspectRatio.subscribe(cropAspectRatio => {
- // exit if no dimensions supplied
- if (!width && !height) return;
- // no crop aspect ratio has been selected, so all is fine
- if (!cropAspectRatio) return;
- // fix size to match new aspect ratio of the crop
- if (width && height && getAspectRatio(width, height) !== cropAspectRatio) {
- $$invalidate(36, height = width / cropAspectRatio);
- consolidateSize(cropAspectRatio);
- } else {
- consolidateSize();
- }
- });
- //
- // size presets
- //
- const formatPresetDimensionOption = option => {
- if (isString(option[0])) {
- option[1] = option[1].map(formatPresetDimensionOption);
- return option;
- }
- return isNumber(option) ? [option, "" + option] : option;
- };
- const formatPresetSizeOption = option => {
- if (isString(option[0])) {
- option[1] = option[1].map(formatPresetSizeOption);
- return option;
- }
- let [value, label] = option;
- // Size only
- if (isNumber(value) && isNumber(label)) {
- const [w, h] = [value, label];
- label = `${w} × ${h}`;
- value = [w, h];
- }
- return [value, label];
- };
- const formattedResizeSizePresetOptions = writable();
- component_subscribe($$self, formattedResizeSizePresetOptions, value => $$invalidate(40, $formattedResizeSizePresetOptions = value));
- const formattedResizeSizePresetOptionsFlattened = writable();
- component_subscribe($$self, formattedResizeSizePresetOptionsFlattened, value => $$invalidate(41, $formattedResizeSizePresetOptionsFlattened = value));
- const formattedResizeWidthPresetOptions = writable();
- component_subscribe($$self, formattedResizeWidthPresetOptions, value => $$invalidate(42, $formattedResizeWidthPresetOptions = value));
- const formattedResizeWidthPresetOptionsFlattened = writable();
- component_subscribe($$self, formattedResizeWidthPresetOptionsFlattened, value => $$invalidate(43, $formattedResizeWidthPresetOptionsFlattened = value));
- const formattedResizeHeightPresetOptions = writable();
- component_subscribe($$self, formattedResizeHeightPresetOptions, value => $$invalidate(44, $formattedResizeHeightPresetOptions = value));
- const formattedResizeHeightPresetOptionsFlattened = writable();
- component_subscribe($$self, formattedResizeHeightPresetOptionsFlattened, value => $$invalidate(45, $formattedResizeHeightPresetOptionsFlattened = value));
- const sizePresetSelectedIndex = derived([imageOutputSize, formattedResizeSizePresetOptionsFlattened], ([$imageOutputSize, $formattedResizeSizePresetOptionsFlattened], set) => {
- if (!$formattedResizeSizePresetOptionsFlattened) return set(-1);
- const index = $formattedResizeSizePresetOptionsFlattened.findIndex(([value]) => {
- if (!value && !$imageOutputSize) return true;
- if (!value) return false;
- const [width, height] = value;
- return $imageOutputSize.width === width && $imageOutputSize.height === height;
- });
- set(index < 0 ? 0 : index);
- });
- component_subscribe($$self, sizePresetSelectedIndex, value => $$invalidate(47, $sizePresetSelectedIndex = value));
- const widthPresetSelectedIndex = derived([imageOutputSize, formattedResizeWidthPresetOptionsFlattened], ([$imageOutputSize, $formattedResizeWidthPresetOptionsFlattened], set) => {
- if (!$formattedResizeWidthPresetOptionsFlattened) return set(-1);
- const index = $formattedResizeWidthPresetOptionsFlattened.findIndex(([value]) => {
- if (!value && !$imageOutputSize) return true;
- if (!value) return false;
- return $imageOutputSize.width === value;
- });
- set(index < 0 ? 0 : index);
- });
- component_subscribe($$self, widthPresetSelectedIndex, value => $$invalidate(49, $widthPresetSelectedIndex = value));
- const heightPresetSelectedIndex = derived([imageOutputSize, formattedResizeHeightPresetOptionsFlattened], ([$imageOutputSize, $formattedResizeHeightPresetOptionsFlattened], set) => {
- if (!$formattedResizeHeightPresetOptionsFlattened) return set(-1);
- const index = $formattedResizeHeightPresetOptionsFlattened.findIndex(([value]) => {
- if (!value && !$imageOutputSize) return true;
- if (!value) return false;
- return $imageOutputSize.height === value;
- });
- set(index < 0 ? 0 : index);
- });
- component_subscribe($$self, heightPresetSelectedIndex, value => $$invalidate(51, $heightPresetSelectedIndex = value));
- let storedCropRect = undefined;
- let storedCropAspectRatio = undefined;
- const setImageOutputSizeWithArray = size => {
- if (size && !storedCropRect) {
- storedCropRect = { ...$imageCropRect };
- storedCropAspectRatio = $imageCropAspectRatio;
- }
- if (!size) {
- set_store_value(imageCropRect, $imageCropRect = storedCropRect, $imageCropRect);
- set_store_value(imageCropAspectRatio, $imageCropAspectRatio = storedCropAspectRatio, $imageCropAspectRatio);
- set_store_value(imageOutputSize, $imageOutputSize = undefined, $imageOutputSize);
- storedCropRect = undefined;
- storedCropAspectRatio = undefined;
- } else {
- set_store_value(imageCropAspectRatio, $imageCropAspectRatio = getAspectRatio(size[0], size[1]), $imageCropAspectRatio);
- set_store_value(imageOutputSize, $imageOutputSize = sizeCreateFromArray(size), $imageOutputSize);
- }
- history.write();
- };
- //
- // toolbar
- //
- let redrawTrigger = {};
- //
- // Footer
- //
- const footerOffset = spring($animation ? 20 : 0);
- component_subscribe($$self, footerOffset, value => $$invalidate(61, $footerOffset = value));
- function div0_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- fieldsGroup = $$value;
- $$invalidate(2, fieldsGroup);
- });
- }
- function measure_handler(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("isActive" in $$props) $$subscribe_isActive($$invalidate(0, isActive = $$props.isActive));
- if ("stores" in $$props) $$invalidate(27, stores = $$props.stores);
- if ("locale" in $$props) $$invalidate(1, locale = $$props.locale);
- if ("resizeMinSize" in $$props) $$invalidate(28, resizeMinSize = $$props.resizeMinSize);
- if ("resizeMaxSize" in $$props) $$invalidate(29, resizeMaxSize = $$props.resizeMaxSize);
- if ("resizeSizePresetOptions" in $$props) $$invalidate(30, resizeSizePresetOptions = $$props.resizeSizePresetOptions);
- if ("resizeWidthPresetOptions" in $$props) $$invalidate(31, resizeWidthPresetOptions = $$props.resizeWidthPresetOptions);
- if ("resizeHeightPresetOptions" in $$props) $$invalidate(32, resizeHeightPresetOptions = $$props.resizeHeightPresetOptions);
- if ("resizeWillRenderFooter" in $$props) $$invalidate(33, resizeWillRenderFooter = $$props.resizeWillRenderFooter);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*resizeSizePresetOptions*/ 1073741824 | $$self.$$.dirty[1] & /*$formattedResizeSizePresetOptions*/ 512) {
- if (resizeSizePresetOptions) {
- set_store_value(formattedResizeSizePresetOptions, $formattedResizeSizePresetOptions = resizeSizePresetOptions.map(formatPresetSizeOption), $formattedResizeSizePresetOptions);
- set_store_value(formattedResizeSizePresetOptionsFlattened, $formattedResizeSizePresetOptionsFlattened = flattenOptions($formattedResizeSizePresetOptions), $formattedResizeSizePresetOptionsFlattened);
- }
- }
- if ($$self.$$.dirty[1] & /*$formattedResizeSizePresetOptions*/ 512) {
- //
- // helper bools
- //
- $$invalidate(53, canRenderSizePresets = !!$formattedResizeSizePresetOptions);
- }
- if ($$self.$$.dirty[1] & /*$sizePresetSelectedIndex, $formattedResizeSizePresetOptionsFlattened*/ 66560) {
- $$invalidate(46, sizePresetLabel = $sizePresetSelectedIndex > -1 && $formattedResizeSizePresetOptionsFlattened[$sizePresetSelectedIndex][1]);
- }
- if ($$self.$$.dirty[1] & /*resizeWidthPresetOptions, $formattedResizeWidthPresetOptions*/ 2049) {
- if (resizeWidthPresetOptions) {
- set_store_value(formattedResizeWidthPresetOptions, $formattedResizeWidthPresetOptions = resizeWidthPresetOptions.map(formatPresetDimensionOption), $formattedResizeWidthPresetOptions);
- set_store_value(formattedResizeWidthPresetOptionsFlattened, $formattedResizeWidthPresetOptionsFlattened = flattenOptions($formattedResizeWidthPresetOptions), $formattedResizeWidthPresetOptionsFlattened);
- }
- }
- if ($$self.$$.dirty[1] & /*canRenderSizePresets, $formattedResizeWidthPresetOptions*/ 4196352) {
- $$invalidate(54, canRenderWidthPresets = !canRenderSizePresets && $formattedResizeWidthPresetOptions);
- }
- if ($$self.$$.dirty[1] & /*$widthPresetSelectedIndex, $formattedResizeWidthPresetOptionsFlattened*/ 266240) {
- $$invalidate(48, widthPresetLabel = $widthPresetSelectedIndex > -1 && $formattedResizeWidthPresetOptionsFlattened[$widthPresetSelectedIndex][1]);
- }
- if ($$self.$$.dirty[1] & /*resizeHeightPresetOptions, $formattedResizeHeightPresetOptions*/ 8194) {
- if (resizeHeightPresetOptions) {
- set_store_value(formattedResizeHeightPresetOptions, $formattedResizeHeightPresetOptions = resizeHeightPresetOptions.map(formatPresetDimensionOption), $formattedResizeHeightPresetOptions);
- set_store_value(formattedResizeHeightPresetOptionsFlattened, $formattedResizeHeightPresetOptionsFlattened = flattenOptions($formattedResizeHeightPresetOptions), $formattedResizeHeightPresetOptionsFlattened);
- }
- }
- if ($$self.$$.dirty[1] & /*canRenderSizePresets, $formattedResizeHeightPresetOptions*/ 4202496) {
- $$invalidate(55, canRenderHeightPresets = !canRenderSizePresets && $formattedResizeHeightPresetOptions);
- }
- if ($$self.$$.dirty[1] & /*$heightPresetSelectedIndex, $formattedResizeHeightPresetOptionsFlattened*/ 1064960) {
- $$invalidate(50, heightPresetLabel = $heightPresetSelectedIndex > -1 && $formattedResizeHeightPresetOptionsFlattened[$heightPresetSelectedIndex][1]);
- }
- if ($$self.$$.dirty[1] & /*canRenderSizePresets, canRenderWidthPresets, canRenderHeightPresets*/ 29360128) {
- $$invalidate(56, canRenderSizeInputs = !canRenderSizePresets && !canRenderWidthPresets && !canRenderHeightPresets);
- }
- if ($$self.$$.dirty[0] & /*locale, resizeMinSize, resizeMaxSize*/ 805306370 | $$self.$$.dirty[1] & /*redrawTrigger, resizeWillRenderFooter, canRenderSizePresets, sizePresetLabel, $formattedResizeSizePresetOptions, $sizePresetSelectedIndex, canRenderWidthPresets, widthPresetLabel, $formattedResizeWidthPresetOptions, $widthPresetSelectedIndex, canRenderHeightPresets, heightPresetLabel, $formattedResizeHeightPresetOptions, $heightPresetSelectedIndex, canRenderSizeInputs, height, $imageCropRectAspectRatio, $imageCropRect, width, activeField, maintainAspectRatio, $iconActiveFraction, $env*/ 268413948) {
- $$invalidate(3, tools = redrawTrigger && resizeWillRenderFooter(
- [
- canRenderSizePresets && [
- "Dropdown",
- "size-presets",
- {
- label: sizePresetLabel,
- options: $formattedResizeSizePresetOptions,
- onchange: item => setImageOutputSizeWithArray(item.value),
- selectedIndex: $sizePresetSelectedIndex
- }
- ],
- canRenderWidthPresets && [
- "Dropdown",
- "width-presets",
- {
- label: widthPresetLabel,
- options: $formattedResizeWidthPresetOptions,
- onchange: item => {
- $$invalidate(35, width = item.value);
- handleSubmit();
- },
- selectedIndex: $widthPresetSelectedIndex
- }
- ],
- canRenderWidthPresets && canRenderHeightPresets && [
- "span",
- "times",
- {
- class: "PinturaResizeLabel",
- innerHTML: "×"
- }
- ],
- canRenderHeightPresets && [
- "Dropdown",
- "height-presets",
- {
- label: heightPresetLabel,
- options: $formattedResizeHeightPresetOptions,
- onchange: item => {
- $$invalidate(36, height = item.value);
- handleSubmit();
- },
- selectedIndex: $heightPresetSelectedIndex
- }
- ],
- canRenderSizeInputs && [
- DimensionInput,
- "width-input",
- {
- id: `width-${formId}`,
- title: locale.resizeTitleInputWidth,
- label: locale.resizeLabelInputWidth,
- placeholder: getWidthPlaceholder(formatValue(height), $imageCropRectAspectRatio, $imageCropRect),
- value: width,
- state: getState(formatValue(width), "width", activeField, resizeMinSize, resizeMaxSize),
- onchange: value => {
- $$invalidate(35, width = value);
- syncFields();
- }
- }
- ],
- canRenderSizeInputs && [
- DimensionLock,
- "aspect-ratio-lock",
- {
- id: `aspect-ratio-lock-${formId}`,
- title: locale.resizeTitleButtonMaintainAspectRatio,
- icon: isString(locale.resizeIconButtonMaintainAspectRatio)
- ? locale.resizeIconButtonMaintainAspectRatio
- : locale.resizeIconButtonMaintainAspectRatio(maintainAspectRatio, $iconActiveFraction),
- locked: maintainAspectRatio,
- onchange: locked => {
- $$invalidate(34, maintainAspectRatio = locked);
- syncFields();
- }
- }
- ],
- canRenderSizeInputs && [
- DimensionInput,
- "height-input",
- {
- id: `height-${formId}`,
- title: locale.resizeTitleInputHeight,
- label: locale.resizeLabelInputHeight,
- placeholder: getHeightPlaceholder(formatValue(width), $imageCropRectAspectRatio, $imageCropRect),
- value: height,
- state: getState(formatValue(height), "height", activeField, resizeMinSize, resizeMaxSize),
- onchange: value => {
- $$invalidate(36, height = value);
- syncFields();
- }
- }
- ]
- ].filter(Boolean),
- { ...$env },
- () => $$invalidate(38, redrawTrigger = {})
- ).filter(Boolean));
- }
- if ($$self.$$.dirty[1] & /*maintainAspectRatio*/ 8) {
- iconActiveFraction.set(maintainAspectRatio ? 1 : 0);
- }
- if ($$self.$$.dirty[1] & /*activeField*/ 64) {
- if (activeField) lastActiveField = activeField;
- }
- if ($$self.$$.dirty[1] & /*$animation, $isActive*/ 805306368) {
- $animation && footerOffset.set($isActive ? 0 : 20);
- }
- if ($$self.$$.dirty[1] & /*$footerOffset*/ 1073741824) {
- $$invalidate(4, footerStyle = $footerOffset
- ? `transform: translateY(${$footerOffset}px)`
- : undefined);
- }
- };
- return [
- isActive,
- locale,
- fieldsGroup,
- tools,
- footerStyle,
- iconActiveFraction,
- animation,
- imageSize,
- imageCropRect,
- imageCropRectAspectRatio,
- imageCropAspectRatio,
- imageOutputSize,
- env,
- handleFocusIn,
- handleFocusOut,
- handleSubmit,
- formattedResizeSizePresetOptions,
- formattedResizeSizePresetOptionsFlattened,
- formattedResizeWidthPresetOptions,
- formattedResizeWidthPresetOptionsFlattened,
- formattedResizeHeightPresetOptions,
- formattedResizeHeightPresetOptionsFlattened,
- sizePresetSelectedIndex,
- widthPresetSelectedIndex,
- heightPresetSelectedIndex,
- footerOffset,
- name,
- stores,
- resizeMinSize,
- resizeMaxSize,
- resizeSizePresetOptions,
- resizeWidthPresetOptions,
- resizeHeightPresetOptions,
- resizeWillRenderFooter,
- maintainAspectRatio,
- width,
- height,
- activeField,
- redrawTrigger,
- $imageCropRectAspectRatio,
- $formattedResizeSizePresetOptions,
- $formattedResizeSizePresetOptionsFlattened,
- $formattedResizeWidthPresetOptions,
- $formattedResizeWidthPresetOptionsFlattened,
- $formattedResizeHeightPresetOptions,
- $formattedResizeHeightPresetOptionsFlattened,
- sizePresetLabel,
- $sizePresetSelectedIndex,
- widthPresetLabel,
- $widthPresetSelectedIndex,
- heightPresetLabel,
- $heightPresetSelectedIndex,
- $imageCropRect,
- canRenderSizePresets,
- canRenderWidthPresets,
- canRenderHeightPresets,
- canRenderSizeInputs,
- $iconActiveFraction,
- $env,
- $animation,
- $isActive,
- $footerOffset,
- div0_binding,
- measure_handler
- ];
- }
- class Resize extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance$2,
- create_fragment$2,
- safe_not_equal,
- {
- name: 26,
- isActive: 0,
- stores: 27,
- locale: 1,
- resizeMinSize: 28,
- resizeMaxSize: 29,
- resizeSizePresetOptions: 30,
- resizeWidthPresetOptions: 31,
- resizeHeightPresetOptions: 32,
- resizeWillRenderFooter: 33
- },
- [-1, -1, -1]
- );
- }
- get name() {
- return this.$$.ctx[26];
- }
- get isActive() {
- return this.$$.ctx[0];
- }
- set isActive(isActive) {
- this.$set({ isActive });
- flush();
- }
- get stores() {
- return this.$$.ctx[27];
- }
- set stores(stores) {
- this.$set({ stores });
- flush();
- }
- get locale() {
- return this.$$.ctx[1];
- }
- set locale(locale) {
- this.$set({ locale });
- flush();
- }
- get resizeMinSize() {
- return this.$$.ctx[28];
- }
- set resizeMinSize(resizeMinSize) {
- this.$set({ resizeMinSize });
- flush();
- }
- get resizeMaxSize() {
- return this.$$.ctx[29];
- }
- set resizeMaxSize(resizeMaxSize) {
- this.$set({ resizeMaxSize });
- flush();
- }
- get resizeSizePresetOptions() {
- return this.$$.ctx[30];
- }
- set resizeSizePresetOptions(resizeSizePresetOptions) {
- this.$set({ resizeSizePresetOptions });
- flush();
- }
- get resizeWidthPresetOptions() {
- return this.$$.ctx[31];
- }
- set resizeWidthPresetOptions(resizeWidthPresetOptions) {
- this.$set({ resizeWidthPresetOptions });
- flush();
- }
- get resizeHeightPresetOptions() {
- return this.$$.ctx[32];
- }
- set resizeHeightPresetOptions(resizeHeightPresetOptions) {
- this.$set({ resizeHeightPresetOptions });
- flush();
- }
- get resizeWillRenderFooter() {
- return this.$$.ctx[33];
- }
- set resizeWillRenderFooter(resizeWillRenderFooter) {
- this.$set({ resizeWillRenderFooter });
- flush();
- }
- }
- // @ts-ignore
- var _plugin_resize = { util: ['resize', Resize] };
- /* src/core/ui/plugins/redact/index.svelte generated by Svelte v3.37.0 */
- function create_fragment$1(ctx) {
- let shapeutil;
- let current;
- shapeutil = new ShapeUtil({
- props: {
- stores: /*stores*/ ctx[3],
- locale: /*locale*/ ctx[4],
- isActive: /*isActive*/ ctx[0],
- isActiveFraction: /*isActiveFraction*/ ctx[1],
- isVisible: /*isVisible*/ ctx[2],
- mapScreenPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[15],
- mapImagePointToScreenPoint: /*mapImagePointToScreenPoint*/ ctx[16],
- utilKey: "redact",
- imageRotation: /*$imageRotation*/ ctx[7],
- imageFlipX: /*$imageFlipX*/ ctx[5],
- imageFlipY: /*$imageFlipY*/ ctx[6],
- shapes: /*imageRedaction*/ ctx[8],
- tools: ["rect"],
- toolShapes: {
- rectangle: [{ x: 0, y: 0, width: 0, height: 0 }]
- },
- toolActive: "rectangle",
- parentRect: /*imageSize*/ ctx[10],
- enablePresetDropImage: false,
- enablePresetSelectImage: false,
- hooks: {
- willRenderShapeControls: /*func*/ ctx[18]
- }
- }
- });
- shapeutil.$on("measure", /*measure_handler*/ ctx[19]);
- return {
- c() {
- create_component(shapeutil.$$.fragment);
- },
- m(target, anchor) {
- mount_component(shapeutil, target, anchor);
- current = true;
- },
- p(ctx, [dirty]) {
- const shapeutil_changes = {};
- if (dirty & /*stores*/ 8) shapeutil_changes.stores = /*stores*/ ctx[3];
- if (dirty & /*locale*/ 16) shapeutil_changes.locale = /*locale*/ ctx[4];
- if (dirty & /*isActive*/ 1) shapeutil_changes.isActive = /*isActive*/ ctx[0];
- if (dirty & /*isActiveFraction*/ 2) shapeutil_changes.isActiveFraction = /*isActiveFraction*/ ctx[1];
- if (dirty & /*isVisible*/ 4) shapeutil_changes.isVisible = /*isVisible*/ ctx[2];
- if (dirty & /*$imageRotation*/ 128) shapeutil_changes.imageRotation = /*$imageRotation*/ ctx[7];
- if (dirty & /*$imageFlipX*/ 32) shapeutil_changes.imageFlipX = /*$imageFlipX*/ ctx[5];
- if (dirty & /*$imageFlipY*/ 64) shapeutil_changes.imageFlipY = /*$imageFlipY*/ ctx[6];
- shapeutil.$set(shapeutil_changes);
- },
- i(local) {
- if (current) return;
- transition_in(shapeutil.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(shapeutil.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- destroy_component(shapeutil, detaching);
- }
- };
- }
- function instance$1($$self, $$props, $$invalidate) {
- let $rootRect;
- let $imageSize;
- let $imageTransforms;
- let $imageFlipX;
- let $imageFlipY;
- let $imageRotation;
- const name = "redact";
- let { isActive } = $$props;
- let { isActiveFraction } = $$props;
- let { isVisible } = $$props;
- let { stores } = $$props;
- let { locale = {} } = $$props;
- // connect filter choice to stores
- const { imageRedaction, rootRect, imageSize, imageTransforms, imageRotation, imageFlipX, imageFlipY } = stores;
- component_subscribe($$self, rootRect, value => $$invalidate(20, $rootRect = value));
- component_subscribe($$self, imageSize, value => $$invalidate(21, $imageSize = value));
- component_subscribe($$self, imageTransforms, value => $$invalidate(22, $imageTransforms = value));
- component_subscribe($$self, imageRotation, value => $$invalidate(7, $imageRotation = value));
- component_subscribe($$self, imageFlipX, value => $$invalidate(5, $imageFlipX = value));
- component_subscribe($$self, imageFlipY, value => $$invalidate(6, $imageFlipY = value));
- //
- // Mapping coordinates
- //
- const mapScreenPointToImagePoint = point => _mapScreenPointToImagePoint(point, $rootRect, $imageSize, $imageTransforms.origin, $imageTransforms.translation, $imageTransforms.rotation.z, $imageTransforms.scale, $imageFlipX, $imageFlipY);
- const mapImagePointToScreenPoint = point => _mapImagePointToScreenPoint(point, $rootRect, $imageSize, $imageTransforms.origin, $imageTransforms.translation, $imageTransforms.rotation.z, $imageTransforms.scale, $imageFlipX, $imageFlipY);
- const func = controls => {
- const children = getNodeChildren(controls[0]);
- removeNode("to-front", children);
- return controls;
- };
- function measure_handler(event) {
- bubble($$self, event);
- }
- $$self.$$set = $$props => {
- if ("isActive" in $$props) $$invalidate(0, isActive = $$props.isActive);
- if ("isActiveFraction" in $$props) $$invalidate(1, isActiveFraction = $$props.isActiveFraction);
- if ("isVisible" in $$props) $$invalidate(2, isVisible = $$props.isVisible);
- if ("stores" in $$props) $$invalidate(3, stores = $$props.stores);
- if ("locale" in $$props) $$invalidate(4, locale = $$props.locale);
- };
- return [
- isActive,
- isActiveFraction,
- isVisible,
- stores,
- locale,
- $imageFlipX,
- $imageFlipY,
- $imageRotation,
- imageRedaction,
- rootRect,
- imageSize,
- imageTransforms,
- imageRotation,
- imageFlipX,
- imageFlipY,
- mapScreenPointToImagePoint,
- mapImagePointToScreenPoint,
- name,
- func,
- measure_handler
- ];
- }
- class Redact extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$1, create_fragment$1, safe_not_equal, {
- name: 17,
- isActive: 0,
- isActiveFraction: 1,
- isVisible: 2,
- stores: 3,
- locale: 4
- });
- }
- get name() {
- return this.$$.ctx[17];
- }
- get isActive() {
- return this.$$.ctx[0];
- }
- set isActive(isActive) {
- this.$set({ isActive });
- flush();
- }
- get isActiveFraction() {
- return this.$$.ctx[1];
- }
- set isActiveFraction(isActiveFraction) {
- this.$set({ isActiveFraction });
- flush();
- }
- get isVisible() {
- return this.$$.ctx[2];
- }
- set isVisible(isVisible) {
- this.$set({ isVisible });
- flush();
- }
- get stores() {
- return this.$$.ctx[3];
- }
- set stores(stores) {
- this.$set({ stores });
- flush();
- }
- get locale() {
- return this.$$.ctx[4];
- }
- set locale(locale) {
- this.$set({ locale });
- flush();
- }
- }
- // @ts-ignore
- var _plugin_redact = { util: ['redact', Redact] };
- const IconCross =
- '<g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width=".125em"><path d="M18 6L6 18M6 6l12 12"></path></path></g>';
- const CharacterA =
- '<path fill="none" d="M9 15 L12 9 L15 15 M10 13.5 h3" stroke="currentColor" stroke-width=".125em"/>';
- var _locale_en_gb = {
- // generic
- labelReset: 'Reset',
- labelDefault: 'Default',
- labelAuto: 'Auto',
- labelNone: 'None',
- labelEdit: 'Edit',
- labelClose: 'Close',
- labelSupportError: (features) => `${features.join(', ')} not supported on this browser`,
- // defaults
- labelColor: 'Color',
- labelWidth: 'Width',
- labelSize: 'Size',
- labelOffset: 'Offset',
- labelAmount: 'Amount',
- labelInset: 'Inset',
- labelRadius: 'Radius',
- // sizes
- labelSizeExtraSmall: 'Extra small',
- labelSizeSmall: 'Small',
- labelSizeMediumSmall: 'Medium small',
- labelSizeMedium: 'Medium',
- labelSizeMediumLarge: 'Medium large',
- labelSizeLarge: 'Large',
- labelSizeExtraLarge: 'Extra large',
- // unused?
- labelButtonRevert: 'Revert',
- labelButtonCancel: 'Cancel',
- labelButtonUndo: 'Undo',
- labelButtonRedo: 'Redo',
- labelButtonExport: 'Done',
- iconSupportError: `<g fill="none" stroke="currentColor" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><g><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></g>`,
- iconButtonClose: IconCross,
- iconButtonRevert: `<g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width=".125em"><path d="M7.388 18.538a8 8 0 10-2.992-9.03"/><path fill="currentColor" d="M2.794 11.696L2.37 6.714l5.088 3.18z"/><path d="M12 8v4M12 12l4 2"/></g>`,
- iconButtonUndo: `<g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width=".125em"><path d="M10 8h4c2.485 0 5 2 5 5s-2.515 5-5 5h-4"/><path fill="currentColor" d="M5 8l4-3v6z"/></g>`,
- iconButtonRedo: `<g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width=".125em"><path d="M14 8h-4c-2.485 0-5 2-5 5s2.515 5 5 5h4"/><path fill="currentColor" d="M19 8l-4-3v6z"/></g>`,
- iconButtonExport: `<polyline points="20 6 9 17 4 12" fill="none" stroke="currentColor" stroke-width=".125em"></polyline>`,
- // status
- statusLabelButtonClose: 'Close',
- statusIconButtonClose: IconCross,
- statusLabelLoadImage: (state) => {
- if (!state || !state.task) return 'Waiting for image';
- if (state.error)
- return state.error.code === 'IMAGE_TOO_SMALL'
- ? 'Minimum image size is {minWidth} × {minHeight}'
- : 'Error loading image';
- if (state.task === 'blob-to-bitmap') return 'Creating preview…';
- return 'Loading image…';
- },
- // processing status message
- statusLabelProcessImage: (state) => {
- if (!state || !state.task) return undefined;
- if (state.task === 'store') {
- if (state.error) return 'Error uploading image';
- return 'Uploading image…';
- }
- if (state.error) return 'Error processing image';
- return 'Processing image…';
- },
- };
- const MarkupEditor = {
- shapeLabelButtonSelectSticker: 'Select image',
- shapeIconButtonSelectSticker: `<g fill="none" stroke="currentColor" stroke-width="0.0625em"><path d="M8 21 L15 11 L19 15"/><path d="M15 2 v5 h5"/><path d="M8 2 h8 l4 4 v12 q0 4 -4 4 h-8 q-4 0 -4 -4 v-12 q0 -4 4 -4z"/></g><circle fill="currentColor" cx="10" cy="8" r="1.5"/>`,
- shapeIconButtonFlipHorizontal: `<g stroke="currentColor" stroke-width=".125em"><path fill="none" d="M6 6.5h5v11H6z"/><path fill="currentColor" d="M15 6.5h3v11h-3z"/><path d="M11 4v16" fill="currentColor"/></g>`,
- shapeIconButtonFlipVertical: `<g stroke="currentColor" stroke-width=".125em"><rect x="7" y="8" width="11" height="5" fill="none"/><rect x="7" y="17" width="11" height="2" fill="currentColor"/><line x1="5" y1="13" x2="20" y2="13"/></g>`,
- shapeIconButtonRemove: `<g fill="none" fill-rule="evenodd"><path stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M7.5 7h9z"/><path d="M7.916 9h8.168a1 1 0 01.99 1.14l-.972 6.862a2 2 0 01-1.473 1.653c-.877.23-1.753.345-2.629.345-.876 0-1.752-.115-2.628-.345a2 2 0 01-1.473-1.653l-.973-6.862A1 1 0 017.916 9z" fill="currentColor"/><rect fill="currentColor" x="10" y="5" width="4" height="3" rx="1"/></g>`,
- shapeIconButtonDuplicate: `<g fill="none" fill-rule="evenodd"><path d="M15 13.994V16a2 2 0 01-2 2H8a2 2 0 01-2-2v-5a2 2 0 012-2h2.142" stroke="currentColor" stroke-width=".125em"/><path d="M15 9V8a1 1 0 00-2 0v1h-1a1 1 0 000 2h1v1a1 1 0 002 0v-1h1a1 1 0 000-2h-1zm-4-4h6a2 2 0 012 2v6a2 2 0 01-2 2h-6a2 2 0 01-2-2V7a2 2 0 012-2z" fill="currentColor"/></g>`,
- shapeIconButtonMoveToFront: `<g fill="none" fill-rule="evenodd"><rect fill="currentColor" x="11" y="13" width="8" height="2" rx="1"/><rect fill="currentColor" x="9" y="17" width="10" height="2" rx="1"/><path d="M11.364 8H10a5 5 0 000 10M12 6.5L14.5 8 12 9.5z" stroke="currentColor" stroke-width=".125em" stroke-linecap="round"/></g>`,
- shapeIconButtonTextLayoutAutoWidth: `${CharacterA}`,
- shapeIconButtonTextLayoutAutoHeight: `<g fill="currentColor"><circle cx="4" cy="12" r="1.5"/><circle cx="20" cy="12" r="1.5"/></g>${CharacterA}`,
- shapeIconButtonTextLayoutFixedSize: `<g fill="currentColor"><circle cx="5" cy="6" r="1.5"/><circle cx="19" cy="6" r="1.5"/><circle cx="19" cy="19" r="1.5"/><circle cx="5" cy="19" r="1.5"/></g>${CharacterA}`,
- shapeTitleButtonTextLayoutAutoWidth: 'Auto width',
- shapeTitleButtonTextLayoutAutoHeight: 'Auto height',
- shapeTitleButtonTextLayoutFixedSize: 'Fixed size',
- shapeTitleButtonFlipHorizontal: 'Flip Horizontal',
- shapeTitleButtonFlipVertical: 'Flip Vertical',
- shapeTitleButtonRemove: 'Remove',
- shapeTitleButtonDuplicate: 'Duplicate',
- shapeTitleButtonMoveToFront: 'Move to front',
- shapeLabelInputText: 'Edit text',
- shapeIconInputCancel: `<g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width=".125em"><path d="M18 6L6 18M6 6l12 12"/></g>`,
- shapeIconInputConfirm: `<g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width=".125em"><polyline points="20 6 9 17 4 12"/></g>`,
- shapeLabelInputCancel: 'Cancel',
- shapeLabelInputConfirm: 'Confirm',
- shapeLabelStrokeNone: 'No outline',
- shapeLabelFontStyleNormal: 'Normal',
- shapeLabelFontStyleBold: 'Bold',
- shapeLabelFontStyleItalic: 'Italic',
- shapeLabelFontStyleItalicBold: 'Bold Italic',
- shapeTitleBackgroundColor: 'Fill color',
- shapeTitleFontFamily: 'Font',
- shapeTitleFontSize: 'Font size',
- shapeTitleFontStyle: 'Font style',
- shapeTitleLineHeight: 'Leading',
- shapeTitleLineStart: 'Start',
- shapeTitleLineEnd: 'End',
- shapeTitleStrokeWidth: 'Line width',
- shapeTitleStrokeColor: 'Line color',
- shapeTitleLineDecorationBar: 'Bar',
- shapeTitleLineDecorationCircle: 'Circle',
- shapeTitleLineDecorationSquare: 'Square',
- shapeTitleLineDecorationArrow: 'Arrow',
- shapeTitleLineDecorationCircleSolid: 'Circle solid',
- shapeTitleLineDecorationSquareSolid: 'Square solid',
- shapeTitleLineDecorationArrowSolid: 'Arrow solid',
- shapeIconLineDecorationBar: `<g stroke="currentColor" stroke-linecap="round" stroke-width=".125em"><path d="M5,12 H16"/><path d="M16,8 V16"/></g>`,
- shapeIconLineDecorationCircle: `<g stroke="currentColor" stroke-linecap="round"><path stroke-width=".125em" d="M5,12 H12"/><circle fill="none" stroke-width=".125em" cx="16" cy="12" r="4"/></g>`,
- shapeIconLineDecorationSquare: `<g stroke="currentColor" stroke-linecap="round"><path stroke-width=".125em" d="M5,12 H12"/><rect fill="none" stroke-width=".125em" x="12" y="8" width="8" height="8"/></g>`,
- shapeIconLineDecorationArrow: `<g stroke="currentColor" stroke-linecap="round" stroke-width=".125em"><path d="M5,12 H16 M13,7 l6,5 l-6,5" fill="none"/></g>`,
- shapeIconLineDecorationCircleSolid: `<g stroke="currentColor" stroke-linecap="round"><path stroke-width=".125em" d="M5,12 H12"/><circle fill="currentColor" cx="16" cy="12" r="4"/></g>`,
- shapeIconLineDecorationSquareSolid: `<g stroke="currentColor" stroke-linecap="round"><path stroke-width=".125em" d="M5,12 H12"/><rect fill="currentColor" x="12" y="8" width="8" height="8"/></g>`,
- shapeIconLineDecorationArrowSolid: `<g stroke="currentColor" stroke-linecap="round" stroke-width=".125em"><path d="M5,12 H16"/><path d="M13,7 l6,5 l-6,5z" fill="currentColor"/></g>`,
- shapeTitleColorTransparent: 'Transparent',
- shapeTitleColorWhite: 'White',
- shapeTitleColorSilver: 'Silver',
- shapeTitleColorGray: 'Gray',
- shapeTitleColorBlack: 'Black',
- shapeTitleColorNavy: 'Navy',
- shapeTitleColorBlue: 'Blue',
- shapeTitleColorAqua: 'Aqua',
- shapeTitleColorTeal: 'Teal',
- shapeTitleColorOlive: 'Olive',
- shapeTitleColorGreen: 'Green',
- shapeTitleColorYellow: 'Yellow',
- shapeTitleColorOrange: 'Orange',
- shapeTitleColorRed: 'Red',
- shapeTitleColorMaroon: 'Maroon',
- shapeTitleColorFuchsia: 'Fuchsia',
- shapeTitleColorPurple: 'Purple',
- shapeTitleTextColor: 'Font color',
- shapeTitleTextAlign: 'Text align',
- shapeTitleTextAlignLeft: 'Left align text',
- shapeTitleTextAlignCenter: 'Center align text',
- shapeTitleTextAlignRight: 'Right align text',
- shapeIconTextAlignLeft: `<g stroke-width=".125em" stroke="currentColor"><line x1="5" y1="8" x2="15" y2="8"/><line x1="5" y1="12" x2="19" y2="12"/><line x1="5" y1="16" x2="14" y2="16"/></g>`,
- shapeIconTextAlignCenter: `<g stroke-width=".125em" stroke="currentColor"><line x1="7" y1="8" x2="17" y2="8"/><line x1="5" y1="12" x2="19" y2="12"/><line x1="8" y1="16" x2="16" y2="16"/></g>`,
- shapeIconTextAlignRight: `<g stroke-width=".125em" stroke="currentColor"><line x1="9" y1="8" x2="19" y2="8"/><line x1="5" y1="12" x2="19" y2="12"/><line x1="11" y1="16" x2="19" y2="16"/></g>`,
- shapeLabelToolSharpie: 'Sharpie',
- shapeLabelToolEraser: 'Eraser',
- shapeLabelToolRectangle: 'Rectangle',
- shapeLabelToolEllipse: 'Ellipse',
- shapeLabelToolArrow: 'Arrow',
- shapeLabelToolLine: 'Line',
- shapeLabelToolText: 'Text',
- shapeLabelToolPreset: 'Stickers',
- shapeIconToolSharpie: `<g stroke-width=".125em" stroke="currentColor" fill="none"><path d="M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1" stroke="currentColor" stroke-width=".125em" fill="none" fill-rule="evenodd" stroke-linejoin="round"/></g>`,
- shapeIconToolEraser: `<g stroke-width=".125em" stroke="currentColor" stroke-linecap="round" fill="none"><g transform="translate(3, 15) rotate(-45)"><rect x="0" y="0" width="18" height="10" rx="3"/></g><line x1="11" y1="21" x2="18" y2="21"/><line x1="20" y1="21" x2="22" y2="21"/></g>`,
- shapeIconToolRectangle: `<g stroke-width=".125em" stroke="currentColor" fill="none"><rect x="2" y="2" width="20" height="20" rx="3"/></g>`,
- shapeIconToolEllipse: `<g stroke-width=".125em" stroke="currentColor" fill="none"><circle cx="12" cy="12" r="11"/></g>`,
- shapeIconToolArrow: `<g stroke-width=".125em" stroke="currentColor" fill="none"><line x1="20" y1="3" x2="6" y2="21"/><path d="m10 5 L22 1 L21 13" fill="currentColor" stroke="none"/></g>`,
- shapeIconToolLine: `<g stroke-width=".125em" stroke="currentColor" fill="none"><line x1="20" y1="3" x2="6" y2="21"/></g>`,
- shapeIconToolText: `<g stroke="none" fill="currentColor" transform="translate(6,0)"><path d="M8.14 20.085c.459 0 .901-.034 1.329-.102a8.597 8.597 0 001.015-.21v1.984c-.281.135-.695.247-1.242.336a9.328 9.328 0 01-1.477.133c-3.312 0-4.968-1.745-4.968-5.235V6.804H.344v-1.25l2.453-1.078L3.89.819h1.5v3.97h4.97v2.015H5.39v10.078c0 1.031.245 1.823.735 2.375s1.161.828 2.015.828z"/>`,
- shapeIconToolPreset: `<g fill="none" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width=".125em"><path d="M12 22c2.773 0 1.189-5.177 3-7 1.796-1.808 7-.25 7-3 0-5.523-4.477-10-10-10S2 6.477 2 12s4.477 10 10 10z"></path><path d="M20 17c-3 3-5 5-8 5"></path></g>`,
- };
- var _plugin_crop_locale_en_gb = {
- cropLabel: 'Crop',
- cropIcon:
- '<g stroke-width=".125em" stroke="currentColor" fill="none"><path d="M23 17H9a2 2 0 0 1-2-2v-5m0-3V1 M1 7h14a2 2 0 0 1 2 2v7m0 4v3"/></g>',
- cropIconButtonRecenter: `<path stroke="currentColor" fill="none" stroke-width="2" stroke-linejoin="bevel" d="M1.5 7.5v-6h6M1.5 16.5v6h6M22.5 16.5v6h-6M22.5 7.5v-6h-6"/><circle cx="12" cy="12" r="3.5" fill="currentColor" stroke="none"/>`,
- cropIconButtonRotateLeft:
- '<g stroke="none" fill="currentColor"><path fill="none" d="M-1-1h582v402H-1z"/><rect x="3" rx="1" height="12" width="12" y="9"/><path d="M15 5h-1a5 5 0 015 5 1 1 0 002 0 7 7 0 00-7-7h-1.374l.747-.747A1 1 0 0011.958.84L9.603 3.194a1 1 0 000 1.415l2.355 2.355a1 1 0 001.415-1.414l-.55-.55H15z"/></g>',
- cropIconButtonRotateRight:
- '<g stroke="none" fill="currentColor"><path fill="none" d="M-1-1h582v402H-1z"/><path d="M11.177 5H10a5 5 0 00-5 5 1 1 0 01-2 0 7 7 0 017-7h1.374l-.747-.747A1 1 0 0112.042.84l2.355 2.355a1 1 0 010 1.415l-2.355 2.354a1 1 0 01-1.415-1.414l.55-.55z"/><rect rx="1" height="12" width="12" y="9" x="9"/></g>',
- cropIconButtonFlipVertical:
- '<g stroke="none" fill="currentColor"><path d="M19.993 12.143H7a1 1 0 0 1-1-1V5.994a1 1 0 0 1 1.368-.93l12.993 5.15a1 1 0 0 1-.368 1.93z"/><path d="M19.993 14a1 1 0 0 1 .368 1.93L7.368 21.078A1 1 0 0 1 6 20.148V15a1 1 0 0 1 1-1h12.993z" opacity=".6"/></g>',
- cropIconButtonFlipHorizontal:
- '<g stroke="none" fill="currentColor"><path d="M11.93 7.007V20a1 1 0 0 1-1 1H5.78a1 1 0 0 1-.93-1.368l5.15-12.993a1 1 0 0 1 1.929.368z"/><path d="M14 7.007V20a1 1 0 0 0 1 1h5.149a1 1 0 0 0 .93-1.368l-5.15-12.993A1 1 0 0 0 14 7.007z" opacity=".6"/></g>',
- cropIconSelectPreset: (locale, aspectRatio) => {
- const [a, b, c] = !aspectRatio
- ? [0.2, 0.3, 0.4]
- : [
- aspectRatio < 1 ? 1 : 0.3,
- aspectRatio === 1 ? 0.85 : 0.5,
- aspectRatio > 1 ? 1 : 0.3,
- ];
- return `<g fill="currentColor">
- <rect opacity="${a}" x="2" y="4" width="10" height="18" rx="1"/>
- <rect opacity="${b}" x="4" y="8" width="14" height="14" rx="1"/>
- <rect opacity="${c}" x="6" y="12" width="17" height="10" rx="1"/>
- </g>`;
- },
- cropIconCropBoundary: (locale, isBoundToImage) => {
- const [a, b, c, d] = isBoundToImage ? [0.3, 1, 0, 0] : [0, 0, 0.3, 1];
- return `<g fill="currentColor">
- <rect opacity="${a}" x="2" y="3" width="20" height="20" rx="1"/>
- <rect opacity="${b}" x="7" y="8" width="10" height="10" rx="1"/>
- <rect opacity="${c}" x="4" y="8" width="14" height="14" rx="1"/>
- <rect opacity="${d}" x="12" y="4" width="10" height="10" rx="1"/>
- </g>`;
- },
- cropLabelButtonRecenter: 'Recenter',
- cropLabelButtonRotateLeft: 'Rotate left',
- cropLabelButtonRotateRight: 'Rotate right',
- cropLabelButtonFlipHorizontal: 'Flip horizontal',
- cropLabelButtonFlipVertical: 'Flip vertical',
- cropLabelSelectPreset: 'Crop shape',
- cropLabelCropBoundary: 'Crop boundary',
- cropLabelCropBoundaryEdge: 'Edge of image',
- cropLabelCropBoundaryNone: 'None',
- cropLabelTabRotation: 'Rotation',
- cropLabelTabZoom: 'Zoom',
- };
- var _plugin_filter_locale_en_gb = {
- filterLabel: 'Filter',
- filterIcon:
- '<g stroke-width=".125em" stroke="currentColor" fill="none"><path d="M18.347 9.907a6.5 6.5 0 1 0-1.872 3.306M3.26 11.574a6.5 6.5 0 1 0 2.815-1.417 M10.15 17.897A6.503 6.503 0 0 0 16.5 23a6.5 6.5 0 1 0-6.183-8.51"/></g>',
- filterLabelChrome: 'Chrome',
- filterLabelFade: 'Fade',
- filterLabelCold: 'Cold',
- filterLabelWarm: 'Warm',
- filterLabelPastel: 'Pastel',
- filterLabelMonoDefault: 'Mono',
- filterLabelMonoNoir: 'Noir',
- filterLabelMonoWash: 'Wash',
- filterLabelMonoStark: 'Stark',
- filterLabelSepiaDefault: 'Sepia',
- filterLabelSepiaBlues: 'Blues',
- filterLabelSepiaRust: 'Rust',
- filterLabelSepiaColor: 'Color',
- };
- var _plugin_finetune_locale_en_gb = {
- finetuneLabel: 'Finetune',
- finetuneIcon:
- '<g stroke-width=".125em" stroke="currentColor" fill="none"><path d="M4 1v5.5m0 3.503V23M12 1v10.5m0 3.5v8M20 1v15.5m0 3.5v3M2 7h4M10 12h4M18 17h4"/></g>',
- finetuneLabelBrightness: 'Brightness',
- finetuneLabelContrast: 'Contrast',
- finetuneLabelSaturation: 'Saturation',
- finetuneLabelExposure: 'Exposure',
- finetuneLabelTemperature: 'Temperature',
- finetuneLabelGamma: 'Gamma',
- finetuneLabelClarity: 'Clarity',
- finetuneLabelVignette: 'Vignette',
- };
- var _plugin_resize_locale_en_gb = {
- resizeLabel: 'Resize',
- resizeIcon:
- '<g stroke-width=".125em" stroke="currentColor" fill="none"><rect x="2" y="12" width="10" height="10" rx="2"/><path d="M4 11.5V4a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-5.5"/><path d="M14 10l3.365-3.365M14 6h4v4"/></g>',
- resizeLabelFormCaption: 'Image output size',
- resizeLabelInputWidth: 'w',
- resizeTitleInputWidth: 'Width',
- resizeLabelInputHeight: 'h',
- resizeTitleInputHeight: 'Height',
- resizeTitleButtonMaintainAspectRatio: 'Maintain aspectratio',
- resizeIconButtonMaintainAspectRatio: (active, activeFraction) => `
- <defs>
- <mask id="mask1" x="0" y="0" width="24" height="24" >
- <rect x="0" y="0" width="24" height="10" fill="#fff" stroke="none"/>
- </mask>
- </defs>
- <g fill="none" fill-rule="evenodd">
- <g mask="url(#mask1)">
- <path transform="translate(0 ${
- (activeFraction - 1) * 3
- })" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" d="M9.401 10.205v-.804a2.599 2.599 0 0 1 5.198 0V17"/>
- </g>
- <rect fill="currentColor" x="7" y="10" width="10" height="7" rx="1.5"/>
- </g>
- `,
- };
- var _plugin_decorate_locale_en_gb = {
- decorateLabel: 'Decorate',
- decorateIcon:
- '<g fill="none" fill-rule="evenodd"><path stroke="currentColor" stroke-width=".125em" stroke-linecap="round" stroke-linejoin="round" d="M12 18.5l-6.466 3.4 1.235-7.2-5.23-5.1 7.228-1.05L12 2l3.233 6.55 7.229 1.05-5.231 5.1 1.235 7.2z"/></g>',
- };
- var _plugin_annotate_locale_en_gb = {
- annotateLabel: 'Annotate',
- annotateIcon:
- '<g stroke-width=".125em" stroke="currentColor" fill="none"><path d="M17.086 2.914a2.828 2.828 0 1 1 4 4l-14.5 14.5-5.5 1.5 1.5-5.5 14.5-14.5z"/></g>',
- };
- var _plugin_sticker_locale_en_gb = {
- stickerLabel: 'Sticker',
- stickerIcon:
- '<g fill="none" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width=".125em"><path d="M12 22c2.773 0 1.189-5.177 3-7 1.796-1.808 7-.25 7-3 0-5.523-4.477-10-10-10S2 6.477 2 12s4.477 10 10 10z"/><path d="M20 17c-3 3-5 5-8 5"/></g>',
- };
- var _plugin_frame_locale_en_gb = {
- frameLabel: 'Frame',
- frameIcon: `<g fill="none" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width=".125em">
- <rect x="2" y="2" width="20" height="20" rx="4"/>
- <rect x="6" y="6" width="12" height="12" rx="1"/>
- </g>`,
- frameLabelMatSharp: 'Mat',
- frameLabelMatRound: 'Bevel',
- frameLabelLineSingle: 'Line',
- frameLabelLineMultiple: 'Zebra',
- frameLabelEdgeSeparate: 'Inset',
- frameLabelEdgeOverlap: 'Plus',
- frameLabelEdgeCross: 'Lumber',
- frameLabelCornerHooks: 'Hook',
- frameLabelPolaroid: 'Polaroid',
- };
- var _plugin_redact_locale_en_gb = {
- redactLabel: 'Redact',
- redactIcon: `<g fill="none" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width=".125em">
- <path d="M 2 7 l 0.1 -.1"/>
- <path d="M 2 12 l 5 -5"/>
- <path d="M 2 17 l 10 -10"/>
- <path d="M 7 17 l 10 -10"/>
- <path d="M 12 17 l 10 -10"/>
- <path d="M 17 17 l 5 -5"/>
- <path d="M 22 17 l .1 -.1"/>
- </g>`,
- };
- var hasDefinedCustomElement = (name) => document.createElement(name).constructor !== HTMLElement;
- var linkAccessors = (destination, origin) => {
- const descriptors = Object.getOwnPropertyDescriptors(destination);
- Object.keys(descriptors).forEach((key) => {
- // props, set new setter and getter
- if (!!descriptors[key]['get']) {
- Object.defineProperty(origin, key, {
- get: () => destination[key],
- set: (value) => (destination[key] = value),
- });
- }
- // method, copy reference
- else {
- origin[key] = destination[key];
- }
- });
- };
- var hasDoctype = () => isBrowser() && document.doctype !== null;
- var initEditorView = (target) => {
- const accessors = {};
- const { sub, pub } = pubsub();
- // catch missing doctype
- if (!hasDoctype())
- console.warn('Browser is in quirks mode, add <!DOCTYPE html> to page to fix render issues');
- // create editor core
- const core = createImageEditor();
- linkAccessors(core, accessors);
- // create editor view
- const view = attachEditorView(target, core.stores);
- linkAccessors(view, accessors);
- // listen for UI interaction and link to editor API (internals)
- const unsubs = ['loadImage', 'processImage', 'abortProcessImage', 'abortLoadImage'].map((event) => view.on(event, (e) => {
- // run core method, if returns a promise, we silence errors as those are passed to the UI via stores
- const returned = core[event](e && e.detail);
- if (returned instanceof Promise)
- returned.catch(() => { });
- }));
- // auto subscribes on each possible publisher
- const subscribe = (event, cb) => {
- const unsubInit = sub(event, cb);
- const unsubCore = core.on(event, cb);
- const unsubView = view.on(event, cb);
- return () => {
- unsubInit();
- unsubCore();
- unsubView();
- };
- };
- // handles every event, useful for routing events from the options object
- accessors.handleEvent = noop$1;
- const handleEventUnsubs = editorEvents.map((type) => subscribe(type, (res) => accessors.handleEvent(type, res)));
- // set up new api
- defineMethods(accessors, {
- on: subscribe,
- updateImage: (src) => new Promise((resolve, reject) => {
- // save history
- const storedHistory = accessors.history.get();
- // save state
- const storedState = accessors.imageState;
- // update image
- core.loadImage(src)
- .then((res) => {
- // restore history
- accessors.history.set(storedHistory);
- // restore state
- accessors.imageState = storedState;
- // done!
- resolve(res);
- })
- .catch(reject);
- }),
- close: () => {
- pub('close');
- },
- destroy: () => {
- // unsub
- [...unsubs, ...handleEventUnsubs].forEach((unsub) => unsub());
- // destroy
- view.destroy();
- core.destroy();
- // destroyed
- pub('destroy');
- },
- });
- return accessors;
- };
- const TAG = 'pintura-editor';
- var _defineCustomElements = () => new Promise((resolve) => {
- if (!PinturaImageEditorElement)
- return resolve([]);
- !hasDefinedCustomElement(TAG) && customElements.define(TAG, PinturaImageEditorElement);
- customElements.whenDefined(TAG).then(() => resolve(document.querySelectorAll(TAG)));
- });
- const PinturaImageEditorElement = isBrowser() &&
- class extends HTMLElement {
- constructor() {
- super();
- this._editor = undefined;
- this._unsubs = undefined;
- }
- static get observedAttributes() {
- return ['src'];
- }
- attributeChangedCallback(attrName, oldValue, newValue) {
- this[attrName] = newValue;
- }
- connectedCallback() {
- this._editor = initEditorView(this);
- linkAccessors(this._editor, this);
- this._editor.src = this.getAttribute('src');
- this._unsubs = dispatchEditorEvents(this._editor, this);
- }
- disconnectedCallback() {
- this._editor.destroy();
- this._unsubs.forEach((unsub) => unsub());
- }
- };
- const CSS_CLASS_NAME = 'pintura-editor';
- var _appendEditor = (target, options = {}) => {
- const element = isString(target)
- ? document.querySelector(target)
- : target;
- if (!isElement(element))
- return undefined;
- options.class = options.class ? `${CSS_CLASS_NAME} ${options.class}` : CSS_CLASS_NAME;
- const accessors = initEditorView(element);
- return Object.assign(accessors, options);
- };
- /* src/core/ui/modal/index.svelte generated by Svelte v3.37.0 */
- const { document: document_1, window: window_1 } = globals;
- function create_fragment(ctx) {
- let t;
- let div;
- let mounted;
- let dispose;
- add_render_callback(/*onwindowresize*/ ctx[27]);
- return {
- c() {
- t = space();
- div = element("div");
- attr(div, "class", /*className*/ ctx[5]);
- attr(div, "style", /*style*/ ctx[4]);
- },
- m(target, anchor) {
- insert(target, t, anchor);
- insert(target, div, anchor);
- /*div_binding*/ ctx[28](div);
- if (!mounted) {
- dispose = [
- listen(window_1, "keydown", /*handleKey*/ ctx[10]),
- listen(window_1, "orientationchange", /*spawnMeasureElement*/ ctx[11]),
- listen(window_1, "resize", /*onwindowresize*/ ctx[27]),
- listen(document_1.body, "focusin", function () {
- if (is_function(!/*hidden*/ ctx[1] && /*handleFocusIn*/ ctx[7])) (!/*hidden*/ ctx[1] && /*handleFocusIn*/ ctx[7]).apply(this, arguments);
- }),
- listen(document_1.body, "focusout", function () {
- if (is_function(/*hasFocussedTextField*/ ctx[2] && /*handleFocusOut*/ ctx[8])) (/*hasFocussedTextField*/ ctx[2] && /*handleFocusOut*/ ctx[8]).apply(this, arguments);
- }),
- listen(div, "wheel", /*handleWheel*/ ctx[9], { passive: false })
- ];
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- if (dirty[0] & /*className*/ 32) {
- attr(div, "class", /*className*/ ctx[5]);
- }
- if (dirty[0] & /*style*/ 16) {
- attr(div, "style", /*style*/ ctx[4]);
- }
- },
- i: noop,
- o: noop,
- d(detaching) {
- if (detaching) detach(t);
- if (detaching) detach(div);
- /*div_binding*/ ctx[28](null);
- mounted = false;
- run_all(dispose);
- }
- };
- }
- function instance($$self, $$props, $$invalidate) {
- let o;
- let viewportRules;
- let isOpaque;
- let isIOSFooterVisible;
- let style;
- let className;
- let scrollsBodyOnInteraction;
- let $opacity;
- const dispatch = createEventDispatcher();
- let { root } = $$props;
- let { preventZoomViewport = true } = $$props;
- let { preventScrollBodyIfNeeded = true } = $$props;
- let { preventFooterOverlapIfNeeded = true } = $$props;
- let { class: klass = undefined } = $$props;
- let hidden = true;
- let hiding = false;
- let showing = false;
- let doc = isBrowser() && document.documentElement;
- let body = isBrowser() && document.body;
- let head = isBrowser() && document.head;
- const opacity = spring(0, { precision: 0.001, damping: 0.5 });
- component_subscribe($$self, opacity, value => $$invalidate(23, $opacity = value));
- // animate hide and show
- const unsub = opacity.subscribe(o => {
- if (showing && o >= 1) {
- $$invalidate(19, showing = false); // now shown
- $$invalidate(1, hidden = false);
- dispatch("show");
- } else if (hiding && o <= 0) {
- $$invalidate(18, hiding = false); // now hidden
- $$invalidate(1, hidden = true);
- dispatch("hide");
- }
- });
- // clean up when removed
- onDestroy(() => {
- // make sure no longer locking body element
- doc.classList.remove("PinturaModalBodyLock");
- // clean up subs
- unsub();
- });
- let hasFocussedTextField = false;
- let viewportDefaults = undefined;
- let themeDefaults = undefined;
- let showTimeoutId = undefined;
- const getViewPortElement = () => document.querySelector("meta[name=viewport]");
- const getThemeElements = () => Array.from(document.querySelectorAll("meta[name=theme-color]"));
- const show = () => {
- // is visible, or busy becoming visible
- if (showing || !hidden) return;
- // now in 'showing' transition
- $$invalidate(19, showing = true);
- // store default viewport element values
- const viewportElement = getViewPortElement() || h("meta", { name: "viewport" });
- viewportDefaults = !viewportDefaults && viewportElement.getAttribute("content");
- viewportElement.setAttribute("content", viewportRules + ((/cover/).test(viewportDefaults)
- ? ",viewport-fit=cover"
- : ""));
- if (!viewportElement.parentNode) head.append(viewportElement);
- // store default theme element values
- const backgroundColor = getComputedStyle(root).getPropertyValue("--color-background");
- const themeElements = getThemeElements();
- if (themeElements.length) {
- // store defaults
- themeDefaults = themeElements.map(element => element.getAttribute("content"));
- } else {
- // create element
- const themeElement = h("meta", { name: "theme-color" });
- head.append(themeElement);
- themeElements.push(themeElement);
- }
- // update colors
- themeElements.forEach(element => element.setAttribute("content", `rgb(${backgroundColor})`));
- clearTimeout(showTimeoutId);
- showTimeoutId = setTimeout(() => opacity.set(1), 250);
- };
- const hide = () => {
- // is hiding or already hidden
- if (hiding || hidden) return;
- // if previous command was show, we need to prevent the timeout from kicking off
- clearTimeout(showTimeoutId);
- // now in 'hiding' transition
- $$invalidate(18, hiding = true);
- // get a reference to the viewport element, it should be there as we created it earlier,
- // we restore defaults if the viewport metatag was defined, if not, we destroy it
- const viewportElement = getViewPortElement();
- if (viewportDefaults) viewportElement.setAttribute("content", viewportDefaults); else viewportElement.remove();
- // restore colors
- const themeElements = getThemeElements();
- if (themeDefaults) {
- themeElements.forEach((element, index) => {
- element.setAttribute("content", themeDefaults[index]);
- });
- } else themeElements.forEach(element => element.remove());
- // let's hide!
- opacity.set(0);
- };
- //
- // handle soft keyboard impact on window height
- //
- let focusOutTimer;
- let focusInWindowHeight;
- const handleFocusIn = e => {
- // test if is text input element
- if (!(/textarea/i).test(e.target)) return;
- // now focussing a field
- $$invalidate(2, hasFocussedTextField = true);
- focusInWindowHeight = windowHeight;
- };
- const handleFocusOut = e => {
- // test if is text input element
- if (!(/textarea/i).test(e.target)) return;
- // prevent accidentally setting two timers
- clearTimeout(focusOutTimer);
- // test if window height changed, if not, no soft keyboard appeared and we can set false to focus state immidiately
- if (focusInWindowHeight === windowHeight) {
- $$invalidate(2, hasFocussedTextField = false);
- } else // soft keyboard might have appeared, test for window height change before setting unfocus state
- {
- const windowCurrentHeight = windowHeight;
- runWhen(() => windowHeight !== windowCurrentHeight, () => $$invalidate(2, hasFocussedTextField = false));
- }
- };
- const runWhen = (test, cb) => {
- const frame = () => {
- if (test()) {
- cb();
- return;
- }
- requestAnimationFrame(frame);
- };
- requestAnimationFrame(frame);
- };
- //
- // end soft keyboard logic
- //
- // prevent mousewheel from scrolling content behind modal
- const handleWheel = e => e.preventDefault();
- // handle escape to close modal
- const handleKey = e => {
- // get key type
- const { key } = e;
- // only deal with escape key
- if (!(/escape/i).test(key)) return;
- // don't close when in an input or textuarea
- const targetElement = e.target;
- if (targetElement && (/input|textarea/i).test(targetElement.nodeName)) return;
- // only close if I'm the top modal
- const modals = document.querySelectorAll(".PinturaModal");
- if (modals[modals.length - 1] !== root) return;
- // request close
- dispatch("close");
- };
- // this logic scales modal to fit viewport height
- let windowHeight = 0;
- let windowHeightComputed;
- // iOS measure actual page height so we can make optional use of available space
- let measureElement;
- let measureElementHeight = undefined;
- const spawnMeasureElement = () => {
- // can't spawn more than one
- if (measureElement) return;
- // create measure element and append to body
- measureElement = h("div", {
- style: "position:fixed;height:100vh;top:0"
- });
- body.append(measureElement);
- };
- onMount(() => {
- // no need to run this logic if is not on iOS
- if (!preventFooterOverlapIfNeeded || !isIOS()) return;
- // will be used in first read to determine page height and bottom padding
- spawnMeasureElement();
- });
- afterUpdate(() => {
- // will only run on iOS
- if (!measureElement) return;
- // get height and store
- $$invalidate(21, measureElementHeight = measureElement.offsetHeight);
- // remove measure element
- measureElement.remove();
- measureElement = undefined;
- });
- //
- // document lock style for iOS 15.0
- //
- let scrollOffsetY = undefined;
- // syncs height of doc lock with window
- const syncHeight = () => doc.style.setProperty("--pintura-document-height", `${window.innerHeight}px`);
- const toggleDocumentLock = isOpaque => {
- if (isOpaque) {
- scrollOffsetY = window.scrollY;
- // prevents safari on iOS 15.0 from scrolling body and showing footer on drag interaction
- doc.classList.add("PinturaDocumentLock");
- // need to do this to sync height of initial window
- syncHeight();
- // also sync on resize
- window.addEventListener("resize", syncHeight);
- } else {
- // stop syncing height
- window.removeEventListener("resize", syncHeight);
- // clean up
- doc.classList.remove("PinturaDocumentLock");
- isNumber(scrollOffsetY) && window.scrollTo(0, scrollOffsetY);
- scrollOffsetY = undefined;
- }
- };
- function onwindowresize() {
- $$invalidate(3, windowHeight = window_1.innerHeight);
- }
- function div_binding($$value) {
- binding_callbacks[$$value ? "unshift" : "push"](() => {
- root = $$value;
- $$invalidate(0, root);
- });
- }
- $$self.$$set = $$props => {
- if ("root" in $$props) $$invalidate(0, root = $$props.root);
- if ("preventZoomViewport" in $$props) $$invalidate(12, preventZoomViewport = $$props.preventZoomViewport);
- if ("preventScrollBodyIfNeeded" in $$props) $$invalidate(13, preventScrollBodyIfNeeded = $$props.preventScrollBodyIfNeeded);
- if ("preventFooterOverlapIfNeeded" in $$props) $$invalidate(14, preventFooterOverlapIfNeeded = $$props.preventFooterOverlapIfNeeded);
- if ("class" in $$props) $$invalidate(15, klass = $$props.class);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*showing, hiding, $opacity, hidden*/ 9175042) {
- $$invalidate(22, o = showing || hiding ? $opacity : hidden ? 0 : 1);
- }
- if ($$self.$$.dirty[0] & /*preventZoomViewport*/ 4096) {
- viewportRules = "width=device-width,height=device-height,initial-scale=1" + (preventZoomViewport
- ? ",maximum-scale=1,user-scalable=0"
- : "");
- }
- if ($$self.$$.dirty[0] & /*showing, hidden, hiding*/ 786434) {
- $$invalidate(24, isOpaque = !showing && !hidden && !hiding);
- }
- if ($$self.$$.dirty[0] & /*hasFocussedTextField, windowHeight*/ 12) {
- if (!hasFocussedTextField) $$invalidate(20, windowHeightComputed = windowHeight);
- }
- if ($$self.$$.dirty[0] & /*measureElementHeight, windowHeight*/ 2097160) {
- $$invalidate(25, isIOSFooterVisible = isNumber(measureElementHeight)
- ? `--viewport-pad-footer:${measureElementHeight > windowHeight ? 0 : 1}`
- : "");
- }
- if ($$self.$$.dirty[0] & /*o, windowHeightComputed, isIOSFooterVisible*/ 38797312) {
- $$invalidate(4, style = `opacity:${o};height:${windowHeightComputed}px;--editor-modal:1;${isIOSFooterVisible}`);
- }
- if ($$self.$$.dirty[0] & /*klass*/ 32768) {
- $$invalidate(5, className = arrayJoin(["pintura-editor", "PinturaModal", klass]));
- }
- if ($$self.$$.dirty[0] & /*preventScrollBodyIfNeeded*/ 8192) {
- $$invalidate(26, scrollsBodyOnInteraction = preventScrollBodyIfNeeded && isIOS() && (/15_/).test(navigator.userAgent));
- }
- if ($$self.$$.dirty[0] & /*scrollsBodyOnInteraction, isOpaque*/ 83886080) {
- scrollsBodyOnInteraction && toggleDocumentLock(isOpaque);
- }
- };
- return [
- root,
- hidden,
- hasFocussedTextField,
- windowHeight,
- style,
- className,
- opacity,
- handleFocusIn,
- handleFocusOut,
- handleWheel,
- handleKey,
- spawnMeasureElement,
- preventZoomViewport,
- preventScrollBodyIfNeeded,
- preventFooterOverlapIfNeeded,
- klass,
- show,
- hide,
- hiding,
- showing,
- windowHeightComputed,
- measureElementHeight,
- o,
- $opacity,
- isOpaque,
- isIOSFooterVisible,
- scrollsBodyOnInteraction,
- onwindowresize,
- div_binding
- ];
- }
- class Modal extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance,
- create_fragment,
- safe_not_equal,
- {
- root: 0,
- preventZoomViewport: 12,
- preventScrollBodyIfNeeded: 13,
- preventFooterOverlapIfNeeded: 14,
- class: 15,
- show: 16,
- hide: 17
- },
- [-1, -1]
- );
- }
- get root() {
- return this.$$.ctx[0];
- }
- set root(root) {
- this.$set({ root });
- flush();
- }
- get preventZoomViewport() {
- return this.$$.ctx[12];
- }
- set preventZoomViewport(preventZoomViewport) {
- this.$set({ preventZoomViewport });
- flush();
- }
- get preventScrollBodyIfNeeded() {
- return this.$$.ctx[13];
- }
- set preventScrollBodyIfNeeded(preventScrollBodyIfNeeded) {
- this.$set({ preventScrollBodyIfNeeded });
- flush();
- }
- get preventFooterOverlapIfNeeded() {
- return this.$$.ctx[14];
- }
- set preventFooterOverlapIfNeeded(preventFooterOverlapIfNeeded) {
- this.$set({ preventFooterOverlapIfNeeded });
- flush();
- }
- get class() {
- return this.$$.ctx[15];
- }
- set class(klass) {
- this.$set({ class: klass });
- flush();
- }
- get show() {
- return this.$$.ctx[16];
- }
- get hide() {
- return this.$$.ctx[17];
- }
- }
- // @ts-ignore
- // we export a function that renders the view as to not export svelte component related code to outside the ui dir
- var createModal = (options = {}, parent) => new Modal({
- target: parent || document.body,
- props: {
- class: options.class,
- preventZoomViewport: options.preventZoomViewport,
- preventScrollBodyIfNeeded: options.preventScrollBodyIfNeeded,
- preventFooterOverlapIfNeeded: options.preventFooterOverlapIfNeeded,
- },
- });
- var _openEditor = (options = {}, parent) => {
- // set up pub/sub for the app layer
- const { sub, pub } = pubsub();
- const accessors = {};
- const modal = createModal(options, parent);
- const hide = () => {
- if (!modal.hide)
- return; // was destroyed
- modal.hide();
- };
- const show = () => {
- if (!modal.show)
- return; // was destroyed
- modal.show();
- };
- const view = initEditorView(modal.root);
- linkAccessors(view, accessors);
- // link up handle event
- accessors.handleEvent = noop$1;
- view.handleEvent = (type, detail) => accessors.handleEvent(type, detail);
- // route close request from view to modal
- view.on('close', async () => {
- const { willClose } = options;
- if (!willClose)
- return hide();
- const shouldClose = await willClose();
- if (shouldClose)
- hide();
- });
- const subscribe = (event, cb) => {
- // capture modal related events
- if (/show|hide/.test(event))
- return sub(event, cb);
- // route rest of events to view
- return view.on(event, cb);
- };
- const modalHandleEventUnsubs = ['show', 'hide'].map((type) => subscribe(type, (detail) => accessors.handleEvent(type, detail)));
- // cleans up view
- const destroy = () => {
- // unsub
- modalHandleEventUnsubs.forEach((unsub) => unsub());
- // remove
- hide();
- modal.$destroy();
- view.destroy();
- };
- defineMethods(accessors, {
- on: subscribe,
- destroy,
- hide,
- show,
- });
- // add element root query
- Object.defineProperty(accessors, 'modal', {
- get: () => modal.root,
- set: () => undefined,
- });
- // route modal events
- modal.$on('close', view.close);
- modal.$on('show', () => pub('show'));
- modal.$on('hide', () => {
- pub('hide');
- if (options.enableAutoDestroy !== false)
- destroy();
- });
- // modal behavior
- if (options.enableAutoHide !== false)
- view.on('process', hide);
- view.on('loadstart', show);
- // test if should
- if (options.enableButtonClose !== false)
- options.enableButtonClose = true;
- // delete class
- delete options.class;
- // update props
- Object.assign(accessors, options);
- return accessors;
- };
- var _overlayEditor = (target, options) => {
- const editor = _appendEditor(target, {
- ...options,
- layout: 'overlay',
- });
- return editor;
- };
- // helper method to calculate end style params that are passed to lineEnd style functions
- const getLineEndParams = (start, end, strokeWidth, isSolid) => {
- const direction = vectorCreate(end.x - start.x, end.y - start.y);
- const normal = vectorNormalize(direction);
- const scaledSize = 5 * strokeWidth;
- let scaledSizeHalf;
- // solid
- if (isSolid) {
- scaledSizeHalf = scaledSize * 0.5;
- }
- // stroke
- else {
- scaledSizeHalf = Math.ceil((scaledSize - 1) * 0.5);
- }
- const offset = vectorMultiply(vectorClone(normal), scaledSizeHalf);
- return {
- anchor: vectorClone(start),
- offset,
- normal,
- solid: isSolid,
- size: scaledSize,
- sizeHalf: scaledSizeHalf,
- };
- };
- // various available styles
- const lineEndStyleArrow = ({ anchor, solid, normal, offset, size, sizeHalf, strokeWidth, strokeColor }, anchorRef) => {
- const x = anchor.x;
- const y = anchor.y;
- const tipOffset = vectorMultiply(vectorClone(normal), size);
- const inset = vectorCreate(x + tipOffset.x, y + tipOffset.y);
- vectorMultiply(tipOffset, 0.55);
- if (solid) {
- // move back so arrow triangle overlaps with end of line (otherwise line sticks out of triangle tip)
- vectorAdd(anchorRef, offset);
- const arrowOffset = vectorMultiply(vectorClone(normal), sizeHalf * 0.5);
- return [
- {
- points: [
- vectorCreate(x - arrowOffset.x, y - arrowOffset.y),
- vectorCreate(inset.x - tipOffset.y, inset.y + tipOffset.x),
- vectorCreate(inset.x + tipOffset.y, inset.y - tipOffset.x),
- ],
- backgroundColor: strokeColor,
- },
- ];
- }
- else {
- // this prevents trouble with sharp line rendering in webgl
- const p = vectorMultiply(vectorPerpendicular(vectorClone(normal)), 0.5);
- const tipLeft = vectorCreate(x - p.x, y - p.y);
- const tipRight = vectorCreate(x + p.x, y + p.y);
- return [
- {
- points: [
- vectorCreate(inset.x + tipOffset.y, inset.y - tipOffset.x),
- tipLeft,
- vectorCreate(x, y),
- tipRight,
- vectorCreate(inset.x - tipOffset.y, inset.y + tipOffset.x),
- ],
- strokeWidth: strokeWidth,
- strokeColor: strokeColor,
- },
- ];
- }
- };
- const lineEndStyleCircle = ({ anchor, solid, offset, normal, sizeHalf, strokeWidth, strokeColor }, anchorRef) => {
- // update anchor point position
- vectorAdd(anchorRef, offset);
- // if solid, move line slightly towards circle as to make them overlap
- if (solid)
- vectorAdd(anchorRef, vectorInvert(vectorClone(normal)));
- return [
- {
- x: anchor.x,
- y: anchor.y,
- rx: sizeHalf,
- ry: sizeHalf,
- backgroundColor: solid ? strokeColor : undefined,
- strokeWidth: solid ? undefined : strokeWidth,
- strokeColor: solid ? undefined : strokeColor,
- },
- ];
- };
- const lineEndStyleBar = ({ anchor, offset, strokeWidth, strokeColor }) => {
- return [
- {
- points: [
- vectorCreate(anchor.x - offset.y, anchor.y + offset.x),
- vectorCreate(anchor.x + offset.y, anchor.y - offset.x),
- ],
- strokeWidth,
- strokeColor,
- },
- ];
- };
- const lineEndStyleSquare = ({ anchor, solid, offset, normal, sizeHalf, strokeWidth, strokeColor }, anchorRef) => {
- // update anchor point position
- vectorAdd(anchorRef, offset);
- return [
- {
- x: anchor.x - sizeHalf,
- y: anchor.y - sizeHalf,
- width: sizeHalf * 2,
- height: sizeHalf * 2,
- rotation: vectorAngle(normal),
- backgroundColor: solid ? strokeColor : undefined,
- strokeWidth: solid ? undefined : strokeWidth,
- strokeColor: solid ? undefined : strokeColor,
- },
- ];
- };
- // this method parses the shape and checks if lineStart or lineEnd is being used
- const createLineEndProcessor = (styles = {}) => (shape) => {
- if (!hasProp(shape, 'lineStart') && !hasProp(shape, 'lineEnd'))
- return;
- // resulting shapes
- const res = [];
- const { lineStart, lineEnd, strokeWidth, strokeColor } = shape;
- const start = vectorCreate(shape.x1, shape.y1);
- const end = vectorCreate(shape.x2, shape.y2);
- const points = [start, end];
- // handle lineStart
- if (lineStart) {
- const [style, solid] = lineStart.split('-');
- const process = styles[style];
- if (process) {
- const params = getLineEndParams(start, end, strokeWidth, !!solid);
- res.push(...process({
- ...params,
- strokeColor,
- strokeWidth,
- }, start));
- }
- }
- // handle lineEnd
- if (lineEnd) {
- const [style, solid] = lineEnd.split('-');
- const process = styles[style];
- if (process) {
- const params = getLineEndParams(end, start, strokeWidth, !!solid);
- res.push(...process({
- ...params,
- strokeColor,
- strokeWidth,
- }, end));
- }
- }
- return [
- // return inner path
- {
- points,
- strokeWidth,
- strokeColor,
- },
- // add line end styles
- ...res,
- ];
- };
- // the default line end styles available, can import and extend
- const createDefaultLineEndStyles = () => ({
- arrow: lineEndStyleArrow,
- circle: lineEndStyleCircle,
- square: lineEndStyleSquare,
- bar: lineEndStyleBar,
- });
- const safeFactor = (value, factor) => {
- const v = parseFloat(value) * factor;
- return isString(value) ? `${v}%` : v;
- };
- const toValue = (value, total) => (isString(value) ? toPixelValue(value, total) : value);
- // const toFraction = (value, total) => toValue(value, total) / total;
- const frameStyleSolid = (shape) => [
- {
- ...shape,
- frameStyle: 'line',
- frameInset: 0,
- frameOffset: 0,
- frameSize: shape.frameSize ? safeFactor(shape.frameSize, 2) : '2.5%',
- frameRadius: shape.frameRound ? safeFactor(shape.frameSize, 2) : 0,
- },
- ];
- const frameStyleLine = ({ x, y, width, height, frameInset = '3.5%', frameSize = '.25%', frameColor = [1, 1, 1], frameOffset = '5%', frameAmount = 1, frameRadius = 0, expandsCanvas = false, }, { isPreview }) => {
- const size = Math.sqrt(width * height);
- let frameSizeValue = toValue(frameSize, size);
- const frameInsetValue = toValue(frameInset, size);
- const frameOffsetValue = toValue(frameOffset, size);
- let center = 0;
- if (!isPreview) {
- frameSizeValue = Math.max(1, Math.round(frameSizeValue));
- center = frameSizeValue % 2 == 0 ? 0 : 0.5;
- }
- const r = toValue(safeFactor(frameRadius, frameAmount), size);
- return new Array(frameAmount).fill(undefined).map((_, index) => {
- const offset = frameOffsetValue * index;
- let left = x + frameInsetValue + offset;
- let top = y + frameInsetValue + offset;
- let right = x + width - frameInsetValue - offset;
- let bottom = y + height - frameInsetValue - offset;
- if (!isPreview) {
- left = Math.round(left);
- top = Math.round(top);
- right = Math.round(right);
- bottom = Math.round(bottom);
- }
- const radius = r > 0 ? r - offset : 0;
- return {
- x: left + center,
- y: top + center,
- width: right - left,
- height: bottom - top,
- cornerRadius: radius,
- strokeWidth: frameSizeValue,
- strokeColor: frameColor,
- expandsCanvas,
- };
- });
- };
- const frameStyleEdge = ({ x, y, width, height, frameSize = '.25%', frameOffset = 0, frameInset = '2.5%', frameColor = [1, 1, 1], }, { isPreview }) => {
- const size = Math.sqrt(width * height);
- let frameSizeValue = toValue(frameSize, size);
- let frameInsetValue = toValue(frameInset, size);
- let frameOffsetValue = toValue(frameOffset, size);
- let center = 0;
- if (!isPreview) {
- frameSizeValue = Math.max(1, Math.round(frameSizeValue));
- frameInsetValue = Math.round(frameInsetValue);
- frameOffsetValue = Math.round(frameOffsetValue);
- center = frameSizeValue % 2 == 0 ? 0 : 0.5;
- }
- const offset = frameOffsetValue - frameInsetValue;
- const left = x + frameInsetValue + center;
- const top = y + frameInsetValue + center;
- const right = x + width - frameInsetValue - center;
- const bottom = y + height - frameInsetValue - center;
- return [
- // top
- {
- points: [vectorCreate(left + offset, top), vectorCreate(right - offset, top)],
- },
- {
- points: [vectorCreate(right, top + offset), vectorCreate(right, bottom - offset)],
- },
- {
- points: [vectorCreate(right - offset, bottom), vectorCreate(left + offset, bottom)],
- },
- {
- points: [vectorCreate(left, bottom - offset), vectorCreate(left, top + offset)],
- },
- ].map((shape) => {
- shape.strokeWidth = frameSizeValue;
- shape.strokeColor = frameColor;
- return shape;
- });
- };
- const frameStyleHook = ({ x, y, width, height, frameSize = '.25%', frameInset = '2.5%', frameLength = '2.5%', frameColor = [1, 1, 1], }, { isPreview }) => {
- const size = Math.sqrt(width * height);
- let frameSizeValue = toValue(frameSize, size);
- let frameInsetValue = toValue(frameInset, size);
- let frameLengthValue = toValue(frameLength, size);
- let center = 0;
- if (!isPreview) {
- frameSizeValue = Math.max(1, Math.round(frameSizeValue));
- frameInsetValue = Math.round(frameInsetValue);
- frameLengthValue = Math.round(frameLengthValue);
- center = frameSizeValue % 2 == 0 ? 0 : 0.5;
- }
- const left = x + frameInsetValue + center;
- const top = y + frameInsetValue + center;
- const right = x + width - frameInsetValue - center;
- const bottom = y + height - frameInsetValue - center;
- return [
- // top
- {
- points: [
- vectorCreate(left, top + frameLengthValue),
- vectorCreate(left, top),
- vectorCreate(left + frameLengthValue, top),
- ],
- },
- {
- points: [
- vectorCreate(right - frameLengthValue, top),
- vectorCreate(right, top),
- vectorCreate(right, top + frameLengthValue),
- ],
- },
- {
- points: [
- vectorCreate(right, bottom - frameLengthValue),
- vectorCreate(right, bottom),
- vectorCreate(right - frameLengthValue, bottom),
- ],
- },
- {
- points: [
- vectorCreate(left + frameLengthValue, bottom),
- vectorCreate(left, bottom),
- vectorCreate(left, bottom - frameLengthValue),
- ],
- },
- ].map((shape) => {
- shape.strokeWidth = frameSizeValue;
- shape.strokeColor = frameColor;
- return shape;
- });
- };
- const frameStylePolaroid = ({ x, y, width, height, frameColor = [1, 1, 1] }, { isPreview }) => {
- const size = Math.sqrt(width * height);
- const borderWidth = 0.1 * size;
- let chinHeight = 0.2 * size;
- const borderWidthHalf = 0.5 * borderWidth;
- let strokeWidth = 0.0025 * size;
- if (!isPreview) {
- // borderWidthHalf = Math.round(borderWidthHalf);
- // borderWidth = Math.round(borderWidth);
- chinHeight = Math.ceil(chinHeight);
- strokeWidth = Math.max(2, strokeWidth);
- }
- // always remove opacity
- frameColor.length = 3;
- return [
- // border
- {
- id: 'border',
- x: x - borderWidthHalf,
- y: y - borderWidthHalf,
- width: width + borderWidth,
- height: height + chinHeight,
- frameStyle: 'line',
- frameInset: 0,
- frameOffset: 0,
- frameSize: borderWidth,
- frameColor,
- expandsCanvas: true,
- },
- // chin
- {
- id: 'chin',
- x: x - borderWidthHalf,
- y: height,
- width: width + borderWidth,
- height: chinHeight,
- backgroundColor: frameColor,
- expandsCanvas: true,
- },
- // for preview only
- isPreview && {
- x,
- y,
- width,
- height,
- strokeWidth,
- strokeColor: frameColor,
- },
- ].filter(Boolean);
- };
- const createFrameStyleProcessor = (styles = {}) => (shape, options) => {
- // handle solid frameStyle
- if (!hasProp(shape, 'frameStyle'))
- return;
- const style = shape.frameStyle;
- // get parser for style
- const process = styles[style];
- if (!process)
- return;
- // remove frameStyle property so we don't get endless looops
- const { frameStyle, ...shapeReadyToParse } = shape;
- return process(shapeReadyToParse, options);
- };
- // the default frame styles available, can import and extend
- const createDefaultFrameStyles = () => ({
- solid: frameStyleSolid,
- hook: frameStyleHook,
- line: frameStyleLine,
- edge: frameStyleEdge,
- polaroid: frameStylePolaroid,
- });
- // the default lineEnd parser to use
- const createDefaultLineEndProcessors = () => createLineEndProcessor(createDefaultLineEndStyles());
- const createDefaultFrameStyleProcessor = () => createFrameStyleProcessor(createDefaultFrameStyles());
- const createDefaultShapeProcessors = () => [
- createDefaultFrameStyleProcessor(),
- createDefaultLineEndProcessors(),
- ];
- const createShapePreprocessor$1 = (processors) => {
- const processShape = (shape, options = { isPreview: true }) => {
- const res = processors
- .map((process) => {
- const res = process(shape, options);
- // processor wasn't a match?
- if (!res)
- return;
- return res.map((shape) => processShape(shape, options));
- })
- .filter(Boolean)
- .flat();
- return !res.length ? shape : res.flat();
- };
- return processShape;
- };
- const createDefaultImageReader = createDefaultImageReader$1;
- const createDefaultImageWriter = createDefaultImageWriter$1;
- const createDefaultImageOrienter = () => ({
- read: getImageOrientationFromFile,
- apply: orientImageData,
- });
- const createDefaultImageScrambler = (configurationOptions = {}) => {
- // default configuration
- const { blurAmount, scrambleAmount, enableSmoothing, backgroundColor } = configurationOptions;
- // as called from editor ui
- return (imageData, uiOptions) =>
- imageDataScramble(imageData, {
- blurAmount,
- scrambleAmount,
- enableSmoothing,
- backgroundColor,
- ...uiOptions,
- });
- };
- const createEditor = createImageEditor;
- const getEditorProps = () => getEditorProps$1().concat(getEditorViewProps()); // private api for framework components
- const createMarkupEditorToolbar = createToolbar;
- const createMarkupEditorToolStyles = createToolStyles;
- // markup editor style controls
- const createMarkupEditorShapeStyleControls = createShapeStyleControls;
- const markup_editor_defaults = {
- markupEditorToolbar: createToolbar(),
- markupEditorToolStyles: createToolStyles(),
- markupEditorShapeStyleControls: createShapeStyleControls(),
- };
- const setPlugins = setEditorViewPlugins;
- const plugin_crop = _plugin_crop;
- const plugin_filter = _plugin_filter;
- const plugin_finetune = _plugin_finetune;
- const plugin_annotate = _plugin_annotate;
- const plugin_decorate = _plugin_decorate;
- const plugin_sticker = _plugin_sticker;
- const plugin_frame = _plugin_frame;
- const plugin_redact = _plugin_redact;
- const plugin_resize = _plugin_resize;
- const plugin_finetune_defaults = _plugin_finetune_defaults;
- const plugin_filter_defaults = _plugin_filter_defaults;
- const plugin_frame_defaults = _plugin_frame_defaults;
- const locale_en_gb = _locale_en_gb;
- const markup_editor_locale_en_gb = MarkupEditor;
- const plugin_crop_locale_en_gb = _plugin_crop_locale_en_gb;
- const plugin_filter_locale_en_gb = _plugin_filter_locale_en_gb;
- const plugin_finetune_locale_en_gb = _plugin_finetune_locale_en_gb;
- const plugin_resize_locale_en_gb = _plugin_resize_locale_en_gb;
- const plugin_decorate_locale_en_gb = _plugin_decorate_locale_en_gb;
- const plugin_annotate_locale_en_gb = _plugin_annotate_locale_en_gb;
- const plugin_sticker_locale_en_gb = _plugin_sticker_locale_en_gb;
- const plugin_frame_locale_en_gb = _plugin_frame_locale_en_gb;
- const plugin_redact_locale_en_gb = _plugin_redact_locale_en_gb;
- const elementsToEditor = (factory, targets, options = {}) => {
- const elements = isString(targets) ? Array.from(document.querySelectorAll(targets)) : targets;
- return elements.filter(Boolean).map((element) => factory(element, deepCopy(options)));
- };
- const appendEditor = _appendEditor;
- const openEditor = _openEditor;
- const overlayEditor = _overlayEditor;
- const appendEditors = (targets, options) => elementsToEditor(appendEditor, targets, options);
- const getEditorDefaultReadWriteOptions = (options = {}) => {
- // allow passing reader / writer / scrambler options as object
- let readerProps = undefined;
- if (!Array.isArray(options.imageWriter)) {
- readerProps = options.imageWriter;
- delete options.imageReader;
- }
- let writerProps = undefined;
- if (!Array.isArray(options.imageWriter)) {
- writerProps = options.imageWriter;
- delete options.imageWriter;
- }
- let scramblerProps = undefined;
- if (!isFunction(options.imageScrambler)) {
- scramblerProps = options.imageScrambler;
- delete options.imageScrambler;
- }
- return {
- // default handling of images
- imageReader: createDefaultImageReader(readerProps),
- imageWriter: createDefaultImageWriter(writerProps),
- imageOrienter: createDefaultImageOrienter(),
- imageScrambler: createDefaultImageScrambler(scramblerProps),
- };
- };
- const createShapePreprocessor = createShapePreprocessor$1;
- const createDefaultShapePreprocessor = () =>
- createShapePreprocessor$1(createDefaultShapeProcessors());
- const processDefaultImage = (src, options = {}) =>
- processImage(src, { ...getEditorDefaultReadWriteOptions(options), ...options });
- const getEditorDefaults = (options = {}) => {
- // load all plugins
- setEditorViewPlugins(
- ...[
- plugin_crop,
- plugin_filter,
- plugin_finetune,
- plugin_annotate,
- plugin_decorate,
- plugin_sticker,
- plugin_frame,
- plugin_redact,
- plugin_resize,
- ].filter(Boolean)
- );
- // auto hide stickers util if no stickers defined
- const utils = [
- 'crop',
- 'filter',
- 'finetune',
- 'annotate',
- 'decorate',
- options.stickers && 'sticker',
- 'frame',
- 'redact',
- 'resize',
- ].filter(Boolean);
- // get default read/write options object
- const defaultReadWriteOptions = getEditorDefaultReadWriteOptions(options);
- // locale
- const locale = {
- ...locale_en_gb,
- ...markup_editor_locale_en_gb,
- ...plugin_crop_locale_en_gb,
- ...plugin_filter_locale_en_gb,
- ...plugin_finetune_locale_en_gb,
- ...plugin_frame_locale_en_gb,
- ...plugin_redact_locale_en_gb,
- ...plugin_resize_locale_en_gb,
- ...plugin_decorate_locale_en_gb,
- ...plugin_annotate_locale_en_gb,
- ...plugin_sticker_locale_en_gb,
- ...options.locale,
- };
- delete options.locale;
- // create huge config object
- return mergeObjects([
- {
- // set reader / writer / orienter
- ...defaultReadWriteOptions,
- // shape preprocessor
- shapePreprocessor: createDefaultShapePreprocessor(),
- // default utils
- utils,
- // default plugin options
- ...plugin_finetune_defaults,
- ...plugin_filter_defaults,
- ...plugin_frame_defaults,
- ...markup_editor_defaults,
- // stickers stick to image by default
- stickerStickToImage: true,
- // locale
- locale,
- },
- options,
- ]);
- };
- const defineCustomElements = async (options = {}) => {
- const elements = await _defineCustomElements();
- elements.forEach((editor) => Object.assign(editor, deepCopy(options)));
- return elements;
- };
- const defineDefaultCustomElements = (options) =>
- defineCustomElements(getEditorDefaults(options));
- const openDefaultEditor = (options) => openEditor(getEditorDefaults(options));
- const appendDefaultEditor = (element, options) =>
- appendEditor(element, getEditorDefaults(options));
- const overlayDefaultEditor = (element, options) =>
- overlayEditor(element, getEditorDefaults(options));
- const appendDefaultEditors = (targets, options) =>
- elementsToEditor(appendDefaultEditor, targets, options);
- export { appendDefaultEditor, appendDefaultEditors, appendEditor, appendEditors, appendNode, blobToFile, colorStringToColorArray, createDefaultColorOptions, createDefaultFontFamilyOptions, createDefaultFontScaleOptions, createDefaultFontSizeOptions, createDefaultFontStyleOptions, createDefaultImageOrienter, createDefaultImageReader, createDefaultImageScrambler, createDefaultImageWriter, createDefaultLineEndStyleOptions, createDefaultShapePreprocessor, createDefaultStrokeScaleOptions, createDefaultStrokeWidthOptions, createDefaultTextAlignOptions, createEditor, createBackgroundColorControl as createMarkupEditorBackgroundColorControl, createColorControl as createMarkupEditorColorControl, createColorOptions as createMarkupEditorColorOptions, createFontColorControl as createMarkupEditorFontColorControl, createFontFamilyControl as createMarkupEditorFontFamilyControl, createFontFamilyOptions as createMarkupEditorFontFamilyOptions, createFontScaleOptions as createMarkupEditorFontScaleOptions, createFontSizeControl as createMarkupEditorFontSizeControl, createFontSizeOptions as createMarkupEditorFontSizeOptions, createFontStyleControl as createMarkupEditorFontStyleControl, createFontStyleOptions as createMarkupEditorFontStyleOptions, createLineEndStyleControl as createMarkupEditorLineEndStyleControl, createLineEndStyleOptions as createMarkupEditorLineEndStyleOptions, createLineHeightControl as createMarkupEditorLineHeightControl, createLineStartStyleControl as createMarkupEditorLineStartStyleControl, createMarkupEditorShapeStyleControls, createStrokeColorControl as createMarkupEditorStrokeColorControl, createStrokeScaleOptions as createMarkupEditorStrokeScaleOptions, createStrokeWidthControl as createMarkupEditorStrokeWidthControl, createStrokeWidthOptions as createMarkupEditorStrokeWidthOptions, createTextAlignControl as createMarkupEditorTextAlignControl, createToolStyle as createMarkupEditorToolStyle, createMarkupEditorToolStyles, createMarkupEditorToolbar, createNode, createShapePreprocessor, defineCustomElements, defineDefaultCustomElements, degToRad, dispatchEditorEvents, brightness as effectBrightness, clarity as effectClarity, contrast as effectContrast, exposure as effectExposure, gamma as effectGamma, saturation as effectSaturation, temperature as effectTemperature, vignette as effectVignette, chrome as filterChrome, cold as filterCold, fade as filterFade, invert as filterInvert, monoDefault as filterMonoDefault, monoNoir as filterMonoNoir, monoStark as filterMonoStark, monoWash as filterMonoWash, pastel as filterPastel, sepiaBlues as filterSepiaBlues, sepiaColor as filterSepiaColor, sepiaDefault as filterSepiaDefault, sepiaRust as filterSepiaRust, warm as filterWarm, findNode, edgeCross as frameEdgeCross, edgeOverlap as frameEdgeOverlap, edgeSeparate as frameEdgeSeparate, hook as frameHook, lineMultiple as frameLineMultiple, lineSingle as frameLineSingle, polaroid as framePolaroid, solidRound as frameSolidRound, solidSharp as frameSolidSharp, getEditorDefaults, getEditorProps, insertNodeAfter, insertNodeBefore, isModernBrowser as isSupported, legacyDataToImageState, locale_en_gb, markup_editor_defaults, markup_editor_locale_en_gb, openDefaultEditor, openEditor, overlayDefaultEditor, overlayEditor, plugin_annotate, plugin_annotate_locale_en_gb, plugin_crop, plugin_crop_locale_en_gb, plugin_decorate, plugin_decorate_locale_en_gb, plugin_filter, plugin_filter_defaults, plugin_filter_locale_en_gb, plugin_finetune, plugin_finetune_defaults, plugin_finetune_locale_en_gb, plugin_frame, plugin_frame_defaults, plugin_frame_locale_en_gb, plugin_redact, plugin_redact_locale_en_gb, plugin_resize, plugin_resize_locale_en_gb, plugin_sticker, plugin_sticker_locale_en_gb, processDefaultImage, processImage, removeNode, setPlugins, supportsWebGL };
|